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 for (Stmt *CC : C->children()) { 3692 if (CC) 3693 Visit(CC); 3694 } 3695 } 3696 } 3697 // Check implicitly captured variables. 3698 VisitSubCaptures(S); 3699 } 3700 void VisitStmt(Stmt *S) { 3701 for (Stmt *C : S->children()) { 3702 if (C) { 3703 // Check implicitly captured variables in the task-based directives to 3704 // check if they must be firstprivatized. 3705 Visit(C); 3706 } 3707 } 3708 } 3709 3710 void visitSubCaptures(CapturedStmt *S) { 3711 for (const CapturedStmt::Capture &Cap : S->captures()) { 3712 if (!Cap.capturesVariable() && !Cap.capturesVariableByCopy()) 3713 continue; 3714 VarDecl *VD = Cap.getCapturedVar(); 3715 // Do not try to map the variable if it or its sub-component was mapped 3716 // already. 3717 if (isOpenMPTargetExecutionDirective(Stack->getCurrentDirective()) && 3718 Stack->checkMappableExprComponentListsForDecl( 3719 VD, /*CurrentRegionOnly=*/true, 3720 [](OMPClauseMappableExprCommon::MappableExprComponentListRef, 3721 OpenMPClauseKind) { return true; })) 3722 continue; 3723 DeclRefExpr *DRE = buildDeclRefExpr( 3724 SemaRef, VD, VD->getType().getNonLValueExprType(SemaRef.Context), 3725 Cap.getLocation(), /*RefersToCapture=*/true); 3726 Visit(DRE); 3727 } 3728 } 3729 bool isErrorFound() const { return ErrorFound; } 3730 ArrayRef<Expr *> getImplicitFirstprivate() const { 3731 return ImplicitFirstprivate; 3732 } 3733 ArrayRef<Expr *> getImplicitMap(OpenMPDefaultmapClauseKind Kind) const { 3734 return ImplicitMap[Kind]; 3735 } 3736 const Sema::VarsWithInheritedDSAType &getVarsWithInheritedDSA() const { 3737 return VarsWithInheritedDSA; 3738 } 3739 3740 DSAAttrChecker(DSAStackTy *S, Sema &SemaRef, CapturedStmt *CS) 3741 : Stack(S), SemaRef(SemaRef), ErrorFound(false), CS(CS) { 3742 // Process declare target link variables for the target directives. 3743 if (isOpenMPTargetExecutionDirective(S->getCurrentDirective())) { 3744 for (DeclRefExpr *E : Stack->getLinkGlobals()) 3745 Visit(E); 3746 } 3747 } 3748 }; 3749 } // namespace 3750 3751 void Sema::ActOnOpenMPRegionStart(OpenMPDirectiveKind DKind, Scope *CurScope) { 3752 switch (DKind) { 3753 case OMPD_parallel: 3754 case OMPD_parallel_for: 3755 case OMPD_parallel_for_simd: 3756 case OMPD_parallel_sections: 3757 case OMPD_parallel_master: 3758 case OMPD_teams: 3759 case OMPD_teams_distribute: 3760 case OMPD_teams_distribute_simd: { 3761 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 3762 QualType KmpInt32PtrTy = 3763 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3764 Sema::CapturedParamNameType Params[] = { 3765 std::make_pair(".global_tid.", KmpInt32PtrTy), 3766 std::make_pair(".bound_tid.", KmpInt32PtrTy), 3767 std::make_pair(StringRef(), QualType()) // __context with shared vars 3768 }; 3769 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3770 Params); 3771 break; 3772 } 3773 case OMPD_target_teams: 3774 case OMPD_target_parallel: 3775 case OMPD_target_parallel_for: 3776 case OMPD_target_parallel_for_simd: 3777 case OMPD_target_teams_distribute: 3778 case OMPD_target_teams_distribute_simd: { 3779 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 3780 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 3781 QualType KmpInt32PtrTy = 3782 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3783 QualType Args[] = {VoidPtrTy}; 3784 FunctionProtoType::ExtProtoInfo EPI; 3785 EPI.Variadic = true; 3786 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 3787 Sema::CapturedParamNameType Params[] = { 3788 std::make_pair(".global_tid.", KmpInt32Ty), 3789 std::make_pair(".part_id.", KmpInt32PtrTy), 3790 std::make_pair(".privates.", VoidPtrTy), 3791 std::make_pair( 3792 ".copy_fn.", 3793 Context.getPointerType(CopyFnType).withConst().withRestrict()), 3794 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 3795 std::make_pair(StringRef(), QualType()) // __context with shared vars 3796 }; 3797 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3798 Params, /*OpenMPCaptureLevel=*/0); 3799 // Mark this captured region as inlined, because we don't use outlined 3800 // function directly. 3801 getCurCapturedRegion()->TheCapturedDecl->addAttr( 3802 AlwaysInlineAttr::CreateImplicit( 3803 Context, {}, AttributeCommonInfo::AS_Keyword, 3804 AlwaysInlineAttr::Keyword_forceinline)); 3805 Sema::CapturedParamNameType ParamsTarget[] = { 3806 std::make_pair(StringRef(), QualType()) // __context with shared vars 3807 }; 3808 // Start a captured region for 'target' with no implicit parameters. 3809 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3810 ParamsTarget, /*OpenMPCaptureLevel=*/1); 3811 Sema::CapturedParamNameType ParamsTeamsOrParallel[] = { 3812 std::make_pair(".global_tid.", KmpInt32PtrTy), 3813 std::make_pair(".bound_tid.", KmpInt32PtrTy), 3814 std::make_pair(StringRef(), QualType()) // __context with shared vars 3815 }; 3816 // Start a captured region for 'teams' or 'parallel'. Both regions have 3817 // the same implicit parameters. 3818 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3819 ParamsTeamsOrParallel, /*OpenMPCaptureLevel=*/2); 3820 break; 3821 } 3822 case OMPD_target: 3823 case OMPD_target_simd: { 3824 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 3825 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 3826 QualType KmpInt32PtrTy = 3827 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3828 QualType Args[] = {VoidPtrTy}; 3829 FunctionProtoType::ExtProtoInfo EPI; 3830 EPI.Variadic = true; 3831 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 3832 Sema::CapturedParamNameType Params[] = { 3833 std::make_pair(".global_tid.", KmpInt32Ty), 3834 std::make_pair(".part_id.", KmpInt32PtrTy), 3835 std::make_pair(".privates.", VoidPtrTy), 3836 std::make_pair( 3837 ".copy_fn.", 3838 Context.getPointerType(CopyFnType).withConst().withRestrict()), 3839 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 3840 std::make_pair(StringRef(), QualType()) // __context with shared vars 3841 }; 3842 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3843 Params, /*OpenMPCaptureLevel=*/0); 3844 // Mark this captured region as inlined, because we don't use outlined 3845 // function directly. 3846 getCurCapturedRegion()->TheCapturedDecl->addAttr( 3847 AlwaysInlineAttr::CreateImplicit( 3848 Context, {}, AttributeCommonInfo::AS_Keyword, 3849 AlwaysInlineAttr::Keyword_forceinline)); 3850 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3851 std::make_pair(StringRef(), QualType()), 3852 /*OpenMPCaptureLevel=*/1); 3853 break; 3854 } 3855 case OMPD_atomic: 3856 case OMPD_critical: 3857 case OMPD_section: 3858 case OMPD_master: 3859 break; 3860 case OMPD_simd: 3861 case OMPD_for: 3862 case OMPD_for_simd: 3863 case OMPD_sections: 3864 case OMPD_single: 3865 case OMPD_taskgroup: 3866 case OMPD_distribute: 3867 case OMPD_distribute_simd: 3868 case OMPD_ordered: 3869 case OMPD_target_data: { 3870 Sema::CapturedParamNameType Params[] = { 3871 std::make_pair(StringRef(), QualType()) // __context with shared vars 3872 }; 3873 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3874 Params); 3875 break; 3876 } 3877 case OMPD_task: { 3878 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 3879 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 3880 QualType KmpInt32PtrTy = 3881 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3882 QualType Args[] = {VoidPtrTy}; 3883 FunctionProtoType::ExtProtoInfo EPI; 3884 EPI.Variadic = true; 3885 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 3886 Sema::CapturedParamNameType Params[] = { 3887 std::make_pair(".global_tid.", KmpInt32Ty), 3888 std::make_pair(".part_id.", KmpInt32PtrTy), 3889 std::make_pair(".privates.", VoidPtrTy), 3890 std::make_pair( 3891 ".copy_fn.", 3892 Context.getPointerType(CopyFnType).withConst().withRestrict()), 3893 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 3894 std::make_pair(StringRef(), QualType()) // __context with shared vars 3895 }; 3896 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3897 Params); 3898 // Mark this captured region as inlined, because we don't use outlined 3899 // function directly. 3900 getCurCapturedRegion()->TheCapturedDecl->addAttr( 3901 AlwaysInlineAttr::CreateImplicit( 3902 Context, {}, AttributeCommonInfo::AS_Keyword, 3903 AlwaysInlineAttr::Keyword_forceinline)); 3904 break; 3905 } 3906 case OMPD_taskloop: 3907 case OMPD_taskloop_simd: 3908 case OMPD_master_taskloop: 3909 case OMPD_master_taskloop_simd: { 3910 QualType KmpInt32Ty = 3911 Context.getIntTypeForBitwidth(/*DestWidth=*/32, /*Signed=*/1) 3912 .withConst(); 3913 QualType KmpUInt64Ty = 3914 Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/0) 3915 .withConst(); 3916 QualType KmpInt64Ty = 3917 Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/1) 3918 .withConst(); 3919 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 3920 QualType KmpInt32PtrTy = 3921 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3922 QualType Args[] = {VoidPtrTy}; 3923 FunctionProtoType::ExtProtoInfo EPI; 3924 EPI.Variadic = true; 3925 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 3926 Sema::CapturedParamNameType Params[] = { 3927 std::make_pair(".global_tid.", KmpInt32Ty), 3928 std::make_pair(".part_id.", KmpInt32PtrTy), 3929 std::make_pair(".privates.", VoidPtrTy), 3930 std::make_pair( 3931 ".copy_fn.", 3932 Context.getPointerType(CopyFnType).withConst().withRestrict()), 3933 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 3934 std::make_pair(".lb.", KmpUInt64Ty), 3935 std::make_pair(".ub.", KmpUInt64Ty), 3936 std::make_pair(".st.", KmpInt64Ty), 3937 std::make_pair(".liter.", KmpInt32Ty), 3938 std::make_pair(".reductions.", VoidPtrTy), 3939 std::make_pair(StringRef(), QualType()) // __context with shared vars 3940 }; 3941 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3942 Params); 3943 // Mark this captured region as inlined, because we don't use outlined 3944 // function directly. 3945 getCurCapturedRegion()->TheCapturedDecl->addAttr( 3946 AlwaysInlineAttr::CreateImplicit( 3947 Context, {}, AttributeCommonInfo::AS_Keyword, 3948 AlwaysInlineAttr::Keyword_forceinline)); 3949 break; 3950 } 3951 case OMPD_parallel_master_taskloop: 3952 case OMPD_parallel_master_taskloop_simd: { 3953 QualType KmpInt32Ty = 3954 Context.getIntTypeForBitwidth(/*DestWidth=*/32, /*Signed=*/1) 3955 .withConst(); 3956 QualType KmpUInt64Ty = 3957 Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/0) 3958 .withConst(); 3959 QualType KmpInt64Ty = 3960 Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/1) 3961 .withConst(); 3962 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 3963 QualType KmpInt32PtrTy = 3964 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3965 Sema::CapturedParamNameType ParamsParallel[] = { 3966 std::make_pair(".global_tid.", KmpInt32PtrTy), 3967 std::make_pair(".bound_tid.", KmpInt32PtrTy), 3968 std::make_pair(StringRef(), QualType()) // __context with shared vars 3969 }; 3970 // Start a captured region for 'parallel'. 3971 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3972 ParamsParallel, /*OpenMPCaptureLevel=*/0); 3973 QualType Args[] = {VoidPtrTy}; 3974 FunctionProtoType::ExtProtoInfo EPI; 3975 EPI.Variadic = true; 3976 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 3977 Sema::CapturedParamNameType Params[] = { 3978 std::make_pair(".global_tid.", KmpInt32Ty), 3979 std::make_pair(".part_id.", KmpInt32PtrTy), 3980 std::make_pair(".privates.", VoidPtrTy), 3981 std::make_pair( 3982 ".copy_fn.", 3983 Context.getPointerType(CopyFnType).withConst().withRestrict()), 3984 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 3985 std::make_pair(".lb.", KmpUInt64Ty), 3986 std::make_pair(".ub.", KmpUInt64Ty), 3987 std::make_pair(".st.", KmpInt64Ty), 3988 std::make_pair(".liter.", KmpInt32Ty), 3989 std::make_pair(".reductions.", VoidPtrTy), 3990 std::make_pair(StringRef(), QualType()) // __context with shared vars 3991 }; 3992 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3993 Params, /*OpenMPCaptureLevel=*/1); 3994 // Mark this captured region as inlined, because we don't use outlined 3995 // function directly. 3996 getCurCapturedRegion()->TheCapturedDecl->addAttr( 3997 AlwaysInlineAttr::CreateImplicit( 3998 Context, {}, AttributeCommonInfo::AS_Keyword, 3999 AlwaysInlineAttr::Keyword_forceinline)); 4000 break; 4001 } 4002 case OMPD_distribute_parallel_for_simd: 4003 case OMPD_distribute_parallel_for: { 4004 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 4005 QualType KmpInt32PtrTy = 4006 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 4007 Sema::CapturedParamNameType Params[] = { 4008 std::make_pair(".global_tid.", KmpInt32PtrTy), 4009 std::make_pair(".bound_tid.", KmpInt32PtrTy), 4010 std::make_pair(".previous.lb.", Context.getSizeType().withConst()), 4011 std::make_pair(".previous.ub.", Context.getSizeType().withConst()), 4012 std::make_pair(StringRef(), QualType()) // __context with shared vars 4013 }; 4014 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 4015 Params); 4016 break; 4017 } 4018 case OMPD_target_teams_distribute_parallel_for: 4019 case OMPD_target_teams_distribute_parallel_for_simd: { 4020 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 4021 QualType KmpInt32PtrTy = 4022 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 4023 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 4024 4025 QualType Args[] = {VoidPtrTy}; 4026 FunctionProtoType::ExtProtoInfo EPI; 4027 EPI.Variadic = true; 4028 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 4029 Sema::CapturedParamNameType Params[] = { 4030 std::make_pair(".global_tid.", KmpInt32Ty), 4031 std::make_pair(".part_id.", KmpInt32PtrTy), 4032 std::make_pair(".privates.", VoidPtrTy), 4033 std::make_pair( 4034 ".copy_fn.", 4035 Context.getPointerType(CopyFnType).withConst().withRestrict()), 4036 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 4037 std::make_pair(StringRef(), QualType()) // __context with shared vars 4038 }; 4039 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 4040 Params, /*OpenMPCaptureLevel=*/0); 4041 // Mark this captured region as inlined, because we don't use outlined 4042 // function directly. 4043 getCurCapturedRegion()->TheCapturedDecl->addAttr( 4044 AlwaysInlineAttr::CreateImplicit( 4045 Context, {}, AttributeCommonInfo::AS_Keyword, 4046 AlwaysInlineAttr::Keyword_forceinline)); 4047 Sema::CapturedParamNameType ParamsTarget[] = { 4048 std::make_pair(StringRef(), QualType()) // __context with shared vars 4049 }; 4050 // Start a captured region for 'target' with no implicit parameters. 4051 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 4052 ParamsTarget, /*OpenMPCaptureLevel=*/1); 4053 4054 Sema::CapturedParamNameType ParamsTeams[] = { 4055 std::make_pair(".global_tid.", KmpInt32PtrTy), 4056 std::make_pair(".bound_tid.", KmpInt32PtrTy), 4057 std::make_pair(StringRef(), QualType()) // __context with shared vars 4058 }; 4059 // Start a captured region for 'target' with no implicit parameters. 4060 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 4061 ParamsTeams, /*OpenMPCaptureLevel=*/2); 4062 4063 Sema::CapturedParamNameType ParamsParallel[] = { 4064 std::make_pair(".global_tid.", KmpInt32PtrTy), 4065 std::make_pair(".bound_tid.", KmpInt32PtrTy), 4066 std::make_pair(".previous.lb.", Context.getSizeType().withConst()), 4067 std::make_pair(".previous.ub.", Context.getSizeType().withConst()), 4068 std::make_pair(StringRef(), QualType()) // __context with shared vars 4069 }; 4070 // Start a captured region for 'teams' or 'parallel'. Both regions have 4071 // the same implicit parameters. 4072 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 4073 ParamsParallel, /*OpenMPCaptureLevel=*/3); 4074 break; 4075 } 4076 4077 case OMPD_teams_distribute_parallel_for: 4078 case OMPD_teams_distribute_parallel_for_simd: { 4079 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 4080 QualType KmpInt32PtrTy = 4081 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 4082 4083 Sema::CapturedParamNameType ParamsTeams[] = { 4084 std::make_pair(".global_tid.", KmpInt32PtrTy), 4085 std::make_pair(".bound_tid.", KmpInt32PtrTy), 4086 std::make_pair(StringRef(), QualType()) // __context with shared vars 4087 }; 4088 // Start a captured region for 'target' with no implicit parameters. 4089 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 4090 ParamsTeams, /*OpenMPCaptureLevel=*/0); 4091 4092 Sema::CapturedParamNameType ParamsParallel[] = { 4093 std::make_pair(".global_tid.", KmpInt32PtrTy), 4094 std::make_pair(".bound_tid.", KmpInt32PtrTy), 4095 std::make_pair(".previous.lb.", Context.getSizeType().withConst()), 4096 std::make_pair(".previous.ub.", Context.getSizeType().withConst()), 4097 std::make_pair(StringRef(), QualType()) // __context with shared vars 4098 }; 4099 // Start a captured region for 'teams' or 'parallel'. Both regions have 4100 // the same implicit parameters. 4101 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 4102 ParamsParallel, /*OpenMPCaptureLevel=*/1); 4103 break; 4104 } 4105 case OMPD_target_update: 4106 case OMPD_target_enter_data: 4107 case OMPD_target_exit_data: { 4108 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 4109 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 4110 QualType KmpInt32PtrTy = 4111 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 4112 QualType Args[] = {VoidPtrTy}; 4113 FunctionProtoType::ExtProtoInfo EPI; 4114 EPI.Variadic = true; 4115 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 4116 Sema::CapturedParamNameType Params[] = { 4117 std::make_pair(".global_tid.", KmpInt32Ty), 4118 std::make_pair(".part_id.", KmpInt32PtrTy), 4119 std::make_pair(".privates.", VoidPtrTy), 4120 std::make_pair( 4121 ".copy_fn.", 4122 Context.getPointerType(CopyFnType).withConst().withRestrict()), 4123 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 4124 std::make_pair(StringRef(), QualType()) // __context with shared vars 4125 }; 4126 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 4127 Params); 4128 // Mark this captured region as inlined, because we don't use outlined 4129 // function directly. 4130 getCurCapturedRegion()->TheCapturedDecl->addAttr( 4131 AlwaysInlineAttr::CreateImplicit( 4132 Context, {}, AttributeCommonInfo::AS_Keyword, 4133 AlwaysInlineAttr::Keyword_forceinline)); 4134 break; 4135 } 4136 case OMPD_threadprivate: 4137 case OMPD_allocate: 4138 case OMPD_taskyield: 4139 case OMPD_barrier: 4140 case OMPD_taskwait: 4141 case OMPD_cancellation_point: 4142 case OMPD_cancel: 4143 case OMPD_flush: 4144 case OMPD_depobj: 4145 case OMPD_scan: 4146 case OMPD_declare_reduction: 4147 case OMPD_declare_mapper: 4148 case OMPD_declare_simd: 4149 case OMPD_declare_target: 4150 case OMPD_end_declare_target: 4151 case OMPD_requires: 4152 case OMPD_declare_variant: 4153 case OMPD_begin_declare_variant: 4154 case OMPD_end_declare_variant: 4155 llvm_unreachable("OpenMP Directive is not allowed"); 4156 case OMPD_unknown: 4157 default: 4158 llvm_unreachable("Unknown OpenMP directive"); 4159 } 4160 DSAStack->setContext(CurContext); 4161 } 4162 4163 int Sema::getNumberOfConstructScopes(unsigned Level) const { 4164 return getOpenMPCaptureLevels(DSAStack->getDirective(Level)); 4165 } 4166 4167 int Sema::getOpenMPCaptureLevels(OpenMPDirectiveKind DKind) { 4168 SmallVector<OpenMPDirectiveKind, 4> CaptureRegions; 4169 getOpenMPCaptureRegions(CaptureRegions, DKind); 4170 return CaptureRegions.size(); 4171 } 4172 4173 static OMPCapturedExprDecl *buildCaptureDecl(Sema &S, IdentifierInfo *Id, 4174 Expr *CaptureExpr, bool WithInit, 4175 bool AsExpression) { 4176 assert(CaptureExpr); 4177 ASTContext &C = S.getASTContext(); 4178 Expr *Init = AsExpression ? CaptureExpr : CaptureExpr->IgnoreImpCasts(); 4179 QualType Ty = Init->getType(); 4180 if (CaptureExpr->getObjectKind() == OK_Ordinary && CaptureExpr->isGLValue()) { 4181 if (S.getLangOpts().CPlusPlus) { 4182 Ty = C.getLValueReferenceType(Ty); 4183 } else { 4184 Ty = C.getPointerType(Ty); 4185 ExprResult Res = 4186 S.CreateBuiltinUnaryOp(CaptureExpr->getExprLoc(), UO_AddrOf, Init); 4187 if (!Res.isUsable()) 4188 return nullptr; 4189 Init = Res.get(); 4190 } 4191 WithInit = true; 4192 } 4193 auto *CED = OMPCapturedExprDecl::Create(C, S.CurContext, Id, Ty, 4194 CaptureExpr->getBeginLoc()); 4195 if (!WithInit) 4196 CED->addAttr(OMPCaptureNoInitAttr::CreateImplicit(C)); 4197 S.CurContext->addHiddenDecl(CED); 4198 S.AddInitializerToDecl(CED, Init, /*DirectInit=*/false); 4199 return CED; 4200 } 4201 4202 static DeclRefExpr *buildCapture(Sema &S, ValueDecl *D, Expr *CaptureExpr, 4203 bool WithInit) { 4204 OMPCapturedExprDecl *CD; 4205 if (VarDecl *VD = S.isOpenMPCapturedDecl(D)) 4206 CD = cast<OMPCapturedExprDecl>(VD); 4207 else 4208 CD = buildCaptureDecl(S, D->getIdentifier(), CaptureExpr, WithInit, 4209 /*AsExpression=*/false); 4210 return buildDeclRefExpr(S, CD, CD->getType().getNonReferenceType(), 4211 CaptureExpr->getExprLoc()); 4212 } 4213 4214 static ExprResult buildCapture(Sema &S, Expr *CaptureExpr, DeclRefExpr *&Ref) { 4215 CaptureExpr = S.DefaultLvalueConversion(CaptureExpr).get(); 4216 if (!Ref) { 4217 OMPCapturedExprDecl *CD = buildCaptureDecl( 4218 S, &S.getASTContext().Idents.get(".capture_expr."), CaptureExpr, 4219 /*WithInit=*/true, /*AsExpression=*/true); 4220 Ref = buildDeclRefExpr(S, CD, CD->getType().getNonReferenceType(), 4221 CaptureExpr->getExprLoc()); 4222 } 4223 ExprResult Res = Ref; 4224 if (!S.getLangOpts().CPlusPlus && 4225 CaptureExpr->getObjectKind() == OK_Ordinary && CaptureExpr->isGLValue() && 4226 Ref->getType()->isPointerType()) { 4227 Res = S.CreateBuiltinUnaryOp(CaptureExpr->getExprLoc(), UO_Deref, Ref); 4228 if (!Res.isUsable()) 4229 return ExprError(); 4230 } 4231 return S.DefaultLvalueConversion(Res.get()); 4232 } 4233 4234 namespace { 4235 // OpenMP directives parsed in this section are represented as a 4236 // CapturedStatement with an associated statement. If a syntax error 4237 // is detected during the parsing of the associated statement, the 4238 // compiler must abort processing and close the CapturedStatement. 4239 // 4240 // Combined directives such as 'target parallel' have more than one 4241 // nested CapturedStatements. This RAII ensures that we unwind out 4242 // of all the nested CapturedStatements when an error is found. 4243 class CaptureRegionUnwinderRAII { 4244 private: 4245 Sema &S; 4246 bool &ErrorFound; 4247 OpenMPDirectiveKind DKind = OMPD_unknown; 4248 4249 public: 4250 CaptureRegionUnwinderRAII(Sema &S, bool &ErrorFound, 4251 OpenMPDirectiveKind DKind) 4252 : S(S), ErrorFound(ErrorFound), DKind(DKind) {} 4253 ~CaptureRegionUnwinderRAII() { 4254 if (ErrorFound) { 4255 int ThisCaptureLevel = S.getOpenMPCaptureLevels(DKind); 4256 while (--ThisCaptureLevel >= 0) 4257 S.ActOnCapturedRegionError(); 4258 } 4259 } 4260 }; 4261 } // namespace 4262 4263 void Sema::tryCaptureOpenMPLambdas(ValueDecl *V) { 4264 // Capture variables captured by reference in lambdas for target-based 4265 // directives. 4266 if (!CurContext->isDependentContext() && 4267 (isOpenMPTargetExecutionDirective(DSAStack->getCurrentDirective()) || 4268 isOpenMPTargetDataManagementDirective( 4269 DSAStack->getCurrentDirective()))) { 4270 QualType Type = V->getType(); 4271 if (const auto *RD = Type.getCanonicalType() 4272 .getNonReferenceType() 4273 ->getAsCXXRecordDecl()) { 4274 bool SavedForceCaptureByReferenceInTargetExecutable = 4275 DSAStack->isForceCaptureByReferenceInTargetExecutable(); 4276 DSAStack->setForceCaptureByReferenceInTargetExecutable( 4277 /*V=*/true); 4278 if (RD->isLambda()) { 4279 llvm::DenseMap<const VarDecl *, FieldDecl *> Captures; 4280 FieldDecl *ThisCapture; 4281 RD->getCaptureFields(Captures, ThisCapture); 4282 for (const LambdaCapture &LC : RD->captures()) { 4283 if (LC.getCaptureKind() == LCK_ByRef) { 4284 VarDecl *VD = LC.getCapturedVar(); 4285 DeclContext *VDC = VD->getDeclContext(); 4286 if (!VDC->Encloses(CurContext)) 4287 continue; 4288 MarkVariableReferenced(LC.getLocation(), VD); 4289 } else if (LC.getCaptureKind() == LCK_This) { 4290 QualType ThisTy = getCurrentThisType(); 4291 if (!ThisTy.isNull() && 4292 Context.typesAreCompatible(ThisTy, ThisCapture->getType())) 4293 CheckCXXThisCapture(LC.getLocation()); 4294 } 4295 } 4296 } 4297 DSAStack->setForceCaptureByReferenceInTargetExecutable( 4298 SavedForceCaptureByReferenceInTargetExecutable); 4299 } 4300 } 4301 } 4302 4303 static bool checkOrderedOrderSpecified(Sema &S, 4304 const ArrayRef<OMPClause *> Clauses) { 4305 const OMPOrderedClause *Ordered = nullptr; 4306 const OMPOrderClause *Order = nullptr; 4307 4308 for (const OMPClause *Clause : Clauses) { 4309 if (Clause->getClauseKind() == OMPC_ordered) 4310 Ordered = cast<OMPOrderedClause>(Clause); 4311 else if (Clause->getClauseKind() == OMPC_order) { 4312 Order = cast<OMPOrderClause>(Clause); 4313 if (Order->getKind() != OMPC_ORDER_concurrent) 4314 Order = nullptr; 4315 } 4316 if (Ordered && Order) 4317 break; 4318 } 4319 4320 if (Ordered && Order) { 4321 S.Diag(Order->getKindKwLoc(), 4322 diag::err_omp_simple_clause_incompatible_with_ordered) 4323 << getOpenMPClauseName(OMPC_order) 4324 << getOpenMPSimpleClauseTypeName(OMPC_order, OMPC_ORDER_concurrent) 4325 << SourceRange(Order->getBeginLoc(), Order->getEndLoc()); 4326 S.Diag(Ordered->getBeginLoc(), diag::note_omp_ordered_param) 4327 << 0 << SourceRange(Ordered->getBeginLoc(), Ordered->getEndLoc()); 4328 return true; 4329 } 4330 return false; 4331 } 4332 4333 StmtResult Sema::ActOnOpenMPRegionEnd(StmtResult S, 4334 ArrayRef<OMPClause *> Clauses) { 4335 if (DSAStack->getCurrentDirective() == OMPD_atomic || 4336 DSAStack->getCurrentDirective() == OMPD_critical || 4337 DSAStack->getCurrentDirective() == OMPD_section || 4338 DSAStack->getCurrentDirective() == OMPD_master) 4339 return S; 4340 4341 bool ErrorFound = false; 4342 CaptureRegionUnwinderRAII CaptureRegionUnwinder( 4343 *this, ErrorFound, DSAStack->getCurrentDirective()); 4344 if (!S.isUsable()) { 4345 ErrorFound = true; 4346 return StmtError(); 4347 } 4348 4349 SmallVector<OpenMPDirectiveKind, 4> CaptureRegions; 4350 getOpenMPCaptureRegions(CaptureRegions, DSAStack->getCurrentDirective()); 4351 OMPOrderedClause *OC = nullptr; 4352 OMPScheduleClause *SC = nullptr; 4353 SmallVector<const OMPLinearClause *, 4> LCs; 4354 SmallVector<const OMPClauseWithPreInit *, 4> PICs; 4355 // This is required for proper codegen. 4356 for (OMPClause *Clause : Clauses) { 4357 if (!LangOpts.OpenMPSimd && 4358 isOpenMPTaskingDirective(DSAStack->getCurrentDirective()) && 4359 Clause->getClauseKind() == OMPC_in_reduction) { 4360 // Capture taskgroup task_reduction descriptors inside the tasking regions 4361 // with the corresponding in_reduction items. 4362 auto *IRC = cast<OMPInReductionClause>(Clause); 4363 for (Expr *E : IRC->taskgroup_descriptors()) 4364 if (E) 4365 MarkDeclarationsReferencedInExpr(E); 4366 } 4367 if (isOpenMPPrivate(Clause->getClauseKind()) || 4368 Clause->getClauseKind() == OMPC_copyprivate || 4369 (getLangOpts().OpenMPUseTLS && 4370 getASTContext().getTargetInfo().isTLSSupported() && 4371 Clause->getClauseKind() == OMPC_copyin)) { 4372 DSAStack->setForceVarCapturing(Clause->getClauseKind() == OMPC_copyin); 4373 // Mark all variables in private list clauses as used in inner region. 4374 for (Stmt *VarRef : Clause->children()) { 4375 if (auto *E = cast_or_null<Expr>(VarRef)) { 4376 MarkDeclarationsReferencedInExpr(E); 4377 } 4378 } 4379 DSAStack->setForceVarCapturing(/*V=*/false); 4380 } else if (CaptureRegions.size() > 1 || 4381 CaptureRegions.back() != OMPD_unknown) { 4382 if (auto *C = OMPClauseWithPreInit::get(Clause)) 4383 PICs.push_back(C); 4384 if (auto *C = OMPClauseWithPostUpdate::get(Clause)) { 4385 if (Expr *E = C->getPostUpdateExpr()) 4386 MarkDeclarationsReferencedInExpr(E); 4387 } 4388 } 4389 if (Clause->getClauseKind() == OMPC_schedule) 4390 SC = cast<OMPScheduleClause>(Clause); 4391 else if (Clause->getClauseKind() == OMPC_ordered) 4392 OC = cast<OMPOrderedClause>(Clause); 4393 else if (Clause->getClauseKind() == OMPC_linear) 4394 LCs.push_back(cast<OMPLinearClause>(Clause)); 4395 } 4396 // Capture allocator expressions if used. 4397 for (Expr *E : DSAStack->getInnerAllocators()) 4398 MarkDeclarationsReferencedInExpr(E); 4399 // OpenMP, 2.7.1 Loop Construct, Restrictions 4400 // The nonmonotonic modifier cannot be specified if an ordered clause is 4401 // specified. 4402 if (SC && 4403 (SC->getFirstScheduleModifier() == OMPC_SCHEDULE_MODIFIER_nonmonotonic || 4404 SC->getSecondScheduleModifier() == 4405 OMPC_SCHEDULE_MODIFIER_nonmonotonic) && 4406 OC) { 4407 Diag(SC->getFirstScheduleModifier() == OMPC_SCHEDULE_MODIFIER_nonmonotonic 4408 ? SC->getFirstScheduleModifierLoc() 4409 : SC->getSecondScheduleModifierLoc(), 4410 diag::err_omp_simple_clause_incompatible_with_ordered) 4411 << getOpenMPClauseName(OMPC_schedule) 4412 << getOpenMPSimpleClauseTypeName(OMPC_schedule, 4413 OMPC_SCHEDULE_MODIFIER_nonmonotonic) 4414 << SourceRange(OC->getBeginLoc(), OC->getEndLoc()); 4415 ErrorFound = true; 4416 } 4417 // OpenMP 5.0, 2.9.2 Worksharing-Loop Construct, Restrictions. 4418 // If an order(concurrent) clause is present, an ordered clause may not appear 4419 // on the same directive. 4420 if (checkOrderedOrderSpecified(*this, Clauses)) 4421 ErrorFound = true; 4422 if (!LCs.empty() && OC && OC->getNumForLoops()) { 4423 for (const OMPLinearClause *C : LCs) { 4424 Diag(C->getBeginLoc(), diag::err_omp_linear_ordered) 4425 << SourceRange(OC->getBeginLoc(), OC->getEndLoc()); 4426 } 4427 ErrorFound = true; 4428 } 4429 if (isOpenMPWorksharingDirective(DSAStack->getCurrentDirective()) && 4430 isOpenMPSimdDirective(DSAStack->getCurrentDirective()) && OC && 4431 OC->getNumForLoops()) { 4432 Diag(OC->getBeginLoc(), diag::err_omp_ordered_simd) 4433 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 4434 ErrorFound = true; 4435 } 4436 if (ErrorFound) { 4437 return StmtError(); 4438 } 4439 StmtResult SR = S; 4440 unsigned CompletedRegions = 0; 4441 for (OpenMPDirectiveKind ThisCaptureRegion : llvm::reverse(CaptureRegions)) { 4442 // Mark all variables in private list clauses as used in inner region. 4443 // Required for proper codegen of combined directives. 4444 // TODO: add processing for other clauses. 4445 if (ThisCaptureRegion != OMPD_unknown) { 4446 for (const clang::OMPClauseWithPreInit *C : PICs) { 4447 OpenMPDirectiveKind CaptureRegion = C->getCaptureRegion(); 4448 // Find the particular capture region for the clause if the 4449 // directive is a combined one with multiple capture regions. 4450 // If the directive is not a combined one, the capture region 4451 // associated with the clause is OMPD_unknown and is generated 4452 // only once. 4453 if (CaptureRegion == ThisCaptureRegion || 4454 CaptureRegion == OMPD_unknown) { 4455 if (auto *DS = cast_or_null<DeclStmt>(C->getPreInitStmt())) { 4456 for (Decl *D : DS->decls()) 4457 MarkVariableReferenced(D->getLocation(), cast<VarDecl>(D)); 4458 } 4459 } 4460 } 4461 } 4462 if (ThisCaptureRegion == OMPD_target) { 4463 // Capture allocator traits in the target region. They are used implicitly 4464 // and, thus, are not captured by default. 4465 for (OMPClause *C : Clauses) { 4466 if (const auto *UAC = dyn_cast<OMPUsesAllocatorsClause>(C)) { 4467 for (unsigned I = 0, End = UAC->getNumberOfAllocators(); I < End; 4468 ++I) { 4469 OMPUsesAllocatorsClause::Data D = UAC->getAllocatorData(I); 4470 if (Expr *E = D.AllocatorTraits) 4471 MarkDeclarationsReferencedInExpr(E); 4472 } 4473 continue; 4474 } 4475 } 4476 } 4477 if (++CompletedRegions == CaptureRegions.size()) 4478 DSAStack->setBodyComplete(); 4479 SR = ActOnCapturedRegionEnd(SR.get()); 4480 } 4481 return SR; 4482 } 4483 4484 static bool checkCancelRegion(Sema &SemaRef, OpenMPDirectiveKind CurrentRegion, 4485 OpenMPDirectiveKind CancelRegion, 4486 SourceLocation StartLoc) { 4487 // CancelRegion is only needed for cancel and cancellation_point. 4488 if (CurrentRegion != OMPD_cancel && CurrentRegion != OMPD_cancellation_point) 4489 return false; 4490 4491 if (CancelRegion == OMPD_parallel || CancelRegion == OMPD_for || 4492 CancelRegion == OMPD_sections || CancelRegion == OMPD_taskgroup) 4493 return false; 4494 4495 SemaRef.Diag(StartLoc, diag::err_omp_wrong_cancel_region) 4496 << getOpenMPDirectiveName(CancelRegion); 4497 return true; 4498 } 4499 4500 static bool checkNestingOfRegions(Sema &SemaRef, const DSAStackTy *Stack, 4501 OpenMPDirectiveKind CurrentRegion, 4502 const DeclarationNameInfo &CurrentName, 4503 OpenMPDirectiveKind CancelRegion, 4504 SourceLocation StartLoc) { 4505 if (Stack->getCurScope()) { 4506 OpenMPDirectiveKind ParentRegion = Stack->getParentDirective(); 4507 OpenMPDirectiveKind OffendingRegion = ParentRegion; 4508 bool NestingProhibited = false; 4509 bool CloseNesting = true; 4510 bool OrphanSeen = false; 4511 enum { 4512 NoRecommend, 4513 ShouldBeInParallelRegion, 4514 ShouldBeInOrderedRegion, 4515 ShouldBeInTargetRegion, 4516 ShouldBeInTeamsRegion, 4517 ShouldBeInLoopSimdRegion, 4518 } Recommend = NoRecommend; 4519 if (isOpenMPSimdDirective(ParentRegion) && 4520 ((SemaRef.LangOpts.OpenMP <= 45 && CurrentRegion != OMPD_ordered) || 4521 (SemaRef.LangOpts.OpenMP >= 50 && CurrentRegion != OMPD_ordered && 4522 CurrentRegion != OMPD_simd && CurrentRegion != OMPD_atomic && 4523 CurrentRegion != OMPD_scan))) { 4524 // OpenMP [2.16, Nesting of Regions] 4525 // OpenMP constructs may not be nested inside a simd region. 4526 // OpenMP [2.8.1,simd Construct, Restrictions] 4527 // An ordered construct with the simd clause is the only OpenMP 4528 // construct that can appear in the simd region. 4529 // Allowing a SIMD construct nested in another SIMD construct is an 4530 // extension. The OpenMP 4.5 spec does not allow it. Issue a warning 4531 // message. 4532 // OpenMP 5.0 [2.9.3.1, simd Construct, Restrictions] 4533 // The only OpenMP constructs that can be encountered during execution of 4534 // a simd region are the atomic construct, the loop construct, the simd 4535 // construct and the ordered construct with the simd clause. 4536 SemaRef.Diag(StartLoc, (CurrentRegion != OMPD_simd) 4537 ? diag::err_omp_prohibited_region_simd 4538 : diag::warn_omp_nesting_simd) 4539 << (SemaRef.LangOpts.OpenMP >= 50 ? 1 : 0); 4540 return CurrentRegion != OMPD_simd; 4541 } 4542 if (ParentRegion == OMPD_atomic) { 4543 // OpenMP [2.16, Nesting of Regions] 4544 // OpenMP constructs may not be nested inside an atomic region. 4545 SemaRef.Diag(StartLoc, diag::err_omp_prohibited_region_atomic); 4546 return true; 4547 } 4548 if (CurrentRegion == OMPD_section) { 4549 // OpenMP [2.7.2, sections Construct, Restrictions] 4550 // Orphaned section directives are prohibited. That is, the section 4551 // directives must appear within the sections construct and must not be 4552 // encountered elsewhere in the sections region. 4553 if (ParentRegion != OMPD_sections && 4554 ParentRegion != OMPD_parallel_sections) { 4555 SemaRef.Diag(StartLoc, diag::err_omp_orphaned_section_directive) 4556 << (ParentRegion != OMPD_unknown) 4557 << getOpenMPDirectiveName(ParentRegion); 4558 return true; 4559 } 4560 return false; 4561 } 4562 // Allow some constructs (except teams and cancellation constructs) to be 4563 // orphaned (they could be used in functions, called from OpenMP regions 4564 // with the required preconditions). 4565 if (ParentRegion == OMPD_unknown && 4566 !isOpenMPNestingTeamsDirective(CurrentRegion) && 4567 CurrentRegion != OMPD_cancellation_point && 4568 CurrentRegion != OMPD_cancel && CurrentRegion != OMPD_scan) 4569 return false; 4570 if (CurrentRegion == OMPD_cancellation_point || 4571 CurrentRegion == OMPD_cancel) { 4572 // OpenMP [2.16, Nesting of Regions] 4573 // A cancellation point construct for which construct-type-clause is 4574 // taskgroup must be nested inside a task construct. A cancellation 4575 // point construct for which construct-type-clause is not taskgroup must 4576 // be closely nested inside an OpenMP construct that matches the type 4577 // specified in construct-type-clause. 4578 // A cancel construct for which construct-type-clause is taskgroup must be 4579 // nested inside a task construct. A cancel construct for which 4580 // construct-type-clause is not taskgroup must be closely nested inside an 4581 // OpenMP construct that matches the type specified in 4582 // construct-type-clause. 4583 NestingProhibited = 4584 !((CancelRegion == OMPD_parallel && 4585 (ParentRegion == OMPD_parallel || 4586 ParentRegion == OMPD_target_parallel)) || 4587 (CancelRegion == OMPD_for && 4588 (ParentRegion == OMPD_for || ParentRegion == OMPD_parallel_for || 4589 ParentRegion == OMPD_target_parallel_for || 4590 ParentRegion == OMPD_distribute_parallel_for || 4591 ParentRegion == OMPD_teams_distribute_parallel_for || 4592 ParentRegion == OMPD_target_teams_distribute_parallel_for)) || 4593 (CancelRegion == OMPD_taskgroup && 4594 (ParentRegion == OMPD_task || 4595 (SemaRef.getLangOpts().OpenMP >= 50 && 4596 (ParentRegion == OMPD_taskloop || 4597 ParentRegion == OMPD_master_taskloop || 4598 ParentRegion == OMPD_parallel_master_taskloop)))) || 4599 (CancelRegion == OMPD_sections && 4600 (ParentRegion == OMPD_section || ParentRegion == OMPD_sections || 4601 ParentRegion == OMPD_parallel_sections))); 4602 OrphanSeen = ParentRegion == OMPD_unknown; 4603 } else if (CurrentRegion == OMPD_master) { 4604 // OpenMP [2.16, Nesting of Regions] 4605 // A master region may not be closely nested inside a worksharing, 4606 // atomic, or explicit task region. 4607 NestingProhibited = isOpenMPWorksharingDirective(ParentRegion) || 4608 isOpenMPTaskingDirective(ParentRegion); 4609 } else if (CurrentRegion == OMPD_critical && CurrentName.getName()) { 4610 // OpenMP [2.16, Nesting of Regions] 4611 // A critical region may not be nested (closely or otherwise) inside a 4612 // critical region with the same name. Note that this restriction is not 4613 // sufficient to prevent deadlock. 4614 SourceLocation PreviousCriticalLoc; 4615 bool DeadLock = Stack->hasDirective( 4616 [CurrentName, &PreviousCriticalLoc](OpenMPDirectiveKind K, 4617 const DeclarationNameInfo &DNI, 4618 SourceLocation Loc) { 4619 if (K == OMPD_critical && DNI.getName() == CurrentName.getName()) { 4620 PreviousCriticalLoc = Loc; 4621 return true; 4622 } 4623 return false; 4624 }, 4625 false /* skip top directive */); 4626 if (DeadLock) { 4627 SemaRef.Diag(StartLoc, 4628 diag::err_omp_prohibited_region_critical_same_name) 4629 << CurrentName.getName(); 4630 if (PreviousCriticalLoc.isValid()) 4631 SemaRef.Diag(PreviousCriticalLoc, 4632 diag::note_omp_previous_critical_region); 4633 return true; 4634 } 4635 } else if (CurrentRegion == OMPD_barrier) { 4636 // OpenMP [2.16, Nesting of Regions] 4637 // A barrier region may not be closely nested inside a worksharing, 4638 // explicit task, critical, ordered, atomic, or master region. 4639 NestingProhibited = isOpenMPWorksharingDirective(ParentRegion) || 4640 isOpenMPTaskingDirective(ParentRegion) || 4641 ParentRegion == OMPD_master || 4642 ParentRegion == OMPD_parallel_master || 4643 ParentRegion == OMPD_critical || 4644 ParentRegion == OMPD_ordered; 4645 } else if (isOpenMPWorksharingDirective(CurrentRegion) && 4646 !isOpenMPParallelDirective(CurrentRegion) && 4647 !isOpenMPTeamsDirective(CurrentRegion)) { 4648 // OpenMP [2.16, Nesting of Regions] 4649 // A worksharing region may not be closely nested inside a worksharing, 4650 // explicit task, critical, ordered, atomic, or master region. 4651 NestingProhibited = isOpenMPWorksharingDirective(ParentRegion) || 4652 isOpenMPTaskingDirective(ParentRegion) || 4653 ParentRegion == OMPD_master || 4654 ParentRegion == OMPD_parallel_master || 4655 ParentRegion == OMPD_critical || 4656 ParentRegion == OMPD_ordered; 4657 Recommend = ShouldBeInParallelRegion; 4658 } else if (CurrentRegion == OMPD_ordered) { 4659 // OpenMP [2.16, Nesting of Regions] 4660 // An ordered region may not be closely nested inside a critical, 4661 // atomic, or explicit task region. 4662 // An ordered region must be closely nested inside a loop region (or 4663 // parallel loop region) with an ordered clause. 4664 // OpenMP [2.8.1,simd Construct, Restrictions] 4665 // An ordered construct with the simd clause is the only OpenMP construct 4666 // that can appear in the simd region. 4667 NestingProhibited = ParentRegion == OMPD_critical || 4668 isOpenMPTaskingDirective(ParentRegion) || 4669 !(isOpenMPSimdDirective(ParentRegion) || 4670 Stack->isParentOrderedRegion()); 4671 Recommend = ShouldBeInOrderedRegion; 4672 } else if (isOpenMPNestingTeamsDirective(CurrentRegion)) { 4673 // OpenMP [2.16, Nesting of Regions] 4674 // If specified, a teams construct must be contained within a target 4675 // construct. 4676 NestingProhibited = 4677 (SemaRef.LangOpts.OpenMP <= 45 && ParentRegion != OMPD_target) || 4678 (SemaRef.LangOpts.OpenMP >= 50 && ParentRegion != OMPD_unknown && 4679 ParentRegion != OMPD_target); 4680 OrphanSeen = ParentRegion == OMPD_unknown; 4681 Recommend = ShouldBeInTargetRegion; 4682 } else if (CurrentRegion == OMPD_scan) { 4683 // OpenMP [2.16, Nesting of Regions] 4684 // If specified, a teams construct must be contained within a target 4685 // construct. 4686 NestingProhibited = 4687 SemaRef.LangOpts.OpenMP < 50 || 4688 (ParentRegion != OMPD_simd && ParentRegion != OMPD_for && 4689 ParentRegion != OMPD_for_simd && ParentRegion != OMPD_parallel_for && 4690 ParentRegion != OMPD_parallel_for_simd); 4691 OrphanSeen = ParentRegion == OMPD_unknown; 4692 Recommend = ShouldBeInLoopSimdRegion; 4693 } 4694 if (!NestingProhibited && 4695 !isOpenMPTargetExecutionDirective(CurrentRegion) && 4696 !isOpenMPTargetDataManagementDirective(CurrentRegion) && 4697 (ParentRegion == OMPD_teams || ParentRegion == OMPD_target_teams)) { 4698 // OpenMP [2.16, Nesting of Regions] 4699 // distribute, parallel, parallel sections, parallel workshare, and the 4700 // parallel loop and parallel loop SIMD constructs are the only OpenMP 4701 // constructs that can be closely nested in the teams region. 4702 NestingProhibited = !isOpenMPParallelDirective(CurrentRegion) && 4703 !isOpenMPDistributeDirective(CurrentRegion); 4704 Recommend = ShouldBeInParallelRegion; 4705 } 4706 if (!NestingProhibited && 4707 isOpenMPNestingDistributeDirective(CurrentRegion)) { 4708 // OpenMP 4.5 [2.17 Nesting of Regions] 4709 // The region associated with the distribute construct must be strictly 4710 // nested inside a teams region 4711 NestingProhibited = 4712 (ParentRegion != OMPD_teams && ParentRegion != OMPD_target_teams); 4713 Recommend = ShouldBeInTeamsRegion; 4714 } 4715 if (!NestingProhibited && 4716 (isOpenMPTargetExecutionDirective(CurrentRegion) || 4717 isOpenMPTargetDataManagementDirective(CurrentRegion))) { 4718 // OpenMP 4.5 [2.17 Nesting of Regions] 4719 // If a target, target update, target data, target enter data, or 4720 // target exit data construct is encountered during execution of a 4721 // target region, the behavior is unspecified. 4722 NestingProhibited = Stack->hasDirective( 4723 [&OffendingRegion](OpenMPDirectiveKind K, const DeclarationNameInfo &, 4724 SourceLocation) { 4725 if (isOpenMPTargetExecutionDirective(K)) { 4726 OffendingRegion = K; 4727 return true; 4728 } 4729 return false; 4730 }, 4731 false /* don't skip top directive */); 4732 CloseNesting = false; 4733 } 4734 if (NestingProhibited) { 4735 if (OrphanSeen) { 4736 SemaRef.Diag(StartLoc, diag::err_omp_orphaned_device_directive) 4737 << getOpenMPDirectiveName(CurrentRegion) << Recommend; 4738 } else { 4739 SemaRef.Diag(StartLoc, diag::err_omp_prohibited_region) 4740 << CloseNesting << getOpenMPDirectiveName(OffendingRegion) 4741 << Recommend << getOpenMPDirectiveName(CurrentRegion); 4742 } 4743 return true; 4744 } 4745 } 4746 return false; 4747 } 4748 4749 struct Kind2Unsigned { 4750 using argument_type = OpenMPDirectiveKind; 4751 unsigned operator()(argument_type DK) { return unsigned(DK); } 4752 }; 4753 static bool checkIfClauses(Sema &S, OpenMPDirectiveKind Kind, 4754 ArrayRef<OMPClause *> Clauses, 4755 ArrayRef<OpenMPDirectiveKind> AllowedNameModifiers) { 4756 bool ErrorFound = false; 4757 unsigned NamedModifiersNumber = 0; 4758 llvm::IndexedMap<const OMPIfClause *, Kind2Unsigned> FoundNameModifiers; 4759 FoundNameModifiers.resize(llvm::omp::Directive_enumSize + 1); 4760 SmallVector<SourceLocation, 4> NameModifierLoc; 4761 for (const OMPClause *C : Clauses) { 4762 if (const auto *IC = dyn_cast_or_null<OMPIfClause>(C)) { 4763 // At most one if clause without a directive-name-modifier can appear on 4764 // the directive. 4765 OpenMPDirectiveKind CurNM = IC->getNameModifier(); 4766 if (FoundNameModifiers[CurNM]) { 4767 S.Diag(C->getBeginLoc(), diag::err_omp_more_one_clause) 4768 << getOpenMPDirectiveName(Kind) << getOpenMPClauseName(OMPC_if) 4769 << (CurNM != OMPD_unknown) << getOpenMPDirectiveName(CurNM); 4770 ErrorFound = true; 4771 } else if (CurNM != OMPD_unknown) { 4772 NameModifierLoc.push_back(IC->getNameModifierLoc()); 4773 ++NamedModifiersNumber; 4774 } 4775 FoundNameModifiers[CurNM] = IC; 4776 if (CurNM == OMPD_unknown) 4777 continue; 4778 // Check if the specified name modifier is allowed for the current 4779 // directive. 4780 // At most one if clause with the particular directive-name-modifier can 4781 // appear on the directive. 4782 bool MatchFound = false; 4783 for (auto NM : AllowedNameModifiers) { 4784 if (CurNM == NM) { 4785 MatchFound = true; 4786 break; 4787 } 4788 } 4789 if (!MatchFound) { 4790 S.Diag(IC->getNameModifierLoc(), 4791 diag::err_omp_wrong_if_directive_name_modifier) 4792 << getOpenMPDirectiveName(CurNM) << getOpenMPDirectiveName(Kind); 4793 ErrorFound = true; 4794 } 4795 } 4796 } 4797 // If any if clause on the directive includes a directive-name-modifier then 4798 // all if clauses on the directive must include a directive-name-modifier. 4799 if (FoundNameModifiers[OMPD_unknown] && NamedModifiersNumber > 0) { 4800 if (NamedModifiersNumber == AllowedNameModifiers.size()) { 4801 S.Diag(FoundNameModifiers[OMPD_unknown]->getBeginLoc(), 4802 diag::err_omp_no_more_if_clause); 4803 } else { 4804 std::string Values; 4805 std::string Sep(", "); 4806 unsigned AllowedCnt = 0; 4807 unsigned TotalAllowedNum = 4808 AllowedNameModifiers.size() - NamedModifiersNumber; 4809 for (unsigned Cnt = 0, End = AllowedNameModifiers.size(); Cnt < End; 4810 ++Cnt) { 4811 OpenMPDirectiveKind NM = AllowedNameModifiers[Cnt]; 4812 if (!FoundNameModifiers[NM]) { 4813 Values += "'"; 4814 Values += getOpenMPDirectiveName(NM); 4815 Values += "'"; 4816 if (AllowedCnt + 2 == TotalAllowedNum) 4817 Values += " or "; 4818 else if (AllowedCnt + 1 != TotalAllowedNum) 4819 Values += Sep; 4820 ++AllowedCnt; 4821 } 4822 } 4823 S.Diag(FoundNameModifiers[OMPD_unknown]->getCondition()->getBeginLoc(), 4824 diag::err_omp_unnamed_if_clause) 4825 << (TotalAllowedNum > 1) << Values; 4826 } 4827 for (SourceLocation Loc : NameModifierLoc) { 4828 S.Diag(Loc, diag::note_omp_previous_named_if_clause); 4829 } 4830 ErrorFound = true; 4831 } 4832 return ErrorFound; 4833 } 4834 4835 static std::pair<ValueDecl *, bool> getPrivateItem(Sema &S, Expr *&RefExpr, 4836 SourceLocation &ELoc, 4837 SourceRange &ERange, 4838 bool AllowArraySection) { 4839 if (RefExpr->isTypeDependent() || RefExpr->isValueDependent() || 4840 RefExpr->containsUnexpandedParameterPack()) 4841 return std::make_pair(nullptr, true); 4842 4843 // OpenMP [3.1, C/C++] 4844 // A list item is a variable name. 4845 // OpenMP [2.9.3.3, Restrictions, p.1] 4846 // A variable that is part of another variable (as an array or 4847 // structure element) cannot appear in a private clause. 4848 RefExpr = RefExpr->IgnoreParens(); 4849 enum { 4850 NoArrayExpr = -1, 4851 ArraySubscript = 0, 4852 OMPArraySection = 1 4853 } IsArrayExpr = NoArrayExpr; 4854 if (AllowArraySection) { 4855 if (auto *ASE = dyn_cast_or_null<ArraySubscriptExpr>(RefExpr)) { 4856 Expr *Base = ASE->getBase()->IgnoreParenImpCasts(); 4857 while (auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base)) 4858 Base = TempASE->getBase()->IgnoreParenImpCasts(); 4859 RefExpr = Base; 4860 IsArrayExpr = ArraySubscript; 4861 } else if (auto *OASE = dyn_cast_or_null<OMPArraySectionExpr>(RefExpr)) { 4862 Expr *Base = OASE->getBase()->IgnoreParenImpCasts(); 4863 while (auto *TempOASE = dyn_cast<OMPArraySectionExpr>(Base)) 4864 Base = TempOASE->getBase()->IgnoreParenImpCasts(); 4865 while (auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base)) 4866 Base = TempASE->getBase()->IgnoreParenImpCasts(); 4867 RefExpr = Base; 4868 IsArrayExpr = OMPArraySection; 4869 } 4870 } 4871 ELoc = RefExpr->getExprLoc(); 4872 ERange = RefExpr->getSourceRange(); 4873 RefExpr = RefExpr->IgnoreParenImpCasts(); 4874 auto *DE = dyn_cast_or_null<DeclRefExpr>(RefExpr); 4875 auto *ME = dyn_cast_or_null<MemberExpr>(RefExpr); 4876 if ((!DE || !isa<VarDecl>(DE->getDecl())) && 4877 (S.getCurrentThisType().isNull() || !ME || 4878 !isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts()) || 4879 !isa<FieldDecl>(ME->getMemberDecl()))) { 4880 if (IsArrayExpr != NoArrayExpr) { 4881 S.Diag(ELoc, diag::err_omp_expected_base_var_name) << IsArrayExpr 4882 << ERange; 4883 } else { 4884 S.Diag(ELoc, 4885 AllowArraySection 4886 ? diag::err_omp_expected_var_name_member_expr_or_array_item 4887 : diag::err_omp_expected_var_name_member_expr) 4888 << (S.getCurrentThisType().isNull() ? 0 : 1) << ERange; 4889 } 4890 return std::make_pair(nullptr, false); 4891 } 4892 return std::make_pair( 4893 getCanonicalDecl(DE ? DE->getDecl() : ME->getMemberDecl()), false); 4894 } 4895 4896 namespace { 4897 /// Checks if the allocator is used in uses_allocators clause to be allowed in 4898 /// target regions. 4899 class AllocatorChecker final : public ConstStmtVisitor<AllocatorChecker, bool> { 4900 DSAStackTy *S = nullptr; 4901 4902 public: 4903 bool VisitDeclRefExpr(const DeclRefExpr *E) { 4904 return S->isUsesAllocatorsDecl(E->getDecl()) 4905 .getValueOr( 4906 DSAStackTy::UsesAllocatorsDeclKind::AllocatorTrait) == 4907 DSAStackTy::UsesAllocatorsDeclKind::AllocatorTrait; 4908 } 4909 bool VisitStmt(const Stmt *S) { 4910 for (const Stmt *Child : S->children()) { 4911 if (Child && Visit(Child)) 4912 return true; 4913 } 4914 return false; 4915 } 4916 explicit AllocatorChecker(DSAStackTy *S) : S(S) {} 4917 }; 4918 } // namespace 4919 4920 static void checkAllocateClauses(Sema &S, DSAStackTy *Stack, 4921 ArrayRef<OMPClause *> Clauses) { 4922 assert(!S.CurContext->isDependentContext() && 4923 "Expected non-dependent context."); 4924 auto AllocateRange = 4925 llvm::make_filter_range(Clauses, OMPAllocateClause::classof); 4926 llvm::DenseMap<CanonicalDeclPtr<Decl>, CanonicalDeclPtr<VarDecl>> 4927 DeclToCopy; 4928 auto PrivateRange = llvm::make_filter_range(Clauses, [](const OMPClause *C) { 4929 return isOpenMPPrivate(C->getClauseKind()); 4930 }); 4931 for (OMPClause *Cl : PrivateRange) { 4932 MutableArrayRef<Expr *>::iterator I, It, Et; 4933 if (Cl->getClauseKind() == OMPC_private) { 4934 auto *PC = cast<OMPPrivateClause>(Cl); 4935 I = PC->private_copies().begin(); 4936 It = PC->varlist_begin(); 4937 Et = PC->varlist_end(); 4938 } else if (Cl->getClauseKind() == OMPC_firstprivate) { 4939 auto *PC = cast<OMPFirstprivateClause>(Cl); 4940 I = PC->private_copies().begin(); 4941 It = PC->varlist_begin(); 4942 Et = PC->varlist_end(); 4943 } else if (Cl->getClauseKind() == OMPC_lastprivate) { 4944 auto *PC = cast<OMPLastprivateClause>(Cl); 4945 I = PC->private_copies().begin(); 4946 It = PC->varlist_begin(); 4947 Et = PC->varlist_end(); 4948 } else if (Cl->getClauseKind() == OMPC_linear) { 4949 auto *PC = cast<OMPLinearClause>(Cl); 4950 I = PC->privates().begin(); 4951 It = PC->varlist_begin(); 4952 Et = PC->varlist_end(); 4953 } else if (Cl->getClauseKind() == OMPC_reduction) { 4954 auto *PC = cast<OMPReductionClause>(Cl); 4955 I = PC->privates().begin(); 4956 It = PC->varlist_begin(); 4957 Et = PC->varlist_end(); 4958 } else if (Cl->getClauseKind() == OMPC_task_reduction) { 4959 auto *PC = cast<OMPTaskReductionClause>(Cl); 4960 I = PC->privates().begin(); 4961 It = PC->varlist_begin(); 4962 Et = PC->varlist_end(); 4963 } else if (Cl->getClauseKind() == OMPC_in_reduction) { 4964 auto *PC = cast<OMPInReductionClause>(Cl); 4965 I = PC->privates().begin(); 4966 It = PC->varlist_begin(); 4967 Et = PC->varlist_end(); 4968 } else { 4969 llvm_unreachable("Expected private clause."); 4970 } 4971 for (Expr *E : llvm::make_range(It, Et)) { 4972 if (!*I) { 4973 ++I; 4974 continue; 4975 } 4976 SourceLocation ELoc; 4977 SourceRange ERange; 4978 Expr *SimpleRefExpr = E; 4979 auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange, 4980 /*AllowArraySection=*/true); 4981 DeclToCopy.try_emplace(Res.first, 4982 cast<VarDecl>(cast<DeclRefExpr>(*I)->getDecl())); 4983 ++I; 4984 } 4985 } 4986 for (OMPClause *C : AllocateRange) { 4987 auto *AC = cast<OMPAllocateClause>(C); 4988 if (S.getLangOpts().OpenMP >= 50 && 4989 !Stack->hasRequiresDeclWithClause<OMPDynamicAllocatorsClause>() && 4990 isOpenMPTargetExecutionDirective(Stack->getCurrentDirective()) && 4991 AC->getAllocator()) { 4992 Expr *Allocator = AC->getAllocator(); 4993 // OpenMP, 2.12.5 target Construct 4994 // Memory allocators that do not appear in a uses_allocators clause cannot 4995 // appear as an allocator in an allocate clause or be used in the target 4996 // region unless a requires directive with the dynamic_allocators clause 4997 // is present in the same compilation unit. 4998 AllocatorChecker Checker(Stack); 4999 if (Checker.Visit(Allocator)) 5000 S.Diag(Allocator->getExprLoc(), 5001 diag::err_omp_allocator_not_in_uses_allocators) 5002 << Allocator->getSourceRange(); 5003 } 5004 OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind = 5005 getAllocatorKind(S, Stack, AC->getAllocator()); 5006 // OpenMP, 2.11.4 allocate Clause, Restrictions. 5007 // For task, taskloop or target directives, allocation requests to memory 5008 // allocators with the trait access set to thread result in unspecified 5009 // behavior. 5010 if (AllocatorKind == OMPAllocateDeclAttr::OMPThreadMemAlloc && 5011 (isOpenMPTaskingDirective(Stack->getCurrentDirective()) || 5012 isOpenMPTargetExecutionDirective(Stack->getCurrentDirective()))) { 5013 S.Diag(AC->getAllocator()->getExprLoc(), 5014 diag::warn_omp_allocate_thread_on_task_target_directive) 5015 << getOpenMPDirectiveName(Stack->getCurrentDirective()); 5016 } 5017 for (Expr *E : AC->varlists()) { 5018 SourceLocation ELoc; 5019 SourceRange ERange; 5020 Expr *SimpleRefExpr = E; 5021 auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange); 5022 ValueDecl *VD = Res.first; 5023 DSAStackTy::DSAVarData Data = Stack->getTopDSA(VD, /*FromParent=*/false); 5024 if (!isOpenMPPrivate(Data.CKind)) { 5025 S.Diag(E->getExprLoc(), 5026 diag::err_omp_expected_private_copy_for_allocate); 5027 continue; 5028 } 5029 VarDecl *PrivateVD = DeclToCopy[VD]; 5030 if (checkPreviousOMPAllocateAttribute(S, Stack, E, PrivateVD, 5031 AllocatorKind, AC->getAllocator())) 5032 continue; 5033 applyOMPAllocateAttribute(S, PrivateVD, AllocatorKind, AC->getAllocator(), 5034 E->getSourceRange()); 5035 } 5036 } 5037 } 5038 5039 StmtResult Sema::ActOnOpenMPExecutableDirective( 5040 OpenMPDirectiveKind Kind, const DeclarationNameInfo &DirName, 5041 OpenMPDirectiveKind CancelRegion, ArrayRef<OMPClause *> Clauses, 5042 Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc) { 5043 StmtResult Res = StmtError(); 5044 // First check CancelRegion which is then used in checkNestingOfRegions. 5045 if (checkCancelRegion(*this, Kind, CancelRegion, StartLoc) || 5046 checkNestingOfRegions(*this, DSAStack, Kind, DirName, CancelRegion, 5047 StartLoc)) 5048 return StmtError(); 5049 5050 llvm::SmallVector<OMPClause *, 8> ClausesWithImplicit; 5051 VarsWithInheritedDSAType VarsWithInheritedDSA; 5052 bool ErrorFound = false; 5053 ClausesWithImplicit.append(Clauses.begin(), Clauses.end()); 5054 if (AStmt && !CurContext->isDependentContext() && Kind != OMPD_atomic && 5055 Kind != OMPD_critical && Kind != OMPD_section && Kind != OMPD_master) { 5056 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 5057 5058 // Check default data sharing attributes for referenced variables. 5059 DSAAttrChecker DSAChecker(DSAStack, *this, cast<CapturedStmt>(AStmt)); 5060 int ThisCaptureLevel = getOpenMPCaptureLevels(Kind); 5061 Stmt *S = AStmt; 5062 while (--ThisCaptureLevel >= 0) 5063 S = cast<CapturedStmt>(S)->getCapturedStmt(); 5064 DSAChecker.Visit(S); 5065 if (!isOpenMPTargetDataManagementDirective(Kind) && 5066 !isOpenMPTaskingDirective(Kind)) { 5067 // Visit subcaptures to generate implicit clauses for captured vars. 5068 auto *CS = cast<CapturedStmt>(AStmt); 5069 SmallVector<OpenMPDirectiveKind, 4> CaptureRegions; 5070 getOpenMPCaptureRegions(CaptureRegions, Kind); 5071 // Ignore outer tasking regions for target directives. 5072 if (CaptureRegions.size() > 1 && CaptureRegions.front() == OMPD_task) 5073 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 5074 DSAChecker.visitSubCaptures(CS); 5075 } 5076 if (DSAChecker.isErrorFound()) 5077 return StmtError(); 5078 // Generate list of implicitly defined firstprivate variables. 5079 VarsWithInheritedDSA = DSAChecker.getVarsWithInheritedDSA(); 5080 5081 SmallVector<Expr *, 4> ImplicitFirstprivates( 5082 DSAChecker.getImplicitFirstprivate().begin(), 5083 DSAChecker.getImplicitFirstprivate().end()); 5084 SmallVector<Expr *, 4> ImplicitMaps[OMPC_MAP_delete]; 5085 for (unsigned I = 0; I < OMPC_MAP_delete; ++I) { 5086 ArrayRef<Expr *> ImplicitMap = 5087 DSAChecker.getImplicitMap(static_cast<OpenMPDefaultmapClauseKind>(I)); 5088 ImplicitMaps[I].append(ImplicitMap.begin(), ImplicitMap.end()); 5089 } 5090 // Mark taskgroup task_reduction descriptors as implicitly firstprivate. 5091 for (OMPClause *C : Clauses) { 5092 if (auto *IRC = dyn_cast<OMPInReductionClause>(C)) { 5093 for (Expr *E : IRC->taskgroup_descriptors()) 5094 if (E) 5095 ImplicitFirstprivates.emplace_back(E); 5096 } 5097 // OpenMP 5.0, 2.10.1 task Construct 5098 // [detach clause]... The event-handle will be considered as if it was 5099 // specified on a firstprivate clause. 5100 if (auto *DC = dyn_cast<OMPDetachClause>(C)) 5101 ImplicitFirstprivates.push_back(DC->getEventHandler()); 5102 } 5103 if (!ImplicitFirstprivates.empty()) { 5104 if (OMPClause *Implicit = ActOnOpenMPFirstprivateClause( 5105 ImplicitFirstprivates, SourceLocation(), SourceLocation(), 5106 SourceLocation())) { 5107 ClausesWithImplicit.push_back(Implicit); 5108 ErrorFound = cast<OMPFirstprivateClause>(Implicit)->varlist_size() != 5109 ImplicitFirstprivates.size(); 5110 } else { 5111 ErrorFound = true; 5112 } 5113 } 5114 int ClauseKindCnt = -1; 5115 for (ArrayRef<Expr *> ImplicitMap : ImplicitMaps) { 5116 ++ClauseKindCnt; 5117 if (ImplicitMap.empty()) 5118 continue; 5119 CXXScopeSpec MapperIdScopeSpec; 5120 DeclarationNameInfo MapperId; 5121 auto Kind = static_cast<OpenMPMapClauseKind>(ClauseKindCnt); 5122 if (OMPClause *Implicit = ActOnOpenMPMapClause( 5123 llvm::None, llvm::None, MapperIdScopeSpec, MapperId, Kind, 5124 /*IsMapTypeImplicit=*/true, SourceLocation(), SourceLocation(), 5125 ImplicitMap, OMPVarListLocTy())) { 5126 ClausesWithImplicit.emplace_back(Implicit); 5127 ErrorFound |= 5128 cast<OMPMapClause>(Implicit)->varlist_size() != ImplicitMap.size(); 5129 } else { 5130 ErrorFound = true; 5131 } 5132 } 5133 } 5134 5135 llvm::SmallVector<OpenMPDirectiveKind, 4> AllowedNameModifiers; 5136 switch (Kind) { 5137 case OMPD_parallel: 5138 Res = ActOnOpenMPParallelDirective(ClausesWithImplicit, AStmt, StartLoc, 5139 EndLoc); 5140 AllowedNameModifiers.push_back(OMPD_parallel); 5141 break; 5142 case OMPD_simd: 5143 Res = ActOnOpenMPSimdDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc, 5144 VarsWithInheritedDSA); 5145 if (LangOpts.OpenMP >= 50) 5146 AllowedNameModifiers.push_back(OMPD_simd); 5147 break; 5148 case OMPD_for: 5149 Res = ActOnOpenMPForDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc, 5150 VarsWithInheritedDSA); 5151 break; 5152 case OMPD_for_simd: 5153 Res = ActOnOpenMPForSimdDirective(ClausesWithImplicit, AStmt, StartLoc, 5154 EndLoc, VarsWithInheritedDSA); 5155 if (LangOpts.OpenMP >= 50) 5156 AllowedNameModifiers.push_back(OMPD_simd); 5157 break; 5158 case OMPD_sections: 5159 Res = ActOnOpenMPSectionsDirective(ClausesWithImplicit, AStmt, StartLoc, 5160 EndLoc); 5161 break; 5162 case OMPD_section: 5163 assert(ClausesWithImplicit.empty() && 5164 "No clauses are allowed for 'omp section' directive"); 5165 Res = ActOnOpenMPSectionDirective(AStmt, StartLoc, EndLoc); 5166 break; 5167 case OMPD_single: 5168 Res = ActOnOpenMPSingleDirective(ClausesWithImplicit, AStmt, StartLoc, 5169 EndLoc); 5170 break; 5171 case OMPD_master: 5172 assert(ClausesWithImplicit.empty() && 5173 "No clauses are allowed for 'omp master' directive"); 5174 Res = ActOnOpenMPMasterDirective(AStmt, StartLoc, EndLoc); 5175 break; 5176 case OMPD_critical: 5177 Res = ActOnOpenMPCriticalDirective(DirName, ClausesWithImplicit, AStmt, 5178 StartLoc, EndLoc); 5179 break; 5180 case OMPD_parallel_for: 5181 Res = ActOnOpenMPParallelForDirective(ClausesWithImplicit, AStmt, StartLoc, 5182 EndLoc, VarsWithInheritedDSA); 5183 AllowedNameModifiers.push_back(OMPD_parallel); 5184 break; 5185 case OMPD_parallel_for_simd: 5186 Res = ActOnOpenMPParallelForSimdDirective( 5187 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 5188 AllowedNameModifiers.push_back(OMPD_parallel); 5189 if (LangOpts.OpenMP >= 50) 5190 AllowedNameModifiers.push_back(OMPD_simd); 5191 break; 5192 case OMPD_parallel_master: 5193 Res = ActOnOpenMPParallelMasterDirective(ClausesWithImplicit, AStmt, 5194 StartLoc, EndLoc); 5195 AllowedNameModifiers.push_back(OMPD_parallel); 5196 break; 5197 case OMPD_parallel_sections: 5198 Res = ActOnOpenMPParallelSectionsDirective(ClausesWithImplicit, AStmt, 5199 StartLoc, EndLoc); 5200 AllowedNameModifiers.push_back(OMPD_parallel); 5201 break; 5202 case OMPD_task: 5203 Res = 5204 ActOnOpenMPTaskDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc); 5205 AllowedNameModifiers.push_back(OMPD_task); 5206 break; 5207 case OMPD_taskyield: 5208 assert(ClausesWithImplicit.empty() && 5209 "No clauses are allowed for 'omp taskyield' directive"); 5210 assert(AStmt == nullptr && 5211 "No associated statement allowed for 'omp taskyield' directive"); 5212 Res = ActOnOpenMPTaskyieldDirective(StartLoc, EndLoc); 5213 break; 5214 case OMPD_barrier: 5215 assert(ClausesWithImplicit.empty() && 5216 "No clauses are allowed for 'omp barrier' directive"); 5217 assert(AStmt == nullptr && 5218 "No associated statement allowed for 'omp barrier' directive"); 5219 Res = ActOnOpenMPBarrierDirective(StartLoc, EndLoc); 5220 break; 5221 case OMPD_taskwait: 5222 assert(ClausesWithImplicit.empty() && 5223 "No clauses are allowed for 'omp taskwait' directive"); 5224 assert(AStmt == nullptr && 5225 "No associated statement allowed for 'omp taskwait' directive"); 5226 Res = ActOnOpenMPTaskwaitDirective(StartLoc, EndLoc); 5227 break; 5228 case OMPD_taskgroup: 5229 Res = ActOnOpenMPTaskgroupDirective(ClausesWithImplicit, AStmt, StartLoc, 5230 EndLoc); 5231 break; 5232 case OMPD_flush: 5233 assert(AStmt == nullptr && 5234 "No associated statement allowed for 'omp flush' directive"); 5235 Res = ActOnOpenMPFlushDirective(ClausesWithImplicit, StartLoc, EndLoc); 5236 break; 5237 case OMPD_depobj: 5238 assert(AStmt == nullptr && 5239 "No associated statement allowed for 'omp depobj' directive"); 5240 Res = ActOnOpenMPDepobjDirective(ClausesWithImplicit, StartLoc, EndLoc); 5241 break; 5242 case OMPD_scan: 5243 assert(AStmt == nullptr && 5244 "No associated statement allowed for 'omp scan' directive"); 5245 Res = ActOnOpenMPScanDirective(ClausesWithImplicit, StartLoc, EndLoc); 5246 break; 5247 case OMPD_ordered: 5248 Res = ActOnOpenMPOrderedDirective(ClausesWithImplicit, AStmt, StartLoc, 5249 EndLoc); 5250 break; 5251 case OMPD_atomic: 5252 Res = ActOnOpenMPAtomicDirective(ClausesWithImplicit, AStmt, StartLoc, 5253 EndLoc); 5254 break; 5255 case OMPD_teams: 5256 Res = 5257 ActOnOpenMPTeamsDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc); 5258 break; 5259 case OMPD_target: 5260 Res = ActOnOpenMPTargetDirective(ClausesWithImplicit, AStmt, StartLoc, 5261 EndLoc); 5262 AllowedNameModifiers.push_back(OMPD_target); 5263 break; 5264 case OMPD_target_parallel: 5265 Res = ActOnOpenMPTargetParallelDirective(ClausesWithImplicit, AStmt, 5266 StartLoc, EndLoc); 5267 AllowedNameModifiers.push_back(OMPD_target); 5268 AllowedNameModifiers.push_back(OMPD_parallel); 5269 break; 5270 case OMPD_target_parallel_for: 5271 Res = ActOnOpenMPTargetParallelForDirective( 5272 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 5273 AllowedNameModifiers.push_back(OMPD_target); 5274 AllowedNameModifiers.push_back(OMPD_parallel); 5275 break; 5276 case OMPD_cancellation_point: 5277 assert(ClausesWithImplicit.empty() && 5278 "No clauses are allowed for 'omp cancellation point' directive"); 5279 assert(AStmt == nullptr && "No associated statement allowed for 'omp " 5280 "cancellation point' directive"); 5281 Res = ActOnOpenMPCancellationPointDirective(StartLoc, EndLoc, CancelRegion); 5282 break; 5283 case OMPD_cancel: 5284 assert(AStmt == nullptr && 5285 "No associated statement allowed for 'omp cancel' directive"); 5286 Res = ActOnOpenMPCancelDirective(ClausesWithImplicit, StartLoc, EndLoc, 5287 CancelRegion); 5288 AllowedNameModifiers.push_back(OMPD_cancel); 5289 break; 5290 case OMPD_target_data: 5291 Res = ActOnOpenMPTargetDataDirective(ClausesWithImplicit, AStmt, StartLoc, 5292 EndLoc); 5293 AllowedNameModifiers.push_back(OMPD_target_data); 5294 break; 5295 case OMPD_target_enter_data: 5296 Res = ActOnOpenMPTargetEnterDataDirective(ClausesWithImplicit, StartLoc, 5297 EndLoc, AStmt); 5298 AllowedNameModifiers.push_back(OMPD_target_enter_data); 5299 break; 5300 case OMPD_target_exit_data: 5301 Res = ActOnOpenMPTargetExitDataDirective(ClausesWithImplicit, StartLoc, 5302 EndLoc, AStmt); 5303 AllowedNameModifiers.push_back(OMPD_target_exit_data); 5304 break; 5305 case OMPD_taskloop: 5306 Res = ActOnOpenMPTaskLoopDirective(ClausesWithImplicit, AStmt, StartLoc, 5307 EndLoc, VarsWithInheritedDSA); 5308 AllowedNameModifiers.push_back(OMPD_taskloop); 5309 break; 5310 case OMPD_taskloop_simd: 5311 Res = ActOnOpenMPTaskLoopSimdDirective(ClausesWithImplicit, AStmt, StartLoc, 5312 EndLoc, VarsWithInheritedDSA); 5313 AllowedNameModifiers.push_back(OMPD_taskloop); 5314 if (LangOpts.OpenMP >= 50) 5315 AllowedNameModifiers.push_back(OMPD_simd); 5316 break; 5317 case OMPD_master_taskloop: 5318 Res = ActOnOpenMPMasterTaskLoopDirective( 5319 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 5320 AllowedNameModifiers.push_back(OMPD_taskloop); 5321 break; 5322 case OMPD_master_taskloop_simd: 5323 Res = ActOnOpenMPMasterTaskLoopSimdDirective( 5324 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 5325 AllowedNameModifiers.push_back(OMPD_taskloop); 5326 if (LangOpts.OpenMP >= 50) 5327 AllowedNameModifiers.push_back(OMPD_simd); 5328 break; 5329 case OMPD_parallel_master_taskloop: 5330 Res = ActOnOpenMPParallelMasterTaskLoopDirective( 5331 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 5332 AllowedNameModifiers.push_back(OMPD_taskloop); 5333 AllowedNameModifiers.push_back(OMPD_parallel); 5334 break; 5335 case OMPD_parallel_master_taskloop_simd: 5336 Res = ActOnOpenMPParallelMasterTaskLoopSimdDirective( 5337 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 5338 AllowedNameModifiers.push_back(OMPD_taskloop); 5339 AllowedNameModifiers.push_back(OMPD_parallel); 5340 if (LangOpts.OpenMP >= 50) 5341 AllowedNameModifiers.push_back(OMPD_simd); 5342 break; 5343 case OMPD_distribute: 5344 Res = ActOnOpenMPDistributeDirective(ClausesWithImplicit, AStmt, StartLoc, 5345 EndLoc, VarsWithInheritedDSA); 5346 break; 5347 case OMPD_target_update: 5348 Res = ActOnOpenMPTargetUpdateDirective(ClausesWithImplicit, StartLoc, 5349 EndLoc, AStmt); 5350 AllowedNameModifiers.push_back(OMPD_target_update); 5351 break; 5352 case OMPD_distribute_parallel_for: 5353 Res = ActOnOpenMPDistributeParallelForDirective( 5354 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 5355 AllowedNameModifiers.push_back(OMPD_parallel); 5356 break; 5357 case OMPD_distribute_parallel_for_simd: 5358 Res = ActOnOpenMPDistributeParallelForSimdDirective( 5359 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 5360 AllowedNameModifiers.push_back(OMPD_parallel); 5361 if (LangOpts.OpenMP >= 50) 5362 AllowedNameModifiers.push_back(OMPD_simd); 5363 break; 5364 case OMPD_distribute_simd: 5365 Res = ActOnOpenMPDistributeSimdDirective( 5366 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 5367 if (LangOpts.OpenMP >= 50) 5368 AllowedNameModifiers.push_back(OMPD_simd); 5369 break; 5370 case OMPD_target_parallel_for_simd: 5371 Res = ActOnOpenMPTargetParallelForSimdDirective( 5372 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 5373 AllowedNameModifiers.push_back(OMPD_target); 5374 AllowedNameModifiers.push_back(OMPD_parallel); 5375 if (LangOpts.OpenMP >= 50) 5376 AllowedNameModifiers.push_back(OMPD_simd); 5377 break; 5378 case OMPD_target_simd: 5379 Res = ActOnOpenMPTargetSimdDirective(ClausesWithImplicit, AStmt, StartLoc, 5380 EndLoc, VarsWithInheritedDSA); 5381 AllowedNameModifiers.push_back(OMPD_target); 5382 if (LangOpts.OpenMP >= 50) 5383 AllowedNameModifiers.push_back(OMPD_simd); 5384 break; 5385 case OMPD_teams_distribute: 5386 Res = ActOnOpenMPTeamsDistributeDirective( 5387 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 5388 break; 5389 case OMPD_teams_distribute_simd: 5390 Res = ActOnOpenMPTeamsDistributeSimdDirective( 5391 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 5392 if (LangOpts.OpenMP >= 50) 5393 AllowedNameModifiers.push_back(OMPD_simd); 5394 break; 5395 case OMPD_teams_distribute_parallel_for_simd: 5396 Res = ActOnOpenMPTeamsDistributeParallelForSimdDirective( 5397 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 5398 AllowedNameModifiers.push_back(OMPD_parallel); 5399 if (LangOpts.OpenMP >= 50) 5400 AllowedNameModifiers.push_back(OMPD_simd); 5401 break; 5402 case OMPD_teams_distribute_parallel_for: 5403 Res = ActOnOpenMPTeamsDistributeParallelForDirective( 5404 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 5405 AllowedNameModifiers.push_back(OMPD_parallel); 5406 break; 5407 case OMPD_target_teams: 5408 Res = ActOnOpenMPTargetTeamsDirective(ClausesWithImplicit, AStmt, StartLoc, 5409 EndLoc); 5410 AllowedNameModifiers.push_back(OMPD_target); 5411 break; 5412 case OMPD_target_teams_distribute: 5413 Res = ActOnOpenMPTargetTeamsDistributeDirective( 5414 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 5415 AllowedNameModifiers.push_back(OMPD_target); 5416 break; 5417 case OMPD_target_teams_distribute_parallel_for: 5418 Res = ActOnOpenMPTargetTeamsDistributeParallelForDirective( 5419 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 5420 AllowedNameModifiers.push_back(OMPD_target); 5421 AllowedNameModifiers.push_back(OMPD_parallel); 5422 break; 5423 case OMPD_target_teams_distribute_parallel_for_simd: 5424 Res = ActOnOpenMPTargetTeamsDistributeParallelForSimdDirective( 5425 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 5426 AllowedNameModifiers.push_back(OMPD_target); 5427 AllowedNameModifiers.push_back(OMPD_parallel); 5428 if (LangOpts.OpenMP >= 50) 5429 AllowedNameModifiers.push_back(OMPD_simd); 5430 break; 5431 case OMPD_target_teams_distribute_simd: 5432 Res = ActOnOpenMPTargetTeamsDistributeSimdDirective( 5433 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 5434 AllowedNameModifiers.push_back(OMPD_target); 5435 if (LangOpts.OpenMP >= 50) 5436 AllowedNameModifiers.push_back(OMPD_simd); 5437 break; 5438 case OMPD_declare_target: 5439 case OMPD_end_declare_target: 5440 case OMPD_threadprivate: 5441 case OMPD_allocate: 5442 case OMPD_declare_reduction: 5443 case OMPD_declare_mapper: 5444 case OMPD_declare_simd: 5445 case OMPD_requires: 5446 case OMPD_declare_variant: 5447 case OMPD_begin_declare_variant: 5448 case OMPD_end_declare_variant: 5449 llvm_unreachable("OpenMP Directive is not allowed"); 5450 case OMPD_unknown: 5451 default: 5452 llvm_unreachable("Unknown OpenMP directive"); 5453 } 5454 5455 ErrorFound = Res.isInvalid() || ErrorFound; 5456 5457 // Check variables in the clauses if default(none) or 5458 // default(firstprivate) was specified. 5459 if (DSAStack->getDefaultDSA() == DSA_none || 5460 DSAStack->getDefaultDSA() == DSA_firstprivate) { 5461 DSAAttrChecker DSAChecker(DSAStack, *this, nullptr); 5462 for (OMPClause *C : Clauses) { 5463 switch (C->getClauseKind()) { 5464 case OMPC_num_threads: 5465 case OMPC_dist_schedule: 5466 // Do not analyse if no parent teams directive. 5467 if (isOpenMPTeamsDirective(Kind)) 5468 break; 5469 continue; 5470 case OMPC_if: 5471 if (isOpenMPTeamsDirective(Kind) && 5472 cast<OMPIfClause>(C)->getNameModifier() != OMPD_target) 5473 break; 5474 if (isOpenMPParallelDirective(Kind) && 5475 isOpenMPTaskLoopDirective(Kind) && 5476 cast<OMPIfClause>(C)->getNameModifier() != OMPD_parallel) 5477 break; 5478 continue; 5479 case OMPC_schedule: 5480 case OMPC_detach: 5481 break; 5482 case OMPC_grainsize: 5483 case OMPC_num_tasks: 5484 case OMPC_final: 5485 case OMPC_priority: 5486 // Do not analyze if no parent parallel directive. 5487 if (isOpenMPParallelDirective(Kind)) 5488 break; 5489 continue; 5490 case OMPC_ordered: 5491 case OMPC_device: 5492 case OMPC_num_teams: 5493 case OMPC_thread_limit: 5494 case OMPC_hint: 5495 case OMPC_collapse: 5496 case OMPC_safelen: 5497 case OMPC_simdlen: 5498 case OMPC_default: 5499 case OMPC_proc_bind: 5500 case OMPC_private: 5501 case OMPC_firstprivate: 5502 case OMPC_lastprivate: 5503 case OMPC_shared: 5504 case OMPC_reduction: 5505 case OMPC_task_reduction: 5506 case OMPC_in_reduction: 5507 case OMPC_linear: 5508 case OMPC_aligned: 5509 case OMPC_copyin: 5510 case OMPC_copyprivate: 5511 case OMPC_nowait: 5512 case OMPC_untied: 5513 case OMPC_mergeable: 5514 case OMPC_allocate: 5515 case OMPC_read: 5516 case OMPC_write: 5517 case OMPC_update: 5518 case OMPC_capture: 5519 case OMPC_seq_cst: 5520 case OMPC_acq_rel: 5521 case OMPC_acquire: 5522 case OMPC_release: 5523 case OMPC_relaxed: 5524 case OMPC_depend: 5525 case OMPC_threads: 5526 case OMPC_simd: 5527 case OMPC_map: 5528 case OMPC_nogroup: 5529 case OMPC_defaultmap: 5530 case OMPC_to: 5531 case OMPC_from: 5532 case OMPC_use_device_ptr: 5533 case OMPC_use_device_addr: 5534 case OMPC_is_device_ptr: 5535 case OMPC_nontemporal: 5536 case OMPC_order: 5537 case OMPC_destroy: 5538 case OMPC_inclusive: 5539 case OMPC_exclusive: 5540 case OMPC_uses_allocators: 5541 case OMPC_affinity: 5542 continue; 5543 case OMPC_allocator: 5544 case OMPC_flush: 5545 case OMPC_depobj: 5546 case OMPC_threadprivate: 5547 case OMPC_uniform: 5548 case OMPC_unknown: 5549 case OMPC_unified_address: 5550 case OMPC_unified_shared_memory: 5551 case OMPC_reverse_offload: 5552 case OMPC_dynamic_allocators: 5553 case OMPC_atomic_default_mem_order: 5554 case OMPC_device_type: 5555 case OMPC_match: 5556 default: 5557 llvm_unreachable("Unexpected clause"); 5558 } 5559 for (Stmt *CC : C->children()) { 5560 if (CC) 5561 DSAChecker.Visit(CC); 5562 } 5563 } 5564 for (const auto &P : DSAChecker.getVarsWithInheritedDSA()) 5565 VarsWithInheritedDSA[P.getFirst()] = P.getSecond(); 5566 } 5567 for (const auto &P : VarsWithInheritedDSA) { 5568 if (P.getFirst()->isImplicit() || isa<OMPCapturedExprDecl>(P.getFirst())) 5569 continue; 5570 ErrorFound = true; 5571 if (DSAStack->getDefaultDSA() == DSA_none || 5572 DSAStack->getDefaultDSA() == DSA_firstprivate) { 5573 Diag(P.second->getExprLoc(), diag::err_omp_no_dsa_for_variable) 5574 << P.first << P.second->getSourceRange(); 5575 Diag(DSAStack->getDefaultDSALocation(), diag::note_omp_default_dsa_none); 5576 } else if (getLangOpts().OpenMP >= 50) { 5577 Diag(P.second->getExprLoc(), 5578 diag::err_omp_defaultmap_no_attr_for_variable) 5579 << P.first << P.second->getSourceRange(); 5580 Diag(DSAStack->getDefaultDSALocation(), 5581 diag::note_omp_defaultmap_attr_none); 5582 } 5583 } 5584 5585 if (!AllowedNameModifiers.empty()) 5586 ErrorFound = checkIfClauses(*this, Kind, Clauses, AllowedNameModifiers) || 5587 ErrorFound; 5588 5589 if (ErrorFound) 5590 return StmtError(); 5591 5592 if (!CurContext->isDependentContext() && 5593 isOpenMPTargetExecutionDirective(Kind) && 5594 !(DSAStack->hasRequiresDeclWithClause<OMPUnifiedSharedMemoryClause>() || 5595 DSAStack->hasRequiresDeclWithClause<OMPUnifiedAddressClause>() || 5596 DSAStack->hasRequiresDeclWithClause<OMPReverseOffloadClause>() || 5597 DSAStack->hasRequiresDeclWithClause<OMPDynamicAllocatorsClause>())) { 5598 // Register target to DSA Stack. 5599 DSAStack->addTargetDirLocation(StartLoc); 5600 } 5601 5602 return Res; 5603 } 5604 5605 Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareSimdDirective( 5606 DeclGroupPtrTy DG, OMPDeclareSimdDeclAttr::BranchStateTy BS, Expr *Simdlen, 5607 ArrayRef<Expr *> Uniforms, ArrayRef<Expr *> Aligneds, 5608 ArrayRef<Expr *> Alignments, ArrayRef<Expr *> Linears, 5609 ArrayRef<unsigned> LinModifiers, ArrayRef<Expr *> Steps, SourceRange SR) { 5610 assert(Aligneds.size() == Alignments.size()); 5611 assert(Linears.size() == LinModifiers.size()); 5612 assert(Linears.size() == Steps.size()); 5613 if (!DG || DG.get().isNull()) 5614 return DeclGroupPtrTy(); 5615 5616 const int SimdId = 0; 5617 if (!DG.get().isSingleDecl()) { 5618 Diag(SR.getBegin(), diag::err_omp_single_decl_in_declare_simd_variant) 5619 << SimdId; 5620 return DG; 5621 } 5622 Decl *ADecl = DG.get().getSingleDecl(); 5623 if (auto *FTD = dyn_cast<FunctionTemplateDecl>(ADecl)) 5624 ADecl = FTD->getTemplatedDecl(); 5625 5626 auto *FD = dyn_cast<FunctionDecl>(ADecl); 5627 if (!FD) { 5628 Diag(ADecl->getLocation(), diag::err_omp_function_expected) << SimdId; 5629 return DeclGroupPtrTy(); 5630 } 5631 5632 // OpenMP [2.8.2, declare simd construct, Description] 5633 // The parameter of the simdlen clause must be a constant positive integer 5634 // expression. 5635 ExprResult SL; 5636 if (Simdlen) 5637 SL = VerifyPositiveIntegerConstantInClause(Simdlen, OMPC_simdlen); 5638 // OpenMP [2.8.2, declare simd construct, Description] 5639 // The special this pointer can be used as if was one of the arguments to the 5640 // function in any of the linear, aligned, or uniform clauses. 5641 // The uniform clause declares one or more arguments to have an invariant 5642 // value for all concurrent invocations of the function in the execution of a 5643 // single SIMD loop. 5644 llvm::DenseMap<const Decl *, const Expr *> UniformedArgs; 5645 const Expr *UniformedLinearThis = nullptr; 5646 for (const Expr *E : Uniforms) { 5647 E = E->IgnoreParenImpCasts(); 5648 if (const auto *DRE = dyn_cast<DeclRefExpr>(E)) 5649 if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) 5650 if (FD->getNumParams() > PVD->getFunctionScopeIndex() && 5651 FD->getParamDecl(PVD->getFunctionScopeIndex()) 5652 ->getCanonicalDecl() == PVD->getCanonicalDecl()) { 5653 UniformedArgs.try_emplace(PVD->getCanonicalDecl(), E); 5654 continue; 5655 } 5656 if (isa<CXXThisExpr>(E)) { 5657 UniformedLinearThis = E; 5658 continue; 5659 } 5660 Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause) 5661 << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0); 5662 } 5663 // OpenMP [2.8.2, declare simd construct, Description] 5664 // The aligned clause declares that the object to which each list item points 5665 // is aligned to the number of bytes expressed in the optional parameter of 5666 // the aligned clause. 5667 // The special this pointer can be used as if was one of the arguments to the 5668 // function in any of the linear, aligned, or uniform clauses. 5669 // The type of list items appearing in the aligned clause must be array, 5670 // pointer, reference to array, or reference to pointer. 5671 llvm::DenseMap<const Decl *, const Expr *> AlignedArgs; 5672 const Expr *AlignedThis = nullptr; 5673 for (const Expr *E : Aligneds) { 5674 E = E->IgnoreParenImpCasts(); 5675 if (const auto *DRE = dyn_cast<DeclRefExpr>(E)) 5676 if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) { 5677 const VarDecl *CanonPVD = PVD->getCanonicalDecl(); 5678 if (FD->getNumParams() > PVD->getFunctionScopeIndex() && 5679 FD->getParamDecl(PVD->getFunctionScopeIndex()) 5680 ->getCanonicalDecl() == CanonPVD) { 5681 // OpenMP [2.8.1, simd construct, Restrictions] 5682 // A list-item cannot appear in more than one aligned clause. 5683 if (AlignedArgs.count(CanonPVD) > 0) { 5684 Diag(E->getExprLoc(), diag::err_omp_used_in_clause_twice) 5685 << 1 << getOpenMPClauseName(OMPC_aligned) 5686 << E->getSourceRange(); 5687 Diag(AlignedArgs[CanonPVD]->getExprLoc(), 5688 diag::note_omp_explicit_dsa) 5689 << getOpenMPClauseName(OMPC_aligned); 5690 continue; 5691 } 5692 AlignedArgs[CanonPVD] = E; 5693 QualType QTy = PVD->getType() 5694 .getNonReferenceType() 5695 .getUnqualifiedType() 5696 .getCanonicalType(); 5697 const Type *Ty = QTy.getTypePtrOrNull(); 5698 if (!Ty || (!Ty->isArrayType() && !Ty->isPointerType())) { 5699 Diag(E->getExprLoc(), diag::err_omp_aligned_expected_array_or_ptr) 5700 << QTy << getLangOpts().CPlusPlus << E->getSourceRange(); 5701 Diag(PVD->getLocation(), diag::note_previous_decl) << PVD; 5702 } 5703 continue; 5704 } 5705 } 5706 if (isa<CXXThisExpr>(E)) { 5707 if (AlignedThis) { 5708 Diag(E->getExprLoc(), diag::err_omp_used_in_clause_twice) 5709 << 2 << getOpenMPClauseName(OMPC_aligned) << E->getSourceRange(); 5710 Diag(AlignedThis->getExprLoc(), diag::note_omp_explicit_dsa) 5711 << getOpenMPClauseName(OMPC_aligned); 5712 } 5713 AlignedThis = E; 5714 continue; 5715 } 5716 Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause) 5717 << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0); 5718 } 5719 // The optional parameter of the aligned clause, alignment, must be a constant 5720 // positive integer expression. If no optional parameter is specified, 5721 // implementation-defined default alignments for SIMD instructions on the 5722 // target platforms are assumed. 5723 SmallVector<const Expr *, 4> NewAligns; 5724 for (Expr *E : Alignments) { 5725 ExprResult Align; 5726 if (E) 5727 Align = VerifyPositiveIntegerConstantInClause(E, OMPC_aligned); 5728 NewAligns.push_back(Align.get()); 5729 } 5730 // OpenMP [2.8.2, declare simd construct, Description] 5731 // The linear clause declares one or more list items to be private to a SIMD 5732 // lane and to have a linear relationship with respect to the iteration space 5733 // of a loop. 5734 // The special this pointer can be used as if was one of the arguments to the 5735 // function in any of the linear, aligned, or uniform clauses. 5736 // When a linear-step expression is specified in a linear clause it must be 5737 // either a constant integer expression or an integer-typed parameter that is 5738 // specified in a uniform clause on the directive. 5739 llvm::DenseMap<const Decl *, const Expr *> LinearArgs; 5740 const bool IsUniformedThis = UniformedLinearThis != nullptr; 5741 auto MI = LinModifiers.begin(); 5742 for (const Expr *E : Linears) { 5743 auto LinKind = static_cast<OpenMPLinearClauseKind>(*MI); 5744 ++MI; 5745 E = E->IgnoreParenImpCasts(); 5746 if (const auto *DRE = dyn_cast<DeclRefExpr>(E)) 5747 if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) { 5748 const VarDecl *CanonPVD = PVD->getCanonicalDecl(); 5749 if (FD->getNumParams() > PVD->getFunctionScopeIndex() && 5750 FD->getParamDecl(PVD->getFunctionScopeIndex()) 5751 ->getCanonicalDecl() == CanonPVD) { 5752 // OpenMP [2.15.3.7, linear Clause, Restrictions] 5753 // A list-item cannot appear in more than one linear clause. 5754 if (LinearArgs.count(CanonPVD) > 0) { 5755 Diag(E->getExprLoc(), diag::err_omp_wrong_dsa) 5756 << getOpenMPClauseName(OMPC_linear) 5757 << getOpenMPClauseName(OMPC_linear) << E->getSourceRange(); 5758 Diag(LinearArgs[CanonPVD]->getExprLoc(), 5759 diag::note_omp_explicit_dsa) 5760 << getOpenMPClauseName(OMPC_linear); 5761 continue; 5762 } 5763 // Each argument can appear in at most one uniform or linear clause. 5764 if (UniformedArgs.count(CanonPVD) > 0) { 5765 Diag(E->getExprLoc(), diag::err_omp_wrong_dsa) 5766 << getOpenMPClauseName(OMPC_linear) 5767 << getOpenMPClauseName(OMPC_uniform) << E->getSourceRange(); 5768 Diag(UniformedArgs[CanonPVD]->getExprLoc(), 5769 diag::note_omp_explicit_dsa) 5770 << getOpenMPClauseName(OMPC_uniform); 5771 continue; 5772 } 5773 LinearArgs[CanonPVD] = E; 5774 if (E->isValueDependent() || E->isTypeDependent() || 5775 E->isInstantiationDependent() || 5776 E->containsUnexpandedParameterPack()) 5777 continue; 5778 (void)CheckOpenMPLinearDecl(CanonPVD, E->getExprLoc(), LinKind, 5779 PVD->getOriginalType(), 5780 /*IsDeclareSimd=*/true); 5781 continue; 5782 } 5783 } 5784 if (isa<CXXThisExpr>(E)) { 5785 if (UniformedLinearThis) { 5786 Diag(E->getExprLoc(), diag::err_omp_wrong_dsa) 5787 << getOpenMPClauseName(OMPC_linear) 5788 << getOpenMPClauseName(IsUniformedThis ? OMPC_uniform : OMPC_linear) 5789 << E->getSourceRange(); 5790 Diag(UniformedLinearThis->getExprLoc(), diag::note_omp_explicit_dsa) 5791 << getOpenMPClauseName(IsUniformedThis ? OMPC_uniform 5792 : OMPC_linear); 5793 continue; 5794 } 5795 UniformedLinearThis = E; 5796 if (E->isValueDependent() || E->isTypeDependent() || 5797 E->isInstantiationDependent() || E->containsUnexpandedParameterPack()) 5798 continue; 5799 (void)CheckOpenMPLinearDecl(/*D=*/nullptr, E->getExprLoc(), LinKind, 5800 E->getType(), /*IsDeclareSimd=*/true); 5801 continue; 5802 } 5803 Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause) 5804 << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0); 5805 } 5806 Expr *Step = nullptr; 5807 Expr *NewStep = nullptr; 5808 SmallVector<Expr *, 4> NewSteps; 5809 for (Expr *E : Steps) { 5810 // Skip the same step expression, it was checked already. 5811 if (Step == E || !E) { 5812 NewSteps.push_back(E ? NewStep : nullptr); 5813 continue; 5814 } 5815 Step = E; 5816 if (const auto *DRE = dyn_cast<DeclRefExpr>(Step)) 5817 if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) { 5818 const VarDecl *CanonPVD = PVD->getCanonicalDecl(); 5819 if (UniformedArgs.count(CanonPVD) == 0) { 5820 Diag(Step->getExprLoc(), diag::err_omp_expected_uniform_param) 5821 << Step->getSourceRange(); 5822 } else if (E->isValueDependent() || E->isTypeDependent() || 5823 E->isInstantiationDependent() || 5824 E->containsUnexpandedParameterPack() || 5825 CanonPVD->getType()->hasIntegerRepresentation()) { 5826 NewSteps.push_back(Step); 5827 } else { 5828 Diag(Step->getExprLoc(), diag::err_omp_expected_int_param) 5829 << Step->getSourceRange(); 5830 } 5831 continue; 5832 } 5833 NewStep = Step; 5834 if (Step && !Step->isValueDependent() && !Step->isTypeDependent() && 5835 !Step->isInstantiationDependent() && 5836 !Step->containsUnexpandedParameterPack()) { 5837 NewStep = PerformOpenMPImplicitIntegerConversion(Step->getExprLoc(), Step) 5838 .get(); 5839 if (NewStep) 5840 NewStep = 5841 VerifyIntegerConstantExpression(NewStep, /*FIXME*/ AllowFold).get(); 5842 } 5843 NewSteps.push_back(NewStep); 5844 } 5845 auto *NewAttr = OMPDeclareSimdDeclAttr::CreateImplicit( 5846 Context, BS, SL.get(), const_cast<Expr **>(Uniforms.data()), 5847 Uniforms.size(), const_cast<Expr **>(Aligneds.data()), Aligneds.size(), 5848 const_cast<Expr **>(NewAligns.data()), NewAligns.size(), 5849 const_cast<Expr **>(Linears.data()), Linears.size(), 5850 const_cast<unsigned *>(LinModifiers.data()), LinModifiers.size(), 5851 NewSteps.data(), NewSteps.size(), SR); 5852 ADecl->addAttr(NewAttr); 5853 return DG; 5854 } 5855 5856 static void setPrototype(Sema &S, FunctionDecl *FD, FunctionDecl *FDWithProto, 5857 QualType NewType) { 5858 assert(NewType->isFunctionProtoType() && 5859 "Expected function type with prototype."); 5860 assert(FD->getType()->isFunctionNoProtoType() && 5861 "Expected function with type with no prototype."); 5862 assert(FDWithProto->getType()->isFunctionProtoType() && 5863 "Expected function with prototype."); 5864 // Synthesize parameters with the same types. 5865 FD->setType(NewType); 5866 SmallVector<ParmVarDecl *, 16> Params; 5867 for (const ParmVarDecl *P : FDWithProto->parameters()) { 5868 auto *Param = ParmVarDecl::Create(S.getASTContext(), FD, SourceLocation(), 5869 SourceLocation(), nullptr, P->getType(), 5870 /*TInfo=*/nullptr, SC_None, nullptr); 5871 Param->setScopeInfo(0, Params.size()); 5872 Param->setImplicit(); 5873 Params.push_back(Param); 5874 } 5875 5876 FD->setParams(Params); 5877 } 5878 5879 Sema::OMPDeclareVariantScope::OMPDeclareVariantScope(OMPTraitInfo &TI) 5880 : TI(&TI), NameSuffix(TI.getMangledName()) {} 5881 5882 void Sema::ActOnStartOfFunctionDefinitionInOpenMPDeclareVariantScope( 5883 Scope *S, Declarator &D, MultiTemplateParamsArg TemplateParamLists, 5884 SmallVectorImpl<FunctionDecl *> &Bases) { 5885 if (!D.getIdentifier()) 5886 return; 5887 5888 OMPDeclareVariantScope &DVScope = OMPDeclareVariantScopes.back(); 5889 5890 // Template specialization is an extension, check if we do it. 5891 bool IsTemplated = !TemplateParamLists.empty(); 5892 if (IsTemplated & 5893 !DVScope.TI->isExtensionActive( 5894 llvm::omp::TraitProperty::implementation_extension_allow_templates)) 5895 return; 5896 5897 IdentifierInfo *BaseII = D.getIdentifier(); 5898 LookupResult Lookup(*this, DeclarationName(BaseII), D.getIdentifierLoc(), 5899 LookupOrdinaryName); 5900 LookupParsedName(Lookup, S, &D.getCXXScopeSpec()); 5901 5902 TypeSourceInfo *TInfo = GetTypeForDeclarator(D, S); 5903 QualType FType = TInfo->getType(); 5904 5905 bool IsConstexpr = D.getDeclSpec().getConstexprSpecifier() == CSK_constexpr; 5906 bool IsConsteval = D.getDeclSpec().getConstexprSpecifier() == CSK_consteval; 5907 5908 for (auto *Candidate : Lookup) { 5909 auto *CandidateDecl = Candidate->getUnderlyingDecl(); 5910 FunctionDecl *UDecl = nullptr; 5911 if (IsTemplated && isa<FunctionTemplateDecl>(CandidateDecl)) 5912 UDecl = cast<FunctionTemplateDecl>(CandidateDecl)->getTemplatedDecl(); 5913 else if (!IsTemplated) 5914 UDecl = dyn_cast<FunctionDecl>(CandidateDecl); 5915 if (!UDecl) 5916 continue; 5917 5918 // Don't specialize constexpr/consteval functions with 5919 // non-constexpr/consteval functions. 5920 if (UDecl->isConstexpr() && !IsConstexpr) 5921 continue; 5922 if (UDecl->isConsteval() && !IsConsteval) 5923 continue; 5924 5925 QualType UDeclTy = UDecl->getType(); 5926 if (!UDeclTy->isDependentType()) { 5927 QualType NewType = Context.mergeFunctionTypes( 5928 FType, UDeclTy, /* OfBlockPointer */ false, 5929 /* Unqualified */ false, /* AllowCXX */ true); 5930 if (NewType.isNull()) 5931 continue; 5932 } 5933 5934 // Found a base! 5935 Bases.push_back(UDecl); 5936 } 5937 5938 bool UseImplicitBase = !DVScope.TI->isExtensionActive( 5939 llvm::omp::TraitProperty::implementation_extension_disable_implicit_base); 5940 // If no base was found we create a declaration that we use as base. 5941 if (Bases.empty() && UseImplicitBase) { 5942 D.setFunctionDefinitionKind(FDK_Declaration); 5943 Decl *BaseD = HandleDeclarator(S, D, TemplateParamLists); 5944 BaseD->setImplicit(true); 5945 if (auto *BaseTemplD = dyn_cast<FunctionTemplateDecl>(BaseD)) 5946 Bases.push_back(BaseTemplD->getTemplatedDecl()); 5947 else 5948 Bases.push_back(cast<FunctionDecl>(BaseD)); 5949 } 5950 5951 std::string MangledName; 5952 MangledName += D.getIdentifier()->getName(); 5953 MangledName += getOpenMPVariantManglingSeparatorStr(); 5954 MangledName += DVScope.NameSuffix; 5955 IdentifierInfo &VariantII = Context.Idents.get(MangledName); 5956 5957 VariantII.setMangledOpenMPVariantName(true); 5958 D.SetIdentifier(&VariantII, D.getBeginLoc()); 5959 } 5960 5961 void Sema::ActOnFinishedFunctionDefinitionInOpenMPDeclareVariantScope( 5962 Decl *D, SmallVectorImpl<FunctionDecl *> &Bases) { 5963 // Do not mark function as is used to prevent its emission if this is the 5964 // only place where it is used. 5965 EnterExpressionEvaluationContext Unevaluated( 5966 *this, Sema::ExpressionEvaluationContext::Unevaluated); 5967 5968 FunctionDecl *FD = nullptr; 5969 if (auto *UTemplDecl = dyn_cast<FunctionTemplateDecl>(D)) 5970 FD = UTemplDecl->getTemplatedDecl(); 5971 else 5972 FD = cast<FunctionDecl>(D); 5973 auto *VariantFuncRef = DeclRefExpr::Create( 5974 Context, NestedNameSpecifierLoc(), SourceLocation(), FD, 5975 /* RefersToEnclosingVariableOrCapture */ false, 5976 /* NameLoc */ FD->getLocation(), FD->getType(), ExprValueKind::VK_RValue); 5977 5978 OMPDeclareVariantScope &DVScope = OMPDeclareVariantScopes.back(); 5979 auto *OMPDeclareVariantA = OMPDeclareVariantAttr::CreateImplicit( 5980 Context, VariantFuncRef, DVScope.TI); 5981 for (FunctionDecl *BaseFD : Bases) 5982 BaseFD->addAttr(OMPDeclareVariantA); 5983 } 5984 5985 ExprResult Sema::ActOnOpenMPCall(ExprResult Call, Scope *Scope, 5986 SourceLocation LParenLoc, 5987 MultiExprArg ArgExprs, 5988 SourceLocation RParenLoc, Expr *ExecConfig) { 5989 // The common case is a regular call we do not want to specialize at all. Try 5990 // to make that case fast by bailing early. 5991 CallExpr *CE = dyn_cast<CallExpr>(Call.get()); 5992 if (!CE) 5993 return Call; 5994 5995 FunctionDecl *CalleeFnDecl = CE->getDirectCallee(); 5996 if (!CalleeFnDecl) 5997 return Call; 5998 5999 if (!CalleeFnDecl->hasAttr<OMPDeclareVariantAttr>()) 6000 return Call; 6001 6002 ASTContext &Context = getASTContext(); 6003 std::function<void(StringRef)> DiagUnknownTrait = [this, 6004 CE](StringRef ISATrait) { 6005 // TODO Track the selector locations in a way that is accessible here to 6006 // improve the diagnostic location. 6007 Diag(CE->getBeginLoc(), diag::warn_unknown_declare_variant_isa_trait) 6008 << ISATrait; 6009 }; 6010 TargetOMPContext OMPCtx(Context, std::move(DiagUnknownTrait), 6011 getCurFunctionDecl()); 6012 6013 QualType CalleeFnType = CalleeFnDecl->getType(); 6014 6015 SmallVector<Expr *, 4> Exprs; 6016 SmallVector<VariantMatchInfo, 4> VMIs; 6017 while (CalleeFnDecl) { 6018 for (OMPDeclareVariantAttr *A : 6019 CalleeFnDecl->specific_attrs<OMPDeclareVariantAttr>()) { 6020 Expr *VariantRef = A->getVariantFuncRef(); 6021 6022 VariantMatchInfo VMI; 6023 OMPTraitInfo &TI = A->getTraitInfo(); 6024 TI.getAsVariantMatchInfo(Context, VMI); 6025 if (!isVariantApplicableInContext(VMI, OMPCtx, 6026 /* DeviceSetOnly */ false)) 6027 continue; 6028 6029 VMIs.push_back(VMI); 6030 Exprs.push_back(VariantRef); 6031 } 6032 6033 CalleeFnDecl = CalleeFnDecl->getPreviousDecl(); 6034 } 6035 6036 ExprResult NewCall; 6037 do { 6038 int BestIdx = getBestVariantMatchForContext(VMIs, OMPCtx); 6039 if (BestIdx < 0) 6040 return Call; 6041 Expr *BestExpr = cast<DeclRefExpr>(Exprs[BestIdx]); 6042 Decl *BestDecl = cast<DeclRefExpr>(BestExpr)->getDecl(); 6043 6044 { 6045 // Try to build a (member) call expression for the current best applicable 6046 // variant expression. We allow this to fail in which case we continue 6047 // with the next best variant expression. The fail case is part of the 6048 // implementation defined behavior in the OpenMP standard when it talks 6049 // about what differences in the function prototypes: "Any differences 6050 // that the specific OpenMP context requires in the prototype of the 6051 // variant from the base function prototype are implementation defined." 6052 // This wording is there to allow the specialized variant to have a 6053 // different type than the base function. This is intended and OK but if 6054 // we cannot create a call the difference is not in the "implementation 6055 // defined range" we allow. 6056 Sema::TentativeAnalysisScope Trap(*this); 6057 6058 if (auto *SpecializedMethod = dyn_cast<CXXMethodDecl>(BestDecl)) { 6059 auto *MemberCall = dyn_cast<CXXMemberCallExpr>(CE); 6060 BestExpr = MemberExpr::CreateImplicit( 6061 Context, MemberCall->getImplicitObjectArgument(), 6062 /* IsArrow */ false, SpecializedMethod, Context.BoundMemberTy, 6063 MemberCall->getValueKind(), MemberCall->getObjectKind()); 6064 } 6065 NewCall = BuildCallExpr(Scope, BestExpr, LParenLoc, ArgExprs, RParenLoc, 6066 ExecConfig); 6067 if (NewCall.isUsable()) { 6068 if (CallExpr *NCE = dyn_cast<CallExpr>(NewCall.get())) { 6069 FunctionDecl *NewCalleeFnDecl = NCE->getDirectCallee(); 6070 QualType NewType = Context.mergeFunctionTypes( 6071 CalleeFnType, NewCalleeFnDecl->getType(), 6072 /* OfBlockPointer */ false, 6073 /* Unqualified */ false, /* AllowCXX */ true); 6074 if (!NewType.isNull()) 6075 break; 6076 // Don't use the call if the function type was not compatible. 6077 NewCall = nullptr; 6078 } 6079 } 6080 } 6081 6082 VMIs.erase(VMIs.begin() + BestIdx); 6083 Exprs.erase(Exprs.begin() + BestIdx); 6084 } while (!VMIs.empty()); 6085 6086 if (!NewCall.isUsable()) 6087 return Call; 6088 return PseudoObjectExpr::Create(Context, CE, {NewCall.get()}, 0); 6089 } 6090 6091 Optional<std::pair<FunctionDecl *, Expr *>> 6092 Sema::checkOpenMPDeclareVariantFunction(Sema::DeclGroupPtrTy DG, 6093 Expr *VariantRef, OMPTraitInfo &TI, 6094 SourceRange SR) { 6095 if (!DG || DG.get().isNull()) 6096 return None; 6097 6098 const int VariantId = 1; 6099 // Must be applied only to single decl. 6100 if (!DG.get().isSingleDecl()) { 6101 Diag(SR.getBegin(), diag::err_omp_single_decl_in_declare_simd_variant) 6102 << VariantId << SR; 6103 return None; 6104 } 6105 Decl *ADecl = DG.get().getSingleDecl(); 6106 if (auto *FTD = dyn_cast<FunctionTemplateDecl>(ADecl)) 6107 ADecl = FTD->getTemplatedDecl(); 6108 6109 // Decl must be a function. 6110 auto *FD = dyn_cast<FunctionDecl>(ADecl); 6111 if (!FD) { 6112 Diag(ADecl->getLocation(), diag::err_omp_function_expected) 6113 << VariantId << SR; 6114 return None; 6115 } 6116 6117 auto &&HasMultiVersionAttributes = [](const FunctionDecl *FD) { 6118 return FD->hasAttrs() && 6119 (FD->hasAttr<CPUDispatchAttr>() || FD->hasAttr<CPUSpecificAttr>() || 6120 FD->hasAttr<TargetAttr>()); 6121 }; 6122 // OpenMP is not compatible with CPU-specific attributes. 6123 if (HasMultiVersionAttributes(FD)) { 6124 Diag(FD->getLocation(), diag::err_omp_declare_variant_incompat_attributes) 6125 << SR; 6126 return None; 6127 } 6128 6129 // Allow #pragma omp declare variant only if the function is not used. 6130 if (FD->isUsed(false)) 6131 Diag(SR.getBegin(), diag::warn_omp_declare_variant_after_used) 6132 << FD->getLocation(); 6133 6134 // Check if the function was emitted already. 6135 const FunctionDecl *Definition; 6136 if (!FD->isThisDeclarationADefinition() && FD->isDefined(Definition) && 6137 (LangOpts.EmitAllDecls || Context.DeclMustBeEmitted(Definition))) 6138 Diag(SR.getBegin(), diag::warn_omp_declare_variant_after_emitted) 6139 << FD->getLocation(); 6140 6141 // The VariantRef must point to function. 6142 if (!VariantRef) { 6143 Diag(SR.getBegin(), diag::err_omp_function_expected) << VariantId; 6144 return None; 6145 } 6146 6147 auto ShouldDelayChecks = [](Expr *&E, bool) { 6148 return E && (E->isTypeDependent() || E->isValueDependent() || 6149 E->containsUnexpandedParameterPack() || 6150 E->isInstantiationDependent()); 6151 }; 6152 // Do not check templates, wait until instantiation. 6153 if (FD->isDependentContext() || ShouldDelayChecks(VariantRef, false) || 6154 TI.anyScoreOrCondition(ShouldDelayChecks)) 6155 return std::make_pair(FD, VariantRef); 6156 6157 // Deal with non-constant score and user condition expressions. 6158 auto HandleNonConstantScoresAndConditions = [this](Expr *&E, 6159 bool IsScore) -> bool { 6160 if (!E || E->isIntegerConstantExpr(Context)) 6161 return false; 6162 6163 if (IsScore) { 6164 // We warn on non-constant scores and pretend they were not present. 6165 Diag(E->getExprLoc(), diag::warn_omp_declare_variant_score_not_constant) 6166 << E; 6167 E = nullptr; 6168 } else { 6169 // We could replace a non-constant user condition with "false" but we 6170 // will soon need to handle these anyway for the dynamic version of 6171 // OpenMP context selectors. 6172 Diag(E->getExprLoc(), 6173 diag::err_omp_declare_variant_user_condition_not_constant) 6174 << E; 6175 } 6176 return true; 6177 }; 6178 if (TI.anyScoreOrCondition(HandleNonConstantScoresAndConditions)) 6179 return None; 6180 6181 // Convert VariantRef expression to the type of the original function to 6182 // resolve possible conflicts. 6183 ExprResult VariantRefCast = VariantRef; 6184 if (LangOpts.CPlusPlus) { 6185 QualType FnPtrType; 6186 auto *Method = dyn_cast<CXXMethodDecl>(FD); 6187 if (Method && !Method->isStatic()) { 6188 const Type *ClassType = 6189 Context.getTypeDeclType(Method->getParent()).getTypePtr(); 6190 FnPtrType = Context.getMemberPointerType(FD->getType(), ClassType); 6191 ExprResult ER; 6192 { 6193 // Build adrr_of unary op to correctly handle type checks for member 6194 // functions. 6195 Sema::TentativeAnalysisScope Trap(*this); 6196 ER = CreateBuiltinUnaryOp(VariantRef->getBeginLoc(), UO_AddrOf, 6197 VariantRef); 6198 } 6199 if (!ER.isUsable()) { 6200 Diag(VariantRef->getExprLoc(), diag::err_omp_function_expected) 6201 << VariantId << VariantRef->getSourceRange(); 6202 return None; 6203 } 6204 VariantRef = ER.get(); 6205 } else { 6206 FnPtrType = Context.getPointerType(FD->getType()); 6207 } 6208 QualType VarianPtrType = Context.getPointerType(VariantRef->getType()); 6209 if (VarianPtrType.getUnqualifiedType() != FnPtrType.getUnqualifiedType()) { 6210 ImplicitConversionSequence ICS = TryImplicitConversion( 6211 VariantRef, FnPtrType.getUnqualifiedType(), 6212 /*SuppressUserConversions=*/false, AllowedExplicit::None, 6213 /*InOverloadResolution=*/false, 6214 /*CStyle=*/false, 6215 /*AllowObjCWritebackConversion=*/false); 6216 if (ICS.isFailure()) { 6217 Diag(VariantRef->getExprLoc(), 6218 diag::err_omp_declare_variant_incompat_types) 6219 << VariantRef->getType() 6220 << ((Method && !Method->isStatic()) ? FnPtrType : FD->getType()) 6221 << VariantRef->getSourceRange(); 6222 return None; 6223 } 6224 VariantRefCast = PerformImplicitConversion( 6225 VariantRef, FnPtrType.getUnqualifiedType(), AA_Converting); 6226 if (!VariantRefCast.isUsable()) 6227 return None; 6228 } 6229 // Drop previously built artificial addr_of unary op for member functions. 6230 if (Method && !Method->isStatic()) { 6231 Expr *PossibleAddrOfVariantRef = VariantRefCast.get(); 6232 if (auto *UO = dyn_cast<UnaryOperator>( 6233 PossibleAddrOfVariantRef->IgnoreImplicit())) 6234 VariantRefCast = UO->getSubExpr(); 6235 } 6236 } 6237 6238 ExprResult ER = CheckPlaceholderExpr(VariantRefCast.get()); 6239 if (!ER.isUsable() || 6240 !ER.get()->IgnoreParenImpCasts()->getType()->isFunctionType()) { 6241 Diag(VariantRef->getExprLoc(), diag::err_omp_function_expected) 6242 << VariantId << VariantRef->getSourceRange(); 6243 return None; 6244 } 6245 6246 // The VariantRef must point to function. 6247 auto *DRE = dyn_cast<DeclRefExpr>(ER.get()->IgnoreParenImpCasts()); 6248 if (!DRE) { 6249 Diag(VariantRef->getExprLoc(), diag::err_omp_function_expected) 6250 << VariantId << VariantRef->getSourceRange(); 6251 return None; 6252 } 6253 auto *NewFD = dyn_cast_or_null<FunctionDecl>(DRE->getDecl()); 6254 if (!NewFD) { 6255 Diag(VariantRef->getExprLoc(), diag::err_omp_function_expected) 6256 << VariantId << VariantRef->getSourceRange(); 6257 return None; 6258 } 6259 6260 // Check if function types are compatible in C. 6261 if (!LangOpts.CPlusPlus) { 6262 QualType NewType = 6263 Context.mergeFunctionTypes(FD->getType(), NewFD->getType()); 6264 if (NewType.isNull()) { 6265 Diag(VariantRef->getExprLoc(), 6266 diag::err_omp_declare_variant_incompat_types) 6267 << NewFD->getType() << FD->getType() << VariantRef->getSourceRange(); 6268 return None; 6269 } 6270 if (NewType->isFunctionProtoType()) { 6271 if (FD->getType()->isFunctionNoProtoType()) 6272 setPrototype(*this, FD, NewFD, NewType); 6273 else if (NewFD->getType()->isFunctionNoProtoType()) 6274 setPrototype(*this, NewFD, FD, NewType); 6275 } 6276 } 6277 6278 // Check if variant function is not marked with declare variant directive. 6279 if (NewFD->hasAttrs() && NewFD->hasAttr<OMPDeclareVariantAttr>()) { 6280 Diag(VariantRef->getExprLoc(), 6281 diag::warn_omp_declare_variant_marked_as_declare_variant) 6282 << VariantRef->getSourceRange(); 6283 SourceRange SR = 6284 NewFD->specific_attr_begin<OMPDeclareVariantAttr>()->getRange(); 6285 Diag(SR.getBegin(), diag::note_omp_marked_declare_variant_here) << SR; 6286 return None; 6287 } 6288 6289 enum DoesntSupport { 6290 VirtFuncs = 1, 6291 Constructors = 3, 6292 Destructors = 4, 6293 DeletedFuncs = 5, 6294 DefaultedFuncs = 6, 6295 ConstexprFuncs = 7, 6296 ConstevalFuncs = 8, 6297 }; 6298 if (const auto *CXXFD = dyn_cast<CXXMethodDecl>(FD)) { 6299 if (CXXFD->isVirtual()) { 6300 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support) 6301 << VirtFuncs; 6302 return None; 6303 } 6304 6305 if (isa<CXXConstructorDecl>(FD)) { 6306 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support) 6307 << Constructors; 6308 return None; 6309 } 6310 6311 if (isa<CXXDestructorDecl>(FD)) { 6312 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support) 6313 << Destructors; 6314 return None; 6315 } 6316 } 6317 6318 if (FD->isDeleted()) { 6319 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support) 6320 << DeletedFuncs; 6321 return None; 6322 } 6323 6324 if (FD->isDefaulted()) { 6325 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support) 6326 << DefaultedFuncs; 6327 return None; 6328 } 6329 6330 if (FD->isConstexpr()) { 6331 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support) 6332 << (NewFD->isConsteval() ? ConstevalFuncs : ConstexprFuncs); 6333 return None; 6334 } 6335 6336 // Check general compatibility. 6337 if (areMultiversionVariantFunctionsCompatible( 6338 FD, NewFD, PartialDiagnostic::NullDiagnostic(), 6339 PartialDiagnosticAt(SourceLocation(), 6340 PartialDiagnostic::NullDiagnostic()), 6341 PartialDiagnosticAt( 6342 VariantRef->getExprLoc(), 6343 PDiag(diag::err_omp_declare_variant_doesnt_support)), 6344 PartialDiagnosticAt(VariantRef->getExprLoc(), 6345 PDiag(diag::err_omp_declare_variant_diff) 6346 << FD->getLocation()), 6347 /*TemplatesSupported=*/true, /*ConstexprSupported=*/false, 6348 /*CLinkageMayDiffer=*/true)) 6349 return None; 6350 return std::make_pair(FD, cast<Expr>(DRE)); 6351 } 6352 6353 void Sema::ActOnOpenMPDeclareVariantDirective(FunctionDecl *FD, 6354 Expr *VariantRef, 6355 OMPTraitInfo &TI, 6356 SourceRange SR) { 6357 auto *NewAttr = 6358 OMPDeclareVariantAttr::CreateImplicit(Context, VariantRef, &TI, SR); 6359 FD->addAttr(NewAttr); 6360 } 6361 6362 StmtResult Sema::ActOnOpenMPParallelDirective(ArrayRef<OMPClause *> Clauses, 6363 Stmt *AStmt, 6364 SourceLocation StartLoc, 6365 SourceLocation EndLoc) { 6366 if (!AStmt) 6367 return StmtError(); 6368 6369 auto *CS = cast<CapturedStmt>(AStmt); 6370 // 1.2.2 OpenMP Language Terminology 6371 // Structured block - An executable statement with a single entry at the 6372 // top and a single exit at the bottom. 6373 // The point of exit cannot be a branch out of the structured block. 6374 // longjmp() and throw() must not violate the entry/exit criteria. 6375 CS->getCapturedDecl()->setNothrow(); 6376 6377 setFunctionHasBranchProtectedScope(); 6378 6379 return OMPParallelDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt, 6380 DSAStack->getTaskgroupReductionRef(), 6381 DSAStack->isCancelRegion()); 6382 } 6383 6384 namespace { 6385 /// Iteration space of a single for loop. 6386 struct LoopIterationSpace final { 6387 /// True if the condition operator is the strict compare operator (<, > or 6388 /// !=). 6389 bool IsStrictCompare = false; 6390 /// Condition of the loop. 6391 Expr *PreCond = nullptr; 6392 /// This expression calculates the number of iterations in the loop. 6393 /// It is always possible to calculate it before starting the loop. 6394 Expr *NumIterations = nullptr; 6395 /// The loop counter variable. 6396 Expr *CounterVar = nullptr; 6397 /// Private loop counter variable. 6398 Expr *PrivateCounterVar = nullptr; 6399 /// This is initializer for the initial value of #CounterVar. 6400 Expr *CounterInit = nullptr; 6401 /// This is step for the #CounterVar used to generate its update: 6402 /// #CounterVar = #CounterInit + #CounterStep * CurrentIteration. 6403 Expr *CounterStep = nullptr; 6404 /// Should step be subtracted? 6405 bool Subtract = false; 6406 /// Source range of the loop init. 6407 SourceRange InitSrcRange; 6408 /// Source range of the loop condition. 6409 SourceRange CondSrcRange; 6410 /// Source range of the loop increment. 6411 SourceRange IncSrcRange; 6412 /// Minimum value that can have the loop control variable. Used to support 6413 /// non-rectangular loops. Applied only for LCV with the non-iterator types, 6414 /// since only such variables can be used in non-loop invariant expressions. 6415 Expr *MinValue = nullptr; 6416 /// Maximum value that can have the loop control variable. Used to support 6417 /// non-rectangular loops. Applied only for LCV with the non-iterator type, 6418 /// since only such variables can be used in non-loop invariant expressions. 6419 Expr *MaxValue = nullptr; 6420 /// true, if the lower bound depends on the outer loop control var. 6421 bool IsNonRectangularLB = false; 6422 /// true, if the upper bound depends on the outer loop control var. 6423 bool IsNonRectangularUB = false; 6424 /// Index of the loop this loop depends on and forms non-rectangular loop 6425 /// nest. 6426 unsigned LoopDependentIdx = 0; 6427 /// Final condition for the non-rectangular loop nest support. It is used to 6428 /// check that the number of iterations for this particular counter must be 6429 /// finished. 6430 Expr *FinalCondition = nullptr; 6431 }; 6432 6433 /// Helper class for checking canonical form of the OpenMP loops and 6434 /// extracting iteration space of each loop in the loop nest, that will be used 6435 /// for IR generation. 6436 class OpenMPIterationSpaceChecker { 6437 /// Reference to Sema. 6438 Sema &SemaRef; 6439 /// Data-sharing stack. 6440 DSAStackTy &Stack; 6441 /// A location for diagnostics (when there is no some better location). 6442 SourceLocation DefaultLoc; 6443 /// A location for diagnostics (when increment is not compatible). 6444 SourceLocation ConditionLoc; 6445 /// A source location for referring to loop init later. 6446 SourceRange InitSrcRange; 6447 /// A source location for referring to condition later. 6448 SourceRange ConditionSrcRange; 6449 /// A source location for referring to increment later. 6450 SourceRange IncrementSrcRange; 6451 /// Loop variable. 6452 ValueDecl *LCDecl = nullptr; 6453 /// Reference to loop variable. 6454 Expr *LCRef = nullptr; 6455 /// Lower bound (initializer for the var). 6456 Expr *LB = nullptr; 6457 /// Upper bound. 6458 Expr *UB = nullptr; 6459 /// Loop step (increment). 6460 Expr *Step = nullptr; 6461 /// This flag is true when condition is one of: 6462 /// Var < UB 6463 /// Var <= UB 6464 /// UB > Var 6465 /// UB >= Var 6466 /// This will have no value when the condition is != 6467 llvm::Optional<bool> TestIsLessOp; 6468 /// This flag is true when condition is strict ( < or > ). 6469 bool TestIsStrictOp = false; 6470 /// This flag is true when step is subtracted on each iteration. 6471 bool SubtractStep = false; 6472 /// The outer loop counter this loop depends on (if any). 6473 const ValueDecl *DepDecl = nullptr; 6474 /// Contains number of loop (starts from 1) on which loop counter init 6475 /// expression of this loop depends on. 6476 Optional<unsigned> InitDependOnLC; 6477 /// Contains number of loop (starts from 1) on which loop counter condition 6478 /// expression of this loop depends on. 6479 Optional<unsigned> CondDependOnLC; 6480 /// Checks if the provide statement depends on the loop counter. 6481 Optional<unsigned> doesDependOnLoopCounter(const Stmt *S, bool IsInitializer); 6482 /// Original condition required for checking of the exit condition for 6483 /// non-rectangular loop. 6484 Expr *Condition = nullptr; 6485 6486 public: 6487 OpenMPIterationSpaceChecker(Sema &SemaRef, DSAStackTy &Stack, 6488 SourceLocation DefaultLoc) 6489 : SemaRef(SemaRef), Stack(Stack), DefaultLoc(DefaultLoc), 6490 ConditionLoc(DefaultLoc) {} 6491 /// Check init-expr for canonical loop form and save loop counter 6492 /// variable - #Var and its initialization value - #LB. 6493 bool checkAndSetInit(Stmt *S, bool EmitDiags = true); 6494 /// Check test-expr for canonical form, save upper-bound (#UB), flags 6495 /// for less/greater and for strict/non-strict comparison. 6496 bool checkAndSetCond(Expr *S); 6497 /// Check incr-expr for canonical loop form and return true if it 6498 /// does not conform, otherwise save loop step (#Step). 6499 bool checkAndSetInc(Expr *S); 6500 /// Return the loop counter variable. 6501 ValueDecl *getLoopDecl() const { return LCDecl; } 6502 /// Return the reference expression to loop counter variable. 6503 Expr *getLoopDeclRefExpr() const { return LCRef; } 6504 /// Source range of the loop init. 6505 SourceRange getInitSrcRange() const { return InitSrcRange; } 6506 /// Source range of the loop condition. 6507 SourceRange getConditionSrcRange() const { return ConditionSrcRange; } 6508 /// Source range of the loop increment. 6509 SourceRange getIncrementSrcRange() const { return IncrementSrcRange; } 6510 /// True if the step should be subtracted. 6511 bool shouldSubtractStep() const { return SubtractStep; } 6512 /// True, if the compare operator is strict (<, > or !=). 6513 bool isStrictTestOp() const { return TestIsStrictOp; } 6514 /// Build the expression to calculate the number of iterations. 6515 Expr *buildNumIterations( 6516 Scope *S, ArrayRef<LoopIterationSpace> ResultIterSpaces, bool LimitedType, 6517 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const; 6518 /// Build the precondition expression for the loops. 6519 Expr * 6520 buildPreCond(Scope *S, Expr *Cond, 6521 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const; 6522 /// Build reference expression to the counter be used for codegen. 6523 DeclRefExpr * 6524 buildCounterVar(llvm::MapVector<const Expr *, DeclRefExpr *> &Captures, 6525 DSAStackTy &DSA) const; 6526 /// Build reference expression to the private counter be used for 6527 /// codegen. 6528 Expr *buildPrivateCounterVar() const; 6529 /// Build initialization of the counter be used for codegen. 6530 Expr *buildCounterInit() const; 6531 /// Build step of the counter be used for codegen. 6532 Expr *buildCounterStep() const; 6533 /// Build loop data with counter value for depend clauses in ordered 6534 /// directives. 6535 Expr * 6536 buildOrderedLoopData(Scope *S, Expr *Counter, 6537 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures, 6538 SourceLocation Loc, Expr *Inc = nullptr, 6539 OverloadedOperatorKind OOK = OO_Amp); 6540 /// Builds the minimum value for the loop counter. 6541 std::pair<Expr *, Expr *> buildMinMaxValues( 6542 Scope *S, llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const; 6543 /// Builds final condition for the non-rectangular loops. 6544 Expr *buildFinalCondition(Scope *S) const; 6545 /// Return true if any expression is dependent. 6546 bool dependent() const; 6547 /// Returns true if the initializer forms non-rectangular loop. 6548 bool doesInitDependOnLC() const { return InitDependOnLC.hasValue(); } 6549 /// Returns true if the condition forms non-rectangular loop. 6550 bool doesCondDependOnLC() const { return CondDependOnLC.hasValue(); } 6551 /// Returns index of the loop we depend on (starting from 1), or 0 otherwise. 6552 unsigned getLoopDependentIdx() const { 6553 return InitDependOnLC.getValueOr(CondDependOnLC.getValueOr(0)); 6554 } 6555 6556 private: 6557 /// Check the right-hand side of an assignment in the increment 6558 /// expression. 6559 bool checkAndSetIncRHS(Expr *RHS); 6560 /// Helper to set loop counter variable and its initializer. 6561 bool setLCDeclAndLB(ValueDecl *NewLCDecl, Expr *NewDeclRefExpr, Expr *NewLB, 6562 bool EmitDiags); 6563 /// Helper to set upper bound. 6564 bool setUB(Expr *NewUB, llvm::Optional<bool> LessOp, bool StrictOp, 6565 SourceRange SR, SourceLocation SL); 6566 /// Helper to set loop increment. 6567 bool setStep(Expr *NewStep, bool Subtract); 6568 }; 6569 6570 bool OpenMPIterationSpaceChecker::dependent() const { 6571 if (!LCDecl) { 6572 assert(!LB && !UB && !Step); 6573 return false; 6574 } 6575 return LCDecl->getType()->isDependentType() || 6576 (LB && LB->isValueDependent()) || (UB && UB->isValueDependent()) || 6577 (Step && Step->isValueDependent()); 6578 } 6579 6580 bool OpenMPIterationSpaceChecker::setLCDeclAndLB(ValueDecl *NewLCDecl, 6581 Expr *NewLCRefExpr, 6582 Expr *NewLB, bool EmitDiags) { 6583 // State consistency checking to ensure correct usage. 6584 assert(LCDecl == nullptr && LB == nullptr && LCRef == nullptr && 6585 UB == nullptr && Step == nullptr && !TestIsLessOp && !TestIsStrictOp); 6586 if (!NewLCDecl || !NewLB) 6587 return true; 6588 LCDecl = getCanonicalDecl(NewLCDecl); 6589 LCRef = NewLCRefExpr; 6590 if (auto *CE = dyn_cast_or_null<CXXConstructExpr>(NewLB)) 6591 if (const CXXConstructorDecl *Ctor = CE->getConstructor()) 6592 if ((Ctor->isCopyOrMoveConstructor() || 6593 Ctor->isConvertingConstructor(/*AllowExplicit=*/false)) && 6594 CE->getNumArgs() > 0 && CE->getArg(0) != nullptr) 6595 NewLB = CE->getArg(0)->IgnoreParenImpCasts(); 6596 LB = NewLB; 6597 if (EmitDiags) 6598 InitDependOnLC = doesDependOnLoopCounter(LB, /*IsInitializer=*/true); 6599 return false; 6600 } 6601 6602 bool OpenMPIterationSpaceChecker::setUB(Expr *NewUB, 6603 llvm::Optional<bool> LessOp, 6604 bool StrictOp, SourceRange SR, 6605 SourceLocation SL) { 6606 // State consistency checking to ensure correct usage. 6607 assert(LCDecl != nullptr && LB != nullptr && UB == nullptr && 6608 Step == nullptr && !TestIsLessOp && !TestIsStrictOp); 6609 if (!NewUB) 6610 return true; 6611 UB = NewUB; 6612 if (LessOp) 6613 TestIsLessOp = LessOp; 6614 TestIsStrictOp = StrictOp; 6615 ConditionSrcRange = SR; 6616 ConditionLoc = SL; 6617 CondDependOnLC = doesDependOnLoopCounter(UB, /*IsInitializer=*/false); 6618 return false; 6619 } 6620 6621 bool OpenMPIterationSpaceChecker::setStep(Expr *NewStep, bool Subtract) { 6622 // State consistency checking to ensure correct usage. 6623 assert(LCDecl != nullptr && LB != nullptr && Step == nullptr); 6624 if (!NewStep) 6625 return true; 6626 if (!NewStep->isValueDependent()) { 6627 // Check that the step is integer expression. 6628 SourceLocation StepLoc = NewStep->getBeginLoc(); 6629 ExprResult Val = SemaRef.PerformOpenMPImplicitIntegerConversion( 6630 StepLoc, getExprAsWritten(NewStep)); 6631 if (Val.isInvalid()) 6632 return true; 6633 NewStep = Val.get(); 6634 6635 // OpenMP [2.6, Canonical Loop Form, Restrictions] 6636 // If test-expr is of form var relational-op b and relational-op is < or 6637 // <= then incr-expr must cause var to increase on each iteration of the 6638 // loop. If test-expr is of form var relational-op b and relational-op is 6639 // > or >= then incr-expr must cause var to decrease on each iteration of 6640 // the loop. 6641 // If test-expr is of form b relational-op var and relational-op is < or 6642 // <= then incr-expr must cause var to decrease on each iteration of the 6643 // loop. If test-expr is of form b relational-op var and relational-op is 6644 // > or >= then incr-expr must cause var to increase on each iteration of 6645 // the loop. 6646 Optional<llvm::APSInt> Result = 6647 NewStep->getIntegerConstantExpr(SemaRef.Context); 6648 bool IsUnsigned = !NewStep->getType()->hasSignedIntegerRepresentation(); 6649 bool IsConstNeg = 6650 Result && Result->isSigned() && (Subtract != Result->isNegative()); 6651 bool IsConstPos = 6652 Result && Result->isSigned() && (Subtract == Result->isNegative()); 6653 bool IsConstZero = Result && !Result->getBoolValue(); 6654 6655 // != with increment is treated as <; != with decrement is treated as > 6656 if (!TestIsLessOp.hasValue()) 6657 TestIsLessOp = IsConstPos || (IsUnsigned && !Subtract); 6658 if (UB && (IsConstZero || 6659 (TestIsLessOp.getValue() ? 6660 (IsConstNeg || (IsUnsigned && Subtract)) : 6661 (IsConstPos || (IsUnsigned && !Subtract))))) { 6662 SemaRef.Diag(NewStep->getExprLoc(), 6663 diag::err_omp_loop_incr_not_compatible) 6664 << LCDecl << TestIsLessOp.getValue() << NewStep->getSourceRange(); 6665 SemaRef.Diag(ConditionLoc, 6666 diag::note_omp_loop_cond_requres_compatible_incr) 6667 << TestIsLessOp.getValue() << ConditionSrcRange; 6668 return true; 6669 } 6670 if (TestIsLessOp.getValue() == Subtract) { 6671 NewStep = 6672 SemaRef.CreateBuiltinUnaryOp(NewStep->getExprLoc(), UO_Minus, NewStep) 6673 .get(); 6674 Subtract = !Subtract; 6675 } 6676 } 6677 6678 Step = NewStep; 6679 SubtractStep = Subtract; 6680 return false; 6681 } 6682 6683 namespace { 6684 /// Checker for the non-rectangular loops. Checks if the initializer or 6685 /// condition expression references loop counter variable. 6686 class LoopCounterRefChecker final 6687 : public ConstStmtVisitor<LoopCounterRefChecker, bool> { 6688 Sema &SemaRef; 6689 DSAStackTy &Stack; 6690 const ValueDecl *CurLCDecl = nullptr; 6691 const ValueDecl *DepDecl = nullptr; 6692 const ValueDecl *PrevDepDecl = nullptr; 6693 bool IsInitializer = true; 6694 unsigned BaseLoopId = 0; 6695 bool checkDecl(const Expr *E, const ValueDecl *VD) { 6696 if (getCanonicalDecl(VD) == getCanonicalDecl(CurLCDecl)) { 6697 SemaRef.Diag(E->getExprLoc(), diag::err_omp_stmt_depends_on_loop_counter) 6698 << (IsInitializer ? 0 : 1); 6699 return false; 6700 } 6701 const auto &&Data = Stack.isLoopControlVariable(VD); 6702 // OpenMP, 2.9.1 Canonical Loop Form, Restrictions. 6703 // The type of the loop iterator on which we depend may not have a random 6704 // access iterator type. 6705 if (Data.first && VD->getType()->isRecordType()) { 6706 SmallString<128> Name; 6707 llvm::raw_svector_ostream OS(Name); 6708 VD->getNameForDiagnostic(OS, SemaRef.getPrintingPolicy(), 6709 /*Qualified=*/true); 6710 SemaRef.Diag(E->getExprLoc(), 6711 diag::err_omp_wrong_dependency_iterator_type) 6712 << OS.str(); 6713 SemaRef.Diag(VD->getLocation(), diag::note_previous_decl) << VD; 6714 return false; 6715 } 6716 if (Data.first && 6717 (DepDecl || (PrevDepDecl && 6718 getCanonicalDecl(VD) != getCanonicalDecl(PrevDepDecl)))) { 6719 if (!DepDecl && PrevDepDecl) 6720 DepDecl = PrevDepDecl; 6721 SmallString<128> Name; 6722 llvm::raw_svector_ostream OS(Name); 6723 DepDecl->getNameForDiagnostic(OS, SemaRef.getPrintingPolicy(), 6724 /*Qualified=*/true); 6725 SemaRef.Diag(E->getExprLoc(), 6726 diag::err_omp_invariant_or_linear_dependency) 6727 << OS.str(); 6728 return false; 6729 } 6730 if (Data.first) { 6731 DepDecl = VD; 6732 BaseLoopId = Data.first; 6733 } 6734 return Data.first; 6735 } 6736 6737 public: 6738 bool VisitDeclRefExpr(const DeclRefExpr *E) { 6739 const ValueDecl *VD = E->getDecl(); 6740 if (isa<VarDecl>(VD)) 6741 return checkDecl(E, VD); 6742 return false; 6743 } 6744 bool VisitMemberExpr(const MemberExpr *E) { 6745 if (isa<CXXThisExpr>(E->getBase()->IgnoreParens())) { 6746 const ValueDecl *VD = E->getMemberDecl(); 6747 if (isa<VarDecl>(VD) || isa<FieldDecl>(VD)) 6748 return checkDecl(E, VD); 6749 } 6750 return false; 6751 } 6752 bool VisitStmt(const Stmt *S) { 6753 bool Res = false; 6754 for (const Stmt *Child : S->children()) 6755 Res = (Child && Visit(Child)) || Res; 6756 return Res; 6757 } 6758 explicit LoopCounterRefChecker(Sema &SemaRef, DSAStackTy &Stack, 6759 const ValueDecl *CurLCDecl, bool IsInitializer, 6760 const ValueDecl *PrevDepDecl = nullptr) 6761 : SemaRef(SemaRef), Stack(Stack), CurLCDecl(CurLCDecl), 6762 PrevDepDecl(PrevDepDecl), IsInitializer(IsInitializer) {} 6763 unsigned getBaseLoopId() const { 6764 assert(CurLCDecl && "Expected loop dependency."); 6765 return BaseLoopId; 6766 } 6767 const ValueDecl *getDepDecl() const { 6768 assert(CurLCDecl && "Expected loop dependency."); 6769 return DepDecl; 6770 } 6771 }; 6772 } // namespace 6773 6774 Optional<unsigned> 6775 OpenMPIterationSpaceChecker::doesDependOnLoopCounter(const Stmt *S, 6776 bool IsInitializer) { 6777 // Check for the non-rectangular loops. 6778 LoopCounterRefChecker LoopStmtChecker(SemaRef, Stack, LCDecl, IsInitializer, 6779 DepDecl); 6780 if (LoopStmtChecker.Visit(S)) { 6781 DepDecl = LoopStmtChecker.getDepDecl(); 6782 return LoopStmtChecker.getBaseLoopId(); 6783 } 6784 return llvm::None; 6785 } 6786 6787 bool OpenMPIterationSpaceChecker::checkAndSetInit(Stmt *S, bool EmitDiags) { 6788 // Check init-expr for canonical loop form and save loop counter 6789 // variable - #Var and its initialization value - #LB. 6790 // OpenMP [2.6] Canonical loop form. init-expr may be one of the following: 6791 // var = lb 6792 // integer-type var = lb 6793 // random-access-iterator-type var = lb 6794 // pointer-type var = lb 6795 // 6796 if (!S) { 6797 if (EmitDiags) { 6798 SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_init); 6799 } 6800 return true; 6801 } 6802 if (auto *ExprTemp = dyn_cast<ExprWithCleanups>(S)) 6803 if (!ExprTemp->cleanupsHaveSideEffects()) 6804 S = ExprTemp->getSubExpr(); 6805 6806 InitSrcRange = S->getSourceRange(); 6807 if (Expr *E = dyn_cast<Expr>(S)) 6808 S = E->IgnoreParens(); 6809 if (auto *BO = dyn_cast<BinaryOperator>(S)) { 6810 if (BO->getOpcode() == BO_Assign) { 6811 Expr *LHS = BO->getLHS()->IgnoreParens(); 6812 if (auto *DRE = dyn_cast<DeclRefExpr>(LHS)) { 6813 if (auto *CED = dyn_cast<OMPCapturedExprDecl>(DRE->getDecl())) 6814 if (auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit()))) 6815 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(), 6816 EmitDiags); 6817 return setLCDeclAndLB(DRE->getDecl(), DRE, BO->getRHS(), EmitDiags); 6818 } 6819 if (auto *ME = dyn_cast<MemberExpr>(LHS)) { 6820 if (ME->isArrow() && 6821 isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts())) 6822 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(), 6823 EmitDiags); 6824 } 6825 } 6826 } else if (auto *DS = dyn_cast<DeclStmt>(S)) { 6827 if (DS->isSingleDecl()) { 6828 if (auto *Var = dyn_cast_or_null<VarDecl>(DS->getSingleDecl())) { 6829 if (Var->hasInit() && !Var->getType()->isReferenceType()) { 6830 // Accept non-canonical init form here but emit ext. warning. 6831 if (Var->getInitStyle() != VarDecl::CInit && EmitDiags) 6832 SemaRef.Diag(S->getBeginLoc(), 6833 diag::ext_omp_loop_not_canonical_init) 6834 << S->getSourceRange(); 6835 return setLCDeclAndLB( 6836 Var, 6837 buildDeclRefExpr(SemaRef, Var, 6838 Var->getType().getNonReferenceType(), 6839 DS->getBeginLoc()), 6840 Var->getInit(), EmitDiags); 6841 } 6842 } 6843 } 6844 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) { 6845 if (CE->getOperator() == OO_Equal) { 6846 Expr *LHS = CE->getArg(0); 6847 if (auto *DRE = dyn_cast<DeclRefExpr>(LHS)) { 6848 if (auto *CED = dyn_cast<OMPCapturedExprDecl>(DRE->getDecl())) 6849 if (auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit()))) 6850 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(), 6851 EmitDiags); 6852 return setLCDeclAndLB(DRE->getDecl(), DRE, CE->getArg(1), EmitDiags); 6853 } 6854 if (auto *ME = dyn_cast<MemberExpr>(LHS)) { 6855 if (ME->isArrow() && 6856 isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts())) 6857 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(), 6858 EmitDiags); 6859 } 6860 } 6861 } 6862 6863 if (dependent() || SemaRef.CurContext->isDependentContext()) 6864 return false; 6865 if (EmitDiags) { 6866 SemaRef.Diag(S->getBeginLoc(), diag::err_omp_loop_not_canonical_init) 6867 << S->getSourceRange(); 6868 } 6869 return true; 6870 } 6871 6872 /// Ignore parenthesizes, implicit casts, copy constructor and return the 6873 /// variable (which may be the loop variable) if possible. 6874 static const ValueDecl *getInitLCDecl(const Expr *E) { 6875 if (!E) 6876 return nullptr; 6877 E = getExprAsWritten(E); 6878 if (const auto *CE = dyn_cast_or_null<CXXConstructExpr>(E)) 6879 if (const CXXConstructorDecl *Ctor = CE->getConstructor()) 6880 if ((Ctor->isCopyOrMoveConstructor() || 6881 Ctor->isConvertingConstructor(/*AllowExplicit=*/false)) && 6882 CE->getNumArgs() > 0 && CE->getArg(0) != nullptr) 6883 E = CE->getArg(0)->IgnoreParenImpCasts(); 6884 if (const auto *DRE = dyn_cast_or_null<DeclRefExpr>(E)) { 6885 if (const auto *VD = dyn_cast<VarDecl>(DRE->getDecl())) 6886 return getCanonicalDecl(VD); 6887 } 6888 if (const auto *ME = dyn_cast_or_null<MemberExpr>(E)) 6889 if (ME->isArrow() && isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts())) 6890 return getCanonicalDecl(ME->getMemberDecl()); 6891 return nullptr; 6892 } 6893 6894 bool OpenMPIterationSpaceChecker::checkAndSetCond(Expr *S) { 6895 // Check test-expr for canonical form, save upper-bound UB, flags for 6896 // less/greater and for strict/non-strict comparison. 6897 // OpenMP [2.9] Canonical loop form. Test-expr may be one of the following: 6898 // var relational-op b 6899 // b relational-op var 6900 // 6901 bool IneqCondIsCanonical = SemaRef.getLangOpts().OpenMP >= 50; 6902 if (!S) { 6903 SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_cond) 6904 << (IneqCondIsCanonical ? 1 : 0) << LCDecl; 6905 return true; 6906 } 6907 Condition = S; 6908 S = getExprAsWritten(S); 6909 SourceLocation CondLoc = S->getBeginLoc(); 6910 if (auto *BO = dyn_cast<BinaryOperator>(S)) { 6911 if (BO->isRelationalOp()) { 6912 if (getInitLCDecl(BO->getLHS()) == LCDecl) 6913 return setUB(BO->getRHS(), 6914 (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_LE), 6915 (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_GT), 6916 BO->getSourceRange(), BO->getOperatorLoc()); 6917 if (getInitLCDecl(BO->getRHS()) == LCDecl) 6918 return setUB(BO->getLHS(), 6919 (BO->getOpcode() == BO_GT || BO->getOpcode() == BO_GE), 6920 (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_GT), 6921 BO->getSourceRange(), BO->getOperatorLoc()); 6922 } else if (IneqCondIsCanonical && BO->getOpcode() == BO_NE) 6923 return setUB( 6924 getInitLCDecl(BO->getLHS()) == LCDecl ? BO->getRHS() : BO->getLHS(), 6925 /*LessOp=*/llvm::None, 6926 /*StrictOp=*/true, BO->getSourceRange(), BO->getOperatorLoc()); 6927 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) { 6928 if (CE->getNumArgs() == 2) { 6929 auto Op = CE->getOperator(); 6930 switch (Op) { 6931 case OO_Greater: 6932 case OO_GreaterEqual: 6933 case OO_Less: 6934 case OO_LessEqual: 6935 if (getInitLCDecl(CE->getArg(0)) == LCDecl) 6936 return setUB(CE->getArg(1), Op == OO_Less || Op == OO_LessEqual, 6937 Op == OO_Less || Op == OO_Greater, CE->getSourceRange(), 6938 CE->getOperatorLoc()); 6939 if (getInitLCDecl(CE->getArg(1)) == LCDecl) 6940 return setUB(CE->getArg(0), Op == OO_Greater || Op == OO_GreaterEqual, 6941 Op == OO_Less || Op == OO_Greater, CE->getSourceRange(), 6942 CE->getOperatorLoc()); 6943 break; 6944 case OO_ExclaimEqual: 6945 if (IneqCondIsCanonical) 6946 return setUB(getInitLCDecl(CE->getArg(0)) == LCDecl ? CE->getArg(1) 6947 : CE->getArg(0), 6948 /*LessOp=*/llvm::None, 6949 /*StrictOp=*/true, CE->getSourceRange(), 6950 CE->getOperatorLoc()); 6951 break; 6952 default: 6953 break; 6954 } 6955 } 6956 } 6957 if (dependent() || SemaRef.CurContext->isDependentContext()) 6958 return false; 6959 SemaRef.Diag(CondLoc, diag::err_omp_loop_not_canonical_cond) 6960 << (IneqCondIsCanonical ? 1 : 0) << S->getSourceRange() << LCDecl; 6961 return true; 6962 } 6963 6964 bool OpenMPIterationSpaceChecker::checkAndSetIncRHS(Expr *RHS) { 6965 // RHS of canonical loop form increment can be: 6966 // var + incr 6967 // incr + var 6968 // var - incr 6969 // 6970 RHS = RHS->IgnoreParenImpCasts(); 6971 if (auto *BO = dyn_cast<BinaryOperator>(RHS)) { 6972 if (BO->isAdditiveOp()) { 6973 bool IsAdd = BO->getOpcode() == BO_Add; 6974 if (getInitLCDecl(BO->getLHS()) == LCDecl) 6975 return setStep(BO->getRHS(), !IsAdd); 6976 if (IsAdd && getInitLCDecl(BO->getRHS()) == LCDecl) 6977 return setStep(BO->getLHS(), /*Subtract=*/false); 6978 } 6979 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(RHS)) { 6980 bool IsAdd = CE->getOperator() == OO_Plus; 6981 if ((IsAdd || CE->getOperator() == OO_Minus) && CE->getNumArgs() == 2) { 6982 if (getInitLCDecl(CE->getArg(0)) == LCDecl) 6983 return setStep(CE->getArg(1), !IsAdd); 6984 if (IsAdd && getInitLCDecl(CE->getArg(1)) == LCDecl) 6985 return setStep(CE->getArg(0), /*Subtract=*/false); 6986 } 6987 } 6988 if (dependent() || SemaRef.CurContext->isDependentContext()) 6989 return false; 6990 SemaRef.Diag(RHS->getBeginLoc(), diag::err_omp_loop_not_canonical_incr) 6991 << RHS->getSourceRange() << LCDecl; 6992 return true; 6993 } 6994 6995 bool OpenMPIterationSpaceChecker::checkAndSetInc(Expr *S) { 6996 // Check incr-expr for canonical loop form and return true if it 6997 // does not conform. 6998 // OpenMP [2.6] Canonical loop form. Test-expr may be one of the following: 6999 // ++var 7000 // var++ 7001 // --var 7002 // var-- 7003 // var += incr 7004 // var -= incr 7005 // var = var + incr 7006 // var = incr + var 7007 // var = var - incr 7008 // 7009 if (!S) { 7010 SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_incr) << LCDecl; 7011 return true; 7012 } 7013 if (auto *ExprTemp = dyn_cast<ExprWithCleanups>(S)) 7014 if (!ExprTemp->cleanupsHaveSideEffects()) 7015 S = ExprTemp->getSubExpr(); 7016 7017 IncrementSrcRange = S->getSourceRange(); 7018 S = S->IgnoreParens(); 7019 if (auto *UO = dyn_cast<UnaryOperator>(S)) { 7020 if (UO->isIncrementDecrementOp() && 7021 getInitLCDecl(UO->getSubExpr()) == LCDecl) 7022 return setStep(SemaRef 7023 .ActOnIntegerConstant(UO->getBeginLoc(), 7024 (UO->isDecrementOp() ? -1 : 1)) 7025 .get(), 7026 /*Subtract=*/false); 7027 } else if (auto *BO = dyn_cast<BinaryOperator>(S)) { 7028 switch (BO->getOpcode()) { 7029 case BO_AddAssign: 7030 case BO_SubAssign: 7031 if (getInitLCDecl(BO->getLHS()) == LCDecl) 7032 return setStep(BO->getRHS(), BO->getOpcode() == BO_SubAssign); 7033 break; 7034 case BO_Assign: 7035 if (getInitLCDecl(BO->getLHS()) == LCDecl) 7036 return checkAndSetIncRHS(BO->getRHS()); 7037 break; 7038 default: 7039 break; 7040 } 7041 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) { 7042 switch (CE->getOperator()) { 7043 case OO_PlusPlus: 7044 case OO_MinusMinus: 7045 if (getInitLCDecl(CE->getArg(0)) == LCDecl) 7046 return setStep(SemaRef 7047 .ActOnIntegerConstant( 7048 CE->getBeginLoc(), 7049 ((CE->getOperator() == OO_MinusMinus) ? -1 : 1)) 7050 .get(), 7051 /*Subtract=*/false); 7052 break; 7053 case OO_PlusEqual: 7054 case OO_MinusEqual: 7055 if (getInitLCDecl(CE->getArg(0)) == LCDecl) 7056 return setStep(CE->getArg(1), CE->getOperator() == OO_MinusEqual); 7057 break; 7058 case OO_Equal: 7059 if (getInitLCDecl(CE->getArg(0)) == LCDecl) 7060 return checkAndSetIncRHS(CE->getArg(1)); 7061 break; 7062 default: 7063 break; 7064 } 7065 } 7066 if (dependent() || SemaRef.CurContext->isDependentContext()) 7067 return false; 7068 SemaRef.Diag(S->getBeginLoc(), diag::err_omp_loop_not_canonical_incr) 7069 << S->getSourceRange() << LCDecl; 7070 return true; 7071 } 7072 7073 static ExprResult 7074 tryBuildCapture(Sema &SemaRef, Expr *Capture, 7075 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) { 7076 if (SemaRef.CurContext->isDependentContext() || Capture->containsErrors()) 7077 return Capture; 7078 if (Capture->isEvaluatable(SemaRef.Context, Expr::SE_AllowSideEffects)) 7079 return SemaRef.PerformImplicitConversion( 7080 Capture->IgnoreImpCasts(), Capture->getType(), Sema::AA_Converting, 7081 /*AllowExplicit=*/true); 7082 auto I = Captures.find(Capture); 7083 if (I != Captures.end()) 7084 return buildCapture(SemaRef, Capture, I->second); 7085 DeclRefExpr *Ref = nullptr; 7086 ExprResult Res = buildCapture(SemaRef, Capture, Ref); 7087 Captures[Capture] = Ref; 7088 return Res; 7089 } 7090 7091 /// Calculate number of iterations, transforming to unsigned, if number of 7092 /// iterations may be larger than the original type. 7093 static Expr * 7094 calculateNumIters(Sema &SemaRef, Scope *S, SourceLocation DefaultLoc, 7095 Expr *Lower, Expr *Upper, Expr *Step, QualType LCTy, 7096 bool TestIsStrictOp, bool RoundToStep, 7097 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) { 7098 ExprResult NewStep = tryBuildCapture(SemaRef, Step, Captures); 7099 if (!NewStep.isUsable()) 7100 return nullptr; 7101 llvm::APSInt LRes, SRes; 7102 bool IsLowerConst = false, IsStepConst = false; 7103 if (Optional<llvm::APSInt> Res = Lower->getIntegerConstantExpr(SemaRef.Context)) { 7104 LRes = *Res; 7105 IsLowerConst = true; 7106 } 7107 if (Optional<llvm::APSInt> Res = Step->getIntegerConstantExpr(SemaRef.Context)) { 7108 SRes = *Res; 7109 IsStepConst = true; 7110 } 7111 bool NoNeedToConvert = IsLowerConst && !RoundToStep && 7112 ((!TestIsStrictOp && LRes.isNonNegative()) || 7113 (TestIsStrictOp && LRes.isStrictlyPositive())); 7114 bool NeedToReorganize = false; 7115 // Check if any subexpressions in Lower -Step [+ 1] lead to overflow. 7116 if (!NoNeedToConvert && IsLowerConst && 7117 (TestIsStrictOp || (RoundToStep && IsStepConst))) { 7118 NoNeedToConvert = true; 7119 if (RoundToStep) { 7120 unsigned BW = LRes.getBitWidth() > SRes.getBitWidth() 7121 ? LRes.getBitWidth() 7122 : SRes.getBitWidth(); 7123 LRes = LRes.extend(BW + 1); 7124 LRes.setIsSigned(true); 7125 SRes = SRes.extend(BW + 1); 7126 SRes.setIsSigned(true); 7127 LRes -= SRes; 7128 NoNeedToConvert = LRes.trunc(BW).extend(BW + 1) == LRes; 7129 LRes = LRes.trunc(BW); 7130 } 7131 if (TestIsStrictOp) { 7132 unsigned BW = LRes.getBitWidth(); 7133 LRes = LRes.extend(BW + 1); 7134 LRes.setIsSigned(true); 7135 ++LRes; 7136 NoNeedToConvert = 7137 NoNeedToConvert && LRes.trunc(BW).extend(BW + 1) == LRes; 7138 // truncate to the original bitwidth. 7139 LRes = LRes.trunc(BW); 7140 } 7141 NeedToReorganize = NoNeedToConvert; 7142 } 7143 llvm::APSInt URes; 7144 bool IsUpperConst = false; 7145 if (Optional<llvm::APSInt> Res = Upper->getIntegerConstantExpr(SemaRef.Context)) { 7146 URes = *Res; 7147 IsUpperConst = true; 7148 } 7149 if (NoNeedToConvert && IsLowerConst && IsUpperConst && 7150 (!RoundToStep || IsStepConst)) { 7151 unsigned BW = LRes.getBitWidth() > URes.getBitWidth() ? LRes.getBitWidth() 7152 : URes.getBitWidth(); 7153 LRes = LRes.extend(BW + 1); 7154 LRes.setIsSigned(true); 7155 URes = URes.extend(BW + 1); 7156 URes.setIsSigned(true); 7157 URes -= LRes; 7158 NoNeedToConvert = URes.trunc(BW).extend(BW + 1) == URes; 7159 NeedToReorganize = NoNeedToConvert; 7160 } 7161 // If the boundaries are not constant or (Lower - Step [+ 1]) is not constant 7162 // or less than zero (Upper - (Lower - Step [+ 1]) may overflow) - promote to 7163 // unsigned. 7164 if ((!NoNeedToConvert || (LRes.isNegative() && !IsUpperConst)) && 7165 !LCTy->isDependentType() && LCTy->isIntegerType()) { 7166 QualType LowerTy = Lower->getType(); 7167 QualType UpperTy = Upper->getType(); 7168 uint64_t LowerSize = SemaRef.Context.getTypeSize(LowerTy); 7169 uint64_t UpperSize = SemaRef.Context.getTypeSize(UpperTy); 7170 if ((LowerSize <= UpperSize && UpperTy->hasSignedIntegerRepresentation()) || 7171 (LowerSize > UpperSize && LowerTy->hasSignedIntegerRepresentation())) { 7172 QualType CastType = SemaRef.Context.getIntTypeForBitwidth( 7173 LowerSize > UpperSize ? LowerSize : UpperSize, /*Signed=*/0); 7174 Upper = 7175 SemaRef 7176 .PerformImplicitConversion( 7177 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Upper).get(), 7178 CastType, Sema::AA_Converting) 7179 .get(); 7180 Lower = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Lower).get(); 7181 NewStep = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, NewStep.get()); 7182 } 7183 } 7184 if (!Lower || !Upper || NewStep.isInvalid()) 7185 return nullptr; 7186 7187 ExprResult Diff; 7188 // If need to reorganize, then calculate the form as Upper - (Lower - Step [+ 7189 // 1]). 7190 if (NeedToReorganize) { 7191 Diff = Lower; 7192 7193 if (RoundToStep) { 7194 // Lower - Step 7195 Diff = 7196 SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Diff.get(), NewStep.get()); 7197 if (!Diff.isUsable()) 7198 return nullptr; 7199 } 7200 7201 // Lower - Step [+ 1] 7202 if (TestIsStrictOp) 7203 Diff = SemaRef.BuildBinOp( 7204 S, DefaultLoc, BO_Add, Diff.get(), 7205 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()); 7206 if (!Diff.isUsable()) 7207 return nullptr; 7208 7209 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get()); 7210 if (!Diff.isUsable()) 7211 return nullptr; 7212 7213 // Upper - (Lower - Step [+ 1]). 7214 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Diff.get()); 7215 if (!Diff.isUsable()) 7216 return nullptr; 7217 } else { 7218 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Lower); 7219 7220 if (!Diff.isUsable() && LCTy->getAsCXXRecordDecl()) { 7221 // BuildBinOp already emitted error, this one is to point user to upper 7222 // and lower bound, and to tell what is passed to 'operator-'. 7223 SemaRef.Diag(Upper->getBeginLoc(), diag::err_omp_loop_diff_cxx) 7224 << Upper->getSourceRange() << Lower->getSourceRange(); 7225 return nullptr; 7226 } 7227 7228 if (!Diff.isUsable()) 7229 return nullptr; 7230 7231 // Upper - Lower [- 1] 7232 if (TestIsStrictOp) 7233 Diff = SemaRef.BuildBinOp( 7234 S, DefaultLoc, BO_Sub, Diff.get(), 7235 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()); 7236 if (!Diff.isUsable()) 7237 return nullptr; 7238 7239 if (RoundToStep) { 7240 // Upper - Lower [- 1] + Step 7241 Diff = 7242 SemaRef.BuildBinOp(S, DefaultLoc, BO_Add, Diff.get(), NewStep.get()); 7243 if (!Diff.isUsable()) 7244 return nullptr; 7245 } 7246 } 7247 7248 // Parentheses (for dumping/debugging purposes only). 7249 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get()); 7250 if (!Diff.isUsable()) 7251 return nullptr; 7252 7253 // (Upper - Lower [- 1] + Step) / Step or (Upper - Lower) / Step 7254 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Div, Diff.get(), NewStep.get()); 7255 if (!Diff.isUsable()) 7256 return nullptr; 7257 7258 return Diff.get(); 7259 } 7260 7261 /// Build the expression to calculate the number of iterations. 7262 Expr *OpenMPIterationSpaceChecker::buildNumIterations( 7263 Scope *S, ArrayRef<LoopIterationSpace> ResultIterSpaces, bool LimitedType, 7264 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const { 7265 QualType VarType = LCDecl->getType().getNonReferenceType(); 7266 if (!VarType->isIntegerType() && !VarType->isPointerType() && 7267 !SemaRef.getLangOpts().CPlusPlus) 7268 return nullptr; 7269 Expr *LBVal = LB; 7270 Expr *UBVal = UB; 7271 // LB = TestIsLessOp.getValue() ? min(LB(MinVal), LB(MaxVal)) : 7272 // max(LB(MinVal), LB(MaxVal)) 7273 if (InitDependOnLC) { 7274 const LoopIterationSpace &IS = 7275 ResultIterSpaces[ResultIterSpaces.size() - 1 - 7276 InitDependOnLC.getValueOr( 7277 CondDependOnLC.getValueOr(0))]; 7278 if (!IS.MinValue || !IS.MaxValue) 7279 return nullptr; 7280 // OuterVar = Min 7281 ExprResult MinValue = 7282 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MinValue); 7283 if (!MinValue.isUsable()) 7284 return nullptr; 7285 7286 ExprResult LBMinVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign, 7287 IS.CounterVar, MinValue.get()); 7288 if (!LBMinVal.isUsable()) 7289 return nullptr; 7290 // OuterVar = Min, LBVal 7291 LBMinVal = 7292 SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, LBMinVal.get(), LBVal); 7293 if (!LBMinVal.isUsable()) 7294 return nullptr; 7295 // (OuterVar = Min, LBVal) 7296 LBMinVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, LBMinVal.get()); 7297 if (!LBMinVal.isUsable()) 7298 return nullptr; 7299 7300 // OuterVar = Max 7301 ExprResult MaxValue = 7302 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MaxValue); 7303 if (!MaxValue.isUsable()) 7304 return nullptr; 7305 7306 ExprResult LBMaxVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign, 7307 IS.CounterVar, MaxValue.get()); 7308 if (!LBMaxVal.isUsable()) 7309 return nullptr; 7310 // OuterVar = Max, LBVal 7311 LBMaxVal = 7312 SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, LBMaxVal.get(), LBVal); 7313 if (!LBMaxVal.isUsable()) 7314 return nullptr; 7315 // (OuterVar = Max, LBVal) 7316 LBMaxVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, LBMaxVal.get()); 7317 if (!LBMaxVal.isUsable()) 7318 return nullptr; 7319 7320 Expr *LBMin = tryBuildCapture(SemaRef, LBMinVal.get(), Captures).get(); 7321 Expr *LBMax = tryBuildCapture(SemaRef, LBMaxVal.get(), Captures).get(); 7322 if (!LBMin || !LBMax) 7323 return nullptr; 7324 // LB(MinVal) < LB(MaxVal) 7325 ExprResult MinLessMaxRes = 7326 SemaRef.BuildBinOp(S, DefaultLoc, BO_LT, LBMin, LBMax); 7327 if (!MinLessMaxRes.isUsable()) 7328 return nullptr; 7329 Expr *MinLessMax = 7330 tryBuildCapture(SemaRef, MinLessMaxRes.get(), Captures).get(); 7331 if (!MinLessMax) 7332 return nullptr; 7333 if (TestIsLessOp.getValue()) { 7334 // LB(MinVal) < LB(MaxVal) ? LB(MinVal) : LB(MaxVal) - min(LB(MinVal), 7335 // LB(MaxVal)) 7336 ExprResult MinLB = SemaRef.ActOnConditionalOp(DefaultLoc, DefaultLoc, 7337 MinLessMax, LBMin, LBMax); 7338 if (!MinLB.isUsable()) 7339 return nullptr; 7340 LBVal = MinLB.get(); 7341 } else { 7342 // LB(MinVal) < LB(MaxVal) ? LB(MaxVal) : LB(MinVal) - max(LB(MinVal), 7343 // LB(MaxVal)) 7344 ExprResult MaxLB = SemaRef.ActOnConditionalOp(DefaultLoc, DefaultLoc, 7345 MinLessMax, LBMax, LBMin); 7346 if (!MaxLB.isUsable()) 7347 return nullptr; 7348 LBVal = MaxLB.get(); 7349 } 7350 } 7351 // UB = TestIsLessOp.getValue() ? max(UB(MinVal), UB(MaxVal)) : 7352 // min(UB(MinVal), UB(MaxVal)) 7353 if (CondDependOnLC) { 7354 const LoopIterationSpace &IS = 7355 ResultIterSpaces[ResultIterSpaces.size() - 1 - 7356 InitDependOnLC.getValueOr( 7357 CondDependOnLC.getValueOr(0))]; 7358 if (!IS.MinValue || !IS.MaxValue) 7359 return nullptr; 7360 // OuterVar = Min 7361 ExprResult MinValue = 7362 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MinValue); 7363 if (!MinValue.isUsable()) 7364 return nullptr; 7365 7366 ExprResult UBMinVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign, 7367 IS.CounterVar, MinValue.get()); 7368 if (!UBMinVal.isUsable()) 7369 return nullptr; 7370 // OuterVar = Min, UBVal 7371 UBMinVal = 7372 SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, UBMinVal.get(), UBVal); 7373 if (!UBMinVal.isUsable()) 7374 return nullptr; 7375 // (OuterVar = Min, UBVal) 7376 UBMinVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, UBMinVal.get()); 7377 if (!UBMinVal.isUsable()) 7378 return nullptr; 7379 7380 // OuterVar = Max 7381 ExprResult MaxValue = 7382 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MaxValue); 7383 if (!MaxValue.isUsable()) 7384 return nullptr; 7385 7386 ExprResult UBMaxVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign, 7387 IS.CounterVar, MaxValue.get()); 7388 if (!UBMaxVal.isUsable()) 7389 return nullptr; 7390 // OuterVar = Max, UBVal 7391 UBMaxVal = 7392 SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, UBMaxVal.get(), UBVal); 7393 if (!UBMaxVal.isUsable()) 7394 return nullptr; 7395 // (OuterVar = Max, UBVal) 7396 UBMaxVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, UBMaxVal.get()); 7397 if (!UBMaxVal.isUsable()) 7398 return nullptr; 7399 7400 Expr *UBMin = tryBuildCapture(SemaRef, UBMinVal.get(), Captures).get(); 7401 Expr *UBMax = tryBuildCapture(SemaRef, UBMaxVal.get(), Captures).get(); 7402 if (!UBMin || !UBMax) 7403 return nullptr; 7404 // UB(MinVal) > UB(MaxVal) 7405 ExprResult MinGreaterMaxRes = 7406 SemaRef.BuildBinOp(S, DefaultLoc, BO_GT, UBMin, UBMax); 7407 if (!MinGreaterMaxRes.isUsable()) 7408 return nullptr; 7409 Expr *MinGreaterMax = 7410 tryBuildCapture(SemaRef, MinGreaterMaxRes.get(), Captures).get(); 7411 if (!MinGreaterMax) 7412 return nullptr; 7413 if (TestIsLessOp.getValue()) { 7414 // UB(MinVal) > UB(MaxVal) ? UB(MinVal) : UB(MaxVal) - max(UB(MinVal), 7415 // UB(MaxVal)) 7416 ExprResult MaxUB = SemaRef.ActOnConditionalOp( 7417 DefaultLoc, DefaultLoc, MinGreaterMax, UBMin, UBMax); 7418 if (!MaxUB.isUsable()) 7419 return nullptr; 7420 UBVal = MaxUB.get(); 7421 } else { 7422 // UB(MinVal) > UB(MaxVal) ? UB(MaxVal) : UB(MinVal) - min(UB(MinVal), 7423 // UB(MaxVal)) 7424 ExprResult MinUB = SemaRef.ActOnConditionalOp( 7425 DefaultLoc, DefaultLoc, MinGreaterMax, UBMax, UBMin); 7426 if (!MinUB.isUsable()) 7427 return nullptr; 7428 UBVal = MinUB.get(); 7429 } 7430 } 7431 Expr *UBExpr = TestIsLessOp.getValue() ? UBVal : LBVal; 7432 Expr *LBExpr = TestIsLessOp.getValue() ? LBVal : UBVal; 7433 Expr *Upper = tryBuildCapture(SemaRef, UBExpr, Captures).get(); 7434 Expr *Lower = tryBuildCapture(SemaRef, LBExpr, Captures).get(); 7435 if (!Upper || !Lower) 7436 return nullptr; 7437 7438 ExprResult Diff = 7439 calculateNumIters(SemaRef, S, DefaultLoc, Lower, Upper, Step, VarType, 7440 TestIsStrictOp, /*RoundToStep=*/true, Captures); 7441 if (!Diff.isUsable()) 7442 return nullptr; 7443 7444 // OpenMP runtime requires 32-bit or 64-bit loop variables. 7445 QualType Type = Diff.get()->getType(); 7446 ASTContext &C = SemaRef.Context; 7447 bool UseVarType = VarType->hasIntegerRepresentation() && 7448 C.getTypeSize(Type) > C.getTypeSize(VarType); 7449 if (!Type->isIntegerType() || UseVarType) { 7450 unsigned NewSize = 7451 UseVarType ? C.getTypeSize(VarType) : C.getTypeSize(Type); 7452 bool IsSigned = UseVarType ? VarType->hasSignedIntegerRepresentation() 7453 : Type->hasSignedIntegerRepresentation(); 7454 Type = C.getIntTypeForBitwidth(NewSize, IsSigned); 7455 if (!SemaRef.Context.hasSameType(Diff.get()->getType(), Type)) { 7456 Diff = SemaRef.PerformImplicitConversion( 7457 Diff.get(), Type, Sema::AA_Converting, /*AllowExplicit=*/true); 7458 if (!Diff.isUsable()) 7459 return nullptr; 7460 } 7461 } 7462 if (LimitedType) { 7463 unsigned NewSize = (C.getTypeSize(Type) > 32) ? 64 : 32; 7464 if (NewSize != C.getTypeSize(Type)) { 7465 if (NewSize < C.getTypeSize(Type)) { 7466 assert(NewSize == 64 && "incorrect loop var size"); 7467 SemaRef.Diag(DefaultLoc, diag::warn_omp_loop_64_bit_var) 7468 << InitSrcRange << ConditionSrcRange; 7469 } 7470 QualType NewType = C.getIntTypeForBitwidth( 7471 NewSize, Type->hasSignedIntegerRepresentation() || 7472 C.getTypeSize(Type) < NewSize); 7473 if (!SemaRef.Context.hasSameType(Diff.get()->getType(), NewType)) { 7474 Diff = SemaRef.PerformImplicitConversion(Diff.get(), NewType, 7475 Sema::AA_Converting, true); 7476 if (!Diff.isUsable()) 7477 return nullptr; 7478 } 7479 } 7480 } 7481 7482 return Diff.get(); 7483 } 7484 7485 std::pair<Expr *, Expr *> OpenMPIterationSpaceChecker::buildMinMaxValues( 7486 Scope *S, llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const { 7487 // Do not build for iterators, they cannot be used in non-rectangular loop 7488 // nests. 7489 if (LCDecl->getType()->isRecordType()) 7490 return std::make_pair(nullptr, nullptr); 7491 // If we subtract, the min is in the condition, otherwise the min is in the 7492 // init value. 7493 Expr *MinExpr = nullptr; 7494 Expr *MaxExpr = nullptr; 7495 Expr *LBExpr = TestIsLessOp.getValue() ? LB : UB; 7496 Expr *UBExpr = TestIsLessOp.getValue() ? UB : LB; 7497 bool LBNonRect = TestIsLessOp.getValue() ? InitDependOnLC.hasValue() 7498 : CondDependOnLC.hasValue(); 7499 bool UBNonRect = TestIsLessOp.getValue() ? CondDependOnLC.hasValue() 7500 : InitDependOnLC.hasValue(); 7501 Expr *Lower = 7502 LBNonRect ? LBExpr : tryBuildCapture(SemaRef, LBExpr, Captures).get(); 7503 Expr *Upper = 7504 UBNonRect ? UBExpr : tryBuildCapture(SemaRef, UBExpr, Captures).get(); 7505 if (!Upper || !Lower) 7506 return std::make_pair(nullptr, nullptr); 7507 7508 if (TestIsLessOp.getValue()) 7509 MinExpr = Lower; 7510 else 7511 MaxExpr = Upper; 7512 7513 // Build minimum/maximum value based on number of iterations. 7514 QualType VarType = LCDecl->getType().getNonReferenceType(); 7515 7516 ExprResult Diff = 7517 calculateNumIters(SemaRef, S, DefaultLoc, Lower, Upper, Step, VarType, 7518 TestIsStrictOp, /*RoundToStep=*/false, Captures); 7519 if (!Diff.isUsable()) 7520 return std::make_pair(nullptr, nullptr); 7521 7522 // ((Upper - Lower [- 1]) / Step) * Step 7523 // Parentheses (for dumping/debugging purposes only). 7524 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get()); 7525 if (!Diff.isUsable()) 7526 return std::make_pair(nullptr, nullptr); 7527 7528 ExprResult NewStep = tryBuildCapture(SemaRef, Step, Captures); 7529 if (!NewStep.isUsable()) 7530 return std::make_pair(nullptr, nullptr); 7531 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Mul, Diff.get(), NewStep.get()); 7532 if (!Diff.isUsable()) 7533 return std::make_pair(nullptr, nullptr); 7534 7535 // Parentheses (for dumping/debugging purposes only). 7536 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get()); 7537 if (!Diff.isUsable()) 7538 return std::make_pair(nullptr, nullptr); 7539 7540 // Convert to the ptrdiff_t, if original type is pointer. 7541 if (VarType->isAnyPointerType() && 7542 !SemaRef.Context.hasSameType( 7543 Diff.get()->getType(), 7544 SemaRef.Context.getUnsignedPointerDiffType())) { 7545 Diff = SemaRef.PerformImplicitConversion( 7546 Diff.get(), SemaRef.Context.getUnsignedPointerDiffType(), 7547 Sema::AA_Converting, /*AllowExplicit=*/true); 7548 } 7549 if (!Diff.isUsable()) 7550 return std::make_pair(nullptr, nullptr); 7551 7552 if (TestIsLessOp.getValue()) { 7553 // MinExpr = Lower; 7554 // MaxExpr = Lower + (((Upper - Lower [- 1]) / Step) * Step) 7555 Diff = SemaRef.BuildBinOp( 7556 S, DefaultLoc, BO_Add, 7557 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Lower).get(), 7558 Diff.get()); 7559 if (!Diff.isUsable()) 7560 return std::make_pair(nullptr, nullptr); 7561 } else { 7562 // MaxExpr = Upper; 7563 // MinExpr = Upper - (((Upper - Lower [- 1]) / Step) * Step) 7564 Diff = SemaRef.BuildBinOp( 7565 S, DefaultLoc, BO_Sub, 7566 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Upper).get(), 7567 Diff.get()); 7568 if (!Diff.isUsable()) 7569 return std::make_pair(nullptr, nullptr); 7570 } 7571 7572 // Convert to the original type. 7573 if (SemaRef.Context.hasSameType(Diff.get()->getType(), VarType)) 7574 Diff = SemaRef.PerformImplicitConversion(Diff.get(), VarType, 7575 Sema::AA_Converting, 7576 /*AllowExplicit=*/true); 7577 if (!Diff.isUsable()) 7578 return std::make_pair(nullptr, nullptr); 7579 7580 Diff = SemaRef.ActOnFinishFullExpr(Diff.get(), /*DiscardedValue=*/false); 7581 if (!Diff.isUsable()) 7582 return std::make_pair(nullptr, nullptr); 7583 7584 if (TestIsLessOp.getValue()) 7585 MaxExpr = Diff.get(); 7586 else 7587 MinExpr = Diff.get(); 7588 7589 return std::make_pair(MinExpr, MaxExpr); 7590 } 7591 7592 Expr *OpenMPIterationSpaceChecker::buildFinalCondition(Scope *S) const { 7593 if (InitDependOnLC || CondDependOnLC) 7594 return Condition; 7595 return nullptr; 7596 } 7597 7598 Expr *OpenMPIterationSpaceChecker::buildPreCond( 7599 Scope *S, Expr *Cond, 7600 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const { 7601 // Do not build a precondition when the condition/initialization is dependent 7602 // to prevent pessimistic early loop exit. 7603 // TODO: this can be improved by calculating min/max values but not sure that 7604 // it will be very effective. 7605 if (CondDependOnLC || InitDependOnLC) 7606 return SemaRef.PerformImplicitConversion( 7607 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get(), 7608 SemaRef.Context.BoolTy, /*Action=*/Sema::AA_Casting, 7609 /*AllowExplicit=*/true).get(); 7610 7611 // Try to build LB <op> UB, where <op> is <, >, <=, or >=. 7612 Sema::TentativeAnalysisScope Trap(SemaRef); 7613 7614 ExprResult NewLB = tryBuildCapture(SemaRef, LB, Captures); 7615 ExprResult NewUB = tryBuildCapture(SemaRef, UB, Captures); 7616 if (!NewLB.isUsable() || !NewUB.isUsable()) 7617 return nullptr; 7618 7619 ExprResult CondExpr = 7620 SemaRef.BuildBinOp(S, DefaultLoc, 7621 TestIsLessOp.getValue() ? 7622 (TestIsStrictOp ? BO_LT : BO_LE) : 7623 (TestIsStrictOp ? BO_GT : BO_GE), 7624 NewLB.get(), NewUB.get()); 7625 if (CondExpr.isUsable()) { 7626 if (!SemaRef.Context.hasSameUnqualifiedType(CondExpr.get()->getType(), 7627 SemaRef.Context.BoolTy)) 7628 CondExpr = SemaRef.PerformImplicitConversion( 7629 CondExpr.get(), SemaRef.Context.BoolTy, /*Action=*/Sema::AA_Casting, 7630 /*AllowExplicit=*/true); 7631 } 7632 7633 // Otherwise use original loop condition and evaluate it in runtime. 7634 return CondExpr.isUsable() ? CondExpr.get() : Cond; 7635 } 7636 7637 /// Build reference expression to the counter be used for codegen. 7638 DeclRefExpr *OpenMPIterationSpaceChecker::buildCounterVar( 7639 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures, 7640 DSAStackTy &DSA) const { 7641 auto *VD = dyn_cast<VarDecl>(LCDecl); 7642 if (!VD) { 7643 VD = SemaRef.isOpenMPCapturedDecl(LCDecl); 7644 DeclRefExpr *Ref = buildDeclRefExpr( 7645 SemaRef, VD, VD->getType().getNonReferenceType(), DefaultLoc); 7646 const DSAStackTy::DSAVarData Data = 7647 DSA.getTopDSA(LCDecl, /*FromParent=*/false); 7648 // If the loop control decl is explicitly marked as private, do not mark it 7649 // as captured again. 7650 if (!isOpenMPPrivate(Data.CKind) || !Data.RefExpr) 7651 Captures.insert(std::make_pair(LCRef, Ref)); 7652 return Ref; 7653 } 7654 return cast<DeclRefExpr>(LCRef); 7655 } 7656 7657 Expr *OpenMPIterationSpaceChecker::buildPrivateCounterVar() const { 7658 if (LCDecl && !LCDecl->isInvalidDecl()) { 7659 QualType Type = LCDecl->getType().getNonReferenceType(); 7660 VarDecl *PrivateVar = buildVarDecl( 7661 SemaRef, DefaultLoc, Type, LCDecl->getName(), 7662 LCDecl->hasAttrs() ? &LCDecl->getAttrs() : nullptr, 7663 isa<VarDecl>(LCDecl) 7664 ? buildDeclRefExpr(SemaRef, cast<VarDecl>(LCDecl), Type, DefaultLoc) 7665 : nullptr); 7666 if (PrivateVar->isInvalidDecl()) 7667 return nullptr; 7668 return buildDeclRefExpr(SemaRef, PrivateVar, Type, DefaultLoc); 7669 } 7670 return nullptr; 7671 } 7672 7673 /// Build initialization of the counter to be used for codegen. 7674 Expr *OpenMPIterationSpaceChecker::buildCounterInit() const { return LB; } 7675 7676 /// Build step of the counter be used for codegen. 7677 Expr *OpenMPIterationSpaceChecker::buildCounterStep() const { return Step; } 7678 7679 Expr *OpenMPIterationSpaceChecker::buildOrderedLoopData( 7680 Scope *S, Expr *Counter, 7681 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures, SourceLocation Loc, 7682 Expr *Inc, OverloadedOperatorKind OOK) { 7683 Expr *Cnt = SemaRef.DefaultLvalueConversion(Counter).get(); 7684 if (!Cnt) 7685 return nullptr; 7686 if (Inc) { 7687 assert((OOK == OO_Plus || OOK == OO_Minus) && 7688 "Expected only + or - operations for depend clauses."); 7689 BinaryOperatorKind BOK = (OOK == OO_Plus) ? BO_Add : BO_Sub; 7690 Cnt = SemaRef.BuildBinOp(S, Loc, BOK, Cnt, Inc).get(); 7691 if (!Cnt) 7692 return nullptr; 7693 } 7694 QualType VarType = LCDecl->getType().getNonReferenceType(); 7695 if (!VarType->isIntegerType() && !VarType->isPointerType() && 7696 !SemaRef.getLangOpts().CPlusPlus) 7697 return nullptr; 7698 // Upper - Lower 7699 Expr *Upper = TestIsLessOp.getValue() 7700 ? Cnt 7701 : tryBuildCapture(SemaRef, LB, Captures).get(); 7702 Expr *Lower = TestIsLessOp.getValue() 7703 ? tryBuildCapture(SemaRef, LB, Captures).get() 7704 : Cnt; 7705 if (!Upper || !Lower) 7706 return nullptr; 7707 7708 ExprResult Diff = calculateNumIters(SemaRef, S, DefaultLoc, Lower, Upper, 7709 Step, VarType, /*TestIsStrictOp=*/false, 7710 /*RoundToStep=*/false, Captures); 7711 if (!Diff.isUsable()) 7712 return nullptr; 7713 7714 return Diff.get(); 7715 } 7716 } // namespace 7717 7718 void Sema::ActOnOpenMPLoopInitialization(SourceLocation ForLoc, Stmt *Init) { 7719 assert(getLangOpts().OpenMP && "OpenMP is not active."); 7720 assert(Init && "Expected loop in canonical form."); 7721 unsigned AssociatedLoops = DSAStack->getAssociatedLoops(); 7722 if (AssociatedLoops > 0 && 7723 isOpenMPLoopDirective(DSAStack->getCurrentDirective())) { 7724 DSAStack->loopStart(); 7725 OpenMPIterationSpaceChecker ISC(*this, *DSAStack, ForLoc); 7726 if (!ISC.checkAndSetInit(Init, /*EmitDiags=*/false)) { 7727 if (ValueDecl *D = ISC.getLoopDecl()) { 7728 auto *VD = dyn_cast<VarDecl>(D); 7729 DeclRefExpr *PrivateRef = nullptr; 7730 if (!VD) { 7731 if (VarDecl *Private = isOpenMPCapturedDecl(D)) { 7732 VD = Private; 7733 } else { 7734 PrivateRef = buildCapture(*this, D, ISC.getLoopDeclRefExpr(), 7735 /*WithInit=*/false); 7736 VD = cast<VarDecl>(PrivateRef->getDecl()); 7737 } 7738 } 7739 DSAStack->addLoopControlVariable(D, VD); 7740 const Decl *LD = DSAStack->getPossiblyLoopCunter(); 7741 if (LD != D->getCanonicalDecl()) { 7742 DSAStack->resetPossibleLoopCounter(); 7743 if (auto *Var = dyn_cast_or_null<VarDecl>(LD)) 7744 MarkDeclarationsReferencedInExpr( 7745 buildDeclRefExpr(*this, const_cast<VarDecl *>(Var), 7746 Var->getType().getNonLValueExprType(Context), 7747 ForLoc, /*RefersToCapture=*/true)); 7748 } 7749 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 7750 // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables 7751 // Referenced in a Construct, C/C++]. The loop iteration variable in the 7752 // associated for-loop of a simd construct with just one associated 7753 // for-loop may be listed in a linear clause with a constant-linear-step 7754 // that is the increment of the associated for-loop. The loop iteration 7755 // variable(s) in the associated for-loop(s) of a for or parallel for 7756 // construct may be listed in a private or lastprivate clause. 7757 DSAStackTy::DSAVarData DVar = 7758 DSAStack->getTopDSA(D, /*FromParent=*/false); 7759 // If LoopVarRefExpr is nullptr it means the corresponding loop variable 7760 // is declared in the loop and it is predetermined as a private. 7761 Expr *LoopDeclRefExpr = ISC.getLoopDeclRefExpr(); 7762 OpenMPClauseKind PredeterminedCKind = 7763 isOpenMPSimdDirective(DKind) 7764 ? (DSAStack->hasMutipleLoops() ? OMPC_lastprivate : OMPC_linear) 7765 : OMPC_private; 7766 if (((isOpenMPSimdDirective(DKind) && DVar.CKind != OMPC_unknown && 7767 DVar.CKind != PredeterminedCKind && DVar.RefExpr && 7768 (LangOpts.OpenMP <= 45 || (DVar.CKind != OMPC_lastprivate && 7769 DVar.CKind != OMPC_private))) || 7770 ((isOpenMPWorksharingDirective(DKind) || DKind == OMPD_taskloop || 7771 DKind == OMPD_master_taskloop || 7772 DKind == OMPD_parallel_master_taskloop || 7773 isOpenMPDistributeDirective(DKind)) && 7774 !isOpenMPSimdDirective(DKind) && DVar.CKind != OMPC_unknown && 7775 DVar.CKind != OMPC_private && DVar.CKind != OMPC_lastprivate)) && 7776 (DVar.CKind != OMPC_private || DVar.RefExpr)) { 7777 Diag(Init->getBeginLoc(), diag::err_omp_loop_var_dsa) 7778 << getOpenMPClauseName(DVar.CKind) 7779 << getOpenMPDirectiveName(DKind) 7780 << getOpenMPClauseName(PredeterminedCKind); 7781 if (DVar.RefExpr == nullptr) 7782 DVar.CKind = PredeterminedCKind; 7783 reportOriginalDsa(*this, DSAStack, D, DVar, 7784 /*IsLoopIterVar=*/true); 7785 } else if (LoopDeclRefExpr) { 7786 // Make the loop iteration variable private (for worksharing 7787 // constructs), linear (for simd directives with the only one 7788 // associated loop) or lastprivate (for simd directives with several 7789 // collapsed or ordered loops). 7790 if (DVar.CKind == OMPC_unknown) 7791 DSAStack->addDSA(D, LoopDeclRefExpr, PredeterminedCKind, 7792 PrivateRef); 7793 } 7794 } 7795 } 7796 DSAStack->setAssociatedLoops(AssociatedLoops - 1); 7797 } 7798 } 7799 7800 /// Called on a for stmt to check and extract its iteration space 7801 /// for further processing (such as collapsing). 7802 static bool checkOpenMPIterationSpace( 7803 OpenMPDirectiveKind DKind, Stmt *S, Sema &SemaRef, DSAStackTy &DSA, 7804 unsigned CurrentNestedLoopCount, unsigned NestedLoopCount, 7805 unsigned TotalNestedLoopCount, Expr *CollapseLoopCountExpr, 7806 Expr *OrderedLoopCountExpr, 7807 Sema::VarsWithInheritedDSAType &VarsWithImplicitDSA, 7808 llvm::MutableArrayRef<LoopIterationSpace> ResultIterSpaces, 7809 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) { 7810 // OpenMP [2.9.1, Canonical Loop Form] 7811 // for (init-expr; test-expr; incr-expr) structured-block 7812 // for (range-decl: range-expr) structured-block 7813 auto *For = dyn_cast_or_null<ForStmt>(S); 7814 auto *CXXFor = dyn_cast_or_null<CXXForRangeStmt>(S); 7815 // Ranged for is supported only in OpenMP 5.0. 7816 if (!For && (SemaRef.LangOpts.OpenMP <= 45 || !CXXFor)) { 7817 SemaRef.Diag(S->getBeginLoc(), diag::err_omp_not_for) 7818 << (CollapseLoopCountExpr != nullptr || OrderedLoopCountExpr != nullptr) 7819 << getOpenMPDirectiveName(DKind) << TotalNestedLoopCount 7820 << (CurrentNestedLoopCount > 0) << CurrentNestedLoopCount; 7821 if (TotalNestedLoopCount > 1) { 7822 if (CollapseLoopCountExpr && OrderedLoopCountExpr) 7823 SemaRef.Diag(DSA.getConstructLoc(), 7824 diag::note_omp_collapse_ordered_expr) 7825 << 2 << CollapseLoopCountExpr->getSourceRange() 7826 << OrderedLoopCountExpr->getSourceRange(); 7827 else if (CollapseLoopCountExpr) 7828 SemaRef.Diag(CollapseLoopCountExpr->getExprLoc(), 7829 diag::note_omp_collapse_ordered_expr) 7830 << 0 << CollapseLoopCountExpr->getSourceRange(); 7831 else 7832 SemaRef.Diag(OrderedLoopCountExpr->getExprLoc(), 7833 diag::note_omp_collapse_ordered_expr) 7834 << 1 << OrderedLoopCountExpr->getSourceRange(); 7835 } 7836 return true; 7837 } 7838 assert(((For && For->getBody()) || (CXXFor && CXXFor->getBody())) && 7839 "No loop body."); 7840 7841 OpenMPIterationSpaceChecker ISC(SemaRef, DSA, 7842 For ? For->getForLoc() : CXXFor->getForLoc()); 7843 7844 // Check init. 7845 Stmt *Init = For ? For->getInit() : CXXFor->getBeginStmt(); 7846 if (ISC.checkAndSetInit(Init)) 7847 return true; 7848 7849 bool HasErrors = false; 7850 7851 // Check loop variable's type. 7852 if (ValueDecl *LCDecl = ISC.getLoopDecl()) { 7853 // OpenMP [2.6, Canonical Loop Form] 7854 // Var is one of the following: 7855 // A variable of signed or unsigned integer type. 7856 // For C++, a variable of a random access iterator type. 7857 // For C, a variable of a pointer type. 7858 QualType VarType = LCDecl->getType().getNonReferenceType(); 7859 if (!VarType->isDependentType() && !VarType->isIntegerType() && 7860 !VarType->isPointerType() && 7861 !(SemaRef.getLangOpts().CPlusPlus && VarType->isOverloadableType())) { 7862 SemaRef.Diag(Init->getBeginLoc(), diag::err_omp_loop_variable_type) 7863 << SemaRef.getLangOpts().CPlusPlus; 7864 HasErrors = true; 7865 } 7866 7867 // OpenMP, 2.14.1.1 Data-sharing Attribute Rules for Variables Referenced in 7868 // a Construct 7869 // The loop iteration variable(s) in the associated for-loop(s) of a for or 7870 // parallel for construct is (are) private. 7871 // The loop iteration variable in the associated for-loop of a simd 7872 // construct with just one associated for-loop is linear with a 7873 // constant-linear-step that is the increment of the associated for-loop. 7874 // Exclude loop var from the list of variables with implicitly defined data 7875 // sharing attributes. 7876 VarsWithImplicitDSA.erase(LCDecl); 7877 7878 assert(isOpenMPLoopDirective(DKind) && "DSA for non-loop vars"); 7879 7880 // Check test-expr. 7881 HasErrors |= ISC.checkAndSetCond(For ? For->getCond() : CXXFor->getCond()); 7882 7883 // Check incr-expr. 7884 HasErrors |= ISC.checkAndSetInc(For ? For->getInc() : CXXFor->getInc()); 7885 } 7886 7887 if (ISC.dependent() || SemaRef.CurContext->isDependentContext() || HasErrors) 7888 return HasErrors; 7889 7890 // Build the loop's iteration space representation. 7891 ResultIterSpaces[CurrentNestedLoopCount].PreCond = ISC.buildPreCond( 7892 DSA.getCurScope(), For ? For->getCond() : CXXFor->getCond(), Captures); 7893 ResultIterSpaces[CurrentNestedLoopCount].NumIterations = 7894 ISC.buildNumIterations(DSA.getCurScope(), ResultIterSpaces, 7895 (isOpenMPWorksharingDirective(DKind) || 7896 isOpenMPTaskLoopDirective(DKind) || 7897 isOpenMPDistributeDirective(DKind)), 7898 Captures); 7899 ResultIterSpaces[CurrentNestedLoopCount].CounterVar = 7900 ISC.buildCounterVar(Captures, DSA); 7901 ResultIterSpaces[CurrentNestedLoopCount].PrivateCounterVar = 7902 ISC.buildPrivateCounterVar(); 7903 ResultIterSpaces[CurrentNestedLoopCount].CounterInit = ISC.buildCounterInit(); 7904 ResultIterSpaces[CurrentNestedLoopCount].CounterStep = ISC.buildCounterStep(); 7905 ResultIterSpaces[CurrentNestedLoopCount].InitSrcRange = ISC.getInitSrcRange(); 7906 ResultIterSpaces[CurrentNestedLoopCount].CondSrcRange = 7907 ISC.getConditionSrcRange(); 7908 ResultIterSpaces[CurrentNestedLoopCount].IncSrcRange = 7909 ISC.getIncrementSrcRange(); 7910 ResultIterSpaces[CurrentNestedLoopCount].Subtract = ISC.shouldSubtractStep(); 7911 ResultIterSpaces[CurrentNestedLoopCount].IsStrictCompare = 7912 ISC.isStrictTestOp(); 7913 std::tie(ResultIterSpaces[CurrentNestedLoopCount].MinValue, 7914 ResultIterSpaces[CurrentNestedLoopCount].MaxValue) = 7915 ISC.buildMinMaxValues(DSA.getCurScope(), Captures); 7916 ResultIterSpaces[CurrentNestedLoopCount].FinalCondition = 7917 ISC.buildFinalCondition(DSA.getCurScope()); 7918 ResultIterSpaces[CurrentNestedLoopCount].IsNonRectangularLB = 7919 ISC.doesInitDependOnLC(); 7920 ResultIterSpaces[CurrentNestedLoopCount].IsNonRectangularUB = 7921 ISC.doesCondDependOnLC(); 7922 ResultIterSpaces[CurrentNestedLoopCount].LoopDependentIdx = 7923 ISC.getLoopDependentIdx(); 7924 7925 HasErrors |= 7926 (ResultIterSpaces[CurrentNestedLoopCount].PreCond == nullptr || 7927 ResultIterSpaces[CurrentNestedLoopCount].NumIterations == nullptr || 7928 ResultIterSpaces[CurrentNestedLoopCount].CounterVar == nullptr || 7929 ResultIterSpaces[CurrentNestedLoopCount].PrivateCounterVar == nullptr || 7930 ResultIterSpaces[CurrentNestedLoopCount].CounterInit == nullptr || 7931 ResultIterSpaces[CurrentNestedLoopCount].CounterStep == nullptr); 7932 if (!HasErrors && DSA.isOrderedRegion()) { 7933 if (DSA.getOrderedRegionParam().second->getNumForLoops()) { 7934 if (CurrentNestedLoopCount < 7935 DSA.getOrderedRegionParam().second->getLoopNumIterations().size()) { 7936 DSA.getOrderedRegionParam().second->setLoopNumIterations( 7937 CurrentNestedLoopCount, 7938 ResultIterSpaces[CurrentNestedLoopCount].NumIterations); 7939 DSA.getOrderedRegionParam().second->setLoopCounter( 7940 CurrentNestedLoopCount, 7941 ResultIterSpaces[CurrentNestedLoopCount].CounterVar); 7942 } 7943 } 7944 for (auto &Pair : DSA.getDoacrossDependClauses()) { 7945 if (CurrentNestedLoopCount >= Pair.first->getNumLoops()) { 7946 // Erroneous case - clause has some problems. 7947 continue; 7948 } 7949 if (Pair.first->getDependencyKind() == OMPC_DEPEND_sink && 7950 Pair.second.size() <= CurrentNestedLoopCount) { 7951 // Erroneous case - clause has some problems. 7952 Pair.first->setLoopData(CurrentNestedLoopCount, nullptr); 7953 continue; 7954 } 7955 Expr *CntValue; 7956 if (Pair.first->getDependencyKind() == OMPC_DEPEND_source) 7957 CntValue = ISC.buildOrderedLoopData( 7958 DSA.getCurScope(), 7959 ResultIterSpaces[CurrentNestedLoopCount].CounterVar, Captures, 7960 Pair.first->getDependencyLoc()); 7961 else 7962 CntValue = ISC.buildOrderedLoopData( 7963 DSA.getCurScope(), 7964 ResultIterSpaces[CurrentNestedLoopCount].CounterVar, Captures, 7965 Pair.first->getDependencyLoc(), 7966 Pair.second[CurrentNestedLoopCount].first, 7967 Pair.second[CurrentNestedLoopCount].second); 7968 Pair.first->setLoopData(CurrentNestedLoopCount, CntValue); 7969 } 7970 } 7971 7972 return HasErrors; 7973 } 7974 7975 /// Build 'VarRef = Start. 7976 static ExprResult 7977 buildCounterInit(Sema &SemaRef, Scope *S, SourceLocation Loc, ExprResult VarRef, 7978 ExprResult Start, bool IsNonRectangularLB, 7979 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) { 7980 // Build 'VarRef = Start. 7981 ExprResult NewStart = IsNonRectangularLB 7982 ? Start.get() 7983 : tryBuildCapture(SemaRef, Start.get(), Captures); 7984 if (!NewStart.isUsable()) 7985 return ExprError(); 7986 if (!SemaRef.Context.hasSameType(NewStart.get()->getType(), 7987 VarRef.get()->getType())) { 7988 NewStart = SemaRef.PerformImplicitConversion( 7989 NewStart.get(), VarRef.get()->getType(), Sema::AA_Converting, 7990 /*AllowExplicit=*/true); 7991 if (!NewStart.isUsable()) 7992 return ExprError(); 7993 } 7994 7995 ExprResult Init = 7996 SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), NewStart.get()); 7997 return Init; 7998 } 7999 8000 /// Build 'VarRef = Start + Iter * Step'. 8001 static ExprResult buildCounterUpdate( 8002 Sema &SemaRef, Scope *S, SourceLocation Loc, ExprResult VarRef, 8003 ExprResult Start, ExprResult Iter, ExprResult Step, bool Subtract, 8004 bool IsNonRectangularLB, 8005 llvm::MapVector<const Expr *, DeclRefExpr *> *Captures = nullptr) { 8006 // Add parentheses (for debugging purposes only). 8007 Iter = SemaRef.ActOnParenExpr(Loc, Loc, Iter.get()); 8008 if (!VarRef.isUsable() || !Start.isUsable() || !Iter.isUsable() || 8009 !Step.isUsable()) 8010 return ExprError(); 8011 8012 ExprResult NewStep = Step; 8013 if (Captures) 8014 NewStep = tryBuildCapture(SemaRef, Step.get(), *Captures); 8015 if (NewStep.isInvalid()) 8016 return ExprError(); 8017 ExprResult Update = 8018 SemaRef.BuildBinOp(S, Loc, BO_Mul, Iter.get(), NewStep.get()); 8019 if (!Update.isUsable()) 8020 return ExprError(); 8021 8022 // Try to build 'VarRef = Start, VarRef (+|-)= Iter * Step' or 8023 // 'VarRef = Start (+|-) Iter * Step'. 8024 if (!Start.isUsable()) 8025 return ExprError(); 8026 ExprResult NewStart = SemaRef.ActOnParenExpr(Loc, Loc, Start.get()); 8027 if (!NewStart.isUsable()) 8028 return ExprError(); 8029 if (Captures && !IsNonRectangularLB) 8030 NewStart = tryBuildCapture(SemaRef, Start.get(), *Captures); 8031 if (NewStart.isInvalid()) 8032 return ExprError(); 8033 8034 // First attempt: try to build 'VarRef = Start, VarRef += Iter * Step'. 8035 ExprResult SavedUpdate = Update; 8036 ExprResult UpdateVal; 8037 if (VarRef.get()->getType()->isOverloadableType() || 8038 NewStart.get()->getType()->isOverloadableType() || 8039 Update.get()->getType()->isOverloadableType()) { 8040 Sema::TentativeAnalysisScope Trap(SemaRef); 8041 8042 Update = 8043 SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), NewStart.get()); 8044 if (Update.isUsable()) { 8045 UpdateVal = 8046 SemaRef.BuildBinOp(S, Loc, Subtract ? BO_SubAssign : BO_AddAssign, 8047 VarRef.get(), SavedUpdate.get()); 8048 if (UpdateVal.isUsable()) { 8049 Update = SemaRef.CreateBuiltinBinOp(Loc, BO_Comma, Update.get(), 8050 UpdateVal.get()); 8051 } 8052 } 8053 } 8054 8055 // Second attempt: try to build 'VarRef = Start (+|-) Iter * Step'. 8056 if (!Update.isUsable() || !UpdateVal.isUsable()) { 8057 Update = SemaRef.BuildBinOp(S, Loc, Subtract ? BO_Sub : BO_Add, 8058 NewStart.get(), SavedUpdate.get()); 8059 if (!Update.isUsable()) 8060 return ExprError(); 8061 8062 if (!SemaRef.Context.hasSameType(Update.get()->getType(), 8063 VarRef.get()->getType())) { 8064 Update = SemaRef.PerformImplicitConversion( 8065 Update.get(), VarRef.get()->getType(), Sema::AA_Converting, true); 8066 if (!Update.isUsable()) 8067 return ExprError(); 8068 } 8069 8070 Update = SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), Update.get()); 8071 } 8072 return Update; 8073 } 8074 8075 /// Convert integer expression \a E to make it have at least \a Bits 8076 /// bits. 8077 static ExprResult widenIterationCount(unsigned Bits, Expr *E, Sema &SemaRef) { 8078 if (E == nullptr) 8079 return ExprError(); 8080 ASTContext &C = SemaRef.Context; 8081 QualType OldType = E->getType(); 8082 unsigned HasBits = C.getTypeSize(OldType); 8083 if (HasBits >= Bits) 8084 return ExprResult(E); 8085 // OK to convert to signed, because new type has more bits than old. 8086 QualType NewType = C.getIntTypeForBitwidth(Bits, /* Signed */ true); 8087 return SemaRef.PerformImplicitConversion(E, NewType, Sema::AA_Converting, 8088 true); 8089 } 8090 8091 /// Check if the given expression \a E is a constant integer that fits 8092 /// into \a Bits bits. 8093 static bool fitsInto(unsigned Bits, bool Signed, const Expr *E, Sema &SemaRef) { 8094 if (E == nullptr) 8095 return false; 8096 if (Optional<llvm::APSInt> Result = 8097 E->getIntegerConstantExpr(SemaRef.Context)) 8098 return Signed ? Result->isSignedIntN(Bits) : Result->isIntN(Bits); 8099 return false; 8100 } 8101 8102 /// Build preinits statement for the given declarations. 8103 static Stmt *buildPreInits(ASTContext &Context, 8104 MutableArrayRef<Decl *> PreInits) { 8105 if (!PreInits.empty()) { 8106 return new (Context) DeclStmt( 8107 DeclGroupRef::Create(Context, PreInits.begin(), PreInits.size()), 8108 SourceLocation(), SourceLocation()); 8109 } 8110 return nullptr; 8111 } 8112 8113 /// Build preinits statement for the given declarations. 8114 static Stmt * 8115 buildPreInits(ASTContext &Context, 8116 const llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) { 8117 if (!Captures.empty()) { 8118 SmallVector<Decl *, 16> PreInits; 8119 for (const auto &Pair : Captures) 8120 PreInits.push_back(Pair.second->getDecl()); 8121 return buildPreInits(Context, PreInits); 8122 } 8123 return nullptr; 8124 } 8125 8126 /// Build postupdate expression for the given list of postupdates expressions. 8127 static Expr *buildPostUpdate(Sema &S, ArrayRef<Expr *> PostUpdates) { 8128 Expr *PostUpdate = nullptr; 8129 if (!PostUpdates.empty()) { 8130 for (Expr *E : PostUpdates) { 8131 Expr *ConvE = S.BuildCStyleCastExpr( 8132 E->getExprLoc(), 8133 S.Context.getTrivialTypeSourceInfo(S.Context.VoidTy), 8134 E->getExprLoc(), E) 8135 .get(); 8136 PostUpdate = PostUpdate 8137 ? S.CreateBuiltinBinOp(ConvE->getExprLoc(), BO_Comma, 8138 PostUpdate, ConvE) 8139 .get() 8140 : ConvE; 8141 } 8142 } 8143 return PostUpdate; 8144 } 8145 8146 /// Called on a for stmt to check itself and nested loops (if any). 8147 /// \return Returns 0 if one of the collapsed stmts is not canonical for loop, 8148 /// number of collapsed loops otherwise. 8149 static unsigned 8150 checkOpenMPLoop(OpenMPDirectiveKind DKind, Expr *CollapseLoopCountExpr, 8151 Expr *OrderedLoopCountExpr, Stmt *AStmt, Sema &SemaRef, 8152 DSAStackTy &DSA, 8153 Sema::VarsWithInheritedDSAType &VarsWithImplicitDSA, 8154 OMPLoopDirective::HelperExprs &Built) { 8155 unsigned NestedLoopCount = 1; 8156 if (CollapseLoopCountExpr) { 8157 // Found 'collapse' clause - calculate collapse number. 8158 Expr::EvalResult Result; 8159 if (!CollapseLoopCountExpr->isValueDependent() && 8160 CollapseLoopCountExpr->EvaluateAsInt(Result, SemaRef.getASTContext())) { 8161 NestedLoopCount = Result.Val.getInt().getLimitedValue(); 8162 } else { 8163 Built.clear(/*Size=*/1); 8164 return 1; 8165 } 8166 } 8167 unsigned OrderedLoopCount = 1; 8168 if (OrderedLoopCountExpr) { 8169 // Found 'ordered' clause - calculate collapse number. 8170 Expr::EvalResult EVResult; 8171 if (!OrderedLoopCountExpr->isValueDependent() && 8172 OrderedLoopCountExpr->EvaluateAsInt(EVResult, 8173 SemaRef.getASTContext())) { 8174 llvm::APSInt Result = EVResult.Val.getInt(); 8175 if (Result.getLimitedValue() < NestedLoopCount) { 8176 SemaRef.Diag(OrderedLoopCountExpr->getExprLoc(), 8177 diag::err_omp_wrong_ordered_loop_count) 8178 << OrderedLoopCountExpr->getSourceRange(); 8179 SemaRef.Diag(CollapseLoopCountExpr->getExprLoc(), 8180 diag::note_collapse_loop_count) 8181 << CollapseLoopCountExpr->getSourceRange(); 8182 } 8183 OrderedLoopCount = Result.getLimitedValue(); 8184 } else { 8185 Built.clear(/*Size=*/1); 8186 return 1; 8187 } 8188 } 8189 // This is helper routine for loop directives (e.g., 'for', 'simd', 8190 // 'for simd', etc.). 8191 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 8192 SmallVector<LoopIterationSpace, 4> IterSpaces( 8193 std::max(OrderedLoopCount, NestedLoopCount)); 8194 Stmt *CurStmt = AStmt->IgnoreContainers(/* IgnoreCaptured */ true); 8195 for (unsigned Cnt = 0; Cnt < NestedLoopCount; ++Cnt) { 8196 if (checkOpenMPIterationSpace( 8197 DKind, CurStmt, SemaRef, DSA, Cnt, NestedLoopCount, 8198 std::max(OrderedLoopCount, NestedLoopCount), CollapseLoopCountExpr, 8199 OrderedLoopCountExpr, VarsWithImplicitDSA, IterSpaces, Captures)) 8200 return 0; 8201 // Move on to the next nested for loop, or to the loop body. 8202 // OpenMP [2.8.1, simd construct, Restrictions] 8203 // All loops associated with the construct must be perfectly nested; that 8204 // is, there must be no intervening code nor any OpenMP directive between 8205 // any two loops. 8206 if (auto *For = dyn_cast<ForStmt>(CurStmt)) { 8207 CurStmt = For->getBody(); 8208 } else { 8209 assert(isa<CXXForRangeStmt>(CurStmt) && 8210 "Expected canonical for or range-based for loops."); 8211 CurStmt = cast<CXXForRangeStmt>(CurStmt)->getBody(); 8212 } 8213 CurStmt = OMPLoopDirective::tryToFindNextInnerLoop( 8214 CurStmt, SemaRef.LangOpts.OpenMP >= 50); 8215 } 8216 for (unsigned Cnt = NestedLoopCount; Cnt < OrderedLoopCount; ++Cnt) { 8217 if (checkOpenMPIterationSpace( 8218 DKind, CurStmt, SemaRef, DSA, Cnt, NestedLoopCount, 8219 std::max(OrderedLoopCount, NestedLoopCount), CollapseLoopCountExpr, 8220 OrderedLoopCountExpr, VarsWithImplicitDSA, IterSpaces, Captures)) 8221 return 0; 8222 if (Cnt > 0 && IterSpaces[Cnt].CounterVar) { 8223 // Handle initialization of captured loop iterator variables. 8224 auto *DRE = cast<DeclRefExpr>(IterSpaces[Cnt].CounterVar); 8225 if (isa<OMPCapturedExprDecl>(DRE->getDecl())) { 8226 Captures[DRE] = DRE; 8227 } 8228 } 8229 // Move on to the next nested for loop, or to the loop body. 8230 // OpenMP [2.8.1, simd construct, Restrictions] 8231 // All loops associated with the construct must be perfectly nested; that 8232 // is, there must be no intervening code nor any OpenMP directive between 8233 // any two loops. 8234 if (auto *For = dyn_cast<ForStmt>(CurStmt)) { 8235 CurStmt = For->getBody(); 8236 } else { 8237 assert(isa<CXXForRangeStmt>(CurStmt) && 8238 "Expected canonical for or range-based for loops."); 8239 CurStmt = cast<CXXForRangeStmt>(CurStmt)->getBody(); 8240 } 8241 CurStmt = OMPLoopDirective::tryToFindNextInnerLoop( 8242 CurStmt, SemaRef.LangOpts.OpenMP >= 50); 8243 } 8244 8245 Built.clear(/* size */ NestedLoopCount); 8246 8247 if (SemaRef.CurContext->isDependentContext()) 8248 return NestedLoopCount; 8249 8250 // An example of what is generated for the following code: 8251 // 8252 // #pragma omp simd collapse(2) ordered(2) 8253 // for (i = 0; i < NI; ++i) 8254 // for (k = 0; k < NK; ++k) 8255 // for (j = J0; j < NJ; j+=2) { 8256 // <loop body> 8257 // } 8258 // 8259 // We generate the code below. 8260 // Note: the loop body may be outlined in CodeGen. 8261 // Note: some counters may be C++ classes, operator- is used to find number of 8262 // iterations and operator+= to calculate counter value. 8263 // Note: decltype(NumIterations) must be integer type (in 'omp for', only i32 8264 // or i64 is currently supported). 8265 // 8266 // #define NumIterations (NI * ((NJ - J0 - 1 + 2) / 2)) 8267 // for (int[32|64]_t IV = 0; IV < NumIterations; ++IV ) { 8268 // .local.i = IV / ((NJ - J0 - 1 + 2) / 2); 8269 // .local.j = J0 + (IV % ((NJ - J0 - 1 + 2) / 2)) * 2; 8270 // // similar updates for vars in clauses (e.g. 'linear') 8271 // <loop body (using local i and j)> 8272 // } 8273 // i = NI; // assign final values of counters 8274 // j = NJ; 8275 // 8276 8277 // Last iteration number is (I1 * I2 * ... In) - 1, where I1, I2 ... In are 8278 // the iteration counts of the collapsed for loops. 8279 // Precondition tests if there is at least one iteration (all conditions are 8280 // true). 8281 auto PreCond = ExprResult(IterSpaces[0].PreCond); 8282 Expr *N0 = IterSpaces[0].NumIterations; 8283 ExprResult LastIteration32 = 8284 widenIterationCount(/*Bits=*/32, 8285 SemaRef 8286 .PerformImplicitConversion( 8287 N0->IgnoreImpCasts(), N0->getType(), 8288 Sema::AA_Converting, /*AllowExplicit=*/true) 8289 .get(), 8290 SemaRef); 8291 ExprResult LastIteration64 = widenIterationCount( 8292 /*Bits=*/64, 8293 SemaRef 8294 .PerformImplicitConversion(N0->IgnoreImpCasts(), N0->getType(), 8295 Sema::AA_Converting, 8296 /*AllowExplicit=*/true) 8297 .get(), 8298 SemaRef); 8299 8300 if (!LastIteration32.isUsable() || !LastIteration64.isUsable()) 8301 return NestedLoopCount; 8302 8303 ASTContext &C = SemaRef.Context; 8304 bool AllCountsNeedLessThan32Bits = C.getTypeSize(N0->getType()) < 32; 8305 8306 Scope *CurScope = DSA.getCurScope(); 8307 for (unsigned Cnt = 1; Cnt < NestedLoopCount; ++Cnt) { 8308 if (PreCond.isUsable()) { 8309 PreCond = 8310 SemaRef.BuildBinOp(CurScope, PreCond.get()->getExprLoc(), BO_LAnd, 8311 PreCond.get(), IterSpaces[Cnt].PreCond); 8312 } 8313 Expr *N = IterSpaces[Cnt].NumIterations; 8314 SourceLocation Loc = N->getExprLoc(); 8315 AllCountsNeedLessThan32Bits &= C.getTypeSize(N->getType()) < 32; 8316 if (LastIteration32.isUsable()) 8317 LastIteration32 = SemaRef.BuildBinOp( 8318 CurScope, Loc, BO_Mul, LastIteration32.get(), 8319 SemaRef 8320 .PerformImplicitConversion(N->IgnoreImpCasts(), N->getType(), 8321 Sema::AA_Converting, 8322 /*AllowExplicit=*/true) 8323 .get()); 8324 if (LastIteration64.isUsable()) 8325 LastIteration64 = SemaRef.BuildBinOp( 8326 CurScope, Loc, BO_Mul, LastIteration64.get(), 8327 SemaRef 8328 .PerformImplicitConversion(N->IgnoreImpCasts(), N->getType(), 8329 Sema::AA_Converting, 8330 /*AllowExplicit=*/true) 8331 .get()); 8332 } 8333 8334 // Choose either the 32-bit or 64-bit version. 8335 ExprResult LastIteration = LastIteration64; 8336 if (SemaRef.getLangOpts().OpenMPOptimisticCollapse || 8337 (LastIteration32.isUsable() && 8338 C.getTypeSize(LastIteration32.get()->getType()) == 32 && 8339 (AllCountsNeedLessThan32Bits || NestedLoopCount == 1 || 8340 fitsInto( 8341 /*Bits=*/32, 8342 LastIteration32.get()->getType()->hasSignedIntegerRepresentation(), 8343 LastIteration64.get(), SemaRef)))) 8344 LastIteration = LastIteration32; 8345 QualType VType = LastIteration.get()->getType(); 8346 QualType RealVType = VType; 8347 QualType StrideVType = VType; 8348 if (isOpenMPTaskLoopDirective(DKind)) { 8349 VType = 8350 SemaRef.Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/0); 8351 StrideVType = 8352 SemaRef.Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/1); 8353 } 8354 8355 if (!LastIteration.isUsable()) 8356 return 0; 8357 8358 // Save the number of iterations. 8359 ExprResult NumIterations = LastIteration; 8360 { 8361 LastIteration = SemaRef.BuildBinOp( 8362 CurScope, LastIteration.get()->getExprLoc(), BO_Sub, 8363 LastIteration.get(), 8364 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()); 8365 if (!LastIteration.isUsable()) 8366 return 0; 8367 } 8368 8369 // Calculate the last iteration number beforehand instead of doing this on 8370 // each iteration. Do not do this if the number of iterations may be kfold-ed. 8371 bool IsConstant = LastIteration.get()->isIntegerConstantExpr(SemaRef.Context); 8372 ExprResult CalcLastIteration; 8373 if (!IsConstant) { 8374 ExprResult SaveRef = 8375 tryBuildCapture(SemaRef, LastIteration.get(), Captures); 8376 LastIteration = SaveRef; 8377 8378 // Prepare SaveRef + 1. 8379 NumIterations = SemaRef.BuildBinOp( 8380 CurScope, SaveRef.get()->getExprLoc(), BO_Add, SaveRef.get(), 8381 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()); 8382 if (!NumIterations.isUsable()) 8383 return 0; 8384 } 8385 8386 SourceLocation InitLoc = IterSpaces[0].InitSrcRange.getBegin(); 8387 8388 // Build variables passed into runtime, necessary for worksharing directives. 8389 ExprResult LB, UB, IL, ST, EUB, CombLB, CombUB, PrevLB, PrevUB, CombEUB; 8390 if (isOpenMPWorksharingDirective(DKind) || isOpenMPTaskLoopDirective(DKind) || 8391 isOpenMPDistributeDirective(DKind)) { 8392 // Lower bound variable, initialized with zero. 8393 VarDecl *LBDecl = buildVarDecl(SemaRef, InitLoc, VType, ".omp.lb"); 8394 LB = buildDeclRefExpr(SemaRef, LBDecl, VType, InitLoc); 8395 SemaRef.AddInitializerToDecl(LBDecl, 8396 SemaRef.ActOnIntegerConstant(InitLoc, 0).get(), 8397 /*DirectInit*/ false); 8398 8399 // Upper bound variable, initialized with last iteration number. 8400 VarDecl *UBDecl = buildVarDecl(SemaRef, InitLoc, VType, ".omp.ub"); 8401 UB = buildDeclRefExpr(SemaRef, UBDecl, VType, InitLoc); 8402 SemaRef.AddInitializerToDecl(UBDecl, LastIteration.get(), 8403 /*DirectInit*/ false); 8404 8405 // A 32-bit variable-flag where runtime returns 1 for the last iteration. 8406 // This will be used to implement clause 'lastprivate'. 8407 QualType Int32Ty = SemaRef.Context.getIntTypeForBitwidth(32, true); 8408 VarDecl *ILDecl = buildVarDecl(SemaRef, InitLoc, Int32Ty, ".omp.is_last"); 8409 IL = buildDeclRefExpr(SemaRef, ILDecl, Int32Ty, InitLoc); 8410 SemaRef.AddInitializerToDecl(ILDecl, 8411 SemaRef.ActOnIntegerConstant(InitLoc, 0).get(), 8412 /*DirectInit*/ false); 8413 8414 // Stride variable returned by runtime (we initialize it to 1 by default). 8415 VarDecl *STDecl = 8416 buildVarDecl(SemaRef, InitLoc, StrideVType, ".omp.stride"); 8417 ST = buildDeclRefExpr(SemaRef, STDecl, StrideVType, InitLoc); 8418 SemaRef.AddInitializerToDecl(STDecl, 8419 SemaRef.ActOnIntegerConstant(InitLoc, 1).get(), 8420 /*DirectInit*/ false); 8421 8422 // Build expression: UB = min(UB, LastIteration) 8423 // It is necessary for CodeGen of directives with static scheduling. 8424 ExprResult IsUBGreater = SemaRef.BuildBinOp(CurScope, InitLoc, BO_GT, 8425 UB.get(), LastIteration.get()); 8426 ExprResult CondOp = SemaRef.ActOnConditionalOp( 8427 LastIteration.get()->getExprLoc(), InitLoc, IsUBGreater.get(), 8428 LastIteration.get(), UB.get()); 8429 EUB = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, UB.get(), 8430 CondOp.get()); 8431 EUB = SemaRef.ActOnFinishFullExpr(EUB.get(), /*DiscardedValue*/ false); 8432 8433 // If we have a combined directive that combines 'distribute', 'for' or 8434 // 'simd' we need to be able to access the bounds of the schedule of the 8435 // enclosing region. E.g. in 'distribute parallel for' the bounds obtained 8436 // by scheduling 'distribute' have to be passed to the schedule of 'for'. 8437 if (isOpenMPLoopBoundSharingDirective(DKind)) { 8438 // Lower bound variable, initialized with zero. 8439 VarDecl *CombLBDecl = 8440 buildVarDecl(SemaRef, InitLoc, VType, ".omp.comb.lb"); 8441 CombLB = buildDeclRefExpr(SemaRef, CombLBDecl, VType, InitLoc); 8442 SemaRef.AddInitializerToDecl( 8443 CombLBDecl, SemaRef.ActOnIntegerConstant(InitLoc, 0).get(), 8444 /*DirectInit*/ false); 8445 8446 // Upper bound variable, initialized with last iteration number. 8447 VarDecl *CombUBDecl = 8448 buildVarDecl(SemaRef, InitLoc, VType, ".omp.comb.ub"); 8449 CombUB = buildDeclRefExpr(SemaRef, CombUBDecl, VType, InitLoc); 8450 SemaRef.AddInitializerToDecl(CombUBDecl, LastIteration.get(), 8451 /*DirectInit*/ false); 8452 8453 ExprResult CombIsUBGreater = SemaRef.BuildBinOp( 8454 CurScope, InitLoc, BO_GT, CombUB.get(), LastIteration.get()); 8455 ExprResult CombCondOp = 8456 SemaRef.ActOnConditionalOp(InitLoc, InitLoc, CombIsUBGreater.get(), 8457 LastIteration.get(), CombUB.get()); 8458 CombEUB = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, CombUB.get(), 8459 CombCondOp.get()); 8460 CombEUB = 8461 SemaRef.ActOnFinishFullExpr(CombEUB.get(), /*DiscardedValue*/ false); 8462 8463 const CapturedDecl *CD = cast<CapturedStmt>(AStmt)->getCapturedDecl(); 8464 // We expect to have at least 2 more parameters than the 'parallel' 8465 // directive does - the lower and upper bounds of the previous schedule. 8466 assert(CD->getNumParams() >= 4 && 8467 "Unexpected number of parameters in loop combined directive"); 8468 8469 // Set the proper type for the bounds given what we learned from the 8470 // enclosed loops. 8471 ImplicitParamDecl *PrevLBDecl = CD->getParam(/*PrevLB=*/2); 8472 ImplicitParamDecl *PrevUBDecl = CD->getParam(/*PrevUB=*/3); 8473 8474 // Previous lower and upper bounds are obtained from the region 8475 // parameters. 8476 PrevLB = 8477 buildDeclRefExpr(SemaRef, PrevLBDecl, PrevLBDecl->getType(), InitLoc); 8478 PrevUB = 8479 buildDeclRefExpr(SemaRef, PrevUBDecl, PrevUBDecl->getType(), InitLoc); 8480 } 8481 } 8482 8483 // Build the iteration variable and its initialization before loop. 8484 ExprResult IV; 8485 ExprResult Init, CombInit; 8486 { 8487 VarDecl *IVDecl = buildVarDecl(SemaRef, InitLoc, RealVType, ".omp.iv"); 8488 IV = buildDeclRefExpr(SemaRef, IVDecl, RealVType, InitLoc); 8489 Expr *RHS = 8490 (isOpenMPWorksharingDirective(DKind) || 8491 isOpenMPTaskLoopDirective(DKind) || isOpenMPDistributeDirective(DKind)) 8492 ? LB.get() 8493 : SemaRef.ActOnIntegerConstant(SourceLocation(), 0).get(); 8494 Init = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, IV.get(), RHS); 8495 Init = SemaRef.ActOnFinishFullExpr(Init.get(), /*DiscardedValue*/ false); 8496 8497 if (isOpenMPLoopBoundSharingDirective(DKind)) { 8498 Expr *CombRHS = 8499 (isOpenMPWorksharingDirective(DKind) || 8500 isOpenMPTaskLoopDirective(DKind) || 8501 isOpenMPDistributeDirective(DKind)) 8502 ? CombLB.get() 8503 : SemaRef.ActOnIntegerConstant(SourceLocation(), 0).get(); 8504 CombInit = 8505 SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, IV.get(), CombRHS); 8506 CombInit = 8507 SemaRef.ActOnFinishFullExpr(CombInit.get(), /*DiscardedValue*/ false); 8508 } 8509 } 8510 8511 bool UseStrictCompare = 8512 RealVType->hasUnsignedIntegerRepresentation() && 8513 llvm::all_of(IterSpaces, [](const LoopIterationSpace &LIS) { 8514 return LIS.IsStrictCompare; 8515 }); 8516 // Loop condition (IV < NumIterations) or (IV <= UB or IV < UB + 1 (for 8517 // unsigned IV)) for worksharing loops. 8518 SourceLocation CondLoc = AStmt->getBeginLoc(); 8519 Expr *BoundUB = UB.get(); 8520 if (UseStrictCompare) { 8521 BoundUB = 8522 SemaRef 8523 .BuildBinOp(CurScope, CondLoc, BO_Add, BoundUB, 8524 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()) 8525 .get(); 8526 BoundUB = 8527 SemaRef.ActOnFinishFullExpr(BoundUB, /*DiscardedValue*/ false).get(); 8528 } 8529 ExprResult Cond = 8530 (isOpenMPWorksharingDirective(DKind) || 8531 isOpenMPTaskLoopDirective(DKind) || isOpenMPDistributeDirective(DKind)) 8532 ? SemaRef.BuildBinOp(CurScope, CondLoc, 8533 UseStrictCompare ? BO_LT : BO_LE, IV.get(), 8534 BoundUB) 8535 : SemaRef.BuildBinOp(CurScope, CondLoc, BO_LT, IV.get(), 8536 NumIterations.get()); 8537 ExprResult CombDistCond; 8538 if (isOpenMPLoopBoundSharingDirective(DKind)) { 8539 CombDistCond = SemaRef.BuildBinOp(CurScope, CondLoc, BO_LT, IV.get(), 8540 NumIterations.get()); 8541 } 8542 8543 ExprResult CombCond; 8544 if (isOpenMPLoopBoundSharingDirective(DKind)) { 8545 Expr *BoundCombUB = CombUB.get(); 8546 if (UseStrictCompare) { 8547 BoundCombUB = 8548 SemaRef 8549 .BuildBinOp( 8550 CurScope, CondLoc, BO_Add, BoundCombUB, 8551 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()) 8552 .get(); 8553 BoundCombUB = 8554 SemaRef.ActOnFinishFullExpr(BoundCombUB, /*DiscardedValue*/ false) 8555 .get(); 8556 } 8557 CombCond = 8558 SemaRef.BuildBinOp(CurScope, CondLoc, UseStrictCompare ? BO_LT : BO_LE, 8559 IV.get(), BoundCombUB); 8560 } 8561 // Loop increment (IV = IV + 1) 8562 SourceLocation IncLoc = AStmt->getBeginLoc(); 8563 ExprResult Inc = 8564 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, IV.get(), 8565 SemaRef.ActOnIntegerConstant(IncLoc, 1).get()); 8566 if (!Inc.isUsable()) 8567 return 0; 8568 Inc = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, IV.get(), Inc.get()); 8569 Inc = SemaRef.ActOnFinishFullExpr(Inc.get(), /*DiscardedValue*/ false); 8570 if (!Inc.isUsable()) 8571 return 0; 8572 8573 // Increments for worksharing loops (LB = LB + ST; UB = UB + ST). 8574 // Used for directives with static scheduling. 8575 // In combined construct, add combined version that use CombLB and CombUB 8576 // base variables for the update 8577 ExprResult NextLB, NextUB, CombNextLB, CombNextUB; 8578 if (isOpenMPWorksharingDirective(DKind) || isOpenMPTaskLoopDirective(DKind) || 8579 isOpenMPDistributeDirective(DKind)) { 8580 // LB + ST 8581 NextLB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, LB.get(), ST.get()); 8582 if (!NextLB.isUsable()) 8583 return 0; 8584 // LB = LB + ST 8585 NextLB = 8586 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, LB.get(), NextLB.get()); 8587 NextLB = 8588 SemaRef.ActOnFinishFullExpr(NextLB.get(), /*DiscardedValue*/ false); 8589 if (!NextLB.isUsable()) 8590 return 0; 8591 // UB + ST 8592 NextUB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, UB.get(), ST.get()); 8593 if (!NextUB.isUsable()) 8594 return 0; 8595 // UB = UB + ST 8596 NextUB = 8597 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, UB.get(), NextUB.get()); 8598 NextUB = 8599 SemaRef.ActOnFinishFullExpr(NextUB.get(), /*DiscardedValue*/ false); 8600 if (!NextUB.isUsable()) 8601 return 0; 8602 if (isOpenMPLoopBoundSharingDirective(DKind)) { 8603 CombNextLB = 8604 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, CombLB.get(), ST.get()); 8605 if (!NextLB.isUsable()) 8606 return 0; 8607 // LB = LB + ST 8608 CombNextLB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, CombLB.get(), 8609 CombNextLB.get()); 8610 CombNextLB = SemaRef.ActOnFinishFullExpr(CombNextLB.get(), 8611 /*DiscardedValue*/ false); 8612 if (!CombNextLB.isUsable()) 8613 return 0; 8614 // UB + ST 8615 CombNextUB = 8616 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, CombUB.get(), ST.get()); 8617 if (!CombNextUB.isUsable()) 8618 return 0; 8619 // UB = UB + ST 8620 CombNextUB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, CombUB.get(), 8621 CombNextUB.get()); 8622 CombNextUB = SemaRef.ActOnFinishFullExpr(CombNextUB.get(), 8623 /*DiscardedValue*/ false); 8624 if (!CombNextUB.isUsable()) 8625 return 0; 8626 } 8627 } 8628 8629 // Create increment expression for distribute loop when combined in a same 8630 // directive with for as IV = IV + ST; ensure upper bound expression based 8631 // on PrevUB instead of NumIterations - used to implement 'for' when found 8632 // in combination with 'distribute', like in 'distribute parallel for' 8633 SourceLocation DistIncLoc = AStmt->getBeginLoc(); 8634 ExprResult DistCond, DistInc, PrevEUB, ParForInDistCond; 8635 if (isOpenMPLoopBoundSharingDirective(DKind)) { 8636 DistCond = SemaRef.BuildBinOp( 8637 CurScope, CondLoc, UseStrictCompare ? BO_LT : BO_LE, IV.get(), BoundUB); 8638 assert(DistCond.isUsable() && "distribute cond expr was not built"); 8639 8640 DistInc = 8641 SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Add, IV.get(), ST.get()); 8642 assert(DistInc.isUsable() && "distribute inc expr was not built"); 8643 DistInc = SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Assign, IV.get(), 8644 DistInc.get()); 8645 DistInc = 8646 SemaRef.ActOnFinishFullExpr(DistInc.get(), /*DiscardedValue*/ false); 8647 assert(DistInc.isUsable() && "distribute inc expr was not built"); 8648 8649 // Build expression: UB = min(UB, prevUB) for #for in composite or combined 8650 // construct 8651 SourceLocation DistEUBLoc = AStmt->getBeginLoc(); 8652 ExprResult IsUBGreater = 8653 SemaRef.BuildBinOp(CurScope, DistEUBLoc, BO_GT, UB.get(), PrevUB.get()); 8654 ExprResult CondOp = SemaRef.ActOnConditionalOp( 8655 DistEUBLoc, DistEUBLoc, IsUBGreater.get(), PrevUB.get(), UB.get()); 8656 PrevEUB = SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Assign, UB.get(), 8657 CondOp.get()); 8658 PrevEUB = 8659 SemaRef.ActOnFinishFullExpr(PrevEUB.get(), /*DiscardedValue*/ false); 8660 8661 // Build IV <= PrevUB or IV < PrevUB + 1 for unsigned IV to be used in 8662 // parallel for is in combination with a distribute directive with 8663 // schedule(static, 1) 8664 Expr *BoundPrevUB = PrevUB.get(); 8665 if (UseStrictCompare) { 8666 BoundPrevUB = 8667 SemaRef 8668 .BuildBinOp( 8669 CurScope, CondLoc, BO_Add, BoundPrevUB, 8670 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()) 8671 .get(); 8672 BoundPrevUB = 8673 SemaRef.ActOnFinishFullExpr(BoundPrevUB, /*DiscardedValue*/ false) 8674 .get(); 8675 } 8676 ParForInDistCond = 8677 SemaRef.BuildBinOp(CurScope, CondLoc, UseStrictCompare ? BO_LT : BO_LE, 8678 IV.get(), BoundPrevUB); 8679 } 8680 8681 // Build updates and final values of the loop counters. 8682 bool HasErrors = false; 8683 Built.Counters.resize(NestedLoopCount); 8684 Built.Inits.resize(NestedLoopCount); 8685 Built.Updates.resize(NestedLoopCount); 8686 Built.Finals.resize(NestedLoopCount); 8687 Built.DependentCounters.resize(NestedLoopCount); 8688 Built.DependentInits.resize(NestedLoopCount); 8689 Built.FinalsConditions.resize(NestedLoopCount); 8690 { 8691 // We implement the following algorithm for obtaining the 8692 // original loop iteration variable values based on the 8693 // value of the collapsed loop iteration variable IV. 8694 // 8695 // Let n+1 be the number of collapsed loops in the nest. 8696 // Iteration variables (I0, I1, .... In) 8697 // Iteration counts (N0, N1, ... Nn) 8698 // 8699 // Acc = IV; 8700 // 8701 // To compute Ik for loop k, 0 <= k <= n, generate: 8702 // Prod = N(k+1) * N(k+2) * ... * Nn; 8703 // Ik = Acc / Prod; 8704 // Acc -= Ik * Prod; 8705 // 8706 ExprResult Acc = IV; 8707 for (unsigned int Cnt = 0; Cnt < NestedLoopCount; ++Cnt) { 8708 LoopIterationSpace &IS = IterSpaces[Cnt]; 8709 SourceLocation UpdLoc = IS.IncSrcRange.getBegin(); 8710 ExprResult Iter; 8711 8712 // Compute prod 8713 ExprResult Prod = 8714 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get(); 8715 for (unsigned int K = Cnt+1; K < NestedLoopCount; ++K) 8716 Prod = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Mul, Prod.get(), 8717 IterSpaces[K].NumIterations); 8718 8719 // Iter = Acc / Prod 8720 // If there is at least one more inner loop to avoid 8721 // multiplication by 1. 8722 if (Cnt + 1 < NestedLoopCount) 8723 Iter = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Div, 8724 Acc.get(), Prod.get()); 8725 else 8726 Iter = Acc; 8727 if (!Iter.isUsable()) { 8728 HasErrors = true; 8729 break; 8730 } 8731 8732 // Update Acc: 8733 // Acc -= Iter * Prod 8734 // Check if there is at least one more inner loop to avoid 8735 // multiplication by 1. 8736 if (Cnt + 1 < NestedLoopCount) 8737 Prod = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Mul, 8738 Iter.get(), Prod.get()); 8739 else 8740 Prod = Iter; 8741 Acc = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Sub, 8742 Acc.get(), Prod.get()); 8743 8744 // Build update: IS.CounterVar(Private) = IS.Start + Iter * IS.Step 8745 auto *VD = cast<VarDecl>(cast<DeclRefExpr>(IS.CounterVar)->getDecl()); 8746 DeclRefExpr *CounterVar = buildDeclRefExpr( 8747 SemaRef, VD, IS.CounterVar->getType(), IS.CounterVar->getExprLoc(), 8748 /*RefersToCapture=*/true); 8749 ExprResult Init = 8750 buildCounterInit(SemaRef, CurScope, UpdLoc, CounterVar, 8751 IS.CounterInit, IS.IsNonRectangularLB, Captures); 8752 if (!Init.isUsable()) { 8753 HasErrors = true; 8754 break; 8755 } 8756 ExprResult Update = buildCounterUpdate( 8757 SemaRef, CurScope, UpdLoc, CounterVar, IS.CounterInit, Iter, 8758 IS.CounterStep, IS.Subtract, IS.IsNonRectangularLB, &Captures); 8759 if (!Update.isUsable()) { 8760 HasErrors = true; 8761 break; 8762 } 8763 8764 // Build final: IS.CounterVar = IS.Start + IS.NumIters * IS.Step 8765 ExprResult Final = 8766 buildCounterUpdate(SemaRef, CurScope, UpdLoc, CounterVar, 8767 IS.CounterInit, IS.NumIterations, IS.CounterStep, 8768 IS.Subtract, IS.IsNonRectangularLB, &Captures); 8769 if (!Final.isUsable()) { 8770 HasErrors = true; 8771 break; 8772 } 8773 8774 if (!Update.isUsable() || !Final.isUsable()) { 8775 HasErrors = true; 8776 break; 8777 } 8778 // Save results 8779 Built.Counters[Cnt] = IS.CounterVar; 8780 Built.PrivateCounters[Cnt] = IS.PrivateCounterVar; 8781 Built.Inits[Cnt] = Init.get(); 8782 Built.Updates[Cnt] = Update.get(); 8783 Built.Finals[Cnt] = Final.get(); 8784 Built.DependentCounters[Cnt] = nullptr; 8785 Built.DependentInits[Cnt] = nullptr; 8786 Built.FinalsConditions[Cnt] = nullptr; 8787 if (IS.IsNonRectangularLB || IS.IsNonRectangularUB) { 8788 Built.DependentCounters[Cnt] = 8789 Built.Counters[NestedLoopCount - 1 - IS.LoopDependentIdx]; 8790 Built.DependentInits[Cnt] = 8791 Built.Inits[NestedLoopCount - 1 - IS.LoopDependentIdx]; 8792 Built.FinalsConditions[Cnt] = IS.FinalCondition; 8793 } 8794 } 8795 } 8796 8797 if (HasErrors) 8798 return 0; 8799 8800 // Save results 8801 Built.IterationVarRef = IV.get(); 8802 Built.LastIteration = LastIteration.get(); 8803 Built.NumIterations = NumIterations.get(); 8804 Built.CalcLastIteration = SemaRef 8805 .ActOnFinishFullExpr(CalcLastIteration.get(), 8806 /*DiscardedValue=*/false) 8807 .get(); 8808 Built.PreCond = PreCond.get(); 8809 Built.PreInits = buildPreInits(C, Captures); 8810 Built.Cond = Cond.get(); 8811 Built.Init = Init.get(); 8812 Built.Inc = Inc.get(); 8813 Built.LB = LB.get(); 8814 Built.UB = UB.get(); 8815 Built.IL = IL.get(); 8816 Built.ST = ST.get(); 8817 Built.EUB = EUB.get(); 8818 Built.NLB = NextLB.get(); 8819 Built.NUB = NextUB.get(); 8820 Built.PrevLB = PrevLB.get(); 8821 Built.PrevUB = PrevUB.get(); 8822 Built.DistInc = DistInc.get(); 8823 Built.PrevEUB = PrevEUB.get(); 8824 Built.DistCombinedFields.LB = CombLB.get(); 8825 Built.DistCombinedFields.UB = CombUB.get(); 8826 Built.DistCombinedFields.EUB = CombEUB.get(); 8827 Built.DistCombinedFields.Init = CombInit.get(); 8828 Built.DistCombinedFields.Cond = CombCond.get(); 8829 Built.DistCombinedFields.NLB = CombNextLB.get(); 8830 Built.DistCombinedFields.NUB = CombNextUB.get(); 8831 Built.DistCombinedFields.DistCond = CombDistCond.get(); 8832 Built.DistCombinedFields.ParForInDistCond = ParForInDistCond.get(); 8833 8834 return NestedLoopCount; 8835 } 8836 8837 static Expr *getCollapseNumberExpr(ArrayRef<OMPClause *> Clauses) { 8838 auto CollapseClauses = 8839 OMPExecutableDirective::getClausesOfKind<OMPCollapseClause>(Clauses); 8840 if (CollapseClauses.begin() != CollapseClauses.end()) 8841 return (*CollapseClauses.begin())->getNumForLoops(); 8842 return nullptr; 8843 } 8844 8845 static Expr *getOrderedNumberExpr(ArrayRef<OMPClause *> Clauses) { 8846 auto OrderedClauses = 8847 OMPExecutableDirective::getClausesOfKind<OMPOrderedClause>(Clauses); 8848 if (OrderedClauses.begin() != OrderedClauses.end()) 8849 return (*OrderedClauses.begin())->getNumForLoops(); 8850 return nullptr; 8851 } 8852 8853 static bool checkSimdlenSafelenSpecified(Sema &S, 8854 const ArrayRef<OMPClause *> Clauses) { 8855 const OMPSafelenClause *Safelen = nullptr; 8856 const OMPSimdlenClause *Simdlen = nullptr; 8857 8858 for (const OMPClause *Clause : Clauses) { 8859 if (Clause->getClauseKind() == OMPC_safelen) 8860 Safelen = cast<OMPSafelenClause>(Clause); 8861 else if (Clause->getClauseKind() == OMPC_simdlen) 8862 Simdlen = cast<OMPSimdlenClause>(Clause); 8863 if (Safelen && Simdlen) 8864 break; 8865 } 8866 8867 if (Simdlen && Safelen) { 8868 const Expr *SimdlenLength = Simdlen->getSimdlen(); 8869 const Expr *SafelenLength = Safelen->getSafelen(); 8870 if (SimdlenLength->isValueDependent() || SimdlenLength->isTypeDependent() || 8871 SimdlenLength->isInstantiationDependent() || 8872 SimdlenLength->containsUnexpandedParameterPack()) 8873 return false; 8874 if (SafelenLength->isValueDependent() || SafelenLength->isTypeDependent() || 8875 SafelenLength->isInstantiationDependent() || 8876 SafelenLength->containsUnexpandedParameterPack()) 8877 return false; 8878 Expr::EvalResult SimdlenResult, SafelenResult; 8879 SimdlenLength->EvaluateAsInt(SimdlenResult, S.Context); 8880 SafelenLength->EvaluateAsInt(SafelenResult, S.Context); 8881 llvm::APSInt SimdlenRes = SimdlenResult.Val.getInt(); 8882 llvm::APSInt SafelenRes = SafelenResult.Val.getInt(); 8883 // OpenMP 4.5 [2.8.1, simd Construct, Restrictions] 8884 // If both simdlen and safelen clauses are specified, the value of the 8885 // simdlen parameter must be less than or equal to the value of the safelen 8886 // parameter. 8887 if (SimdlenRes > SafelenRes) { 8888 S.Diag(SimdlenLength->getExprLoc(), 8889 diag::err_omp_wrong_simdlen_safelen_values) 8890 << SimdlenLength->getSourceRange() << SafelenLength->getSourceRange(); 8891 return true; 8892 } 8893 } 8894 return false; 8895 } 8896 8897 StmtResult 8898 Sema::ActOnOpenMPSimdDirective(ArrayRef<OMPClause *> Clauses, Stmt *AStmt, 8899 SourceLocation StartLoc, SourceLocation EndLoc, 8900 VarsWithInheritedDSAType &VarsWithImplicitDSA) { 8901 if (!AStmt) 8902 return StmtError(); 8903 8904 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 8905 OMPLoopDirective::HelperExprs B; 8906 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 8907 // define the nested loops number. 8908 unsigned NestedLoopCount = checkOpenMPLoop( 8909 OMPD_simd, getCollapseNumberExpr(Clauses), getOrderedNumberExpr(Clauses), 8910 AStmt, *this, *DSAStack, VarsWithImplicitDSA, B); 8911 if (NestedLoopCount == 0) 8912 return StmtError(); 8913 8914 assert((CurContext->isDependentContext() || B.builtAll()) && 8915 "omp simd loop exprs were not built"); 8916 8917 if (!CurContext->isDependentContext()) { 8918 // Finalize the clauses that need pre-built expressions for CodeGen. 8919 for (OMPClause *C : Clauses) { 8920 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 8921 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 8922 B.NumIterations, *this, CurScope, 8923 DSAStack)) 8924 return StmtError(); 8925 } 8926 } 8927 8928 if (checkSimdlenSafelenSpecified(*this, Clauses)) 8929 return StmtError(); 8930 8931 setFunctionHasBranchProtectedScope(); 8932 return OMPSimdDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount, 8933 Clauses, AStmt, B); 8934 } 8935 8936 StmtResult 8937 Sema::ActOnOpenMPForDirective(ArrayRef<OMPClause *> Clauses, Stmt *AStmt, 8938 SourceLocation StartLoc, SourceLocation EndLoc, 8939 VarsWithInheritedDSAType &VarsWithImplicitDSA) { 8940 if (!AStmt) 8941 return StmtError(); 8942 8943 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 8944 OMPLoopDirective::HelperExprs B; 8945 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 8946 // define the nested loops number. 8947 unsigned NestedLoopCount = checkOpenMPLoop( 8948 OMPD_for, getCollapseNumberExpr(Clauses), getOrderedNumberExpr(Clauses), 8949 AStmt, *this, *DSAStack, VarsWithImplicitDSA, B); 8950 if (NestedLoopCount == 0) 8951 return StmtError(); 8952 8953 assert((CurContext->isDependentContext() || B.builtAll()) && 8954 "omp for loop exprs were not built"); 8955 8956 if (!CurContext->isDependentContext()) { 8957 // Finalize the clauses that need pre-built expressions for CodeGen. 8958 for (OMPClause *C : Clauses) { 8959 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 8960 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 8961 B.NumIterations, *this, CurScope, 8962 DSAStack)) 8963 return StmtError(); 8964 } 8965 } 8966 8967 setFunctionHasBranchProtectedScope(); 8968 return OMPForDirective::Create( 8969 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B, 8970 DSAStack->getTaskgroupReductionRef(), DSAStack->isCancelRegion()); 8971 } 8972 8973 StmtResult Sema::ActOnOpenMPForSimdDirective( 8974 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 8975 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 8976 if (!AStmt) 8977 return StmtError(); 8978 8979 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 8980 OMPLoopDirective::HelperExprs B; 8981 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 8982 // define the nested loops number. 8983 unsigned NestedLoopCount = 8984 checkOpenMPLoop(OMPD_for_simd, getCollapseNumberExpr(Clauses), 8985 getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack, 8986 VarsWithImplicitDSA, B); 8987 if (NestedLoopCount == 0) 8988 return StmtError(); 8989 8990 assert((CurContext->isDependentContext() || B.builtAll()) && 8991 "omp for simd loop exprs were not built"); 8992 8993 if (!CurContext->isDependentContext()) { 8994 // Finalize the clauses that need pre-built expressions for CodeGen. 8995 for (OMPClause *C : Clauses) { 8996 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 8997 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 8998 B.NumIterations, *this, CurScope, 8999 DSAStack)) 9000 return StmtError(); 9001 } 9002 } 9003 9004 if (checkSimdlenSafelenSpecified(*this, Clauses)) 9005 return StmtError(); 9006 9007 setFunctionHasBranchProtectedScope(); 9008 return OMPForSimdDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount, 9009 Clauses, AStmt, B); 9010 } 9011 9012 StmtResult Sema::ActOnOpenMPSectionsDirective(ArrayRef<OMPClause *> Clauses, 9013 Stmt *AStmt, 9014 SourceLocation StartLoc, 9015 SourceLocation EndLoc) { 9016 if (!AStmt) 9017 return StmtError(); 9018 9019 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 9020 auto BaseStmt = AStmt; 9021 while (auto *CS = dyn_cast_or_null<CapturedStmt>(BaseStmt)) 9022 BaseStmt = CS->getCapturedStmt(); 9023 if (auto *C = dyn_cast_or_null<CompoundStmt>(BaseStmt)) { 9024 auto S = C->children(); 9025 if (S.begin() == S.end()) 9026 return StmtError(); 9027 // All associated statements must be '#pragma omp section' except for 9028 // the first one. 9029 for (Stmt *SectionStmt : llvm::make_range(std::next(S.begin()), S.end())) { 9030 if (!SectionStmt || !isa<OMPSectionDirective>(SectionStmt)) { 9031 if (SectionStmt) 9032 Diag(SectionStmt->getBeginLoc(), 9033 diag::err_omp_sections_substmt_not_section); 9034 return StmtError(); 9035 } 9036 cast<OMPSectionDirective>(SectionStmt) 9037 ->setHasCancel(DSAStack->isCancelRegion()); 9038 } 9039 } else { 9040 Diag(AStmt->getBeginLoc(), diag::err_omp_sections_not_compound_stmt); 9041 return StmtError(); 9042 } 9043 9044 setFunctionHasBranchProtectedScope(); 9045 9046 return OMPSectionsDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt, 9047 DSAStack->getTaskgroupReductionRef(), 9048 DSAStack->isCancelRegion()); 9049 } 9050 9051 StmtResult Sema::ActOnOpenMPSectionDirective(Stmt *AStmt, 9052 SourceLocation StartLoc, 9053 SourceLocation EndLoc) { 9054 if (!AStmt) 9055 return StmtError(); 9056 9057 setFunctionHasBranchProtectedScope(); 9058 DSAStack->setParentCancelRegion(DSAStack->isCancelRegion()); 9059 9060 return OMPSectionDirective::Create(Context, StartLoc, EndLoc, AStmt, 9061 DSAStack->isCancelRegion()); 9062 } 9063 9064 StmtResult Sema::ActOnOpenMPSingleDirective(ArrayRef<OMPClause *> Clauses, 9065 Stmt *AStmt, 9066 SourceLocation StartLoc, 9067 SourceLocation EndLoc) { 9068 if (!AStmt) 9069 return StmtError(); 9070 9071 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 9072 9073 setFunctionHasBranchProtectedScope(); 9074 9075 // OpenMP [2.7.3, single Construct, Restrictions] 9076 // The copyprivate clause must not be used with the nowait clause. 9077 const OMPClause *Nowait = nullptr; 9078 const OMPClause *Copyprivate = nullptr; 9079 for (const OMPClause *Clause : Clauses) { 9080 if (Clause->getClauseKind() == OMPC_nowait) 9081 Nowait = Clause; 9082 else if (Clause->getClauseKind() == OMPC_copyprivate) 9083 Copyprivate = Clause; 9084 if (Copyprivate && Nowait) { 9085 Diag(Copyprivate->getBeginLoc(), 9086 diag::err_omp_single_copyprivate_with_nowait); 9087 Diag(Nowait->getBeginLoc(), diag::note_omp_nowait_clause_here); 9088 return StmtError(); 9089 } 9090 } 9091 9092 return OMPSingleDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt); 9093 } 9094 9095 StmtResult Sema::ActOnOpenMPMasterDirective(Stmt *AStmt, 9096 SourceLocation StartLoc, 9097 SourceLocation EndLoc) { 9098 if (!AStmt) 9099 return StmtError(); 9100 9101 setFunctionHasBranchProtectedScope(); 9102 9103 return OMPMasterDirective::Create(Context, StartLoc, EndLoc, AStmt); 9104 } 9105 9106 StmtResult Sema::ActOnOpenMPCriticalDirective( 9107 const DeclarationNameInfo &DirName, ArrayRef<OMPClause *> Clauses, 9108 Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc) { 9109 if (!AStmt) 9110 return StmtError(); 9111 9112 bool ErrorFound = false; 9113 llvm::APSInt Hint; 9114 SourceLocation HintLoc; 9115 bool DependentHint = false; 9116 for (const OMPClause *C : Clauses) { 9117 if (C->getClauseKind() == OMPC_hint) { 9118 if (!DirName.getName()) { 9119 Diag(C->getBeginLoc(), diag::err_omp_hint_clause_no_name); 9120 ErrorFound = true; 9121 } 9122 Expr *E = cast<OMPHintClause>(C)->getHint(); 9123 if (E->isTypeDependent() || E->isValueDependent() || 9124 E->isInstantiationDependent()) { 9125 DependentHint = true; 9126 } else { 9127 Hint = E->EvaluateKnownConstInt(Context); 9128 HintLoc = C->getBeginLoc(); 9129 } 9130 } 9131 } 9132 if (ErrorFound) 9133 return StmtError(); 9134 const auto Pair = DSAStack->getCriticalWithHint(DirName); 9135 if (Pair.first && DirName.getName() && !DependentHint) { 9136 if (llvm::APSInt::compareValues(Hint, Pair.second) != 0) { 9137 Diag(StartLoc, diag::err_omp_critical_with_hint); 9138 if (HintLoc.isValid()) 9139 Diag(HintLoc, diag::note_omp_critical_hint_here) 9140 << 0 << Hint.toString(/*Radix=*/10, /*Signed=*/false); 9141 else 9142 Diag(StartLoc, diag::note_omp_critical_no_hint) << 0; 9143 if (const auto *C = Pair.first->getSingleClause<OMPHintClause>()) { 9144 Diag(C->getBeginLoc(), diag::note_omp_critical_hint_here) 9145 << 1 9146 << C->getHint()->EvaluateKnownConstInt(Context).toString( 9147 /*Radix=*/10, /*Signed=*/false); 9148 } else { 9149 Diag(Pair.first->getBeginLoc(), diag::note_omp_critical_no_hint) << 1; 9150 } 9151 } 9152 } 9153 9154 setFunctionHasBranchProtectedScope(); 9155 9156 auto *Dir = OMPCriticalDirective::Create(Context, DirName, StartLoc, EndLoc, 9157 Clauses, AStmt); 9158 if (!Pair.first && DirName.getName() && !DependentHint) 9159 DSAStack->addCriticalWithHint(Dir, Hint); 9160 return Dir; 9161 } 9162 9163 StmtResult Sema::ActOnOpenMPParallelForDirective( 9164 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 9165 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 9166 if (!AStmt) 9167 return StmtError(); 9168 9169 auto *CS = cast<CapturedStmt>(AStmt); 9170 // 1.2.2 OpenMP Language Terminology 9171 // Structured block - An executable statement with a single entry at the 9172 // top and a single exit at the bottom. 9173 // The point of exit cannot be a branch out of the structured block. 9174 // longjmp() and throw() must not violate the entry/exit criteria. 9175 CS->getCapturedDecl()->setNothrow(); 9176 9177 OMPLoopDirective::HelperExprs B; 9178 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 9179 // define the nested loops number. 9180 unsigned NestedLoopCount = 9181 checkOpenMPLoop(OMPD_parallel_for, getCollapseNumberExpr(Clauses), 9182 getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack, 9183 VarsWithImplicitDSA, B); 9184 if (NestedLoopCount == 0) 9185 return StmtError(); 9186 9187 assert((CurContext->isDependentContext() || B.builtAll()) && 9188 "omp parallel for loop exprs were not built"); 9189 9190 if (!CurContext->isDependentContext()) { 9191 // Finalize the clauses that need pre-built expressions for CodeGen. 9192 for (OMPClause *C : Clauses) { 9193 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 9194 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 9195 B.NumIterations, *this, CurScope, 9196 DSAStack)) 9197 return StmtError(); 9198 } 9199 } 9200 9201 setFunctionHasBranchProtectedScope(); 9202 return OMPParallelForDirective::Create( 9203 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B, 9204 DSAStack->getTaskgroupReductionRef(), DSAStack->isCancelRegion()); 9205 } 9206 9207 StmtResult Sema::ActOnOpenMPParallelForSimdDirective( 9208 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 9209 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 9210 if (!AStmt) 9211 return StmtError(); 9212 9213 auto *CS = cast<CapturedStmt>(AStmt); 9214 // 1.2.2 OpenMP Language Terminology 9215 // Structured block - An executable statement with a single entry at the 9216 // top and a single exit at the bottom. 9217 // The point of exit cannot be a branch out of the structured block. 9218 // longjmp() and throw() must not violate the entry/exit criteria. 9219 CS->getCapturedDecl()->setNothrow(); 9220 9221 OMPLoopDirective::HelperExprs B; 9222 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 9223 // define the nested loops number. 9224 unsigned NestedLoopCount = 9225 checkOpenMPLoop(OMPD_parallel_for_simd, getCollapseNumberExpr(Clauses), 9226 getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack, 9227 VarsWithImplicitDSA, B); 9228 if (NestedLoopCount == 0) 9229 return StmtError(); 9230 9231 if (!CurContext->isDependentContext()) { 9232 // Finalize the clauses that need pre-built expressions for CodeGen. 9233 for (OMPClause *C : Clauses) { 9234 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 9235 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 9236 B.NumIterations, *this, CurScope, 9237 DSAStack)) 9238 return StmtError(); 9239 } 9240 } 9241 9242 if (checkSimdlenSafelenSpecified(*this, Clauses)) 9243 return StmtError(); 9244 9245 setFunctionHasBranchProtectedScope(); 9246 return OMPParallelForSimdDirective::Create( 9247 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 9248 } 9249 9250 StmtResult 9251 Sema::ActOnOpenMPParallelMasterDirective(ArrayRef<OMPClause *> Clauses, 9252 Stmt *AStmt, SourceLocation StartLoc, 9253 SourceLocation EndLoc) { 9254 if (!AStmt) 9255 return StmtError(); 9256 9257 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 9258 auto *CS = cast<CapturedStmt>(AStmt); 9259 // 1.2.2 OpenMP Language Terminology 9260 // Structured block - An executable statement with a single entry at the 9261 // top and a single exit at the bottom. 9262 // The point of exit cannot be a branch out of the structured block. 9263 // longjmp() and throw() must not violate the entry/exit criteria. 9264 CS->getCapturedDecl()->setNothrow(); 9265 9266 setFunctionHasBranchProtectedScope(); 9267 9268 return OMPParallelMasterDirective::Create( 9269 Context, StartLoc, EndLoc, Clauses, AStmt, 9270 DSAStack->getTaskgroupReductionRef()); 9271 } 9272 9273 StmtResult 9274 Sema::ActOnOpenMPParallelSectionsDirective(ArrayRef<OMPClause *> Clauses, 9275 Stmt *AStmt, SourceLocation StartLoc, 9276 SourceLocation EndLoc) { 9277 if (!AStmt) 9278 return StmtError(); 9279 9280 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 9281 auto BaseStmt = AStmt; 9282 while (auto *CS = dyn_cast_or_null<CapturedStmt>(BaseStmt)) 9283 BaseStmt = CS->getCapturedStmt(); 9284 if (auto *C = dyn_cast_or_null<CompoundStmt>(BaseStmt)) { 9285 auto S = C->children(); 9286 if (S.begin() == S.end()) 9287 return StmtError(); 9288 // All associated statements must be '#pragma omp section' except for 9289 // the first one. 9290 for (Stmt *SectionStmt : llvm::make_range(std::next(S.begin()), S.end())) { 9291 if (!SectionStmt || !isa<OMPSectionDirective>(SectionStmt)) { 9292 if (SectionStmt) 9293 Diag(SectionStmt->getBeginLoc(), 9294 diag::err_omp_parallel_sections_substmt_not_section); 9295 return StmtError(); 9296 } 9297 cast<OMPSectionDirective>(SectionStmt) 9298 ->setHasCancel(DSAStack->isCancelRegion()); 9299 } 9300 } else { 9301 Diag(AStmt->getBeginLoc(), 9302 diag::err_omp_parallel_sections_not_compound_stmt); 9303 return StmtError(); 9304 } 9305 9306 setFunctionHasBranchProtectedScope(); 9307 9308 return OMPParallelSectionsDirective::Create( 9309 Context, StartLoc, EndLoc, Clauses, AStmt, 9310 DSAStack->getTaskgroupReductionRef(), DSAStack->isCancelRegion()); 9311 } 9312 9313 /// detach and mergeable clauses are mutially exclusive, check for it. 9314 static bool checkDetachMergeableClauses(Sema &S, 9315 ArrayRef<OMPClause *> Clauses) { 9316 const OMPClause *PrevClause = nullptr; 9317 bool ErrorFound = false; 9318 for (const OMPClause *C : Clauses) { 9319 if (C->getClauseKind() == OMPC_detach || 9320 C->getClauseKind() == OMPC_mergeable) { 9321 if (!PrevClause) { 9322 PrevClause = C; 9323 } else if (PrevClause->getClauseKind() != C->getClauseKind()) { 9324 S.Diag(C->getBeginLoc(), diag::err_omp_clauses_mutually_exclusive) 9325 << getOpenMPClauseName(C->getClauseKind()) 9326 << getOpenMPClauseName(PrevClause->getClauseKind()); 9327 S.Diag(PrevClause->getBeginLoc(), diag::note_omp_previous_clause) 9328 << getOpenMPClauseName(PrevClause->getClauseKind()); 9329 ErrorFound = true; 9330 } 9331 } 9332 } 9333 return ErrorFound; 9334 } 9335 9336 StmtResult Sema::ActOnOpenMPTaskDirective(ArrayRef<OMPClause *> Clauses, 9337 Stmt *AStmt, SourceLocation StartLoc, 9338 SourceLocation EndLoc) { 9339 if (!AStmt) 9340 return StmtError(); 9341 9342 // OpenMP 5.0, 2.10.1 task Construct 9343 // If a detach clause appears on the directive, then a mergeable clause cannot 9344 // appear on the same directive. 9345 if (checkDetachMergeableClauses(*this, Clauses)) 9346 return StmtError(); 9347 9348 auto *CS = cast<CapturedStmt>(AStmt); 9349 // 1.2.2 OpenMP Language Terminology 9350 // Structured block - An executable statement with a single entry at the 9351 // top and a single exit at the bottom. 9352 // The point of exit cannot be a branch out of the structured block. 9353 // longjmp() and throw() must not violate the entry/exit criteria. 9354 CS->getCapturedDecl()->setNothrow(); 9355 9356 setFunctionHasBranchProtectedScope(); 9357 9358 return OMPTaskDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt, 9359 DSAStack->isCancelRegion()); 9360 } 9361 9362 StmtResult Sema::ActOnOpenMPTaskyieldDirective(SourceLocation StartLoc, 9363 SourceLocation EndLoc) { 9364 return OMPTaskyieldDirective::Create(Context, StartLoc, EndLoc); 9365 } 9366 9367 StmtResult Sema::ActOnOpenMPBarrierDirective(SourceLocation StartLoc, 9368 SourceLocation EndLoc) { 9369 return OMPBarrierDirective::Create(Context, StartLoc, EndLoc); 9370 } 9371 9372 StmtResult Sema::ActOnOpenMPTaskwaitDirective(SourceLocation StartLoc, 9373 SourceLocation EndLoc) { 9374 return OMPTaskwaitDirective::Create(Context, StartLoc, EndLoc); 9375 } 9376 9377 StmtResult Sema::ActOnOpenMPTaskgroupDirective(ArrayRef<OMPClause *> Clauses, 9378 Stmt *AStmt, 9379 SourceLocation StartLoc, 9380 SourceLocation EndLoc) { 9381 if (!AStmt) 9382 return StmtError(); 9383 9384 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 9385 9386 setFunctionHasBranchProtectedScope(); 9387 9388 return OMPTaskgroupDirective::Create(Context, StartLoc, EndLoc, Clauses, 9389 AStmt, 9390 DSAStack->getTaskgroupReductionRef()); 9391 } 9392 9393 StmtResult Sema::ActOnOpenMPFlushDirective(ArrayRef<OMPClause *> Clauses, 9394 SourceLocation StartLoc, 9395 SourceLocation EndLoc) { 9396 OMPFlushClause *FC = nullptr; 9397 OMPClause *OrderClause = nullptr; 9398 for (OMPClause *C : Clauses) { 9399 if (C->getClauseKind() == OMPC_flush) 9400 FC = cast<OMPFlushClause>(C); 9401 else 9402 OrderClause = C; 9403 } 9404 OpenMPClauseKind MemOrderKind = OMPC_unknown; 9405 SourceLocation MemOrderLoc; 9406 for (const OMPClause *C : Clauses) { 9407 if (C->getClauseKind() == OMPC_acq_rel || 9408 C->getClauseKind() == OMPC_acquire || 9409 C->getClauseKind() == OMPC_release) { 9410 if (MemOrderKind != OMPC_unknown) { 9411 Diag(C->getBeginLoc(), diag::err_omp_several_mem_order_clauses) 9412 << getOpenMPDirectiveName(OMPD_flush) << 1 9413 << SourceRange(C->getBeginLoc(), C->getEndLoc()); 9414 Diag(MemOrderLoc, diag::note_omp_previous_mem_order_clause) 9415 << getOpenMPClauseName(MemOrderKind); 9416 } else { 9417 MemOrderKind = C->getClauseKind(); 9418 MemOrderLoc = C->getBeginLoc(); 9419 } 9420 } 9421 } 9422 if (FC && OrderClause) { 9423 Diag(FC->getLParenLoc(), diag::err_omp_flush_order_clause_and_list) 9424 << getOpenMPClauseName(OrderClause->getClauseKind()); 9425 Diag(OrderClause->getBeginLoc(), diag::note_omp_flush_order_clause_here) 9426 << getOpenMPClauseName(OrderClause->getClauseKind()); 9427 return StmtError(); 9428 } 9429 return OMPFlushDirective::Create(Context, StartLoc, EndLoc, Clauses); 9430 } 9431 9432 StmtResult Sema::ActOnOpenMPDepobjDirective(ArrayRef<OMPClause *> Clauses, 9433 SourceLocation StartLoc, 9434 SourceLocation EndLoc) { 9435 if (Clauses.empty()) { 9436 Diag(StartLoc, diag::err_omp_depobj_expected); 9437 return StmtError(); 9438 } else if (Clauses[0]->getClauseKind() != OMPC_depobj) { 9439 Diag(Clauses[0]->getBeginLoc(), diag::err_omp_depobj_expected); 9440 return StmtError(); 9441 } 9442 // Only depobj expression and another single clause is allowed. 9443 if (Clauses.size() > 2) { 9444 Diag(Clauses[2]->getBeginLoc(), 9445 diag::err_omp_depobj_single_clause_expected); 9446 return StmtError(); 9447 } else if (Clauses.size() < 1) { 9448 Diag(Clauses[0]->getEndLoc(), diag::err_omp_depobj_single_clause_expected); 9449 return StmtError(); 9450 } 9451 return OMPDepobjDirective::Create(Context, StartLoc, EndLoc, Clauses); 9452 } 9453 9454 StmtResult Sema::ActOnOpenMPScanDirective(ArrayRef<OMPClause *> Clauses, 9455 SourceLocation StartLoc, 9456 SourceLocation EndLoc) { 9457 // Check that exactly one clause is specified. 9458 if (Clauses.size() != 1) { 9459 Diag(Clauses.empty() ? EndLoc : Clauses[1]->getBeginLoc(), 9460 diag::err_omp_scan_single_clause_expected); 9461 return StmtError(); 9462 } 9463 // Check that scan directive is used in the scopeof the OpenMP loop body. 9464 if (Scope *S = DSAStack->getCurScope()) { 9465 Scope *ParentS = S->getParent(); 9466 if (!ParentS || ParentS->getParent() != ParentS->getBreakParent() || 9467 !ParentS->getBreakParent()->isOpenMPLoopScope()) 9468 return StmtError(Diag(StartLoc, diag::err_omp_orphaned_device_directive) 9469 << getOpenMPDirectiveName(OMPD_scan) << 5); 9470 } 9471 // Check that only one instance of scan directives is used in the same outer 9472 // region. 9473 if (DSAStack->doesParentHasScanDirective()) { 9474 Diag(StartLoc, diag::err_omp_several_directives_in_region) << "scan"; 9475 Diag(DSAStack->getParentScanDirectiveLoc(), 9476 diag::note_omp_previous_directive) 9477 << "scan"; 9478 return StmtError(); 9479 } 9480 DSAStack->setParentHasScanDirective(StartLoc); 9481 return OMPScanDirective::Create(Context, StartLoc, EndLoc, Clauses); 9482 } 9483 9484 StmtResult Sema::ActOnOpenMPOrderedDirective(ArrayRef<OMPClause *> Clauses, 9485 Stmt *AStmt, 9486 SourceLocation StartLoc, 9487 SourceLocation EndLoc) { 9488 const OMPClause *DependFound = nullptr; 9489 const OMPClause *DependSourceClause = nullptr; 9490 const OMPClause *DependSinkClause = nullptr; 9491 bool ErrorFound = false; 9492 const OMPThreadsClause *TC = nullptr; 9493 const OMPSIMDClause *SC = nullptr; 9494 for (const OMPClause *C : Clauses) { 9495 if (auto *DC = dyn_cast<OMPDependClause>(C)) { 9496 DependFound = C; 9497 if (DC->getDependencyKind() == OMPC_DEPEND_source) { 9498 if (DependSourceClause) { 9499 Diag(C->getBeginLoc(), diag::err_omp_more_one_clause) 9500 << getOpenMPDirectiveName(OMPD_ordered) 9501 << getOpenMPClauseName(OMPC_depend) << 2; 9502 ErrorFound = true; 9503 } else { 9504 DependSourceClause = C; 9505 } 9506 if (DependSinkClause) { 9507 Diag(C->getBeginLoc(), diag::err_omp_depend_sink_source_not_allowed) 9508 << 0; 9509 ErrorFound = true; 9510 } 9511 } else if (DC->getDependencyKind() == OMPC_DEPEND_sink) { 9512 if (DependSourceClause) { 9513 Diag(C->getBeginLoc(), diag::err_omp_depend_sink_source_not_allowed) 9514 << 1; 9515 ErrorFound = true; 9516 } 9517 DependSinkClause = C; 9518 } 9519 } else if (C->getClauseKind() == OMPC_threads) { 9520 TC = cast<OMPThreadsClause>(C); 9521 } else if (C->getClauseKind() == OMPC_simd) { 9522 SC = cast<OMPSIMDClause>(C); 9523 } 9524 } 9525 if (!ErrorFound && !SC && 9526 isOpenMPSimdDirective(DSAStack->getParentDirective())) { 9527 // OpenMP [2.8.1,simd Construct, Restrictions] 9528 // An ordered construct with the simd clause is the only OpenMP construct 9529 // that can appear in the simd region. 9530 Diag(StartLoc, diag::err_omp_prohibited_region_simd) 9531 << (LangOpts.OpenMP >= 50 ? 1 : 0); 9532 ErrorFound = true; 9533 } else if (DependFound && (TC || SC)) { 9534 Diag(DependFound->getBeginLoc(), diag::err_omp_depend_clause_thread_simd) 9535 << getOpenMPClauseName(TC ? TC->getClauseKind() : SC->getClauseKind()); 9536 ErrorFound = true; 9537 } else if (DependFound && !DSAStack->getParentOrderedRegionParam().first) { 9538 Diag(DependFound->getBeginLoc(), 9539 diag::err_omp_ordered_directive_without_param); 9540 ErrorFound = true; 9541 } else if (TC || Clauses.empty()) { 9542 if (const Expr *Param = DSAStack->getParentOrderedRegionParam().first) { 9543 SourceLocation ErrLoc = TC ? TC->getBeginLoc() : StartLoc; 9544 Diag(ErrLoc, diag::err_omp_ordered_directive_with_param) 9545 << (TC != nullptr); 9546 Diag(Param->getBeginLoc(), diag::note_omp_ordered_param) << 1; 9547 ErrorFound = true; 9548 } 9549 } 9550 if ((!AStmt && !DependFound) || ErrorFound) 9551 return StmtError(); 9552 9553 // OpenMP 5.0, 2.17.9, ordered Construct, Restrictions. 9554 // During execution of an iteration of a worksharing-loop or a loop nest 9555 // within a worksharing-loop, simd, or worksharing-loop SIMD region, a thread 9556 // must not execute more than one ordered region corresponding to an ordered 9557 // construct without a depend clause. 9558 if (!DependFound) { 9559 if (DSAStack->doesParentHasOrderedDirective()) { 9560 Diag(StartLoc, diag::err_omp_several_directives_in_region) << "ordered"; 9561 Diag(DSAStack->getParentOrderedDirectiveLoc(), 9562 diag::note_omp_previous_directive) 9563 << "ordered"; 9564 return StmtError(); 9565 } 9566 DSAStack->setParentHasOrderedDirective(StartLoc); 9567 } 9568 9569 if (AStmt) { 9570 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 9571 9572 setFunctionHasBranchProtectedScope(); 9573 } 9574 9575 return OMPOrderedDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt); 9576 } 9577 9578 namespace { 9579 /// Helper class for checking expression in 'omp atomic [update]' 9580 /// construct. 9581 class OpenMPAtomicUpdateChecker { 9582 /// Error results for atomic update expressions. 9583 enum ExprAnalysisErrorCode { 9584 /// A statement is not an expression statement. 9585 NotAnExpression, 9586 /// Expression is not builtin binary or unary operation. 9587 NotABinaryOrUnaryExpression, 9588 /// Unary operation is not post-/pre- increment/decrement operation. 9589 NotAnUnaryIncDecExpression, 9590 /// An expression is not of scalar type. 9591 NotAScalarType, 9592 /// A binary operation is not an assignment operation. 9593 NotAnAssignmentOp, 9594 /// RHS part of the binary operation is not a binary expression. 9595 NotABinaryExpression, 9596 /// RHS part is not additive/multiplicative/shift/biwise binary 9597 /// expression. 9598 NotABinaryOperator, 9599 /// RHS binary operation does not have reference to the updated LHS 9600 /// part. 9601 NotAnUpdateExpression, 9602 /// No errors is found. 9603 NoError 9604 }; 9605 /// Reference to Sema. 9606 Sema &SemaRef; 9607 /// A location for note diagnostics (when error is found). 9608 SourceLocation NoteLoc; 9609 /// 'x' lvalue part of the source atomic expression. 9610 Expr *X; 9611 /// 'expr' rvalue part of the source atomic expression. 9612 Expr *E; 9613 /// Helper expression of the form 9614 /// 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or 9615 /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'. 9616 Expr *UpdateExpr; 9617 /// Is 'x' a LHS in a RHS part of full update expression. It is 9618 /// important for non-associative operations. 9619 bool IsXLHSInRHSPart; 9620 BinaryOperatorKind Op; 9621 SourceLocation OpLoc; 9622 /// true if the source expression is a postfix unary operation, false 9623 /// if it is a prefix unary operation. 9624 bool IsPostfixUpdate; 9625 9626 public: 9627 OpenMPAtomicUpdateChecker(Sema &SemaRef) 9628 : SemaRef(SemaRef), X(nullptr), E(nullptr), UpdateExpr(nullptr), 9629 IsXLHSInRHSPart(false), Op(BO_PtrMemD), IsPostfixUpdate(false) {} 9630 /// Check specified statement that it is suitable for 'atomic update' 9631 /// constructs and extract 'x', 'expr' and Operation from the original 9632 /// expression. If DiagId and NoteId == 0, then only check is performed 9633 /// without error notification. 9634 /// \param DiagId Diagnostic which should be emitted if error is found. 9635 /// \param NoteId Diagnostic note for the main error message. 9636 /// \return true if statement is not an update expression, false otherwise. 9637 bool checkStatement(Stmt *S, unsigned DiagId = 0, unsigned NoteId = 0); 9638 /// Return the 'x' lvalue part of the source atomic expression. 9639 Expr *getX() const { return X; } 9640 /// Return the 'expr' rvalue part of the source atomic expression. 9641 Expr *getExpr() const { return E; } 9642 /// Return the update expression used in calculation of the updated 9643 /// value. Always has form 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or 9644 /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'. 9645 Expr *getUpdateExpr() const { return UpdateExpr; } 9646 /// Return true if 'x' is LHS in RHS part of full update expression, 9647 /// false otherwise. 9648 bool isXLHSInRHSPart() const { return IsXLHSInRHSPart; } 9649 9650 /// true if the source expression is a postfix unary operation, false 9651 /// if it is a prefix unary operation. 9652 bool isPostfixUpdate() const { return IsPostfixUpdate; } 9653 9654 private: 9655 bool checkBinaryOperation(BinaryOperator *AtomicBinOp, unsigned DiagId = 0, 9656 unsigned NoteId = 0); 9657 }; 9658 } // namespace 9659 9660 bool OpenMPAtomicUpdateChecker::checkBinaryOperation( 9661 BinaryOperator *AtomicBinOp, unsigned DiagId, unsigned NoteId) { 9662 ExprAnalysisErrorCode ErrorFound = NoError; 9663 SourceLocation ErrorLoc, NoteLoc; 9664 SourceRange ErrorRange, NoteRange; 9665 // Allowed constructs are: 9666 // x = x binop expr; 9667 // x = expr binop x; 9668 if (AtomicBinOp->getOpcode() == BO_Assign) { 9669 X = AtomicBinOp->getLHS(); 9670 if (const auto *AtomicInnerBinOp = dyn_cast<BinaryOperator>( 9671 AtomicBinOp->getRHS()->IgnoreParenImpCasts())) { 9672 if (AtomicInnerBinOp->isMultiplicativeOp() || 9673 AtomicInnerBinOp->isAdditiveOp() || AtomicInnerBinOp->isShiftOp() || 9674 AtomicInnerBinOp->isBitwiseOp()) { 9675 Op = AtomicInnerBinOp->getOpcode(); 9676 OpLoc = AtomicInnerBinOp->getOperatorLoc(); 9677 Expr *LHS = AtomicInnerBinOp->getLHS(); 9678 Expr *RHS = AtomicInnerBinOp->getRHS(); 9679 llvm::FoldingSetNodeID XId, LHSId, RHSId; 9680 X->IgnoreParenImpCasts()->Profile(XId, SemaRef.getASTContext(), 9681 /*Canonical=*/true); 9682 LHS->IgnoreParenImpCasts()->Profile(LHSId, SemaRef.getASTContext(), 9683 /*Canonical=*/true); 9684 RHS->IgnoreParenImpCasts()->Profile(RHSId, SemaRef.getASTContext(), 9685 /*Canonical=*/true); 9686 if (XId == LHSId) { 9687 E = RHS; 9688 IsXLHSInRHSPart = true; 9689 } else if (XId == RHSId) { 9690 E = LHS; 9691 IsXLHSInRHSPart = false; 9692 } else { 9693 ErrorLoc = AtomicInnerBinOp->getExprLoc(); 9694 ErrorRange = AtomicInnerBinOp->getSourceRange(); 9695 NoteLoc = X->getExprLoc(); 9696 NoteRange = X->getSourceRange(); 9697 ErrorFound = NotAnUpdateExpression; 9698 } 9699 } else { 9700 ErrorLoc = AtomicInnerBinOp->getExprLoc(); 9701 ErrorRange = AtomicInnerBinOp->getSourceRange(); 9702 NoteLoc = AtomicInnerBinOp->getOperatorLoc(); 9703 NoteRange = SourceRange(NoteLoc, NoteLoc); 9704 ErrorFound = NotABinaryOperator; 9705 } 9706 } else { 9707 NoteLoc = ErrorLoc = AtomicBinOp->getRHS()->getExprLoc(); 9708 NoteRange = ErrorRange = AtomicBinOp->getRHS()->getSourceRange(); 9709 ErrorFound = NotABinaryExpression; 9710 } 9711 } else { 9712 ErrorLoc = AtomicBinOp->getExprLoc(); 9713 ErrorRange = AtomicBinOp->getSourceRange(); 9714 NoteLoc = AtomicBinOp->getOperatorLoc(); 9715 NoteRange = SourceRange(NoteLoc, NoteLoc); 9716 ErrorFound = NotAnAssignmentOp; 9717 } 9718 if (ErrorFound != NoError && DiagId != 0 && NoteId != 0) { 9719 SemaRef.Diag(ErrorLoc, DiagId) << ErrorRange; 9720 SemaRef.Diag(NoteLoc, NoteId) << ErrorFound << NoteRange; 9721 return true; 9722 } 9723 if (SemaRef.CurContext->isDependentContext()) 9724 E = X = UpdateExpr = nullptr; 9725 return ErrorFound != NoError; 9726 } 9727 9728 bool OpenMPAtomicUpdateChecker::checkStatement(Stmt *S, unsigned DiagId, 9729 unsigned NoteId) { 9730 ExprAnalysisErrorCode ErrorFound = NoError; 9731 SourceLocation ErrorLoc, NoteLoc; 9732 SourceRange ErrorRange, NoteRange; 9733 // Allowed constructs are: 9734 // x++; 9735 // x--; 9736 // ++x; 9737 // --x; 9738 // x binop= expr; 9739 // x = x binop expr; 9740 // x = expr binop x; 9741 if (auto *AtomicBody = dyn_cast<Expr>(S)) { 9742 AtomicBody = AtomicBody->IgnoreParenImpCasts(); 9743 if (AtomicBody->getType()->isScalarType() || 9744 AtomicBody->isInstantiationDependent()) { 9745 if (const auto *AtomicCompAssignOp = dyn_cast<CompoundAssignOperator>( 9746 AtomicBody->IgnoreParenImpCasts())) { 9747 // Check for Compound Assignment Operation 9748 Op = BinaryOperator::getOpForCompoundAssignment( 9749 AtomicCompAssignOp->getOpcode()); 9750 OpLoc = AtomicCompAssignOp->getOperatorLoc(); 9751 E = AtomicCompAssignOp->getRHS(); 9752 X = AtomicCompAssignOp->getLHS()->IgnoreParens(); 9753 IsXLHSInRHSPart = true; 9754 } else if (auto *AtomicBinOp = dyn_cast<BinaryOperator>( 9755 AtomicBody->IgnoreParenImpCasts())) { 9756 // Check for Binary Operation 9757 if (checkBinaryOperation(AtomicBinOp, DiagId, NoteId)) 9758 return true; 9759 } else if (const auto *AtomicUnaryOp = dyn_cast<UnaryOperator>( 9760 AtomicBody->IgnoreParenImpCasts())) { 9761 // Check for Unary Operation 9762 if (AtomicUnaryOp->isIncrementDecrementOp()) { 9763 IsPostfixUpdate = AtomicUnaryOp->isPostfix(); 9764 Op = AtomicUnaryOp->isIncrementOp() ? BO_Add : BO_Sub; 9765 OpLoc = AtomicUnaryOp->getOperatorLoc(); 9766 X = AtomicUnaryOp->getSubExpr()->IgnoreParens(); 9767 E = SemaRef.ActOnIntegerConstant(OpLoc, /*uint64_t Val=*/1).get(); 9768 IsXLHSInRHSPart = true; 9769 } else { 9770 ErrorFound = NotAnUnaryIncDecExpression; 9771 ErrorLoc = AtomicUnaryOp->getExprLoc(); 9772 ErrorRange = AtomicUnaryOp->getSourceRange(); 9773 NoteLoc = AtomicUnaryOp->getOperatorLoc(); 9774 NoteRange = SourceRange(NoteLoc, NoteLoc); 9775 } 9776 } else if (!AtomicBody->isInstantiationDependent()) { 9777 ErrorFound = NotABinaryOrUnaryExpression; 9778 NoteLoc = ErrorLoc = AtomicBody->getExprLoc(); 9779 NoteRange = ErrorRange = AtomicBody->getSourceRange(); 9780 } 9781 } else { 9782 ErrorFound = NotAScalarType; 9783 NoteLoc = ErrorLoc = AtomicBody->getBeginLoc(); 9784 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc); 9785 } 9786 } else { 9787 ErrorFound = NotAnExpression; 9788 NoteLoc = ErrorLoc = S->getBeginLoc(); 9789 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc); 9790 } 9791 if (ErrorFound != NoError && DiagId != 0 && NoteId != 0) { 9792 SemaRef.Diag(ErrorLoc, DiagId) << ErrorRange; 9793 SemaRef.Diag(NoteLoc, NoteId) << ErrorFound << NoteRange; 9794 return true; 9795 } 9796 if (SemaRef.CurContext->isDependentContext()) 9797 E = X = UpdateExpr = nullptr; 9798 if (ErrorFound == NoError && E && X) { 9799 // Build an update expression of form 'OpaqueValueExpr(x) binop 9800 // OpaqueValueExpr(expr)' or 'OpaqueValueExpr(expr) binop 9801 // OpaqueValueExpr(x)' and then cast it to the type of the 'x' expression. 9802 auto *OVEX = new (SemaRef.getASTContext()) 9803 OpaqueValueExpr(X->getExprLoc(), X->getType(), VK_RValue); 9804 auto *OVEExpr = new (SemaRef.getASTContext()) 9805 OpaqueValueExpr(E->getExprLoc(), E->getType(), VK_RValue); 9806 ExprResult Update = 9807 SemaRef.CreateBuiltinBinOp(OpLoc, Op, IsXLHSInRHSPart ? OVEX : OVEExpr, 9808 IsXLHSInRHSPart ? OVEExpr : OVEX); 9809 if (Update.isInvalid()) 9810 return true; 9811 Update = SemaRef.PerformImplicitConversion(Update.get(), X->getType(), 9812 Sema::AA_Casting); 9813 if (Update.isInvalid()) 9814 return true; 9815 UpdateExpr = Update.get(); 9816 } 9817 return ErrorFound != NoError; 9818 } 9819 9820 StmtResult Sema::ActOnOpenMPAtomicDirective(ArrayRef<OMPClause *> Clauses, 9821 Stmt *AStmt, 9822 SourceLocation StartLoc, 9823 SourceLocation EndLoc) { 9824 // Register location of the first atomic directive. 9825 DSAStack->addAtomicDirectiveLoc(StartLoc); 9826 if (!AStmt) 9827 return StmtError(); 9828 9829 // 1.2.2 OpenMP Language Terminology 9830 // Structured block - An executable statement with a single entry at the 9831 // top and a single exit at the bottom. 9832 // The point of exit cannot be a branch out of the structured block. 9833 // longjmp() and throw() must not violate the entry/exit criteria. 9834 OpenMPClauseKind AtomicKind = OMPC_unknown; 9835 SourceLocation AtomicKindLoc; 9836 OpenMPClauseKind MemOrderKind = OMPC_unknown; 9837 SourceLocation MemOrderLoc; 9838 for (const OMPClause *C : Clauses) { 9839 if (C->getClauseKind() == OMPC_read || C->getClauseKind() == OMPC_write || 9840 C->getClauseKind() == OMPC_update || 9841 C->getClauseKind() == OMPC_capture) { 9842 if (AtomicKind != OMPC_unknown) { 9843 Diag(C->getBeginLoc(), diag::err_omp_atomic_several_clauses) 9844 << SourceRange(C->getBeginLoc(), C->getEndLoc()); 9845 Diag(AtomicKindLoc, diag::note_omp_previous_mem_order_clause) 9846 << getOpenMPClauseName(AtomicKind); 9847 } else { 9848 AtomicKind = C->getClauseKind(); 9849 AtomicKindLoc = C->getBeginLoc(); 9850 } 9851 } 9852 if (C->getClauseKind() == OMPC_seq_cst || 9853 C->getClauseKind() == OMPC_acq_rel || 9854 C->getClauseKind() == OMPC_acquire || 9855 C->getClauseKind() == OMPC_release || 9856 C->getClauseKind() == OMPC_relaxed) { 9857 if (MemOrderKind != OMPC_unknown) { 9858 Diag(C->getBeginLoc(), diag::err_omp_several_mem_order_clauses) 9859 << getOpenMPDirectiveName(OMPD_atomic) << 0 9860 << SourceRange(C->getBeginLoc(), C->getEndLoc()); 9861 Diag(MemOrderLoc, diag::note_omp_previous_mem_order_clause) 9862 << getOpenMPClauseName(MemOrderKind); 9863 } else { 9864 MemOrderKind = C->getClauseKind(); 9865 MemOrderLoc = C->getBeginLoc(); 9866 } 9867 } 9868 } 9869 // OpenMP 5.0, 2.17.7 atomic Construct, Restrictions 9870 // If atomic-clause is read then memory-order-clause must not be acq_rel or 9871 // release. 9872 // If atomic-clause is write then memory-order-clause must not be acq_rel or 9873 // acquire. 9874 // If atomic-clause is update or not present then memory-order-clause must not 9875 // be acq_rel or acquire. 9876 if ((AtomicKind == OMPC_read && 9877 (MemOrderKind == OMPC_acq_rel || MemOrderKind == OMPC_release)) || 9878 ((AtomicKind == OMPC_write || AtomicKind == OMPC_update || 9879 AtomicKind == OMPC_unknown) && 9880 (MemOrderKind == OMPC_acq_rel || MemOrderKind == OMPC_acquire))) { 9881 SourceLocation Loc = AtomicKindLoc; 9882 if (AtomicKind == OMPC_unknown) 9883 Loc = StartLoc; 9884 Diag(Loc, diag::err_omp_atomic_incompatible_mem_order_clause) 9885 << getOpenMPClauseName(AtomicKind) 9886 << (AtomicKind == OMPC_unknown ? 1 : 0) 9887 << getOpenMPClauseName(MemOrderKind); 9888 Diag(MemOrderLoc, diag::note_omp_previous_mem_order_clause) 9889 << getOpenMPClauseName(MemOrderKind); 9890 } 9891 9892 Stmt *Body = AStmt; 9893 if (auto *EWC = dyn_cast<ExprWithCleanups>(Body)) 9894 Body = EWC->getSubExpr(); 9895 9896 Expr *X = nullptr; 9897 Expr *V = nullptr; 9898 Expr *E = nullptr; 9899 Expr *UE = nullptr; 9900 bool IsXLHSInRHSPart = false; 9901 bool IsPostfixUpdate = false; 9902 // OpenMP [2.12.6, atomic Construct] 9903 // In the next expressions: 9904 // * x and v (as applicable) are both l-value expressions with scalar type. 9905 // * During the execution of an atomic region, multiple syntactic 9906 // occurrences of x must designate the same storage location. 9907 // * Neither of v and expr (as applicable) may access the storage location 9908 // designated by x. 9909 // * Neither of x and expr (as applicable) may access the storage location 9910 // designated by v. 9911 // * expr is an expression with scalar type. 9912 // * binop is one of +, *, -, /, &, ^, |, <<, or >>. 9913 // * binop, binop=, ++, and -- are not overloaded operators. 9914 // * The expression x binop expr must be numerically equivalent to x binop 9915 // (expr). This requirement is satisfied if the operators in expr have 9916 // precedence greater than binop, or by using parentheses around expr or 9917 // subexpressions of expr. 9918 // * The expression expr binop x must be numerically equivalent to (expr) 9919 // binop x. This requirement is satisfied if the operators in expr have 9920 // precedence equal to or greater than binop, or by using parentheses around 9921 // expr or subexpressions of expr. 9922 // * For forms that allow multiple occurrences of x, the number of times 9923 // that x is evaluated is unspecified. 9924 if (AtomicKind == OMPC_read) { 9925 enum { 9926 NotAnExpression, 9927 NotAnAssignmentOp, 9928 NotAScalarType, 9929 NotAnLValue, 9930 NoError 9931 } ErrorFound = NoError; 9932 SourceLocation ErrorLoc, NoteLoc; 9933 SourceRange ErrorRange, NoteRange; 9934 // If clause is read: 9935 // v = x; 9936 if (const auto *AtomicBody = dyn_cast<Expr>(Body)) { 9937 const auto *AtomicBinOp = 9938 dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts()); 9939 if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) { 9940 X = AtomicBinOp->getRHS()->IgnoreParenImpCasts(); 9941 V = AtomicBinOp->getLHS()->IgnoreParenImpCasts(); 9942 if ((X->isInstantiationDependent() || X->getType()->isScalarType()) && 9943 (V->isInstantiationDependent() || V->getType()->isScalarType())) { 9944 if (!X->isLValue() || !V->isLValue()) { 9945 const Expr *NotLValueExpr = X->isLValue() ? V : X; 9946 ErrorFound = NotAnLValue; 9947 ErrorLoc = AtomicBinOp->getExprLoc(); 9948 ErrorRange = AtomicBinOp->getSourceRange(); 9949 NoteLoc = NotLValueExpr->getExprLoc(); 9950 NoteRange = NotLValueExpr->getSourceRange(); 9951 } 9952 } else if (!X->isInstantiationDependent() || 9953 !V->isInstantiationDependent()) { 9954 const Expr *NotScalarExpr = 9955 (X->isInstantiationDependent() || X->getType()->isScalarType()) 9956 ? V 9957 : X; 9958 ErrorFound = NotAScalarType; 9959 ErrorLoc = AtomicBinOp->getExprLoc(); 9960 ErrorRange = AtomicBinOp->getSourceRange(); 9961 NoteLoc = NotScalarExpr->getExprLoc(); 9962 NoteRange = NotScalarExpr->getSourceRange(); 9963 } 9964 } else if (!AtomicBody->isInstantiationDependent()) { 9965 ErrorFound = NotAnAssignmentOp; 9966 ErrorLoc = AtomicBody->getExprLoc(); 9967 ErrorRange = AtomicBody->getSourceRange(); 9968 NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc() 9969 : AtomicBody->getExprLoc(); 9970 NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange() 9971 : AtomicBody->getSourceRange(); 9972 } 9973 } else { 9974 ErrorFound = NotAnExpression; 9975 NoteLoc = ErrorLoc = Body->getBeginLoc(); 9976 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc); 9977 } 9978 if (ErrorFound != NoError) { 9979 Diag(ErrorLoc, diag::err_omp_atomic_read_not_expression_statement) 9980 << ErrorRange; 9981 Diag(NoteLoc, diag::note_omp_atomic_read_write) << ErrorFound 9982 << NoteRange; 9983 return StmtError(); 9984 } 9985 if (CurContext->isDependentContext()) 9986 V = X = nullptr; 9987 } else if (AtomicKind == OMPC_write) { 9988 enum { 9989 NotAnExpression, 9990 NotAnAssignmentOp, 9991 NotAScalarType, 9992 NotAnLValue, 9993 NoError 9994 } ErrorFound = NoError; 9995 SourceLocation ErrorLoc, NoteLoc; 9996 SourceRange ErrorRange, NoteRange; 9997 // If clause is write: 9998 // x = expr; 9999 if (const auto *AtomicBody = dyn_cast<Expr>(Body)) { 10000 const auto *AtomicBinOp = 10001 dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts()); 10002 if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) { 10003 X = AtomicBinOp->getLHS(); 10004 E = AtomicBinOp->getRHS(); 10005 if ((X->isInstantiationDependent() || X->getType()->isScalarType()) && 10006 (E->isInstantiationDependent() || E->getType()->isScalarType())) { 10007 if (!X->isLValue()) { 10008 ErrorFound = NotAnLValue; 10009 ErrorLoc = AtomicBinOp->getExprLoc(); 10010 ErrorRange = AtomicBinOp->getSourceRange(); 10011 NoteLoc = X->getExprLoc(); 10012 NoteRange = X->getSourceRange(); 10013 } 10014 } else if (!X->isInstantiationDependent() || 10015 !E->isInstantiationDependent()) { 10016 const Expr *NotScalarExpr = 10017 (X->isInstantiationDependent() || X->getType()->isScalarType()) 10018 ? E 10019 : X; 10020 ErrorFound = NotAScalarType; 10021 ErrorLoc = AtomicBinOp->getExprLoc(); 10022 ErrorRange = AtomicBinOp->getSourceRange(); 10023 NoteLoc = NotScalarExpr->getExprLoc(); 10024 NoteRange = NotScalarExpr->getSourceRange(); 10025 } 10026 } else if (!AtomicBody->isInstantiationDependent()) { 10027 ErrorFound = NotAnAssignmentOp; 10028 ErrorLoc = AtomicBody->getExprLoc(); 10029 ErrorRange = AtomicBody->getSourceRange(); 10030 NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc() 10031 : AtomicBody->getExprLoc(); 10032 NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange() 10033 : AtomicBody->getSourceRange(); 10034 } 10035 } else { 10036 ErrorFound = NotAnExpression; 10037 NoteLoc = ErrorLoc = Body->getBeginLoc(); 10038 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc); 10039 } 10040 if (ErrorFound != NoError) { 10041 Diag(ErrorLoc, diag::err_omp_atomic_write_not_expression_statement) 10042 << ErrorRange; 10043 Diag(NoteLoc, diag::note_omp_atomic_read_write) << ErrorFound 10044 << NoteRange; 10045 return StmtError(); 10046 } 10047 if (CurContext->isDependentContext()) 10048 E = X = nullptr; 10049 } else if (AtomicKind == OMPC_update || AtomicKind == OMPC_unknown) { 10050 // If clause is update: 10051 // x++; 10052 // x--; 10053 // ++x; 10054 // --x; 10055 // x binop= expr; 10056 // x = x binop expr; 10057 // x = expr binop x; 10058 OpenMPAtomicUpdateChecker Checker(*this); 10059 if (Checker.checkStatement( 10060 Body, (AtomicKind == OMPC_update) 10061 ? diag::err_omp_atomic_update_not_expression_statement 10062 : diag::err_omp_atomic_not_expression_statement, 10063 diag::note_omp_atomic_update)) 10064 return StmtError(); 10065 if (!CurContext->isDependentContext()) { 10066 E = Checker.getExpr(); 10067 X = Checker.getX(); 10068 UE = Checker.getUpdateExpr(); 10069 IsXLHSInRHSPart = Checker.isXLHSInRHSPart(); 10070 } 10071 } else if (AtomicKind == OMPC_capture) { 10072 enum { 10073 NotAnAssignmentOp, 10074 NotACompoundStatement, 10075 NotTwoSubstatements, 10076 NotASpecificExpression, 10077 NoError 10078 } ErrorFound = NoError; 10079 SourceLocation ErrorLoc, NoteLoc; 10080 SourceRange ErrorRange, NoteRange; 10081 if (const auto *AtomicBody = dyn_cast<Expr>(Body)) { 10082 // If clause is a capture: 10083 // v = x++; 10084 // v = x--; 10085 // v = ++x; 10086 // v = --x; 10087 // v = x binop= expr; 10088 // v = x = x binop expr; 10089 // v = x = expr binop x; 10090 const auto *AtomicBinOp = 10091 dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts()); 10092 if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) { 10093 V = AtomicBinOp->getLHS(); 10094 Body = AtomicBinOp->getRHS()->IgnoreParenImpCasts(); 10095 OpenMPAtomicUpdateChecker Checker(*this); 10096 if (Checker.checkStatement( 10097 Body, diag::err_omp_atomic_capture_not_expression_statement, 10098 diag::note_omp_atomic_update)) 10099 return StmtError(); 10100 E = Checker.getExpr(); 10101 X = Checker.getX(); 10102 UE = Checker.getUpdateExpr(); 10103 IsXLHSInRHSPart = Checker.isXLHSInRHSPart(); 10104 IsPostfixUpdate = Checker.isPostfixUpdate(); 10105 } else if (!AtomicBody->isInstantiationDependent()) { 10106 ErrorLoc = AtomicBody->getExprLoc(); 10107 ErrorRange = AtomicBody->getSourceRange(); 10108 NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc() 10109 : AtomicBody->getExprLoc(); 10110 NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange() 10111 : AtomicBody->getSourceRange(); 10112 ErrorFound = NotAnAssignmentOp; 10113 } 10114 if (ErrorFound != NoError) { 10115 Diag(ErrorLoc, diag::err_omp_atomic_capture_not_expression_statement) 10116 << ErrorRange; 10117 Diag(NoteLoc, diag::note_omp_atomic_capture) << ErrorFound << NoteRange; 10118 return StmtError(); 10119 } 10120 if (CurContext->isDependentContext()) 10121 UE = V = E = X = nullptr; 10122 } else { 10123 // If clause is a capture: 10124 // { v = x; x = expr; } 10125 // { v = x; x++; } 10126 // { v = x; x--; } 10127 // { v = x; ++x; } 10128 // { v = x; --x; } 10129 // { v = x; x binop= expr; } 10130 // { v = x; x = x binop expr; } 10131 // { v = x; x = expr binop x; } 10132 // { x++; v = x; } 10133 // { x--; v = x; } 10134 // { ++x; v = x; } 10135 // { --x; v = x; } 10136 // { x binop= expr; v = x; } 10137 // { x = x binop expr; v = x; } 10138 // { x = expr binop x; v = x; } 10139 if (auto *CS = dyn_cast<CompoundStmt>(Body)) { 10140 // Check that this is { expr1; expr2; } 10141 if (CS->size() == 2) { 10142 Stmt *First = CS->body_front(); 10143 Stmt *Second = CS->body_back(); 10144 if (auto *EWC = dyn_cast<ExprWithCleanups>(First)) 10145 First = EWC->getSubExpr()->IgnoreParenImpCasts(); 10146 if (auto *EWC = dyn_cast<ExprWithCleanups>(Second)) 10147 Second = EWC->getSubExpr()->IgnoreParenImpCasts(); 10148 // Need to find what subexpression is 'v' and what is 'x'. 10149 OpenMPAtomicUpdateChecker Checker(*this); 10150 bool IsUpdateExprFound = !Checker.checkStatement(Second); 10151 BinaryOperator *BinOp = nullptr; 10152 if (IsUpdateExprFound) { 10153 BinOp = dyn_cast<BinaryOperator>(First); 10154 IsUpdateExprFound = BinOp && BinOp->getOpcode() == BO_Assign; 10155 } 10156 if (IsUpdateExprFound && !CurContext->isDependentContext()) { 10157 // { v = x; x++; } 10158 // { v = x; x--; } 10159 // { v = x; ++x; } 10160 // { v = x; --x; } 10161 // { v = x; x binop= expr; } 10162 // { v = x; x = x binop expr; } 10163 // { v = x; x = expr binop x; } 10164 // Check that the first expression has form v = x. 10165 Expr *PossibleX = BinOp->getRHS()->IgnoreParenImpCasts(); 10166 llvm::FoldingSetNodeID XId, PossibleXId; 10167 Checker.getX()->Profile(XId, Context, /*Canonical=*/true); 10168 PossibleX->Profile(PossibleXId, Context, /*Canonical=*/true); 10169 IsUpdateExprFound = XId == PossibleXId; 10170 if (IsUpdateExprFound) { 10171 V = BinOp->getLHS(); 10172 X = Checker.getX(); 10173 E = Checker.getExpr(); 10174 UE = Checker.getUpdateExpr(); 10175 IsXLHSInRHSPart = Checker.isXLHSInRHSPart(); 10176 IsPostfixUpdate = true; 10177 } 10178 } 10179 if (!IsUpdateExprFound) { 10180 IsUpdateExprFound = !Checker.checkStatement(First); 10181 BinOp = nullptr; 10182 if (IsUpdateExprFound) { 10183 BinOp = dyn_cast<BinaryOperator>(Second); 10184 IsUpdateExprFound = BinOp && BinOp->getOpcode() == BO_Assign; 10185 } 10186 if (IsUpdateExprFound && !CurContext->isDependentContext()) { 10187 // { x++; v = x; } 10188 // { x--; v = x; } 10189 // { ++x; v = x; } 10190 // { --x; v = x; } 10191 // { x binop= expr; v = x; } 10192 // { x = x binop expr; v = x; } 10193 // { x = expr binop x; v = x; } 10194 // Check that the second expression has form v = x. 10195 Expr *PossibleX = BinOp->getRHS()->IgnoreParenImpCasts(); 10196 llvm::FoldingSetNodeID XId, PossibleXId; 10197 Checker.getX()->Profile(XId, Context, /*Canonical=*/true); 10198 PossibleX->Profile(PossibleXId, Context, /*Canonical=*/true); 10199 IsUpdateExprFound = XId == PossibleXId; 10200 if (IsUpdateExprFound) { 10201 V = BinOp->getLHS(); 10202 X = Checker.getX(); 10203 E = Checker.getExpr(); 10204 UE = Checker.getUpdateExpr(); 10205 IsXLHSInRHSPart = Checker.isXLHSInRHSPart(); 10206 IsPostfixUpdate = false; 10207 } 10208 } 10209 } 10210 if (!IsUpdateExprFound) { 10211 // { v = x; x = expr; } 10212 auto *FirstExpr = dyn_cast<Expr>(First); 10213 auto *SecondExpr = dyn_cast<Expr>(Second); 10214 if (!FirstExpr || !SecondExpr || 10215 !(FirstExpr->isInstantiationDependent() || 10216 SecondExpr->isInstantiationDependent())) { 10217 auto *FirstBinOp = dyn_cast<BinaryOperator>(First); 10218 if (!FirstBinOp || FirstBinOp->getOpcode() != BO_Assign) { 10219 ErrorFound = NotAnAssignmentOp; 10220 NoteLoc = ErrorLoc = FirstBinOp ? FirstBinOp->getOperatorLoc() 10221 : First->getBeginLoc(); 10222 NoteRange = ErrorRange = FirstBinOp 10223 ? FirstBinOp->getSourceRange() 10224 : SourceRange(ErrorLoc, ErrorLoc); 10225 } else { 10226 auto *SecondBinOp = dyn_cast<BinaryOperator>(Second); 10227 if (!SecondBinOp || SecondBinOp->getOpcode() != BO_Assign) { 10228 ErrorFound = NotAnAssignmentOp; 10229 NoteLoc = ErrorLoc = SecondBinOp 10230 ? SecondBinOp->getOperatorLoc() 10231 : Second->getBeginLoc(); 10232 NoteRange = ErrorRange = 10233 SecondBinOp ? SecondBinOp->getSourceRange() 10234 : SourceRange(ErrorLoc, ErrorLoc); 10235 } else { 10236 Expr *PossibleXRHSInFirst = 10237 FirstBinOp->getRHS()->IgnoreParenImpCasts(); 10238 Expr *PossibleXLHSInSecond = 10239 SecondBinOp->getLHS()->IgnoreParenImpCasts(); 10240 llvm::FoldingSetNodeID X1Id, X2Id; 10241 PossibleXRHSInFirst->Profile(X1Id, Context, 10242 /*Canonical=*/true); 10243 PossibleXLHSInSecond->Profile(X2Id, Context, 10244 /*Canonical=*/true); 10245 IsUpdateExprFound = X1Id == X2Id; 10246 if (IsUpdateExprFound) { 10247 V = FirstBinOp->getLHS(); 10248 X = SecondBinOp->getLHS(); 10249 E = SecondBinOp->getRHS(); 10250 UE = nullptr; 10251 IsXLHSInRHSPart = false; 10252 IsPostfixUpdate = true; 10253 } else { 10254 ErrorFound = NotASpecificExpression; 10255 ErrorLoc = FirstBinOp->getExprLoc(); 10256 ErrorRange = FirstBinOp->getSourceRange(); 10257 NoteLoc = SecondBinOp->getLHS()->getExprLoc(); 10258 NoteRange = SecondBinOp->getRHS()->getSourceRange(); 10259 } 10260 } 10261 } 10262 } 10263 } 10264 } else { 10265 NoteLoc = ErrorLoc = Body->getBeginLoc(); 10266 NoteRange = ErrorRange = 10267 SourceRange(Body->getBeginLoc(), Body->getBeginLoc()); 10268 ErrorFound = NotTwoSubstatements; 10269 } 10270 } else { 10271 NoteLoc = ErrorLoc = Body->getBeginLoc(); 10272 NoteRange = ErrorRange = 10273 SourceRange(Body->getBeginLoc(), Body->getBeginLoc()); 10274 ErrorFound = NotACompoundStatement; 10275 } 10276 if (ErrorFound != NoError) { 10277 Diag(ErrorLoc, diag::err_omp_atomic_capture_not_compound_statement) 10278 << ErrorRange; 10279 Diag(NoteLoc, diag::note_omp_atomic_capture) << ErrorFound << NoteRange; 10280 return StmtError(); 10281 } 10282 if (CurContext->isDependentContext()) 10283 UE = V = E = X = nullptr; 10284 } 10285 } 10286 10287 setFunctionHasBranchProtectedScope(); 10288 10289 return OMPAtomicDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt, 10290 X, V, E, UE, IsXLHSInRHSPart, 10291 IsPostfixUpdate); 10292 } 10293 10294 StmtResult Sema::ActOnOpenMPTargetDirective(ArrayRef<OMPClause *> Clauses, 10295 Stmt *AStmt, 10296 SourceLocation StartLoc, 10297 SourceLocation EndLoc) { 10298 if (!AStmt) 10299 return StmtError(); 10300 10301 auto *CS = cast<CapturedStmt>(AStmt); 10302 // 1.2.2 OpenMP Language Terminology 10303 // Structured block - An executable statement with a single entry at the 10304 // top and a single exit at the bottom. 10305 // The point of exit cannot be a branch out of the structured block. 10306 // longjmp() and throw() must not violate the entry/exit criteria. 10307 CS->getCapturedDecl()->setNothrow(); 10308 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target); 10309 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10310 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10311 // 1.2.2 OpenMP Language Terminology 10312 // Structured block - An executable statement with a single entry at the 10313 // top and a single exit at the bottom. 10314 // The point of exit cannot be a branch out of the structured block. 10315 // longjmp() and throw() must not violate the entry/exit criteria. 10316 CS->getCapturedDecl()->setNothrow(); 10317 } 10318 10319 // OpenMP [2.16, Nesting of Regions] 10320 // If specified, a teams construct must be contained within a target 10321 // construct. That target construct must contain no statements or directives 10322 // outside of the teams construct. 10323 if (DSAStack->hasInnerTeamsRegion()) { 10324 const Stmt *S = CS->IgnoreContainers(/*IgnoreCaptured=*/true); 10325 bool OMPTeamsFound = true; 10326 if (const auto *CS = dyn_cast<CompoundStmt>(S)) { 10327 auto I = CS->body_begin(); 10328 while (I != CS->body_end()) { 10329 const auto *OED = dyn_cast<OMPExecutableDirective>(*I); 10330 if (!OED || !isOpenMPTeamsDirective(OED->getDirectiveKind()) || 10331 OMPTeamsFound) { 10332 10333 OMPTeamsFound = false; 10334 break; 10335 } 10336 ++I; 10337 } 10338 assert(I != CS->body_end() && "Not found statement"); 10339 S = *I; 10340 } else { 10341 const auto *OED = dyn_cast<OMPExecutableDirective>(S); 10342 OMPTeamsFound = OED && isOpenMPTeamsDirective(OED->getDirectiveKind()); 10343 } 10344 if (!OMPTeamsFound) { 10345 Diag(StartLoc, diag::err_omp_target_contains_not_only_teams); 10346 Diag(DSAStack->getInnerTeamsRegionLoc(), 10347 diag::note_omp_nested_teams_construct_here); 10348 Diag(S->getBeginLoc(), diag::note_omp_nested_statement_here) 10349 << isa<OMPExecutableDirective>(S); 10350 return StmtError(); 10351 } 10352 } 10353 10354 setFunctionHasBranchProtectedScope(); 10355 10356 return OMPTargetDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt); 10357 } 10358 10359 StmtResult 10360 Sema::ActOnOpenMPTargetParallelDirective(ArrayRef<OMPClause *> Clauses, 10361 Stmt *AStmt, SourceLocation StartLoc, 10362 SourceLocation EndLoc) { 10363 if (!AStmt) 10364 return StmtError(); 10365 10366 auto *CS = cast<CapturedStmt>(AStmt); 10367 // 1.2.2 OpenMP Language Terminology 10368 // Structured block - An executable statement with a single entry at the 10369 // top and a single exit at the bottom. 10370 // The point of exit cannot be a branch out of the structured block. 10371 // longjmp() and throw() must not violate the entry/exit criteria. 10372 CS->getCapturedDecl()->setNothrow(); 10373 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel); 10374 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10375 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10376 // 1.2.2 OpenMP Language Terminology 10377 // Structured block - An executable statement with a single entry at the 10378 // top and a single exit at the bottom. 10379 // The point of exit cannot be a branch out of the structured block. 10380 // longjmp() and throw() must not violate the entry/exit criteria. 10381 CS->getCapturedDecl()->setNothrow(); 10382 } 10383 10384 setFunctionHasBranchProtectedScope(); 10385 10386 return OMPTargetParallelDirective::Create( 10387 Context, StartLoc, EndLoc, Clauses, AStmt, 10388 DSAStack->getTaskgroupReductionRef(), DSAStack->isCancelRegion()); 10389 } 10390 10391 StmtResult Sema::ActOnOpenMPTargetParallelForDirective( 10392 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10393 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10394 if (!AStmt) 10395 return StmtError(); 10396 10397 auto *CS = cast<CapturedStmt>(AStmt); 10398 // 1.2.2 OpenMP Language Terminology 10399 // Structured block - An executable statement with a single entry at the 10400 // top and a single exit at the bottom. 10401 // The point of exit cannot be a branch out of the structured block. 10402 // longjmp() and throw() must not violate the entry/exit criteria. 10403 CS->getCapturedDecl()->setNothrow(); 10404 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel_for); 10405 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10406 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10407 // 1.2.2 OpenMP Language Terminology 10408 // Structured block - An executable statement with a single entry at the 10409 // top and a single exit at the bottom. 10410 // The point of exit cannot be a branch out of the structured block. 10411 // longjmp() and throw() must not violate the entry/exit criteria. 10412 CS->getCapturedDecl()->setNothrow(); 10413 } 10414 10415 OMPLoopDirective::HelperExprs B; 10416 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 10417 // define the nested loops number. 10418 unsigned NestedLoopCount = 10419 checkOpenMPLoop(OMPD_target_parallel_for, getCollapseNumberExpr(Clauses), 10420 getOrderedNumberExpr(Clauses), CS, *this, *DSAStack, 10421 VarsWithImplicitDSA, B); 10422 if (NestedLoopCount == 0) 10423 return StmtError(); 10424 10425 assert((CurContext->isDependentContext() || B.builtAll()) && 10426 "omp target parallel for loop exprs were not built"); 10427 10428 if (!CurContext->isDependentContext()) { 10429 // Finalize the clauses that need pre-built expressions for CodeGen. 10430 for (OMPClause *C : Clauses) { 10431 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 10432 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 10433 B.NumIterations, *this, CurScope, 10434 DSAStack)) 10435 return StmtError(); 10436 } 10437 } 10438 10439 setFunctionHasBranchProtectedScope(); 10440 return OMPTargetParallelForDirective::Create( 10441 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B, 10442 DSAStack->getTaskgroupReductionRef(), DSAStack->isCancelRegion()); 10443 } 10444 10445 /// Check for existence of a map clause in the list of clauses. 10446 static bool hasClauses(ArrayRef<OMPClause *> Clauses, 10447 const OpenMPClauseKind K) { 10448 return llvm::any_of( 10449 Clauses, [K](const OMPClause *C) { return C->getClauseKind() == K; }); 10450 } 10451 10452 template <typename... Params> 10453 static bool hasClauses(ArrayRef<OMPClause *> Clauses, const OpenMPClauseKind K, 10454 const Params... ClauseTypes) { 10455 return hasClauses(Clauses, K) || hasClauses(Clauses, ClauseTypes...); 10456 } 10457 10458 StmtResult Sema::ActOnOpenMPTargetDataDirective(ArrayRef<OMPClause *> Clauses, 10459 Stmt *AStmt, 10460 SourceLocation StartLoc, 10461 SourceLocation EndLoc) { 10462 if (!AStmt) 10463 return StmtError(); 10464 10465 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 10466 10467 // OpenMP [2.12.2, target data Construct, Restrictions] 10468 // At least one map, use_device_addr or use_device_ptr clause must appear on 10469 // the directive. 10470 if (!hasClauses(Clauses, OMPC_map, OMPC_use_device_ptr) && 10471 (LangOpts.OpenMP < 50 || !hasClauses(Clauses, OMPC_use_device_addr))) { 10472 StringRef Expected; 10473 if (LangOpts.OpenMP < 50) 10474 Expected = "'map' or 'use_device_ptr'"; 10475 else 10476 Expected = "'map', 'use_device_ptr', or 'use_device_addr'"; 10477 Diag(StartLoc, diag::err_omp_no_clause_for_directive) 10478 << Expected << getOpenMPDirectiveName(OMPD_target_data); 10479 return StmtError(); 10480 } 10481 10482 setFunctionHasBranchProtectedScope(); 10483 10484 return OMPTargetDataDirective::Create(Context, StartLoc, EndLoc, Clauses, 10485 AStmt); 10486 } 10487 10488 StmtResult 10489 Sema::ActOnOpenMPTargetEnterDataDirective(ArrayRef<OMPClause *> Clauses, 10490 SourceLocation StartLoc, 10491 SourceLocation EndLoc, Stmt *AStmt) { 10492 if (!AStmt) 10493 return StmtError(); 10494 10495 auto *CS = cast<CapturedStmt>(AStmt); 10496 // 1.2.2 OpenMP Language Terminology 10497 // Structured block - An executable statement with a single entry at the 10498 // top and a single exit at the bottom. 10499 // The point of exit cannot be a branch out of the structured block. 10500 // longjmp() and throw() must not violate the entry/exit criteria. 10501 CS->getCapturedDecl()->setNothrow(); 10502 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_enter_data); 10503 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10504 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10505 // 1.2.2 OpenMP Language Terminology 10506 // Structured block - An executable statement with a single entry at the 10507 // top and a single exit at the bottom. 10508 // The point of exit cannot be a branch out of the structured block. 10509 // longjmp() and throw() must not violate the entry/exit criteria. 10510 CS->getCapturedDecl()->setNothrow(); 10511 } 10512 10513 // OpenMP [2.10.2, Restrictions, p. 99] 10514 // At least one map clause must appear on the directive. 10515 if (!hasClauses(Clauses, OMPC_map)) { 10516 Diag(StartLoc, diag::err_omp_no_clause_for_directive) 10517 << "'map'" << getOpenMPDirectiveName(OMPD_target_enter_data); 10518 return StmtError(); 10519 } 10520 10521 return OMPTargetEnterDataDirective::Create(Context, StartLoc, EndLoc, Clauses, 10522 AStmt); 10523 } 10524 10525 StmtResult 10526 Sema::ActOnOpenMPTargetExitDataDirective(ArrayRef<OMPClause *> Clauses, 10527 SourceLocation StartLoc, 10528 SourceLocation EndLoc, Stmt *AStmt) { 10529 if (!AStmt) 10530 return StmtError(); 10531 10532 auto *CS = cast<CapturedStmt>(AStmt); 10533 // 1.2.2 OpenMP Language Terminology 10534 // Structured block - An executable statement with a single entry at the 10535 // top and a single exit at the bottom. 10536 // The point of exit cannot be a branch out of the structured block. 10537 // longjmp() and throw() must not violate the entry/exit criteria. 10538 CS->getCapturedDecl()->setNothrow(); 10539 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_exit_data); 10540 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10541 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10542 // 1.2.2 OpenMP Language Terminology 10543 // Structured block - An executable statement with a single entry at the 10544 // top and a single exit at the bottom. 10545 // The point of exit cannot be a branch out of the structured block. 10546 // longjmp() and throw() must not violate the entry/exit criteria. 10547 CS->getCapturedDecl()->setNothrow(); 10548 } 10549 10550 // OpenMP [2.10.3, Restrictions, p. 102] 10551 // At least one map clause must appear on the directive. 10552 if (!hasClauses(Clauses, OMPC_map)) { 10553 Diag(StartLoc, diag::err_omp_no_clause_for_directive) 10554 << "'map'" << getOpenMPDirectiveName(OMPD_target_exit_data); 10555 return StmtError(); 10556 } 10557 10558 return OMPTargetExitDataDirective::Create(Context, StartLoc, EndLoc, Clauses, 10559 AStmt); 10560 } 10561 10562 StmtResult Sema::ActOnOpenMPTargetUpdateDirective(ArrayRef<OMPClause *> Clauses, 10563 SourceLocation StartLoc, 10564 SourceLocation EndLoc, 10565 Stmt *AStmt) { 10566 if (!AStmt) 10567 return StmtError(); 10568 10569 auto *CS = cast<CapturedStmt>(AStmt); 10570 // 1.2.2 OpenMP Language Terminology 10571 // Structured block - An executable statement with a single entry at the 10572 // top and a single exit at the bottom. 10573 // The point of exit cannot be a branch out of the structured block. 10574 // longjmp() and throw() must not violate the entry/exit criteria. 10575 CS->getCapturedDecl()->setNothrow(); 10576 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_update); 10577 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10578 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10579 // 1.2.2 OpenMP Language Terminology 10580 // Structured block - An executable statement with a single entry at the 10581 // top and a single exit at the bottom. 10582 // The point of exit cannot be a branch out of the structured block. 10583 // longjmp() and throw() must not violate the entry/exit criteria. 10584 CS->getCapturedDecl()->setNothrow(); 10585 } 10586 10587 if (!hasClauses(Clauses, OMPC_to, OMPC_from)) { 10588 Diag(StartLoc, diag::err_omp_at_least_one_motion_clause_required); 10589 return StmtError(); 10590 } 10591 return OMPTargetUpdateDirective::Create(Context, StartLoc, EndLoc, Clauses, 10592 AStmt); 10593 } 10594 10595 StmtResult Sema::ActOnOpenMPTeamsDirective(ArrayRef<OMPClause *> Clauses, 10596 Stmt *AStmt, SourceLocation StartLoc, 10597 SourceLocation EndLoc) { 10598 if (!AStmt) 10599 return StmtError(); 10600 10601 auto *CS = cast<CapturedStmt>(AStmt); 10602 // 1.2.2 OpenMP Language Terminology 10603 // Structured block - An executable statement with a single entry at the 10604 // top and a single exit at the bottom. 10605 // The point of exit cannot be a branch out of the structured block. 10606 // longjmp() and throw() must not violate the entry/exit criteria. 10607 CS->getCapturedDecl()->setNothrow(); 10608 10609 setFunctionHasBranchProtectedScope(); 10610 10611 DSAStack->setParentTeamsRegionLoc(StartLoc); 10612 10613 return OMPTeamsDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt); 10614 } 10615 10616 StmtResult 10617 Sema::ActOnOpenMPCancellationPointDirective(SourceLocation StartLoc, 10618 SourceLocation EndLoc, 10619 OpenMPDirectiveKind CancelRegion) { 10620 if (DSAStack->isParentNowaitRegion()) { 10621 Diag(StartLoc, diag::err_omp_parent_cancel_region_nowait) << 0; 10622 return StmtError(); 10623 } 10624 if (DSAStack->isParentOrderedRegion()) { 10625 Diag(StartLoc, diag::err_omp_parent_cancel_region_ordered) << 0; 10626 return StmtError(); 10627 } 10628 return OMPCancellationPointDirective::Create(Context, StartLoc, EndLoc, 10629 CancelRegion); 10630 } 10631 10632 StmtResult Sema::ActOnOpenMPCancelDirective(ArrayRef<OMPClause *> Clauses, 10633 SourceLocation StartLoc, 10634 SourceLocation EndLoc, 10635 OpenMPDirectiveKind CancelRegion) { 10636 if (DSAStack->isParentNowaitRegion()) { 10637 Diag(StartLoc, diag::err_omp_parent_cancel_region_nowait) << 1; 10638 return StmtError(); 10639 } 10640 if (DSAStack->isParentOrderedRegion()) { 10641 Diag(StartLoc, diag::err_omp_parent_cancel_region_ordered) << 1; 10642 return StmtError(); 10643 } 10644 DSAStack->setParentCancelRegion(/*Cancel=*/true); 10645 return OMPCancelDirective::Create(Context, StartLoc, EndLoc, Clauses, 10646 CancelRegion); 10647 } 10648 10649 static bool checkGrainsizeNumTasksClauses(Sema &S, 10650 ArrayRef<OMPClause *> Clauses) { 10651 const OMPClause *PrevClause = nullptr; 10652 bool ErrorFound = false; 10653 for (const OMPClause *C : Clauses) { 10654 if (C->getClauseKind() == OMPC_grainsize || 10655 C->getClauseKind() == OMPC_num_tasks) { 10656 if (!PrevClause) 10657 PrevClause = C; 10658 else if (PrevClause->getClauseKind() != C->getClauseKind()) { 10659 S.Diag(C->getBeginLoc(), diag::err_omp_clauses_mutually_exclusive) 10660 << getOpenMPClauseName(C->getClauseKind()) 10661 << getOpenMPClauseName(PrevClause->getClauseKind()); 10662 S.Diag(PrevClause->getBeginLoc(), diag::note_omp_previous_clause) 10663 << getOpenMPClauseName(PrevClause->getClauseKind()); 10664 ErrorFound = true; 10665 } 10666 } 10667 } 10668 return ErrorFound; 10669 } 10670 10671 static bool checkReductionClauseWithNogroup(Sema &S, 10672 ArrayRef<OMPClause *> Clauses) { 10673 const OMPClause *ReductionClause = nullptr; 10674 const OMPClause *NogroupClause = nullptr; 10675 for (const OMPClause *C : Clauses) { 10676 if (C->getClauseKind() == OMPC_reduction) { 10677 ReductionClause = C; 10678 if (NogroupClause) 10679 break; 10680 continue; 10681 } 10682 if (C->getClauseKind() == OMPC_nogroup) { 10683 NogroupClause = C; 10684 if (ReductionClause) 10685 break; 10686 continue; 10687 } 10688 } 10689 if (ReductionClause && NogroupClause) { 10690 S.Diag(ReductionClause->getBeginLoc(), diag::err_omp_reduction_with_nogroup) 10691 << SourceRange(NogroupClause->getBeginLoc(), 10692 NogroupClause->getEndLoc()); 10693 return true; 10694 } 10695 return false; 10696 } 10697 10698 StmtResult Sema::ActOnOpenMPTaskLoopDirective( 10699 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10700 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10701 if (!AStmt) 10702 return StmtError(); 10703 10704 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 10705 OMPLoopDirective::HelperExprs B; 10706 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 10707 // define the nested loops number. 10708 unsigned NestedLoopCount = 10709 checkOpenMPLoop(OMPD_taskloop, getCollapseNumberExpr(Clauses), 10710 /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack, 10711 VarsWithImplicitDSA, B); 10712 if (NestedLoopCount == 0) 10713 return StmtError(); 10714 10715 assert((CurContext->isDependentContext() || B.builtAll()) && 10716 "omp for loop exprs were not built"); 10717 10718 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 10719 // The grainsize clause and num_tasks clause are mutually exclusive and may 10720 // not appear on the same taskloop directive. 10721 if (checkGrainsizeNumTasksClauses(*this, Clauses)) 10722 return StmtError(); 10723 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 10724 // If a reduction clause is present on the taskloop directive, the nogroup 10725 // clause must not be specified. 10726 if (checkReductionClauseWithNogroup(*this, Clauses)) 10727 return StmtError(); 10728 10729 setFunctionHasBranchProtectedScope(); 10730 return OMPTaskLoopDirective::Create(Context, StartLoc, EndLoc, 10731 NestedLoopCount, Clauses, AStmt, B, 10732 DSAStack->isCancelRegion()); 10733 } 10734 10735 StmtResult Sema::ActOnOpenMPTaskLoopSimdDirective( 10736 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10737 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10738 if (!AStmt) 10739 return StmtError(); 10740 10741 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 10742 OMPLoopDirective::HelperExprs B; 10743 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 10744 // define the nested loops number. 10745 unsigned NestedLoopCount = 10746 checkOpenMPLoop(OMPD_taskloop_simd, getCollapseNumberExpr(Clauses), 10747 /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack, 10748 VarsWithImplicitDSA, B); 10749 if (NestedLoopCount == 0) 10750 return StmtError(); 10751 10752 assert((CurContext->isDependentContext() || B.builtAll()) && 10753 "omp for loop exprs were not built"); 10754 10755 if (!CurContext->isDependentContext()) { 10756 // Finalize the clauses that need pre-built expressions for CodeGen. 10757 for (OMPClause *C : Clauses) { 10758 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 10759 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 10760 B.NumIterations, *this, CurScope, 10761 DSAStack)) 10762 return StmtError(); 10763 } 10764 } 10765 10766 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 10767 // The grainsize clause and num_tasks clause are mutually exclusive and may 10768 // not appear on the same taskloop directive. 10769 if (checkGrainsizeNumTasksClauses(*this, Clauses)) 10770 return StmtError(); 10771 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 10772 // If a reduction clause is present on the taskloop directive, the nogroup 10773 // clause must not be specified. 10774 if (checkReductionClauseWithNogroup(*this, Clauses)) 10775 return StmtError(); 10776 if (checkSimdlenSafelenSpecified(*this, Clauses)) 10777 return StmtError(); 10778 10779 setFunctionHasBranchProtectedScope(); 10780 return OMPTaskLoopSimdDirective::Create(Context, StartLoc, EndLoc, 10781 NestedLoopCount, Clauses, AStmt, B); 10782 } 10783 10784 StmtResult Sema::ActOnOpenMPMasterTaskLoopDirective( 10785 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10786 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10787 if (!AStmt) 10788 return StmtError(); 10789 10790 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 10791 OMPLoopDirective::HelperExprs B; 10792 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 10793 // define the nested loops number. 10794 unsigned NestedLoopCount = 10795 checkOpenMPLoop(OMPD_master_taskloop, getCollapseNumberExpr(Clauses), 10796 /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack, 10797 VarsWithImplicitDSA, B); 10798 if (NestedLoopCount == 0) 10799 return StmtError(); 10800 10801 assert((CurContext->isDependentContext() || B.builtAll()) && 10802 "omp for loop exprs were not built"); 10803 10804 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 10805 // The grainsize clause and num_tasks clause are mutually exclusive and may 10806 // not appear on the same taskloop directive. 10807 if (checkGrainsizeNumTasksClauses(*this, Clauses)) 10808 return StmtError(); 10809 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 10810 // If a reduction clause is present on the taskloop directive, the nogroup 10811 // clause must not be specified. 10812 if (checkReductionClauseWithNogroup(*this, Clauses)) 10813 return StmtError(); 10814 10815 setFunctionHasBranchProtectedScope(); 10816 return OMPMasterTaskLoopDirective::Create(Context, StartLoc, EndLoc, 10817 NestedLoopCount, Clauses, AStmt, B, 10818 DSAStack->isCancelRegion()); 10819 } 10820 10821 StmtResult Sema::ActOnOpenMPMasterTaskLoopSimdDirective( 10822 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10823 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10824 if (!AStmt) 10825 return StmtError(); 10826 10827 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 10828 OMPLoopDirective::HelperExprs B; 10829 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 10830 // define the nested loops number. 10831 unsigned NestedLoopCount = 10832 checkOpenMPLoop(OMPD_master_taskloop_simd, getCollapseNumberExpr(Clauses), 10833 /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack, 10834 VarsWithImplicitDSA, B); 10835 if (NestedLoopCount == 0) 10836 return StmtError(); 10837 10838 assert((CurContext->isDependentContext() || B.builtAll()) && 10839 "omp for loop exprs were not built"); 10840 10841 if (!CurContext->isDependentContext()) { 10842 // Finalize the clauses that need pre-built expressions for CodeGen. 10843 for (OMPClause *C : Clauses) { 10844 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 10845 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 10846 B.NumIterations, *this, CurScope, 10847 DSAStack)) 10848 return StmtError(); 10849 } 10850 } 10851 10852 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 10853 // The grainsize clause and num_tasks clause are mutually exclusive and may 10854 // not appear on the same taskloop directive. 10855 if (checkGrainsizeNumTasksClauses(*this, Clauses)) 10856 return StmtError(); 10857 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 10858 // If a reduction clause is present on the taskloop directive, the nogroup 10859 // clause must not be specified. 10860 if (checkReductionClauseWithNogroup(*this, Clauses)) 10861 return StmtError(); 10862 if (checkSimdlenSafelenSpecified(*this, Clauses)) 10863 return StmtError(); 10864 10865 setFunctionHasBranchProtectedScope(); 10866 return OMPMasterTaskLoopSimdDirective::Create( 10867 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 10868 } 10869 10870 StmtResult Sema::ActOnOpenMPParallelMasterTaskLoopDirective( 10871 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10872 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10873 if (!AStmt) 10874 return StmtError(); 10875 10876 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 10877 auto *CS = cast<CapturedStmt>(AStmt); 10878 // 1.2.2 OpenMP Language Terminology 10879 // Structured block - An executable statement with a single entry at the 10880 // top and a single exit at the bottom. 10881 // The point of exit cannot be a branch out of the structured block. 10882 // longjmp() and throw() must not violate the entry/exit criteria. 10883 CS->getCapturedDecl()->setNothrow(); 10884 for (int ThisCaptureLevel = 10885 getOpenMPCaptureLevels(OMPD_parallel_master_taskloop); 10886 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10887 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10888 // 1.2.2 OpenMP Language Terminology 10889 // Structured block - An executable statement with a single entry at the 10890 // top and a single exit at the bottom. 10891 // The point of exit cannot be a branch out of the structured block. 10892 // longjmp() and throw() must not violate the entry/exit criteria. 10893 CS->getCapturedDecl()->setNothrow(); 10894 } 10895 10896 OMPLoopDirective::HelperExprs B; 10897 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 10898 // define the nested loops number. 10899 unsigned NestedLoopCount = checkOpenMPLoop( 10900 OMPD_parallel_master_taskloop, getCollapseNumberExpr(Clauses), 10901 /*OrderedLoopCountExpr=*/nullptr, CS, *this, *DSAStack, 10902 VarsWithImplicitDSA, B); 10903 if (NestedLoopCount == 0) 10904 return StmtError(); 10905 10906 assert((CurContext->isDependentContext() || B.builtAll()) && 10907 "omp for loop exprs were not built"); 10908 10909 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 10910 // The grainsize clause and num_tasks clause are mutually exclusive and may 10911 // not appear on the same taskloop directive. 10912 if (checkGrainsizeNumTasksClauses(*this, Clauses)) 10913 return StmtError(); 10914 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 10915 // If a reduction clause is present on the taskloop directive, the nogroup 10916 // clause must not be specified. 10917 if (checkReductionClauseWithNogroup(*this, Clauses)) 10918 return StmtError(); 10919 10920 setFunctionHasBranchProtectedScope(); 10921 return OMPParallelMasterTaskLoopDirective::Create( 10922 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B, 10923 DSAStack->isCancelRegion()); 10924 } 10925 10926 StmtResult Sema::ActOnOpenMPParallelMasterTaskLoopSimdDirective( 10927 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10928 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10929 if (!AStmt) 10930 return StmtError(); 10931 10932 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 10933 auto *CS = cast<CapturedStmt>(AStmt); 10934 // 1.2.2 OpenMP Language Terminology 10935 // Structured block - An executable statement with a single entry at the 10936 // top and a single exit at the bottom. 10937 // The point of exit cannot be a branch out of the structured block. 10938 // longjmp() and throw() must not violate the entry/exit criteria. 10939 CS->getCapturedDecl()->setNothrow(); 10940 for (int ThisCaptureLevel = 10941 getOpenMPCaptureLevels(OMPD_parallel_master_taskloop_simd); 10942 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10943 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10944 // 1.2.2 OpenMP Language Terminology 10945 // Structured block - An executable statement with a single entry at the 10946 // top and a single exit at the bottom. 10947 // The point of exit cannot be a branch out of the structured block. 10948 // longjmp() and throw() must not violate the entry/exit criteria. 10949 CS->getCapturedDecl()->setNothrow(); 10950 } 10951 10952 OMPLoopDirective::HelperExprs B; 10953 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 10954 // define the nested loops number. 10955 unsigned NestedLoopCount = checkOpenMPLoop( 10956 OMPD_parallel_master_taskloop_simd, getCollapseNumberExpr(Clauses), 10957 /*OrderedLoopCountExpr=*/nullptr, CS, *this, *DSAStack, 10958 VarsWithImplicitDSA, B); 10959 if (NestedLoopCount == 0) 10960 return StmtError(); 10961 10962 assert((CurContext->isDependentContext() || B.builtAll()) && 10963 "omp for loop exprs were not built"); 10964 10965 if (!CurContext->isDependentContext()) { 10966 // Finalize the clauses that need pre-built expressions for CodeGen. 10967 for (OMPClause *C : Clauses) { 10968 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 10969 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 10970 B.NumIterations, *this, CurScope, 10971 DSAStack)) 10972 return StmtError(); 10973 } 10974 } 10975 10976 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 10977 // The grainsize clause and num_tasks clause are mutually exclusive and may 10978 // not appear on the same taskloop directive. 10979 if (checkGrainsizeNumTasksClauses(*this, Clauses)) 10980 return StmtError(); 10981 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 10982 // If a reduction clause is present on the taskloop directive, the nogroup 10983 // clause must not be specified. 10984 if (checkReductionClauseWithNogroup(*this, Clauses)) 10985 return StmtError(); 10986 if (checkSimdlenSafelenSpecified(*this, Clauses)) 10987 return StmtError(); 10988 10989 setFunctionHasBranchProtectedScope(); 10990 return OMPParallelMasterTaskLoopSimdDirective::Create( 10991 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 10992 } 10993 10994 StmtResult Sema::ActOnOpenMPDistributeDirective( 10995 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10996 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10997 if (!AStmt) 10998 return StmtError(); 10999 11000 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 11001 OMPLoopDirective::HelperExprs B; 11002 // In presence of clause 'collapse' with number of loops, it will 11003 // define the nested loops number. 11004 unsigned NestedLoopCount = 11005 checkOpenMPLoop(OMPD_distribute, getCollapseNumberExpr(Clauses), 11006 nullptr /*ordered not a clause on distribute*/, AStmt, 11007 *this, *DSAStack, VarsWithImplicitDSA, B); 11008 if (NestedLoopCount == 0) 11009 return StmtError(); 11010 11011 assert((CurContext->isDependentContext() || B.builtAll()) && 11012 "omp for loop exprs were not built"); 11013 11014 setFunctionHasBranchProtectedScope(); 11015 return OMPDistributeDirective::Create(Context, StartLoc, EndLoc, 11016 NestedLoopCount, Clauses, AStmt, B); 11017 } 11018 11019 StmtResult Sema::ActOnOpenMPDistributeParallelForDirective( 11020 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 11021 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 11022 if (!AStmt) 11023 return StmtError(); 11024 11025 auto *CS = cast<CapturedStmt>(AStmt); 11026 // 1.2.2 OpenMP Language Terminology 11027 // Structured block - An executable statement with a single entry at the 11028 // top and a single exit at the bottom. 11029 // The point of exit cannot be a branch out of the structured block. 11030 // longjmp() and throw() must not violate the entry/exit criteria. 11031 CS->getCapturedDecl()->setNothrow(); 11032 for (int ThisCaptureLevel = 11033 getOpenMPCaptureLevels(OMPD_distribute_parallel_for); 11034 ThisCaptureLevel > 1; --ThisCaptureLevel) { 11035 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 11036 // 1.2.2 OpenMP Language Terminology 11037 // Structured block - An executable statement with a single entry at the 11038 // top and a single exit at the bottom. 11039 // The point of exit cannot be a branch out of the structured block. 11040 // longjmp() and throw() must not violate the entry/exit criteria. 11041 CS->getCapturedDecl()->setNothrow(); 11042 } 11043 11044 OMPLoopDirective::HelperExprs B; 11045 // In presence of clause 'collapse' with number of loops, it will 11046 // define the nested loops number. 11047 unsigned NestedLoopCount = checkOpenMPLoop( 11048 OMPD_distribute_parallel_for, getCollapseNumberExpr(Clauses), 11049 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 11050 VarsWithImplicitDSA, B); 11051 if (NestedLoopCount == 0) 11052 return StmtError(); 11053 11054 assert((CurContext->isDependentContext() || B.builtAll()) && 11055 "omp for loop exprs were not built"); 11056 11057 setFunctionHasBranchProtectedScope(); 11058 return OMPDistributeParallelForDirective::Create( 11059 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B, 11060 DSAStack->getTaskgroupReductionRef(), DSAStack->isCancelRegion()); 11061 } 11062 11063 StmtResult Sema::ActOnOpenMPDistributeParallelForSimdDirective( 11064 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 11065 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 11066 if (!AStmt) 11067 return StmtError(); 11068 11069 auto *CS = cast<CapturedStmt>(AStmt); 11070 // 1.2.2 OpenMP Language Terminology 11071 // Structured block - An executable statement with a single entry at the 11072 // top and a single exit at the bottom. 11073 // The point of exit cannot be a branch out of the structured block. 11074 // longjmp() and throw() must not violate the entry/exit criteria. 11075 CS->getCapturedDecl()->setNothrow(); 11076 for (int ThisCaptureLevel = 11077 getOpenMPCaptureLevels(OMPD_distribute_parallel_for_simd); 11078 ThisCaptureLevel > 1; --ThisCaptureLevel) { 11079 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 11080 // 1.2.2 OpenMP Language Terminology 11081 // Structured block - An executable statement with a single entry at the 11082 // top and a single exit at the bottom. 11083 // The point of exit cannot be a branch out of the structured block. 11084 // longjmp() and throw() must not violate the entry/exit criteria. 11085 CS->getCapturedDecl()->setNothrow(); 11086 } 11087 11088 OMPLoopDirective::HelperExprs B; 11089 // In presence of clause 'collapse' with number of loops, it will 11090 // define the nested loops number. 11091 unsigned NestedLoopCount = checkOpenMPLoop( 11092 OMPD_distribute_parallel_for_simd, getCollapseNumberExpr(Clauses), 11093 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 11094 VarsWithImplicitDSA, B); 11095 if (NestedLoopCount == 0) 11096 return StmtError(); 11097 11098 assert((CurContext->isDependentContext() || B.builtAll()) && 11099 "omp for loop exprs were not built"); 11100 11101 if (!CurContext->isDependentContext()) { 11102 // Finalize the clauses that need pre-built expressions for CodeGen. 11103 for (OMPClause *C : Clauses) { 11104 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 11105 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 11106 B.NumIterations, *this, CurScope, 11107 DSAStack)) 11108 return StmtError(); 11109 } 11110 } 11111 11112 if (checkSimdlenSafelenSpecified(*this, Clauses)) 11113 return StmtError(); 11114 11115 setFunctionHasBranchProtectedScope(); 11116 return OMPDistributeParallelForSimdDirective::Create( 11117 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 11118 } 11119 11120 StmtResult Sema::ActOnOpenMPDistributeSimdDirective( 11121 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 11122 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 11123 if (!AStmt) 11124 return StmtError(); 11125 11126 auto *CS = cast<CapturedStmt>(AStmt); 11127 // 1.2.2 OpenMP Language Terminology 11128 // Structured block - An executable statement with a single entry at the 11129 // top and a single exit at the bottom. 11130 // The point of exit cannot be a branch out of the structured block. 11131 // longjmp() and throw() must not violate the entry/exit criteria. 11132 CS->getCapturedDecl()->setNothrow(); 11133 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_distribute_simd); 11134 ThisCaptureLevel > 1; --ThisCaptureLevel) { 11135 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 11136 // 1.2.2 OpenMP Language Terminology 11137 // Structured block - An executable statement with a single entry at the 11138 // top and a single exit at the bottom. 11139 // The point of exit cannot be a branch out of the structured block. 11140 // longjmp() and throw() must not violate the entry/exit criteria. 11141 CS->getCapturedDecl()->setNothrow(); 11142 } 11143 11144 OMPLoopDirective::HelperExprs B; 11145 // In presence of clause 'collapse' with number of loops, it will 11146 // define the nested loops number. 11147 unsigned NestedLoopCount = 11148 checkOpenMPLoop(OMPD_distribute_simd, getCollapseNumberExpr(Clauses), 11149 nullptr /*ordered not a clause on distribute*/, CS, *this, 11150 *DSAStack, VarsWithImplicitDSA, B); 11151 if (NestedLoopCount == 0) 11152 return StmtError(); 11153 11154 assert((CurContext->isDependentContext() || B.builtAll()) && 11155 "omp for loop exprs were not built"); 11156 11157 if (!CurContext->isDependentContext()) { 11158 // Finalize the clauses that need pre-built expressions for CodeGen. 11159 for (OMPClause *C : Clauses) { 11160 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 11161 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 11162 B.NumIterations, *this, CurScope, 11163 DSAStack)) 11164 return StmtError(); 11165 } 11166 } 11167 11168 if (checkSimdlenSafelenSpecified(*this, Clauses)) 11169 return StmtError(); 11170 11171 setFunctionHasBranchProtectedScope(); 11172 return OMPDistributeSimdDirective::Create(Context, StartLoc, EndLoc, 11173 NestedLoopCount, Clauses, AStmt, B); 11174 } 11175 11176 StmtResult Sema::ActOnOpenMPTargetParallelForSimdDirective( 11177 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 11178 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 11179 if (!AStmt) 11180 return StmtError(); 11181 11182 auto *CS = cast<CapturedStmt>(AStmt); 11183 // 1.2.2 OpenMP Language Terminology 11184 // Structured block - An executable statement with a single entry at the 11185 // top and a single exit at the bottom. 11186 // The point of exit cannot be a branch out of the structured block. 11187 // longjmp() and throw() must not violate the entry/exit criteria. 11188 CS->getCapturedDecl()->setNothrow(); 11189 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel_for); 11190 ThisCaptureLevel > 1; --ThisCaptureLevel) { 11191 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 11192 // 1.2.2 OpenMP Language Terminology 11193 // Structured block - An executable statement with a single entry at the 11194 // top and a single exit at the bottom. 11195 // The point of exit cannot be a branch out of the structured block. 11196 // longjmp() and throw() must not violate the entry/exit criteria. 11197 CS->getCapturedDecl()->setNothrow(); 11198 } 11199 11200 OMPLoopDirective::HelperExprs B; 11201 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 11202 // define the nested loops number. 11203 unsigned NestedLoopCount = checkOpenMPLoop( 11204 OMPD_target_parallel_for_simd, getCollapseNumberExpr(Clauses), 11205 getOrderedNumberExpr(Clauses), CS, *this, *DSAStack, 11206 VarsWithImplicitDSA, B); 11207 if (NestedLoopCount == 0) 11208 return StmtError(); 11209 11210 assert((CurContext->isDependentContext() || B.builtAll()) && 11211 "omp target parallel for simd loop exprs were not built"); 11212 11213 if (!CurContext->isDependentContext()) { 11214 // Finalize the clauses that need pre-built expressions for CodeGen. 11215 for (OMPClause *C : Clauses) { 11216 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 11217 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 11218 B.NumIterations, *this, CurScope, 11219 DSAStack)) 11220 return StmtError(); 11221 } 11222 } 11223 if (checkSimdlenSafelenSpecified(*this, Clauses)) 11224 return StmtError(); 11225 11226 setFunctionHasBranchProtectedScope(); 11227 return OMPTargetParallelForSimdDirective::Create( 11228 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 11229 } 11230 11231 StmtResult Sema::ActOnOpenMPTargetSimdDirective( 11232 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 11233 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 11234 if (!AStmt) 11235 return StmtError(); 11236 11237 auto *CS = cast<CapturedStmt>(AStmt); 11238 // 1.2.2 OpenMP Language Terminology 11239 // Structured block - An executable statement with a single entry at the 11240 // top and a single exit at the bottom. 11241 // The point of exit cannot be a branch out of the structured block. 11242 // longjmp() and throw() must not violate the entry/exit criteria. 11243 CS->getCapturedDecl()->setNothrow(); 11244 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_simd); 11245 ThisCaptureLevel > 1; --ThisCaptureLevel) { 11246 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 11247 // 1.2.2 OpenMP Language Terminology 11248 // Structured block - An executable statement with a single entry at the 11249 // top and a single exit at the bottom. 11250 // The point of exit cannot be a branch out of the structured block. 11251 // longjmp() and throw() must not violate the entry/exit criteria. 11252 CS->getCapturedDecl()->setNothrow(); 11253 } 11254 11255 OMPLoopDirective::HelperExprs B; 11256 // In presence of clause 'collapse' with number of loops, it will define the 11257 // nested loops number. 11258 unsigned NestedLoopCount = 11259 checkOpenMPLoop(OMPD_target_simd, getCollapseNumberExpr(Clauses), 11260 getOrderedNumberExpr(Clauses), CS, *this, *DSAStack, 11261 VarsWithImplicitDSA, B); 11262 if (NestedLoopCount == 0) 11263 return StmtError(); 11264 11265 assert((CurContext->isDependentContext() || B.builtAll()) && 11266 "omp target simd loop exprs were not built"); 11267 11268 if (!CurContext->isDependentContext()) { 11269 // Finalize the clauses that need pre-built expressions for CodeGen. 11270 for (OMPClause *C : Clauses) { 11271 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 11272 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 11273 B.NumIterations, *this, CurScope, 11274 DSAStack)) 11275 return StmtError(); 11276 } 11277 } 11278 11279 if (checkSimdlenSafelenSpecified(*this, Clauses)) 11280 return StmtError(); 11281 11282 setFunctionHasBranchProtectedScope(); 11283 return OMPTargetSimdDirective::Create(Context, StartLoc, EndLoc, 11284 NestedLoopCount, Clauses, AStmt, B); 11285 } 11286 11287 StmtResult Sema::ActOnOpenMPTeamsDistributeDirective( 11288 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 11289 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 11290 if (!AStmt) 11291 return StmtError(); 11292 11293 auto *CS = cast<CapturedStmt>(AStmt); 11294 // 1.2.2 OpenMP Language Terminology 11295 // Structured block - An executable statement with a single entry at the 11296 // top and a single exit at the bottom. 11297 // The point of exit cannot be a branch out of the structured block. 11298 // longjmp() and throw() must not violate the entry/exit criteria. 11299 CS->getCapturedDecl()->setNothrow(); 11300 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_teams_distribute); 11301 ThisCaptureLevel > 1; --ThisCaptureLevel) { 11302 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 11303 // 1.2.2 OpenMP Language Terminology 11304 // Structured block - An executable statement with a single entry at the 11305 // top and a single exit at the bottom. 11306 // The point of exit cannot be a branch out of the structured block. 11307 // longjmp() and throw() must not violate the entry/exit criteria. 11308 CS->getCapturedDecl()->setNothrow(); 11309 } 11310 11311 OMPLoopDirective::HelperExprs B; 11312 // In presence of clause 'collapse' with number of loops, it will 11313 // define the nested loops number. 11314 unsigned NestedLoopCount = 11315 checkOpenMPLoop(OMPD_teams_distribute, getCollapseNumberExpr(Clauses), 11316 nullptr /*ordered not a clause on distribute*/, CS, *this, 11317 *DSAStack, VarsWithImplicitDSA, B); 11318 if (NestedLoopCount == 0) 11319 return StmtError(); 11320 11321 assert((CurContext->isDependentContext() || B.builtAll()) && 11322 "omp teams distribute loop exprs were not built"); 11323 11324 setFunctionHasBranchProtectedScope(); 11325 11326 DSAStack->setParentTeamsRegionLoc(StartLoc); 11327 11328 return OMPTeamsDistributeDirective::Create( 11329 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 11330 } 11331 11332 StmtResult Sema::ActOnOpenMPTeamsDistributeSimdDirective( 11333 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 11334 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 11335 if (!AStmt) 11336 return StmtError(); 11337 11338 auto *CS = cast<CapturedStmt>(AStmt); 11339 // 1.2.2 OpenMP Language Terminology 11340 // Structured block - An executable statement with a single entry at the 11341 // top and a single exit at the bottom. 11342 // The point of exit cannot be a branch out of the structured block. 11343 // longjmp() and throw() must not violate the entry/exit criteria. 11344 CS->getCapturedDecl()->setNothrow(); 11345 for (int ThisCaptureLevel = 11346 getOpenMPCaptureLevels(OMPD_teams_distribute_simd); 11347 ThisCaptureLevel > 1; --ThisCaptureLevel) { 11348 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 11349 // 1.2.2 OpenMP Language Terminology 11350 // Structured block - An executable statement with a single entry at the 11351 // top and a single exit at the bottom. 11352 // The point of exit cannot be a branch out of the structured block. 11353 // longjmp() and throw() must not violate the entry/exit criteria. 11354 CS->getCapturedDecl()->setNothrow(); 11355 } 11356 11357 OMPLoopDirective::HelperExprs B; 11358 // In presence of clause 'collapse' with number of loops, it will 11359 // define the nested loops number. 11360 unsigned NestedLoopCount = checkOpenMPLoop( 11361 OMPD_teams_distribute_simd, getCollapseNumberExpr(Clauses), 11362 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 11363 VarsWithImplicitDSA, B); 11364 11365 if (NestedLoopCount == 0) 11366 return StmtError(); 11367 11368 assert((CurContext->isDependentContext() || B.builtAll()) && 11369 "omp teams distribute simd loop exprs were not built"); 11370 11371 if (!CurContext->isDependentContext()) { 11372 // Finalize the clauses that need pre-built expressions for CodeGen. 11373 for (OMPClause *C : Clauses) { 11374 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 11375 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 11376 B.NumIterations, *this, CurScope, 11377 DSAStack)) 11378 return StmtError(); 11379 } 11380 } 11381 11382 if (checkSimdlenSafelenSpecified(*this, Clauses)) 11383 return StmtError(); 11384 11385 setFunctionHasBranchProtectedScope(); 11386 11387 DSAStack->setParentTeamsRegionLoc(StartLoc); 11388 11389 return OMPTeamsDistributeSimdDirective::Create( 11390 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 11391 } 11392 11393 StmtResult Sema::ActOnOpenMPTeamsDistributeParallelForSimdDirective( 11394 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 11395 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 11396 if (!AStmt) 11397 return StmtError(); 11398 11399 auto *CS = cast<CapturedStmt>(AStmt); 11400 // 1.2.2 OpenMP Language Terminology 11401 // Structured block - An executable statement with a single entry at the 11402 // top and a single exit at the bottom. 11403 // The point of exit cannot be a branch out of the structured block. 11404 // longjmp() and throw() must not violate the entry/exit criteria. 11405 CS->getCapturedDecl()->setNothrow(); 11406 11407 for (int ThisCaptureLevel = 11408 getOpenMPCaptureLevels(OMPD_teams_distribute_parallel_for_simd); 11409 ThisCaptureLevel > 1; --ThisCaptureLevel) { 11410 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 11411 // 1.2.2 OpenMP Language Terminology 11412 // Structured block - An executable statement with a single entry at the 11413 // top and a single exit at the bottom. 11414 // The point of exit cannot be a branch out of the structured block. 11415 // longjmp() and throw() must not violate the entry/exit criteria. 11416 CS->getCapturedDecl()->setNothrow(); 11417 } 11418 11419 OMPLoopDirective::HelperExprs B; 11420 // In presence of clause 'collapse' with number of loops, it will 11421 // define the nested loops number. 11422 unsigned NestedLoopCount = checkOpenMPLoop( 11423 OMPD_teams_distribute_parallel_for_simd, getCollapseNumberExpr(Clauses), 11424 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 11425 VarsWithImplicitDSA, B); 11426 11427 if (NestedLoopCount == 0) 11428 return StmtError(); 11429 11430 assert((CurContext->isDependentContext() || B.builtAll()) && 11431 "omp for loop exprs were not built"); 11432 11433 if (!CurContext->isDependentContext()) { 11434 // Finalize the clauses that need pre-built expressions for CodeGen. 11435 for (OMPClause *C : Clauses) { 11436 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 11437 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 11438 B.NumIterations, *this, CurScope, 11439 DSAStack)) 11440 return StmtError(); 11441 } 11442 } 11443 11444 if (checkSimdlenSafelenSpecified(*this, Clauses)) 11445 return StmtError(); 11446 11447 setFunctionHasBranchProtectedScope(); 11448 11449 DSAStack->setParentTeamsRegionLoc(StartLoc); 11450 11451 return OMPTeamsDistributeParallelForSimdDirective::Create( 11452 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 11453 } 11454 11455 StmtResult Sema::ActOnOpenMPTeamsDistributeParallelForDirective( 11456 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 11457 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 11458 if (!AStmt) 11459 return StmtError(); 11460 11461 auto *CS = cast<CapturedStmt>(AStmt); 11462 // 1.2.2 OpenMP Language Terminology 11463 // Structured block - An executable statement with a single entry at the 11464 // top and a single exit at the bottom. 11465 // The point of exit cannot be a branch out of the structured block. 11466 // longjmp() and throw() must not violate the entry/exit criteria. 11467 CS->getCapturedDecl()->setNothrow(); 11468 11469 for (int ThisCaptureLevel = 11470 getOpenMPCaptureLevels(OMPD_teams_distribute_parallel_for); 11471 ThisCaptureLevel > 1; --ThisCaptureLevel) { 11472 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 11473 // 1.2.2 OpenMP Language Terminology 11474 // Structured block - An executable statement with a single entry at the 11475 // top and a single exit at the bottom. 11476 // The point of exit cannot be a branch out of the structured block. 11477 // longjmp() and throw() must not violate the entry/exit criteria. 11478 CS->getCapturedDecl()->setNothrow(); 11479 } 11480 11481 OMPLoopDirective::HelperExprs B; 11482 // In presence of clause 'collapse' with number of loops, it will 11483 // define the nested loops number. 11484 unsigned NestedLoopCount = checkOpenMPLoop( 11485 OMPD_teams_distribute_parallel_for, getCollapseNumberExpr(Clauses), 11486 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 11487 VarsWithImplicitDSA, B); 11488 11489 if (NestedLoopCount == 0) 11490 return StmtError(); 11491 11492 assert((CurContext->isDependentContext() || B.builtAll()) && 11493 "omp for loop exprs were not built"); 11494 11495 setFunctionHasBranchProtectedScope(); 11496 11497 DSAStack->setParentTeamsRegionLoc(StartLoc); 11498 11499 return OMPTeamsDistributeParallelForDirective::Create( 11500 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B, 11501 DSAStack->getTaskgroupReductionRef(), DSAStack->isCancelRegion()); 11502 } 11503 11504 StmtResult Sema::ActOnOpenMPTargetTeamsDirective(ArrayRef<OMPClause *> Clauses, 11505 Stmt *AStmt, 11506 SourceLocation StartLoc, 11507 SourceLocation EndLoc) { 11508 if (!AStmt) 11509 return StmtError(); 11510 11511 auto *CS = cast<CapturedStmt>(AStmt); 11512 // 1.2.2 OpenMP Language Terminology 11513 // Structured block - An executable statement with a single entry at the 11514 // top and a single exit at the bottom. 11515 // The point of exit cannot be a branch out of the structured block. 11516 // longjmp() and throw() must not violate the entry/exit criteria. 11517 CS->getCapturedDecl()->setNothrow(); 11518 11519 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_teams); 11520 ThisCaptureLevel > 1; --ThisCaptureLevel) { 11521 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 11522 // 1.2.2 OpenMP Language Terminology 11523 // Structured block - An executable statement with a single entry at the 11524 // top and a single exit at the bottom. 11525 // The point of exit cannot be a branch out of the structured block. 11526 // longjmp() and throw() must not violate the entry/exit criteria. 11527 CS->getCapturedDecl()->setNothrow(); 11528 } 11529 setFunctionHasBranchProtectedScope(); 11530 11531 return OMPTargetTeamsDirective::Create(Context, StartLoc, EndLoc, Clauses, 11532 AStmt); 11533 } 11534 11535 StmtResult Sema::ActOnOpenMPTargetTeamsDistributeDirective( 11536 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 11537 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 11538 if (!AStmt) 11539 return StmtError(); 11540 11541 auto *CS = cast<CapturedStmt>(AStmt); 11542 // 1.2.2 OpenMP Language Terminology 11543 // Structured block - An executable statement with a single entry at the 11544 // top and a single exit at the bottom. 11545 // The point of exit cannot be a branch out of the structured block. 11546 // longjmp() and throw() must not violate the entry/exit criteria. 11547 CS->getCapturedDecl()->setNothrow(); 11548 for (int ThisCaptureLevel = 11549 getOpenMPCaptureLevels(OMPD_target_teams_distribute); 11550 ThisCaptureLevel > 1; --ThisCaptureLevel) { 11551 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 11552 // 1.2.2 OpenMP Language Terminology 11553 // Structured block - An executable statement with a single entry at the 11554 // top and a single exit at the bottom. 11555 // The point of exit cannot be a branch out of the structured block. 11556 // longjmp() and throw() must not violate the entry/exit criteria. 11557 CS->getCapturedDecl()->setNothrow(); 11558 } 11559 11560 OMPLoopDirective::HelperExprs B; 11561 // In presence of clause 'collapse' with number of loops, it will 11562 // define the nested loops number. 11563 unsigned NestedLoopCount = checkOpenMPLoop( 11564 OMPD_target_teams_distribute, getCollapseNumberExpr(Clauses), 11565 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 11566 VarsWithImplicitDSA, B); 11567 if (NestedLoopCount == 0) 11568 return StmtError(); 11569 11570 assert((CurContext->isDependentContext() || B.builtAll()) && 11571 "omp target teams distribute loop exprs were not built"); 11572 11573 setFunctionHasBranchProtectedScope(); 11574 return OMPTargetTeamsDistributeDirective::Create( 11575 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 11576 } 11577 11578 StmtResult Sema::ActOnOpenMPTargetTeamsDistributeParallelForDirective( 11579 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 11580 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 11581 if (!AStmt) 11582 return StmtError(); 11583 11584 auto *CS = cast<CapturedStmt>(AStmt); 11585 // 1.2.2 OpenMP Language Terminology 11586 // Structured block - An executable statement with a single entry at the 11587 // top and a single exit at the bottom. 11588 // The point of exit cannot be a branch out of the structured block. 11589 // longjmp() and throw() must not violate the entry/exit criteria. 11590 CS->getCapturedDecl()->setNothrow(); 11591 for (int ThisCaptureLevel = 11592 getOpenMPCaptureLevels(OMPD_target_teams_distribute_parallel_for); 11593 ThisCaptureLevel > 1; --ThisCaptureLevel) { 11594 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 11595 // 1.2.2 OpenMP Language Terminology 11596 // Structured block - An executable statement with a single entry at the 11597 // top and a single exit at the bottom. 11598 // The point of exit cannot be a branch out of the structured block. 11599 // longjmp() and throw() must not violate the entry/exit criteria. 11600 CS->getCapturedDecl()->setNothrow(); 11601 } 11602 11603 OMPLoopDirective::HelperExprs B; 11604 // In presence of clause 'collapse' with number of loops, it will 11605 // define the nested loops number. 11606 unsigned NestedLoopCount = checkOpenMPLoop( 11607 OMPD_target_teams_distribute_parallel_for, getCollapseNumberExpr(Clauses), 11608 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 11609 VarsWithImplicitDSA, B); 11610 if (NestedLoopCount == 0) 11611 return StmtError(); 11612 11613 assert((CurContext->isDependentContext() || B.builtAll()) && 11614 "omp target teams distribute parallel for loop exprs were not built"); 11615 11616 if (!CurContext->isDependentContext()) { 11617 // Finalize the clauses that need pre-built expressions for CodeGen. 11618 for (OMPClause *C : Clauses) { 11619 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 11620 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 11621 B.NumIterations, *this, CurScope, 11622 DSAStack)) 11623 return StmtError(); 11624 } 11625 } 11626 11627 setFunctionHasBranchProtectedScope(); 11628 return OMPTargetTeamsDistributeParallelForDirective::Create( 11629 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B, 11630 DSAStack->getTaskgroupReductionRef(), DSAStack->isCancelRegion()); 11631 } 11632 11633 StmtResult Sema::ActOnOpenMPTargetTeamsDistributeParallelForSimdDirective( 11634 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 11635 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 11636 if (!AStmt) 11637 return StmtError(); 11638 11639 auto *CS = cast<CapturedStmt>(AStmt); 11640 // 1.2.2 OpenMP Language Terminology 11641 // Structured block - An executable statement with a single entry at the 11642 // top and a single exit at the bottom. 11643 // The point of exit cannot be a branch out of the structured block. 11644 // longjmp() and throw() must not violate the entry/exit criteria. 11645 CS->getCapturedDecl()->setNothrow(); 11646 for (int ThisCaptureLevel = getOpenMPCaptureLevels( 11647 OMPD_target_teams_distribute_parallel_for_simd); 11648 ThisCaptureLevel > 1; --ThisCaptureLevel) { 11649 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 11650 // 1.2.2 OpenMP Language Terminology 11651 // Structured block - An executable statement with a single entry at the 11652 // top and a single exit at the bottom. 11653 // The point of exit cannot be a branch out of the structured block. 11654 // longjmp() and throw() must not violate the entry/exit criteria. 11655 CS->getCapturedDecl()->setNothrow(); 11656 } 11657 11658 OMPLoopDirective::HelperExprs B; 11659 // In presence of clause 'collapse' with number of loops, it will 11660 // define the nested loops number. 11661 unsigned NestedLoopCount = 11662 checkOpenMPLoop(OMPD_target_teams_distribute_parallel_for_simd, 11663 getCollapseNumberExpr(Clauses), 11664 nullptr /*ordered not a clause on distribute*/, CS, *this, 11665 *DSAStack, VarsWithImplicitDSA, B); 11666 if (NestedLoopCount == 0) 11667 return StmtError(); 11668 11669 assert((CurContext->isDependentContext() || B.builtAll()) && 11670 "omp target teams distribute parallel for simd loop exprs were not " 11671 "built"); 11672 11673 if (!CurContext->isDependentContext()) { 11674 // Finalize the clauses that need pre-built expressions for CodeGen. 11675 for (OMPClause *C : Clauses) { 11676 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 11677 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 11678 B.NumIterations, *this, CurScope, 11679 DSAStack)) 11680 return StmtError(); 11681 } 11682 } 11683 11684 if (checkSimdlenSafelenSpecified(*this, Clauses)) 11685 return StmtError(); 11686 11687 setFunctionHasBranchProtectedScope(); 11688 return OMPTargetTeamsDistributeParallelForSimdDirective::Create( 11689 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 11690 } 11691 11692 StmtResult Sema::ActOnOpenMPTargetTeamsDistributeSimdDirective( 11693 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 11694 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 11695 if (!AStmt) 11696 return StmtError(); 11697 11698 auto *CS = cast<CapturedStmt>(AStmt); 11699 // 1.2.2 OpenMP Language Terminology 11700 // Structured block - An executable statement with a single entry at the 11701 // top and a single exit at the bottom. 11702 // The point of exit cannot be a branch out of the structured block. 11703 // longjmp() and throw() must not violate the entry/exit criteria. 11704 CS->getCapturedDecl()->setNothrow(); 11705 for (int ThisCaptureLevel = 11706 getOpenMPCaptureLevels(OMPD_target_teams_distribute_simd); 11707 ThisCaptureLevel > 1; --ThisCaptureLevel) { 11708 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 11709 // 1.2.2 OpenMP Language Terminology 11710 // Structured block - An executable statement with a single entry at the 11711 // top and a single exit at the bottom. 11712 // The point of exit cannot be a branch out of the structured block. 11713 // longjmp() and throw() must not violate the entry/exit criteria. 11714 CS->getCapturedDecl()->setNothrow(); 11715 } 11716 11717 OMPLoopDirective::HelperExprs B; 11718 // In presence of clause 'collapse' with number of loops, it will 11719 // define the nested loops number. 11720 unsigned NestedLoopCount = checkOpenMPLoop( 11721 OMPD_target_teams_distribute_simd, getCollapseNumberExpr(Clauses), 11722 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 11723 VarsWithImplicitDSA, B); 11724 if (NestedLoopCount == 0) 11725 return StmtError(); 11726 11727 assert((CurContext->isDependentContext() || B.builtAll()) && 11728 "omp target teams distribute simd loop exprs were not built"); 11729 11730 if (!CurContext->isDependentContext()) { 11731 // Finalize the clauses that need pre-built expressions for CodeGen. 11732 for (OMPClause *C : Clauses) { 11733 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 11734 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 11735 B.NumIterations, *this, CurScope, 11736 DSAStack)) 11737 return StmtError(); 11738 } 11739 } 11740 11741 if (checkSimdlenSafelenSpecified(*this, Clauses)) 11742 return StmtError(); 11743 11744 setFunctionHasBranchProtectedScope(); 11745 return OMPTargetTeamsDistributeSimdDirective::Create( 11746 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 11747 } 11748 11749 OMPClause *Sema::ActOnOpenMPSingleExprClause(OpenMPClauseKind Kind, Expr *Expr, 11750 SourceLocation StartLoc, 11751 SourceLocation LParenLoc, 11752 SourceLocation EndLoc) { 11753 OMPClause *Res = nullptr; 11754 switch (Kind) { 11755 case OMPC_final: 11756 Res = ActOnOpenMPFinalClause(Expr, StartLoc, LParenLoc, EndLoc); 11757 break; 11758 case OMPC_num_threads: 11759 Res = ActOnOpenMPNumThreadsClause(Expr, StartLoc, LParenLoc, EndLoc); 11760 break; 11761 case OMPC_safelen: 11762 Res = ActOnOpenMPSafelenClause(Expr, StartLoc, LParenLoc, EndLoc); 11763 break; 11764 case OMPC_simdlen: 11765 Res = ActOnOpenMPSimdlenClause(Expr, StartLoc, LParenLoc, EndLoc); 11766 break; 11767 case OMPC_allocator: 11768 Res = ActOnOpenMPAllocatorClause(Expr, StartLoc, LParenLoc, EndLoc); 11769 break; 11770 case OMPC_collapse: 11771 Res = ActOnOpenMPCollapseClause(Expr, StartLoc, LParenLoc, EndLoc); 11772 break; 11773 case OMPC_ordered: 11774 Res = ActOnOpenMPOrderedClause(StartLoc, EndLoc, LParenLoc, Expr); 11775 break; 11776 case OMPC_num_teams: 11777 Res = ActOnOpenMPNumTeamsClause(Expr, StartLoc, LParenLoc, EndLoc); 11778 break; 11779 case OMPC_thread_limit: 11780 Res = ActOnOpenMPThreadLimitClause(Expr, StartLoc, LParenLoc, EndLoc); 11781 break; 11782 case OMPC_priority: 11783 Res = ActOnOpenMPPriorityClause(Expr, StartLoc, LParenLoc, EndLoc); 11784 break; 11785 case OMPC_grainsize: 11786 Res = ActOnOpenMPGrainsizeClause(Expr, StartLoc, LParenLoc, EndLoc); 11787 break; 11788 case OMPC_num_tasks: 11789 Res = ActOnOpenMPNumTasksClause(Expr, StartLoc, LParenLoc, EndLoc); 11790 break; 11791 case OMPC_hint: 11792 Res = ActOnOpenMPHintClause(Expr, StartLoc, LParenLoc, EndLoc); 11793 break; 11794 case OMPC_depobj: 11795 Res = ActOnOpenMPDepobjClause(Expr, StartLoc, LParenLoc, EndLoc); 11796 break; 11797 case OMPC_detach: 11798 Res = ActOnOpenMPDetachClause(Expr, StartLoc, LParenLoc, EndLoc); 11799 break; 11800 case OMPC_device: 11801 case OMPC_if: 11802 case OMPC_default: 11803 case OMPC_proc_bind: 11804 case OMPC_schedule: 11805 case OMPC_private: 11806 case OMPC_firstprivate: 11807 case OMPC_lastprivate: 11808 case OMPC_shared: 11809 case OMPC_reduction: 11810 case OMPC_task_reduction: 11811 case OMPC_in_reduction: 11812 case OMPC_linear: 11813 case OMPC_aligned: 11814 case OMPC_copyin: 11815 case OMPC_copyprivate: 11816 case OMPC_nowait: 11817 case OMPC_untied: 11818 case OMPC_mergeable: 11819 case OMPC_threadprivate: 11820 case OMPC_allocate: 11821 case OMPC_flush: 11822 case OMPC_read: 11823 case OMPC_write: 11824 case OMPC_update: 11825 case OMPC_capture: 11826 case OMPC_seq_cst: 11827 case OMPC_acq_rel: 11828 case OMPC_acquire: 11829 case OMPC_release: 11830 case OMPC_relaxed: 11831 case OMPC_depend: 11832 case OMPC_threads: 11833 case OMPC_simd: 11834 case OMPC_map: 11835 case OMPC_nogroup: 11836 case OMPC_dist_schedule: 11837 case OMPC_defaultmap: 11838 case OMPC_unknown: 11839 case OMPC_uniform: 11840 case OMPC_to: 11841 case OMPC_from: 11842 case OMPC_use_device_ptr: 11843 case OMPC_use_device_addr: 11844 case OMPC_is_device_ptr: 11845 case OMPC_unified_address: 11846 case OMPC_unified_shared_memory: 11847 case OMPC_reverse_offload: 11848 case OMPC_dynamic_allocators: 11849 case OMPC_atomic_default_mem_order: 11850 case OMPC_device_type: 11851 case OMPC_match: 11852 case OMPC_nontemporal: 11853 case OMPC_order: 11854 case OMPC_destroy: 11855 case OMPC_inclusive: 11856 case OMPC_exclusive: 11857 case OMPC_uses_allocators: 11858 case OMPC_affinity: 11859 default: 11860 llvm_unreachable("Clause is not allowed."); 11861 } 11862 return Res; 11863 } 11864 11865 // An OpenMP directive such as 'target parallel' has two captured regions: 11866 // for the 'target' and 'parallel' respectively. This function returns 11867 // the region in which to capture expressions associated with a clause. 11868 // A return value of OMPD_unknown signifies that the expression should not 11869 // be captured. 11870 static OpenMPDirectiveKind getOpenMPCaptureRegionForClause( 11871 OpenMPDirectiveKind DKind, OpenMPClauseKind CKind, unsigned OpenMPVersion, 11872 OpenMPDirectiveKind NameModifier = OMPD_unknown) { 11873 OpenMPDirectiveKind CaptureRegion = OMPD_unknown; 11874 switch (CKind) { 11875 case OMPC_if: 11876 switch (DKind) { 11877 case OMPD_target_parallel_for_simd: 11878 if (OpenMPVersion >= 50 && 11879 (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)) { 11880 CaptureRegion = OMPD_parallel; 11881 break; 11882 } 11883 LLVM_FALLTHROUGH; 11884 case OMPD_target_parallel: 11885 case OMPD_target_parallel_for: 11886 // If this clause applies to the nested 'parallel' region, capture within 11887 // the 'target' region, otherwise do not capture. 11888 if (NameModifier == OMPD_unknown || NameModifier == OMPD_parallel) 11889 CaptureRegion = OMPD_target; 11890 break; 11891 case OMPD_target_teams_distribute_parallel_for_simd: 11892 if (OpenMPVersion >= 50 && 11893 (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)) { 11894 CaptureRegion = OMPD_parallel; 11895 break; 11896 } 11897 LLVM_FALLTHROUGH; 11898 case OMPD_target_teams_distribute_parallel_for: 11899 // If this clause applies to the nested 'parallel' region, capture within 11900 // the 'teams' region, otherwise do not capture. 11901 if (NameModifier == OMPD_unknown || NameModifier == OMPD_parallel) 11902 CaptureRegion = OMPD_teams; 11903 break; 11904 case OMPD_teams_distribute_parallel_for_simd: 11905 if (OpenMPVersion >= 50 && 11906 (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)) { 11907 CaptureRegion = OMPD_parallel; 11908 break; 11909 } 11910 LLVM_FALLTHROUGH; 11911 case OMPD_teams_distribute_parallel_for: 11912 CaptureRegion = OMPD_teams; 11913 break; 11914 case OMPD_target_update: 11915 case OMPD_target_enter_data: 11916 case OMPD_target_exit_data: 11917 CaptureRegion = OMPD_task; 11918 break; 11919 case OMPD_parallel_master_taskloop: 11920 if (NameModifier == OMPD_unknown || NameModifier == OMPD_taskloop) 11921 CaptureRegion = OMPD_parallel; 11922 break; 11923 case OMPD_parallel_master_taskloop_simd: 11924 if ((OpenMPVersion <= 45 && NameModifier == OMPD_unknown) || 11925 NameModifier == OMPD_taskloop) { 11926 CaptureRegion = OMPD_parallel; 11927 break; 11928 } 11929 if (OpenMPVersion <= 45) 11930 break; 11931 if (NameModifier == OMPD_unknown || NameModifier == OMPD_simd) 11932 CaptureRegion = OMPD_taskloop; 11933 break; 11934 case OMPD_parallel_for_simd: 11935 if (OpenMPVersion <= 45) 11936 break; 11937 if (NameModifier == OMPD_unknown || NameModifier == OMPD_simd) 11938 CaptureRegion = OMPD_parallel; 11939 break; 11940 case OMPD_taskloop_simd: 11941 case OMPD_master_taskloop_simd: 11942 if (OpenMPVersion <= 45) 11943 break; 11944 if (NameModifier == OMPD_unknown || NameModifier == OMPD_simd) 11945 CaptureRegion = OMPD_taskloop; 11946 break; 11947 case OMPD_distribute_parallel_for_simd: 11948 if (OpenMPVersion <= 45) 11949 break; 11950 if (NameModifier == OMPD_unknown || NameModifier == OMPD_simd) 11951 CaptureRegion = OMPD_parallel; 11952 break; 11953 case OMPD_target_simd: 11954 if (OpenMPVersion >= 50 && 11955 (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)) 11956 CaptureRegion = OMPD_target; 11957 break; 11958 case OMPD_teams_distribute_simd: 11959 case OMPD_target_teams_distribute_simd: 11960 if (OpenMPVersion >= 50 && 11961 (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)) 11962 CaptureRegion = OMPD_teams; 11963 break; 11964 case OMPD_cancel: 11965 case OMPD_parallel: 11966 case OMPD_parallel_master: 11967 case OMPD_parallel_sections: 11968 case OMPD_parallel_for: 11969 case OMPD_target: 11970 case OMPD_target_teams: 11971 case OMPD_target_teams_distribute: 11972 case OMPD_distribute_parallel_for: 11973 case OMPD_task: 11974 case OMPD_taskloop: 11975 case OMPD_master_taskloop: 11976 case OMPD_target_data: 11977 case OMPD_simd: 11978 case OMPD_for_simd: 11979 case OMPD_distribute_simd: 11980 // Do not capture if-clause expressions. 11981 break; 11982 case OMPD_threadprivate: 11983 case OMPD_allocate: 11984 case OMPD_taskyield: 11985 case OMPD_barrier: 11986 case OMPD_taskwait: 11987 case OMPD_cancellation_point: 11988 case OMPD_flush: 11989 case OMPD_depobj: 11990 case OMPD_scan: 11991 case OMPD_declare_reduction: 11992 case OMPD_declare_mapper: 11993 case OMPD_declare_simd: 11994 case OMPD_declare_variant: 11995 case OMPD_begin_declare_variant: 11996 case OMPD_end_declare_variant: 11997 case OMPD_declare_target: 11998 case OMPD_end_declare_target: 11999 case OMPD_teams: 12000 case OMPD_for: 12001 case OMPD_sections: 12002 case OMPD_section: 12003 case OMPD_single: 12004 case OMPD_master: 12005 case OMPD_critical: 12006 case OMPD_taskgroup: 12007 case OMPD_distribute: 12008 case OMPD_ordered: 12009 case OMPD_atomic: 12010 case OMPD_teams_distribute: 12011 case OMPD_requires: 12012 llvm_unreachable("Unexpected OpenMP directive with if-clause"); 12013 case OMPD_unknown: 12014 default: 12015 llvm_unreachable("Unknown OpenMP directive"); 12016 } 12017 break; 12018 case OMPC_num_threads: 12019 switch (DKind) { 12020 case OMPD_target_parallel: 12021 case OMPD_target_parallel_for: 12022 case OMPD_target_parallel_for_simd: 12023 CaptureRegion = OMPD_target; 12024 break; 12025 case OMPD_teams_distribute_parallel_for: 12026 case OMPD_teams_distribute_parallel_for_simd: 12027 case OMPD_target_teams_distribute_parallel_for: 12028 case OMPD_target_teams_distribute_parallel_for_simd: 12029 CaptureRegion = OMPD_teams; 12030 break; 12031 case OMPD_parallel: 12032 case OMPD_parallel_master: 12033 case OMPD_parallel_sections: 12034 case OMPD_parallel_for: 12035 case OMPD_parallel_for_simd: 12036 case OMPD_distribute_parallel_for: 12037 case OMPD_distribute_parallel_for_simd: 12038 case OMPD_parallel_master_taskloop: 12039 case OMPD_parallel_master_taskloop_simd: 12040 // Do not capture num_threads-clause expressions. 12041 break; 12042 case OMPD_target_data: 12043 case OMPD_target_enter_data: 12044 case OMPD_target_exit_data: 12045 case OMPD_target_update: 12046 case OMPD_target: 12047 case OMPD_target_simd: 12048 case OMPD_target_teams: 12049 case OMPD_target_teams_distribute: 12050 case OMPD_target_teams_distribute_simd: 12051 case OMPD_cancel: 12052 case OMPD_task: 12053 case OMPD_taskloop: 12054 case OMPD_taskloop_simd: 12055 case OMPD_master_taskloop: 12056 case OMPD_master_taskloop_simd: 12057 case OMPD_threadprivate: 12058 case OMPD_allocate: 12059 case OMPD_taskyield: 12060 case OMPD_barrier: 12061 case OMPD_taskwait: 12062 case OMPD_cancellation_point: 12063 case OMPD_flush: 12064 case OMPD_depobj: 12065 case OMPD_scan: 12066 case OMPD_declare_reduction: 12067 case OMPD_declare_mapper: 12068 case OMPD_declare_simd: 12069 case OMPD_declare_variant: 12070 case OMPD_begin_declare_variant: 12071 case OMPD_end_declare_variant: 12072 case OMPD_declare_target: 12073 case OMPD_end_declare_target: 12074 case OMPD_teams: 12075 case OMPD_simd: 12076 case OMPD_for: 12077 case OMPD_for_simd: 12078 case OMPD_sections: 12079 case OMPD_section: 12080 case OMPD_single: 12081 case OMPD_master: 12082 case OMPD_critical: 12083 case OMPD_taskgroup: 12084 case OMPD_distribute: 12085 case OMPD_ordered: 12086 case OMPD_atomic: 12087 case OMPD_distribute_simd: 12088 case OMPD_teams_distribute: 12089 case OMPD_teams_distribute_simd: 12090 case OMPD_requires: 12091 llvm_unreachable("Unexpected OpenMP directive with num_threads-clause"); 12092 case OMPD_unknown: 12093 default: 12094 llvm_unreachable("Unknown OpenMP directive"); 12095 } 12096 break; 12097 case OMPC_num_teams: 12098 switch (DKind) { 12099 case OMPD_target_teams: 12100 case OMPD_target_teams_distribute: 12101 case OMPD_target_teams_distribute_simd: 12102 case OMPD_target_teams_distribute_parallel_for: 12103 case OMPD_target_teams_distribute_parallel_for_simd: 12104 CaptureRegion = OMPD_target; 12105 break; 12106 case OMPD_teams_distribute_parallel_for: 12107 case OMPD_teams_distribute_parallel_for_simd: 12108 case OMPD_teams: 12109 case OMPD_teams_distribute: 12110 case OMPD_teams_distribute_simd: 12111 // Do not capture num_teams-clause expressions. 12112 break; 12113 case OMPD_distribute_parallel_for: 12114 case OMPD_distribute_parallel_for_simd: 12115 case OMPD_task: 12116 case OMPD_taskloop: 12117 case OMPD_taskloop_simd: 12118 case OMPD_master_taskloop: 12119 case OMPD_master_taskloop_simd: 12120 case OMPD_parallel_master_taskloop: 12121 case OMPD_parallel_master_taskloop_simd: 12122 case OMPD_target_data: 12123 case OMPD_target_enter_data: 12124 case OMPD_target_exit_data: 12125 case OMPD_target_update: 12126 case OMPD_cancel: 12127 case OMPD_parallel: 12128 case OMPD_parallel_master: 12129 case OMPD_parallel_sections: 12130 case OMPD_parallel_for: 12131 case OMPD_parallel_for_simd: 12132 case OMPD_target: 12133 case OMPD_target_simd: 12134 case OMPD_target_parallel: 12135 case OMPD_target_parallel_for: 12136 case OMPD_target_parallel_for_simd: 12137 case OMPD_threadprivate: 12138 case OMPD_allocate: 12139 case OMPD_taskyield: 12140 case OMPD_barrier: 12141 case OMPD_taskwait: 12142 case OMPD_cancellation_point: 12143 case OMPD_flush: 12144 case OMPD_depobj: 12145 case OMPD_scan: 12146 case OMPD_declare_reduction: 12147 case OMPD_declare_mapper: 12148 case OMPD_declare_simd: 12149 case OMPD_declare_variant: 12150 case OMPD_begin_declare_variant: 12151 case OMPD_end_declare_variant: 12152 case OMPD_declare_target: 12153 case OMPD_end_declare_target: 12154 case OMPD_simd: 12155 case OMPD_for: 12156 case OMPD_for_simd: 12157 case OMPD_sections: 12158 case OMPD_section: 12159 case OMPD_single: 12160 case OMPD_master: 12161 case OMPD_critical: 12162 case OMPD_taskgroup: 12163 case OMPD_distribute: 12164 case OMPD_ordered: 12165 case OMPD_atomic: 12166 case OMPD_distribute_simd: 12167 case OMPD_requires: 12168 llvm_unreachable("Unexpected OpenMP directive with num_teams-clause"); 12169 case OMPD_unknown: 12170 default: 12171 llvm_unreachable("Unknown OpenMP directive"); 12172 } 12173 break; 12174 case OMPC_thread_limit: 12175 switch (DKind) { 12176 case OMPD_target_teams: 12177 case OMPD_target_teams_distribute: 12178 case OMPD_target_teams_distribute_simd: 12179 case OMPD_target_teams_distribute_parallel_for: 12180 case OMPD_target_teams_distribute_parallel_for_simd: 12181 CaptureRegion = OMPD_target; 12182 break; 12183 case OMPD_teams_distribute_parallel_for: 12184 case OMPD_teams_distribute_parallel_for_simd: 12185 case OMPD_teams: 12186 case OMPD_teams_distribute: 12187 case OMPD_teams_distribute_simd: 12188 // Do not capture thread_limit-clause expressions. 12189 break; 12190 case OMPD_distribute_parallel_for: 12191 case OMPD_distribute_parallel_for_simd: 12192 case OMPD_task: 12193 case OMPD_taskloop: 12194 case OMPD_taskloop_simd: 12195 case OMPD_master_taskloop: 12196 case OMPD_master_taskloop_simd: 12197 case OMPD_parallel_master_taskloop: 12198 case OMPD_parallel_master_taskloop_simd: 12199 case OMPD_target_data: 12200 case OMPD_target_enter_data: 12201 case OMPD_target_exit_data: 12202 case OMPD_target_update: 12203 case OMPD_cancel: 12204 case OMPD_parallel: 12205 case OMPD_parallel_master: 12206 case OMPD_parallel_sections: 12207 case OMPD_parallel_for: 12208 case OMPD_parallel_for_simd: 12209 case OMPD_target: 12210 case OMPD_target_simd: 12211 case OMPD_target_parallel: 12212 case OMPD_target_parallel_for: 12213 case OMPD_target_parallel_for_simd: 12214 case OMPD_threadprivate: 12215 case OMPD_allocate: 12216 case OMPD_taskyield: 12217 case OMPD_barrier: 12218 case OMPD_taskwait: 12219 case OMPD_cancellation_point: 12220 case OMPD_flush: 12221 case OMPD_depobj: 12222 case OMPD_scan: 12223 case OMPD_declare_reduction: 12224 case OMPD_declare_mapper: 12225 case OMPD_declare_simd: 12226 case OMPD_declare_variant: 12227 case OMPD_begin_declare_variant: 12228 case OMPD_end_declare_variant: 12229 case OMPD_declare_target: 12230 case OMPD_end_declare_target: 12231 case OMPD_simd: 12232 case OMPD_for: 12233 case OMPD_for_simd: 12234 case OMPD_sections: 12235 case OMPD_section: 12236 case OMPD_single: 12237 case OMPD_master: 12238 case OMPD_critical: 12239 case OMPD_taskgroup: 12240 case OMPD_distribute: 12241 case OMPD_ordered: 12242 case OMPD_atomic: 12243 case OMPD_distribute_simd: 12244 case OMPD_requires: 12245 llvm_unreachable("Unexpected OpenMP directive with thread_limit-clause"); 12246 case OMPD_unknown: 12247 default: 12248 llvm_unreachable("Unknown OpenMP directive"); 12249 } 12250 break; 12251 case OMPC_schedule: 12252 switch (DKind) { 12253 case OMPD_parallel_for: 12254 case OMPD_parallel_for_simd: 12255 case OMPD_distribute_parallel_for: 12256 case OMPD_distribute_parallel_for_simd: 12257 case OMPD_teams_distribute_parallel_for: 12258 case OMPD_teams_distribute_parallel_for_simd: 12259 case OMPD_target_parallel_for: 12260 case OMPD_target_parallel_for_simd: 12261 case OMPD_target_teams_distribute_parallel_for: 12262 case OMPD_target_teams_distribute_parallel_for_simd: 12263 CaptureRegion = OMPD_parallel; 12264 break; 12265 case OMPD_for: 12266 case OMPD_for_simd: 12267 // Do not capture schedule-clause expressions. 12268 break; 12269 case OMPD_task: 12270 case OMPD_taskloop: 12271 case OMPD_taskloop_simd: 12272 case OMPD_master_taskloop: 12273 case OMPD_master_taskloop_simd: 12274 case OMPD_parallel_master_taskloop: 12275 case OMPD_parallel_master_taskloop_simd: 12276 case OMPD_target_data: 12277 case OMPD_target_enter_data: 12278 case OMPD_target_exit_data: 12279 case OMPD_target_update: 12280 case OMPD_teams: 12281 case OMPD_teams_distribute: 12282 case OMPD_teams_distribute_simd: 12283 case OMPD_target_teams_distribute: 12284 case OMPD_target_teams_distribute_simd: 12285 case OMPD_target: 12286 case OMPD_target_simd: 12287 case OMPD_target_parallel: 12288 case OMPD_cancel: 12289 case OMPD_parallel: 12290 case OMPD_parallel_master: 12291 case OMPD_parallel_sections: 12292 case OMPD_threadprivate: 12293 case OMPD_allocate: 12294 case OMPD_taskyield: 12295 case OMPD_barrier: 12296 case OMPD_taskwait: 12297 case OMPD_cancellation_point: 12298 case OMPD_flush: 12299 case OMPD_depobj: 12300 case OMPD_scan: 12301 case OMPD_declare_reduction: 12302 case OMPD_declare_mapper: 12303 case OMPD_declare_simd: 12304 case OMPD_declare_variant: 12305 case OMPD_begin_declare_variant: 12306 case OMPD_end_declare_variant: 12307 case OMPD_declare_target: 12308 case OMPD_end_declare_target: 12309 case OMPD_simd: 12310 case OMPD_sections: 12311 case OMPD_section: 12312 case OMPD_single: 12313 case OMPD_master: 12314 case OMPD_critical: 12315 case OMPD_taskgroup: 12316 case OMPD_distribute: 12317 case OMPD_ordered: 12318 case OMPD_atomic: 12319 case OMPD_distribute_simd: 12320 case OMPD_target_teams: 12321 case OMPD_requires: 12322 llvm_unreachable("Unexpected OpenMP directive with schedule clause"); 12323 case OMPD_unknown: 12324 default: 12325 llvm_unreachable("Unknown OpenMP directive"); 12326 } 12327 break; 12328 case OMPC_dist_schedule: 12329 switch (DKind) { 12330 case OMPD_teams_distribute_parallel_for: 12331 case OMPD_teams_distribute_parallel_for_simd: 12332 case OMPD_teams_distribute: 12333 case OMPD_teams_distribute_simd: 12334 case OMPD_target_teams_distribute_parallel_for: 12335 case OMPD_target_teams_distribute_parallel_for_simd: 12336 case OMPD_target_teams_distribute: 12337 case OMPD_target_teams_distribute_simd: 12338 CaptureRegion = OMPD_teams; 12339 break; 12340 case OMPD_distribute_parallel_for: 12341 case OMPD_distribute_parallel_for_simd: 12342 case OMPD_distribute: 12343 case OMPD_distribute_simd: 12344 // Do not capture thread_limit-clause expressions. 12345 break; 12346 case OMPD_parallel_for: 12347 case OMPD_parallel_for_simd: 12348 case OMPD_target_parallel_for_simd: 12349 case OMPD_target_parallel_for: 12350 case OMPD_task: 12351 case OMPD_taskloop: 12352 case OMPD_taskloop_simd: 12353 case OMPD_master_taskloop: 12354 case OMPD_master_taskloop_simd: 12355 case OMPD_parallel_master_taskloop: 12356 case OMPD_parallel_master_taskloop_simd: 12357 case OMPD_target_data: 12358 case OMPD_target_enter_data: 12359 case OMPD_target_exit_data: 12360 case OMPD_target_update: 12361 case OMPD_teams: 12362 case OMPD_target: 12363 case OMPD_target_simd: 12364 case OMPD_target_parallel: 12365 case OMPD_cancel: 12366 case OMPD_parallel: 12367 case OMPD_parallel_master: 12368 case OMPD_parallel_sections: 12369 case OMPD_threadprivate: 12370 case OMPD_allocate: 12371 case OMPD_taskyield: 12372 case OMPD_barrier: 12373 case OMPD_taskwait: 12374 case OMPD_cancellation_point: 12375 case OMPD_flush: 12376 case OMPD_depobj: 12377 case OMPD_scan: 12378 case OMPD_declare_reduction: 12379 case OMPD_declare_mapper: 12380 case OMPD_declare_simd: 12381 case OMPD_declare_variant: 12382 case OMPD_begin_declare_variant: 12383 case OMPD_end_declare_variant: 12384 case OMPD_declare_target: 12385 case OMPD_end_declare_target: 12386 case OMPD_simd: 12387 case OMPD_for: 12388 case OMPD_for_simd: 12389 case OMPD_sections: 12390 case OMPD_section: 12391 case OMPD_single: 12392 case OMPD_master: 12393 case OMPD_critical: 12394 case OMPD_taskgroup: 12395 case OMPD_ordered: 12396 case OMPD_atomic: 12397 case OMPD_target_teams: 12398 case OMPD_requires: 12399 llvm_unreachable("Unexpected OpenMP directive with schedule clause"); 12400 case OMPD_unknown: 12401 default: 12402 llvm_unreachable("Unknown OpenMP directive"); 12403 } 12404 break; 12405 case OMPC_device: 12406 switch (DKind) { 12407 case OMPD_target_update: 12408 case OMPD_target_enter_data: 12409 case OMPD_target_exit_data: 12410 case OMPD_target: 12411 case OMPD_target_simd: 12412 case OMPD_target_teams: 12413 case OMPD_target_parallel: 12414 case OMPD_target_teams_distribute: 12415 case OMPD_target_teams_distribute_simd: 12416 case OMPD_target_parallel_for: 12417 case OMPD_target_parallel_for_simd: 12418 case OMPD_target_teams_distribute_parallel_for: 12419 case OMPD_target_teams_distribute_parallel_for_simd: 12420 CaptureRegion = OMPD_task; 12421 break; 12422 case OMPD_target_data: 12423 // Do not capture device-clause expressions. 12424 break; 12425 case OMPD_teams_distribute_parallel_for: 12426 case OMPD_teams_distribute_parallel_for_simd: 12427 case OMPD_teams: 12428 case OMPD_teams_distribute: 12429 case OMPD_teams_distribute_simd: 12430 case OMPD_distribute_parallel_for: 12431 case OMPD_distribute_parallel_for_simd: 12432 case OMPD_task: 12433 case OMPD_taskloop: 12434 case OMPD_taskloop_simd: 12435 case OMPD_master_taskloop: 12436 case OMPD_master_taskloop_simd: 12437 case OMPD_parallel_master_taskloop: 12438 case OMPD_parallel_master_taskloop_simd: 12439 case OMPD_cancel: 12440 case OMPD_parallel: 12441 case OMPD_parallel_master: 12442 case OMPD_parallel_sections: 12443 case OMPD_parallel_for: 12444 case OMPD_parallel_for_simd: 12445 case OMPD_threadprivate: 12446 case OMPD_allocate: 12447 case OMPD_taskyield: 12448 case OMPD_barrier: 12449 case OMPD_taskwait: 12450 case OMPD_cancellation_point: 12451 case OMPD_flush: 12452 case OMPD_depobj: 12453 case OMPD_scan: 12454 case OMPD_declare_reduction: 12455 case OMPD_declare_mapper: 12456 case OMPD_declare_simd: 12457 case OMPD_declare_variant: 12458 case OMPD_begin_declare_variant: 12459 case OMPD_end_declare_variant: 12460 case OMPD_declare_target: 12461 case OMPD_end_declare_target: 12462 case OMPD_simd: 12463 case OMPD_for: 12464 case OMPD_for_simd: 12465 case OMPD_sections: 12466 case OMPD_section: 12467 case OMPD_single: 12468 case OMPD_master: 12469 case OMPD_critical: 12470 case OMPD_taskgroup: 12471 case OMPD_distribute: 12472 case OMPD_ordered: 12473 case OMPD_atomic: 12474 case OMPD_distribute_simd: 12475 case OMPD_requires: 12476 llvm_unreachable("Unexpected OpenMP directive with num_teams-clause"); 12477 case OMPD_unknown: 12478 default: 12479 llvm_unreachable("Unknown OpenMP directive"); 12480 } 12481 break; 12482 case OMPC_grainsize: 12483 case OMPC_num_tasks: 12484 case OMPC_final: 12485 case OMPC_priority: 12486 switch (DKind) { 12487 case OMPD_task: 12488 case OMPD_taskloop: 12489 case OMPD_taskloop_simd: 12490 case OMPD_master_taskloop: 12491 case OMPD_master_taskloop_simd: 12492 break; 12493 case OMPD_parallel_master_taskloop: 12494 case OMPD_parallel_master_taskloop_simd: 12495 CaptureRegion = OMPD_parallel; 12496 break; 12497 case OMPD_target_update: 12498 case OMPD_target_enter_data: 12499 case OMPD_target_exit_data: 12500 case OMPD_target: 12501 case OMPD_target_simd: 12502 case OMPD_target_teams: 12503 case OMPD_target_parallel: 12504 case OMPD_target_teams_distribute: 12505 case OMPD_target_teams_distribute_simd: 12506 case OMPD_target_parallel_for: 12507 case OMPD_target_parallel_for_simd: 12508 case OMPD_target_teams_distribute_parallel_for: 12509 case OMPD_target_teams_distribute_parallel_for_simd: 12510 case OMPD_target_data: 12511 case OMPD_teams_distribute_parallel_for: 12512 case OMPD_teams_distribute_parallel_for_simd: 12513 case OMPD_teams: 12514 case OMPD_teams_distribute: 12515 case OMPD_teams_distribute_simd: 12516 case OMPD_distribute_parallel_for: 12517 case OMPD_distribute_parallel_for_simd: 12518 case OMPD_cancel: 12519 case OMPD_parallel: 12520 case OMPD_parallel_master: 12521 case OMPD_parallel_sections: 12522 case OMPD_parallel_for: 12523 case OMPD_parallel_for_simd: 12524 case OMPD_threadprivate: 12525 case OMPD_allocate: 12526 case OMPD_taskyield: 12527 case OMPD_barrier: 12528 case OMPD_taskwait: 12529 case OMPD_cancellation_point: 12530 case OMPD_flush: 12531 case OMPD_depobj: 12532 case OMPD_scan: 12533 case OMPD_declare_reduction: 12534 case OMPD_declare_mapper: 12535 case OMPD_declare_simd: 12536 case OMPD_declare_variant: 12537 case OMPD_begin_declare_variant: 12538 case OMPD_end_declare_variant: 12539 case OMPD_declare_target: 12540 case OMPD_end_declare_target: 12541 case OMPD_simd: 12542 case OMPD_for: 12543 case OMPD_for_simd: 12544 case OMPD_sections: 12545 case OMPD_section: 12546 case OMPD_single: 12547 case OMPD_master: 12548 case OMPD_critical: 12549 case OMPD_taskgroup: 12550 case OMPD_distribute: 12551 case OMPD_ordered: 12552 case OMPD_atomic: 12553 case OMPD_distribute_simd: 12554 case OMPD_requires: 12555 llvm_unreachable("Unexpected OpenMP directive with grainsize-clause"); 12556 case OMPD_unknown: 12557 default: 12558 llvm_unreachable("Unknown OpenMP directive"); 12559 } 12560 break; 12561 case OMPC_firstprivate: 12562 case OMPC_lastprivate: 12563 case OMPC_reduction: 12564 case OMPC_task_reduction: 12565 case OMPC_in_reduction: 12566 case OMPC_linear: 12567 case OMPC_default: 12568 case OMPC_proc_bind: 12569 case OMPC_safelen: 12570 case OMPC_simdlen: 12571 case OMPC_allocator: 12572 case OMPC_collapse: 12573 case OMPC_private: 12574 case OMPC_shared: 12575 case OMPC_aligned: 12576 case OMPC_copyin: 12577 case OMPC_copyprivate: 12578 case OMPC_ordered: 12579 case OMPC_nowait: 12580 case OMPC_untied: 12581 case OMPC_mergeable: 12582 case OMPC_threadprivate: 12583 case OMPC_allocate: 12584 case OMPC_flush: 12585 case OMPC_depobj: 12586 case OMPC_read: 12587 case OMPC_write: 12588 case OMPC_update: 12589 case OMPC_capture: 12590 case OMPC_seq_cst: 12591 case OMPC_acq_rel: 12592 case OMPC_acquire: 12593 case OMPC_release: 12594 case OMPC_relaxed: 12595 case OMPC_depend: 12596 case OMPC_threads: 12597 case OMPC_simd: 12598 case OMPC_map: 12599 case OMPC_nogroup: 12600 case OMPC_hint: 12601 case OMPC_defaultmap: 12602 case OMPC_unknown: 12603 case OMPC_uniform: 12604 case OMPC_to: 12605 case OMPC_from: 12606 case OMPC_use_device_ptr: 12607 case OMPC_use_device_addr: 12608 case OMPC_is_device_ptr: 12609 case OMPC_unified_address: 12610 case OMPC_unified_shared_memory: 12611 case OMPC_reverse_offload: 12612 case OMPC_dynamic_allocators: 12613 case OMPC_atomic_default_mem_order: 12614 case OMPC_device_type: 12615 case OMPC_match: 12616 case OMPC_nontemporal: 12617 case OMPC_order: 12618 case OMPC_destroy: 12619 case OMPC_detach: 12620 case OMPC_inclusive: 12621 case OMPC_exclusive: 12622 case OMPC_uses_allocators: 12623 case OMPC_affinity: 12624 default: 12625 llvm_unreachable("Unexpected OpenMP clause."); 12626 } 12627 return CaptureRegion; 12628 } 12629 12630 OMPClause *Sema::ActOnOpenMPIfClause(OpenMPDirectiveKind NameModifier, 12631 Expr *Condition, SourceLocation StartLoc, 12632 SourceLocation LParenLoc, 12633 SourceLocation NameModifierLoc, 12634 SourceLocation ColonLoc, 12635 SourceLocation EndLoc) { 12636 Expr *ValExpr = Condition; 12637 Stmt *HelperValStmt = nullptr; 12638 OpenMPDirectiveKind CaptureRegion = OMPD_unknown; 12639 if (!Condition->isValueDependent() && !Condition->isTypeDependent() && 12640 !Condition->isInstantiationDependent() && 12641 !Condition->containsUnexpandedParameterPack()) { 12642 ExprResult Val = CheckBooleanCondition(StartLoc, Condition); 12643 if (Val.isInvalid()) 12644 return nullptr; 12645 12646 ValExpr = Val.get(); 12647 12648 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 12649 CaptureRegion = getOpenMPCaptureRegionForClause( 12650 DKind, OMPC_if, LangOpts.OpenMP, NameModifier); 12651 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 12652 ValExpr = MakeFullExpr(ValExpr).get(); 12653 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 12654 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 12655 HelperValStmt = buildPreInits(Context, Captures); 12656 } 12657 } 12658 12659 return new (Context) 12660 OMPIfClause(NameModifier, ValExpr, HelperValStmt, CaptureRegion, StartLoc, 12661 LParenLoc, NameModifierLoc, ColonLoc, EndLoc); 12662 } 12663 12664 OMPClause *Sema::ActOnOpenMPFinalClause(Expr *Condition, 12665 SourceLocation StartLoc, 12666 SourceLocation LParenLoc, 12667 SourceLocation EndLoc) { 12668 Expr *ValExpr = Condition; 12669 Stmt *HelperValStmt = nullptr; 12670 OpenMPDirectiveKind CaptureRegion = OMPD_unknown; 12671 if (!Condition->isValueDependent() && !Condition->isTypeDependent() && 12672 !Condition->isInstantiationDependent() && 12673 !Condition->containsUnexpandedParameterPack()) { 12674 ExprResult Val = CheckBooleanCondition(StartLoc, Condition); 12675 if (Val.isInvalid()) 12676 return nullptr; 12677 12678 ValExpr = MakeFullExpr(Val.get()).get(); 12679 12680 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 12681 CaptureRegion = 12682 getOpenMPCaptureRegionForClause(DKind, OMPC_final, LangOpts.OpenMP); 12683 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 12684 ValExpr = MakeFullExpr(ValExpr).get(); 12685 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 12686 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 12687 HelperValStmt = buildPreInits(Context, Captures); 12688 } 12689 } 12690 12691 return new (Context) OMPFinalClause(ValExpr, HelperValStmt, CaptureRegion, 12692 StartLoc, LParenLoc, EndLoc); 12693 } 12694 12695 ExprResult Sema::PerformOpenMPImplicitIntegerConversion(SourceLocation Loc, 12696 Expr *Op) { 12697 if (!Op) 12698 return ExprError(); 12699 12700 class IntConvertDiagnoser : public ICEConvertDiagnoser { 12701 public: 12702 IntConvertDiagnoser() 12703 : ICEConvertDiagnoser(/*AllowScopedEnumerations*/ false, false, true) {} 12704 SemaDiagnosticBuilder diagnoseNotInt(Sema &S, SourceLocation Loc, 12705 QualType T) override { 12706 return S.Diag(Loc, diag::err_omp_not_integral) << T; 12707 } 12708 SemaDiagnosticBuilder diagnoseIncomplete(Sema &S, SourceLocation Loc, 12709 QualType T) override { 12710 return S.Diag(Loc, diag::err_omp_incomplete_type) << T; 12711 } 12712 SemaDiagnosticBuilder diagnoseExplicitConv(Sema &S, SourceLocation Loc, 12713 QualType T, 12714 QualType ConvTy) override { 12715 return S.Diag(Loc, diag::err_omp_explicit_conversion) << T << ConvTy; 12716 } 12717 SemaDiagnosticBuilder noteExplicitConv(Sema &S, CXXConversionDecl *Conv, 12718 QualType ConvTy) override { 12719 return S.Diag(Conv->getLocation(), diag::note_omp_conversion_here) 12720 << ConvTy->isEnumeralType() << ConvTy; 12721 } 12722 SemaDiagnosticBuilder diagnoseAmbiguous(Sema &S, SourceLocation Loc, 12723 QualType T) override { 12724 return S.Diag(Loc, diag::err_omp_ambiguous_conversion) << T; 12725 } 12726 SemaDiagnosticBuilder noteAmbiguous(Sema &S, CXXConversionDecl *Conv, 12727 QualType ConvTy) override { 12728 return S.Diag(Conv->getLocation(), diag::note_omp_conversion_here) 12729 << ConvTy->isEnumeralType() << ConvTy; 12730 } 12731 SemaDiagnosticBuilder diagnoseConversion(Sema &, SourceLocation, QualType, 12732 QualType) override { 12733 llvm_unreachable("conversion functions are permitted"); 12734 } 12735 } ConvertDiagnoser; 12736 return PerformContextualImplicitConversion(Loc, Op, ConvertDiagnoser); 12737 } 12738 12739 static bool 12740 isNonNegativeIntegerValue(Expr *&ValExpr, Sema &SemaRef, OpenMPClauseKind CKind, 12741 bool StrictlyPositive, bool BuildCapture = false, 12742 OpenMPDirectiveKind DKind = OMPD_unknown, 12743 OpenMPDirectiveKind *CaptureRegion = nullptr, 12744 Stmt **HelperValStmt = nullptr) { 12745 if (!ValExpr->isTypeDependent() && !ValExpr->isValueDependent() && 12746 !ValExpr->isInstantiationDependent()) { 12747 SourceLocation Loc = ValExpr->getExprLoc(); 12748 ExprResult Value = 12749 SemaRef.PerformOpenMPImplicitIntegerConversion(Loc, ValExpr); 12750 if (Value.isInvalid()) 12751 return false; 12752 12753 ValExpr = Value.get(); 12754 // The expression must evaluate to a non-negative integer value. 12755 if (Optional<llvm::APSInt> Result = 12756 ValExpr->getIntegerConstantExpr(SemaRef.Context)) { 12757 if (Result->isSigned() && 12758 !((!StrictlyPositive && Result->isNonNegative()) || 12759 (StrictlyPositive && Result->isStrictlyPositive()))) { 12760 SemaRef.Diag(Loc, diag::err_omp_negative_expression_in_clause) 12761 << getOpenMPClauseName(CKind) << (StrictlyPositive ? 1 : 0) 12762 << ValExpr->getSourceRange(); 12763 return false; 12764 } 12765 } 12766 if (!BuildCapture) 12767 return true; 12768 *CaptureRegion = 12769 getOpenMPCaptureRegionForClause(DKind, CKind, SemaRef.LangOpts.OpenMP); 12770 if (*CaptureRegion != OMPD_unknown && 12771 !SemaRef.CurContext->isDependentContext()) { 12772 ValExpr = SemaRef.MakeFullExpr(ValExpr).get(); 12773 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 12774 ValExpr = tryBuildCapture(SemaRef, ValExpr, Captures).get(); 12775 *HelperValStmt = buildPreInits(SemaRef.Context, Captures); 12776 } 12777 } 12778 return true; 12779 } 12780 12781 OMPClause *Sema::ActOnOpenMPNumThreadsClause(Expr *NumThreads, 12782 SourceLocation StartLoc, 12783 SourceLocation LParenLoc, 12784 SourceLocation EndLoc) { 12785 Expr *ValExpr = NumThreads; 12786 Stmt *HelperValStmt = nullptr; 12787 12788 // OpenMP [2.5, Restrictions] 12789 // The num_threads expression must evaluate to a positive integer value. 12790 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_num_threads, 12791 /*StrictlyPositive=*/true)) 12792 return nullptr; 12793 12794 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 12795 OpenMPDirectiveKind CaptureRegion = 12796 getOpenMPCaptureRegionForClause(DKind, OMPC_num_threads, LangOpts.OpenMP); 12797 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 12798 ValExpr = MakeFullExpr(ValExpr).get(); 12799 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 12800 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 12801 HelperValStmt = buildPreInits(Context, Captures); 12802 } 12803 12804 return new (Context) OMPNumThreadsClause( 12805 ValExpr, HelperValStmt, CaptureRegion, StartLoc, LParenLoc, EndLoc); 12806 } 12807 12808 ExprResult Sema::VerifyPositiveIntegerConstantInClause(Expr *E, 12809 OpenMPClauseKind CKind, 12810 bool StrictlyPositive) { 12811 if (!E) 12812 return ExprError(); 12813 if (E->isValueDependent() || E->isTypeDependent() || 12814 E->isInstantiationDependent() || E->containsUnexpandedParameterPack()) 12815 return E; 12816 llvm::APSInt Result; 12817 ExprResult ICE = 12818 VerifyIntegerConstantExpression(E, &Result, /*FIXME*/ AllowFold); 12819 if (ICE.isInvalid()) 12820 return ExprError(); 12821 if ((StrictlyPositive && !Result.isStrictlyPositive()) || 12822 (!StrictlyPositive && !Result.isNonNegative())) { 12823 Diag(E->getExprLoc(), diag::err_omp_negative_expression_in_clause) 12824 << getOpenMPClauseName(CKind) << (StrictlyPositive ? 1 : 0) 12825 << E->getSourceRange(); 12826 return ExprError(); 12827 } 12828 if (CKind == OMPC_aligned && !Result.isPowerOf2()) { 12829 Diag(E->getExprLoc(), diag::warn_omp_alignment_not_power_of_two) 12830 << E->getSourceRange(); 12831 return ExprError(); 12832 } 12833 if (CKind == OMPC_collapse && DSAStack->getAssociatedLoops() == 1) 12834 DSAStack->setAssociatedLoops(Result.getExtValue()); 12835 else if (CKind == OMPC_ordered) 12836 DSAStack->setAssociatedLoops(Result.getExtValue()); 12837 return ICE; 12838 } 12839 12840 OMPClause *Sema::ActOnOpenMPSafelenClause(Expr *Len, SourceLocation StartLoc, 12841 SourceLocation LParenLoc, 12842 SourceLocation EndLoc) { 12843 // OpenMP [2.8.1, simd construct, Description] 12844 // The parameter of the safelen clause must be a constant 12845 // positive integer expression. 12846 ExprResult Safelen = VerifyPositiveIntegerConstantInClause(Len, OMPC_safelen); 12847 if (Safelen.isInvalid()) 12848 return nullptr; 12849 return new (Context) 12850 OMPSafelenClause(Safelen.get(), StartLoc, LParenLoc, EndLoc); 12851 } 12852 12853 OMPClause *Sema::ActOnOpenMPSimdlenClause(Expr *Len, SourceLocation StartLoc, 12854 SourceLocation LParenLoc, 12855 SourceLocation EndLoc) { 12856 // OpenMP [2.8.1, simd construct, Description] 12857 // The parameter of the simdlen clause must be a constant 12858 // positive integer expression. 12859 ExprResult Simdlen = VerifyPositiveIntegerConstantInClause(Len, OMPC_simdlen); 12860 if (Simdlen.isInvalid()) 12861 return nullptr; 12862 return new (Context) 12863 OMPSimdlenClause(Simdlen.get(), StartLoc, LParenLoc, EndLoc); 12864 } 12865 12866 /// Tries to find omp_allocator_handle_t type. 12867 static bool findOMPAllocatorHandleT(Sema &S, SourceLocation Loc, 12868 DSAStackTy *Stack) { 12869 QualType OMPAllocatorHandleT = Stack->getOMPAllocatorHandleT(); 12870 if (!OMPAllocatorHandleT.isNull()) 12871 return true; 12872 // Build the predefined allocator expressions. 12873 bool ErrorFound = false; 12874 for (int I = 0; I < OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; ++I) { 12875 auto AllocatorKind = static_cast<OMPAllocateDeclAttr::AllocatorTypeTy>(I); 12876 StringRef Allocator = 12877 OMPAllocateDeclAttr::ConvertAllocatorTypeTyToStr(AllocatorKind); 12878 DeclarationName AllocatorName = &S.getASTContext().Idents.get(Allocator); 12879 auto *VD = dyn_cast_or_null<ValueDecl>( 12880 S.LookupSingleName(S.TUScope, AllocatorName, Loc, Sema::LookupAnyName)); 12881 if (!VD) { 12882 ErrorFound = true; 12883 break; 12884 } 12885 QualType AllocatorType = 12886 VD->getType().getNonLValueExprType(S.getASTContext()); 12887 ExprResult Res = S.BuildDeclRefExpr(VD, AllocatorType, VK_LValue, Loc); 12888 if (!Res.isUsable()) { 12889 ErrorFound = true; 12890 break; 12891 } 12892 if (OMPAllocatorHandleT.isNull()) 12893 OMPAllocatorHandleT = AllocatorType; 12894 if (!S.getASTContext().hasSameType(OMPAllocatorHandleT, AllocatorType)) { 12895 ErrorFound = true; 12896 break; 12897 } 12898 Stack->setAllocator(AllocatorKind, Res.get()); 12899 } 12900 if (ErrorFound) { 12901 S.Diag(Loc, diag::err_omp_implied_type_not_found) 12902 << "omp_allocator_handle_t"; 12903 return false; 12904 } 12905 OMPAllocatorHandleT.addConst(); 12906 Stack->setOMPAllocatorHandleT(OMPAllocatorHandleT); 12907 return true; 12908 } 12909 12910 OMPClause *Sema::ActOnOpenMPAllocatorClause(Expr *A, SourceLocation StartLoc, 12911 SourceLocation LParenLoc, 12912 SourceLocation EndLoc) { 12913 // OpenMP [2.11.3, allocate Directive, Description] 12914 // allocator is an expression of omp_allocator_handle_t type. 12915 if (!findOMPAllocatorHandleT(*this, A->getExprLoc(), DSAStack)) 12916 return nullptr; 12917 12918 ExprResult Allocator = DefaultLvalueConversion(A); 12919 if (Allocator.isInvalid()) 12920 return nullptr; 12921 Allocator = PerformImplicitConversion(Allocator.get(), 12922 DSAStack->getOMPAllocatorHandleT(), 12923 Sema::AA_Initializing, 12924 /*AllowExplicit=*/true); 12925 if (Allocator.isInvalid()) 12926 return nullptr; 12927 return new (Context) 12928 OMPAllocatorClause(Allocator.get(), StartLoc, LParenLoc, EndLoc); 12929 } 12930 12931 OMPClause *Sema::ActOnOpenMPCollapseClause(Expr *NumForLoops, 12932 SourceLocation StartLoc, 12933 SourceLocation LParenLoc, 12934 SourceLocation EndLoc) { 12935 // OpenMP [2.7.1, loop construct, Description] 12936 // OpenMP [2.8.1, simd construct, Description] 12937 // OpenMP [2.9.6, distribute construct, Description] 12938 // The parameter of the collapse clause must be a constant 12939 // positive integer expression. 12940 ExprResult NumForLoopsResult = 12941 VerifyPositiveIntegerConstantInClause(NumForLoops, OMPC_collapse); 12942 if (NumForLoopsResult.isInvalid()) 12943 return nullptr; 12944 return new (Context) 12945 OMPCollapseClause(NumForLoopsResult.get(), StartLoc, LParenLoc, EndLoc); 12946 } 12947 12948 OMPClause *Sema::ActOnOpenMPOrderedClause(SourceLocation StartLoc, 12949 SourceLocation EndLoc, 12950 SourceLocation LParenLoc, 12951 Expr *NumForLoops) { 12952 // OpenMP [2.7.1, loop construct, Description] 12953 // OpenMP [2.8.1, simd construct, Description] 12954 // OpenMP [2.9.6, distribute construct, Description] 12955 // The parameter of the ordered clause must be a constant 12956 // positive integer expression if any. 12957 if (NumForLoops && LParenLoc.isValid()) { 12958 ExprResult NumForLoopsResult = 12959 VerifyPositiveIntegerConstantInClause(NumForLoops, OMPC_ordered); 12960 if (NumForLoopsResult.isInvalid()) 12961 return nullptr; 12962 NumForLoops = NumForLoopsResult.get(); 12963 } else { 12964 NumForLoops = nullptr; 12965 } 12966 auto *Clause = OMPOrderedClause::Create( 12967 Context, NumForLoops, NumForLoops ? DSAStack->getAssociatedLoops() : 0, 12968 StartLoc, LParenLoc, EndLoc); 12969 DSAStack->setOrderedRegion(/*IsOrdered=*/true, NumForLoops, Clause); 12970 return Clause; 12971 } 12972 12973 OMPClause *Sema::ActOnOpenMPSimpleClause( 12974 OpenMPClauseKind Kind, unsigned Argument, SourceLocation ArgumentLoc, 12975 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) { 12976 OMPClause *Res = nullptr; 12977 switch (Kind) { 12978 case OMPC_default: 12979 Res = ActOnOpenMPDefaultClause(static_cast<DefaultKind>(Argument), 12980 ArgumentLoc, StartLoc, LParenLoc, EndLoc); 12981 break; 12982 case OMPC_proc_bind: 12983 Res = ActOnOpenMPProcBindClause(static_cast<ProcBindKind>(Argument), 12984 ArgumentLoc, StartLoc, LParenLoc, EndLoc); 12985 break; 12986 case OMPC_atomic_default_mem_order: 12987 Res = ActOnOpenMPAtomicDefaultMemOrderClause( 12988 static_cast<OpenMPAtomicDefaultMemOrderClauseKind>(Argument), 12989 ArgumentLoc, StartLoc, LParenLoc, EndLoc); 12990 break; 12991 case OMPC_order: 12992 Res = ActOnOpenMPOrderClause(static_cast<OpenMPOrderClauseKind>(Argument), 12993 ArgumentLoc, StartLoc, LParenLoc, EndLoc); 12994 break; 12995 case OMPC_update: 12996 Res = ActOnOpenMPUpdateClause(static_cast<OpenMPDependClauseKind>(Argument), 12997 ArgumentLoc, StartLoc, LParenLoc, EndLoc); 12998 break; 12999 case OMPC_if: 13000 case OMPC_final: 13001 case OMPC_num_threads: 13002 case OMPC_safelen: 13003 case OMPC_simdlen: 13004 case OMPC_allocator: 13005 case OMPC_collapse: 13006 case OMPC_schedule: 13007 case OMPC_private: 13008 case OMPC_firstprivate: 13009 case OMPC_lastprivate: 13010 case OMPC_shared: 13011 case OMPC_reduction: 13012 case OMPC_task_reduction: 13013 case OMPC_in_reduction: 13014 case OMPC_linear: 13015 case OMPC_aligned: 13016 case OMPC_copyin: 13017 case OMPC_copyprivate: 13018 case OMPC_ordered: 13019 case OMPC_nowait: 13020 case OMPC_untied: 13021 case OMPC_mergeable: 13022 case OMPC_threadprivate: 13023 case OMPC_allocate: 13024 case OMPC_flush: 13025 case OMPC_depobj: 13026 case OMPC_read: 13027 case OMPC_write: 13028 case OMPC_capture: 13029 case OMPC_seq_cst: 13030 case OMPC_acq_rel: 13031 case OMPC_acquire: 13032 case OMPC_release: 13033 case OMPC_relaxed: 13034 case OMPC_depend: 13035 case OMPC_device: 13036 case OMPC_threads: 13037 case OMPC_simd: 13038 case OMPC_map: 13039 case OMPC_num_teams: 13040 case OMPC_thread_limit: 13041 case OMPC_priority: 13042 case OMPC_grainsize: 13043 case OMPC_nogroup: 13044 case OMPC_num_tasks: 13045 case OMPC_hint: 13046 case OMPC_dist_schedule: 13047 case OMPC_defaultmap: 13048 case OMPC_unknown: 13049 case OMPC_uniform: 13050 case OMPC_to: 13051 case OMPC_from: 13052 case OMPC_use_device_ptr: 13053 case OMPC_use_device_addr: 13054 case OMPC_is_device_ptr: 13055 case OMPC_unified_address: 13056 case OMPC_unified_shared_memory: 13057 case OMPC_reverse_offload: 13058 case OMPC_dynamic_allocators: 13059 case OMPC_device_type: 13060 case OMPC_match: 13061 case OMPC_nontemporal: 13062 case OMPC_destroy: 13063 case OMPC_detach: 13064 case OMPC_inclusive: 13065 case OMPC_exclusive: 13066 case OMPC_uses_allocators: 13067 case OMPC_affinity: 13068 default: 13069 llvm_unreachable("Clause is not allowed."); 13070 } 13071 return Res; 13072 } 13073 13074 static std::string 13075 getListOfPossibleValues(OpenMPClauseKind K, unsigned First, unsigned Last, 13076 ArrayRef<unsigned> Exclude = llvm::None) { 13077 SmallString<256> Buffer; 13078 llvm::raw_svector_ostream Out(Buffer); 13079 unsigned Skipped = Exclude.size(); 13080 auto S = Exclude.begin(), E = Exclude.end(); 13081 for (unsigned I = First; I < Last; ++I) { 13082 if (std::find(S, E, I) != E) { 13083 --Skipped; 13084 continue; 13085 } 13086 Out << "'" << getOpenMPSimpleClauseTypeName(K, I) << "'"; 13087 if (I + Skipped + 2 == Last) 13088 Out << " or "; 13089 else if (I + Skipped + 1 != Last) 13090 Out << ", "; 13091 } 13092 return std::string(Out.str()); 13093 } 13094 13095 OMPClause *Sema::ActOnOpenMPDefaultClause(DefaultKind Kind, 13096 SourceLocation KindKwLoc, 13097 SourceLocation StartLoc, 13098 SourceLocation LParenLoc, 13099 SourceLocation EndLoc) { 13100 if (Kind == OMP_DEFAULT_unknown) { 13101 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value) 13102 << getListOfPossibleValues(OMPC_default, /*First=*/0, 13103 /*Last=*/unsigned(OMP_DEFAULT_unknown)) 13104 << getOpenMPClauseName(OMPC_default); 13105 return nullptr; 13106 } 13107 13108 switch (Kind) { 13109 case OMP_DEFAULT_none: 13110 DSAStack->setDefaultDSANone(KindKwLoc); 13111 break; 13112 case OMP_DEFAULT_shared: 13113 DSAStack->setDefaultDSAShared(KindKwLoc); 13114 break; 13115 case OMP_DEFAULT_firstprivate: 13116 DSAStack->setDefaultDSAFirstPrivate(KindKwLoc); 13117 break; 13118 default: 13119 llvm_unreachable("DSA unexpected in OpenMP default clause"); 13120 } 13121 13122 return new (Context) 13123 OMPDefaultClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc); 13124 } 13125 13126 OMPClause *Sema::ActOnOpenMPProcBindClause(ProcBindKind Kind, 13127 SourceLocation KindKwLoc, 13128 SourceLocation StartLoc, 13129 SourceLocation LParenLoc, 13130 SourceLocation EndLoc) { 13131 if (Kind == OMP_PROC_BIND_unknown) { 13132 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value) 13133 << getListOfPossibleValues(OMPC_proc_bind, 13134 /*First=*/unsigned(OMP_PROC_BIND_master), 13135 /*Last=*/5) 13136 << getOpenMPClauseName(OMPC_proc_bind); 13137 return nullptr; 13138 } 13139 return new (Context) 13140 OMPProcBindClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc); 13141 } 13142 13143 OMPClause *Sema::ActOnOpenMPAtomicDefaultMemOrderClause( 13144 OpenMPAtomicDefaultMemOrderClauseKind Kind, SourceLocation KindKwLoc, 13145 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) { 13146 if (Kind == OMPC_ATOMIC_DEFAULT_MEM_ORDER_unknown) { 13147 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value) 13148 << getListOfPossibleValues( 13149 OMPC_atomic_default_mem_order, /*First=*/0, 13150 /*Last=*/OMPC_ATOMIC_DEFAULT_MEM_ORDER_unknown) 13151 << getOpenMPClauseName(OMPC_atomic_default_mem_order); 13152 return nullptr; 13153 } 13154 return new (Context) OMPAtomicDefaultMemOrderClause(Kind, KindKwLoc, StartLoc, 13155 LParenLoc, EndLoc); 13156 } 13157 13158 OMPClause *Sema::ActOnOpenMPOrderClause(OpenMPOrderClauseKind Kind, 13159 SourceLocation KindKwLoc, 13160 SourceLocation StartLoc, 13161 SourceLocation LParenLoc, 13162 SourceLocation EndLoc) { 13163 if (Kind == OMPC_ORDER_unknown) { 13164 static_assert(OMPC_ORDER_unknown > 0, 13165 "OMPC_ORDER_unknown not greater than 0"); 13166 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value) 13167 << getListOfPossibleValues(OMPC_order, /*First=*/0, 13168 /*Last=*/OMPC_ORDER_unknown) 13169 << getOpenMPClauseName(OMPC_order); 13170 return nullptr; 13171 } 13172 return new (Context) 13173 OMPOrderClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc); 13174 } 13175 13176 OMPClause *Sema::ActOnOpenMPUpdateClause(OpenMPDependClauseKind Kind, 13177 SourceLocation KindKwLoc, 13178 SourceLocation StartLoc, 13179 SourceLocation LParenLoc, 13180 SourceLocation EndLoc) { 13181 if (Kind == OMPC_DEPEND_unknown || Kind == OMPC_DEPEND_source || 13182 Kind == OMPC_DEPEND_sink || Kind == OMPC_DEPEND_depobj) { 13183 unsigned Except[] = {OMPC_DEPEND_source, OMPC_DEPEND_sink, 13184 OMPC_DEPEND_depobj}; 13185 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value) 13186 << getListOfPossibleValues(OMPC_depend, /*First=*/0, 13187 /*Last=*/OMPC_DEPEND_unknown, Except) 13188 << getOpenMPClauseName(OMPC_update); 13189 return nullptr; 13190 } 13191 return OMPUpdateClause::Create(Context, StartLoc, LParenLoc, KindKwLoc, Kind, 13192 EndLoc); 13193 } 13194 13195 OMPClause *Sema::ActOnOpenMPSingleExprWithArgClause( 13196 OpenMPClauseKind Kind, ArrayRef<unsigned> Argument, Expr *Expr, 13197 SourceLocation StartLoc, SourceLocation LParenLoc, 13198 ArrayRef<SourceLocation> ArgumentLoc, SourceLocation DelimLoc, 13199 SourceLocation EndLoc) { 13200 OMPClause *Res = nullptr; 13201 switch (Kind) { 13202 case OMPC_schedule: 13203 enum { Modifier1, Modifier2, ScheduleKind, NumberOfElements }; 13204 assert(Argument.size() == NumberOfElements && 13205 ArgumentLoc.size() == NumberOfElements); 13206 Res = ActOnOpenMPScheduleClause( 13207 static_cast<OpenMPScheduleClauseModifier>(Argument[Modifier1]), 13208 static_cast<OpenMPScheduleClauseModifier>(Argument[Modifier2]), 13209 static_cast<OpenMPScheduleClauseKind>(Argument[ScheduleKind]), Expr, 13210 StartLoc, LParenLoc, ArgumentLoc[Modifier1], ArgumentLoc[Modifier2], 13211 ArgumentLoc[ScheduleKind], DelimLoc, EndLoc); 13212 break; 13213 case OMPC_if: 13214 assert(Argument.size() == 1 && ArgumentLoc.size() == 1); 13215 Res = ActOnOpenMPIfClause(static_cast<OpenMPDirectiveKind>(Argument.back()), 13216 Expr, StartLoc, LParenLoc, ArgumentLoc.back(), 13217 DelimLoc, EndLoc); 13218 break; 13219 case OMPC_dist_schedule: 13220 Res = ActOnOpenMPDistScheduleClause( 13221 static_cast<OpenMPDistScheduleClauseKind>(Argument.back()), Expr, 13222 StartLoc, LParenLoc, ArgumentLoc.back(), DelimLoc, EndLoc); 13223 break; 13224 case OMPC_defaultmap: 13225 enum { Modifier, DefaultmapKind }; 13226 Res = ActOnOpenMPDefaultmapClause( 13227 static_cast<OpenMPDefaultmapClauseModifier>(Argument[Modifier]), 13228 static_cast<OpenMPDefaultmapClauseKind>(Argument[DefaultmapKind]), 13229 StartLoc, LParenLoc, ArgumentLoc[Modifier], ArgumentLoc[DefaultmapKind], 13230 EndLoc); 13231 break; 13232 case OMPC_device: 13233 assert(Argument.size() == 1 && ArgumentLoc.size() == 1); 13234 Res = ActOnOpenMPDeviceClause( 13235 static_cast<OpenMPDeviceClauseModifier>(Argument.back()), Expr, 13236 StartLoc, LParenLoc, ArgumentLoc.back(), EndLoc); 13237 break; 13238 case OMPC_final: 13239 case OMPC_num_threads: 13240 case OMPC_safelen: 13241 case OMPC_simdlen: 13242 case OMPC_allocator: 13243 case OMPC_collapse: 13244 case OMPC_default: 13245 case OMPC_proc_bind: 13246 case OMPC_private: 13247 case OMPC_firstprivate: 13248 case OMPC_lastprivate: 13249 case OMPC_shared: 13250 case OMPC_reduction: 13251 case OMPC_task_reduction: 13252 case OMPC_in_reduction: 13253 case OMPC_linear: 13254 case OMPC_aligned: 13255 case OMPC_copyin: 13256 case OMPC_copyprivate: 13257 case OMPC_ordered: 13258 case OMPC_nowait: 13259 case OMPC_untied: 13260 case OMPC_mergeable: 13261 case OMPC_threadprivate: 13262 case OMPC_allocate: 13263 case OMPC_flush: 13264 case OMPC_depobj: 13265 case OMPC_read: 13266 case OMPC_write: 13267 case OMPC_update: 13268 case OMPC_capture: 13269 case OMPC_seq_cst: 13270 case OMPC_acq_rel: 13271 case OMPC_acquire: 13272 case OMPC_release: 13273 case OMPC_relaxed: 13274 case OMPC_depend: 13275 case OMPC_threads: 13276 case OMPC_simd: 13277 case OMPC_map: 13278 case OMPC_num_teams: 13279 case OMPC_thread_limit: 13280 case OMPC_priority: 13281 case OMPC_grainsize: 13282 case OMPC_nogroup: 13283 case OMPC_num_tasks: 13284 case OMPC_hint: 13285 case OMPC_unknown: 13286 case OMPC_uniform: 13287 case OMPC_to: 13288 case OMPC_from: 13289 case OMPC_use_device_ptr: 13290 case OMPC_use_device_addr: 13291 case OMPC_is_device_ptr: 13292 case OMPC_unified_address: 13293 case OMPC_unified_shared_memory: 13294 case OMPC_reverse_offload: 13295 case OMPC_dynamic_allocators: 13296 case OMPC_atomic_default_mem_order: 13297 case OMPC_device_type: 13298 case OMPC_match: 13299 case OMPC_nontemporal: 13300 case OMPC_order: 13301 case OMPC_destroy: 13302 case OMPC_detach: 13303 case OMPC_inclusive: 13304 case OMPC_exclusive: 13305 case OMPC_uses_allocators: 13306 case OMPC_affinity: 13307 default: 13308 llvm_unreachable("Clause is not allowed."); 13309 } 13310 return Res; 13311 } 13312 13313 static bool checkScheduleModifiers(Sema &S, OpenMPScheduleClauseModifier M1, 13314 OpenMPScheduleClauseModifier M2, 13315 SourceLocation M1Loc, SourceLocation M2Loc) { 13316 if (M1 == OMPC_SCHEDULE_MODIFIER_unknown && M1Loc.isValid()) { 13317 SmallVector<unsigned, 2> Excluded; 13318 if (M2 != OMPC_SCHEDULE_MODIFIER_unknown) 13319 Excluded.push_back(M2); 13320 if (M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) 13321 Excluded.push_back(OMPC_SCHEDULE_MODIFIER_monotonic); 13322 if (M2 == OMPC_SCHEDULE_MODIFIER_monotonic) 13323 Excluded.push_back(OMPC_SCHEDULE_MODIFIER_nonmonotonic); 13324 S.Diag(M1Loc, diag::err_omp_unexpected_clause_value) 13325 << getListOfPossibleValues(OMPC_schedule, 13326 /*First=*/OMPC_SCHEDULE_MODIFIER_unknown + 1, 13327 /*Last=*/OMPC_SCHEDULE_MODIFIER_last, 13328 Excluded) 13329 << getOpenMPClauseName(OMPC_schedule); 13330 return true; 13331 } 13332 return false; 13333 } 13334 13335 OMPClause *Sema::ActOnOpenMPScheduleClause( 13336 OpenMPScheduleClauseModifier M1, OpenMPScheduleClauseModifier M2, 13337 OpenMPScheduleClauseKind Kind, Expr *ChunkSize, SourceLocation StartLoc, 13338 SourceLocation LParenLoc, SourceLocation M1Loc, SourceLocation M2Loc, 13339 SourceLocation KindLoc, SourceLocation CommaLoc, SourceLocation EndLoc) { 13340 if (checkScheduleModifiers(*this, M1, M2, M1Loc, M2Loc) || 13341 checkScheduleModifiers(*this, M2, M1, M2Loc, M1Loc)) 13342 return nullptr; 13343 // OpenMP, 2.7.1, Loop Construct, Restrictions 13344 // Either the monotonic modifier or the nonmonotonic modifier can be specified 13345 // but not both. 13346 if ((M1 == M2 && M1 != OMPC_SCHEDULE_MODIFIER_unknown) || 13347 (M1 == OMPC_SCHEDULE_MODIFIER_monotonic && 13348 M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) || 13349 (M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic && 13350 M2 == OMPC_SCHEDULE_MODIFIER_monotonic)) { 13351 Diag(M2Loc, diag::err_omp_unexpected_schedule_modifier) 13352 << getOpenMPSimpleClauseTypeName(OMPC_schedule, M2) 13353 << getOpenMPSimpleClauseTypeName(OMPC_schedule, M1); 13354 return nullptr; 13355 } 13356 if (Kind == OMPC_SCHEDULE_unknown) { 13357 std::string Values; 13358 if (M1Loc.isInvalid() && M2Loc.isInvalid()) { 13359 unsigned Exclude[] = {OMPC_SCHEDULE_unknown}; 13360 Values = getListOfPossibleValues(OMPC_schedule, /*First=*/0, 13361 /*Last=*/OMPC_SCHEDULE_MODIFIER_last, 13362 Exclude); 13363 } else { 13364 Values = getListOfPossibleValues(OMPC_schedule, /*First=*/0, 13365 /*Last=*/OMPC_SCHEDULE_unknown); 13366 } 13367 Diag(KindLoc, diag::err_omp_unexpected_clause_value) 13368 << Values << getOpenMPClauseName(OMPC_schedule); 13369 return nullptr; 13370 } 13371 // OpenMP, 2.7.1, Loop Construct, Restrictions 13372 // The nonmonotonic modifier can only be specified with schedule(dynamic) or 13373 // schedule(guided). 13374 // OpenMP 5.0 does not have this restriction. 13375 if (LangOpts.OpenMP < 50 && 13376 (M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic || 13377 M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) && 13378 Kind != OMPC_SCHEDULE_dynamic && Kind != OMPC_SCHEDULE_guided) { 13379 Diag(M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic ? M1Loc : M2Loc, 13380 diag::err_omp_schedule_nonmonotonic_static); 13381 return nullptr; 13382 } 13383 Expr *ValExpr = ChunkSize; 13384 Stmt *HelperValStmt = nullptr; 13385 if (ChunkSize) { 13386 if (!ChunkSize->isValueDependent() && !ChunkSize->isTypeDependent() && 13387 !ChunkSize->isInstantiationDependent() && 13388 !ChunkSize->containsUnexpandedParameterPack()) { 13389 SourceLocation ChunkSizeLoc = ChunkSize->getBeginLoc(); 13390 ExprResult Val = 13391 PerformOpenMPImplicitIntegerConversion(ChunkSizeLoc, ChunkSize); 13392 if (Val.isInvalid()) 13393 return nullptr; 13394 13395 ValExpr = Val.get(); 13396 13397 // OpenMP [2.7.1, Restrictions] 13398 // chunk_size must be a loop invariant integer expression with a positive 13399 // value. 13400 if (Optional<llvm::APSInt> Result = 13401 ValExpr->getIntegerConstantExpr(Context)) { 13402 if (Result->isSigned() && !Result->isStrictlyPositive()) { 13403 Diag(ChunkSizeLoc, diag::err_omp_negative_expression_in_clause) 13404 << "schedule" << 1 << ChunkSize->getSourceRange(); 13405 return nullptr; 13406 } 13407 } else if (getOpenMPCaptureRegionForClause( 13408 DSAStack->getCurrentDirective(), OMPC_schedule, 13409 LangOpts.OpenMP) != OMPD_unknown && 13410 !CurContext->isDependentContext()) { 13411 ValExpr = MakeFullExpr(ValExpr).get(); 13412 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 13413 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 13414 HelperValStmt = buildPreInits(Context, Captures); 13415 } 13416 } 13417 } 13418 13419 return new (Context) 13420 OMPScheduleClause(StartLoc, LParenLoc, KindLoc, CommaLoc, EndLoc, Kind, 13421 ValExpr, HelperValStmt, M1, M1Loc, M2, M2Loc); 13422 } 13423 13424 OMPClause *Sema::ActOnOpenMPClause(OpenMPClauseKind Kind, 13425 SourceLocation StartLoc, 13426 SourceLocation EndLoc) { 13427 OMPClause *Res = nullptr; 13428 switch (Kind) { 13429 case OMPC_ordered: 13430 Res = ActOnOpenMPOrderedClause(StartLoc, EndLoc); 13431 break; 13432 case OMPC_nowait: 13433 Res = ActOnOpenMPNowaitClause(StartLoc, EndLoc); 13434 break; 13435 case OMPC_untied: 13436 Res = ActOnOpenMPUntiedClause(StartLoc, EndLoc); 13437 break; 13438 case OMPC_mergeable: 13439 Res = ActOnOpenMPMergeableClause(StartLoc, EndLoc); 13440 break; 13441 case OMPC_read: 13442 Res = ActOnOpenMPReadClause(StartLoc, EndLoc); 13443 break; 13444 case OMPC_write: 13445 Res = ActOnOpenMPWriteClause(StartLoc, EndLoc); 13446 break; 13447 case OMPC_update: 13448 Res = ActOnOpenMPUpdateClause(StartLoc, EndLoc); 13449 break; 13450 case OMPC_capture: 13451 Res = ActOnOpenMPCaptureClause(StartLoc, EndLoc); 13452 break; 13453 case OMPC_seq_cst: 13454 Res = ActOnOpenMPSeqCstClause(StartLoc, EndLoc); 13455 break; 13456 case OMPC_acq_rel: 13457 Res = ActOnOpenMPAcqRelClause(StartLoc, EndLoc); 13458 break; 13459 case OMPC_acquire: 13460 Res = ActOnOpenMPAcquireClause(StartLoc, EndLoc); 13461 break; 13462 case OMPC_release: 13463 Res = ActOnOpenMPReleaseClause(StartLoc, EndLoc); 13464 break; 13465 case OMPC_relaxed: 13466 Res = ActOnOpenMPRelaxedClause(StartLoc, EndLoc); 13467 break; 13468 case OMPC_threads: 13469 Res = ActOnOpenMPThreadsClause(StartLoc, EndLoc); 13470 break; 13471 case OMPC_simd: 13472 Res = ActOnOpenMPSIMDClause(StartLoc, EndLoc); 13473 break; 13474 case OMPC_nogroup: 13475 Res = ActOnOpenMPNogroupClause(StartLoc, EndLoc); 13476 break; 13477 case OMPC_unified_address: 13478 Res = ActOnOpenMPUnifiedAddressClause(StartLoc, EndLoc); 13479 break; 13480 case OMPC_unified_shared_memory: 13481 Res = ActOnOpenMPUnifiedSharedMemoryClause(StartLoc, EndLoc); 13482 break; 13483 case OMPC_reverse_offload: 13484 Res = ActOnOpenMPReverseOffloadClause(StartLoc, EndLoc); 13485 break; 13486 case OMPC_dynamic_allocators: 13487 Res = ActOnOpenMPDynamicAllocatorsClause(StartLoc, EndLoc); 13488 break; 13489 case OMPC_destroy: 13490 Res = ActOnOpenMPDestroyClause(StartLoc, EndLoc); 13491 break; 13492 case OMPC_if: 13493 case OMPC_final: 13494 case OMPC_num_threads: 13495 case OMPC_safelen: 13496 case OMPC_simdlen: 13497 case OMPC_allocator: 13498 case OMPC_collapse: 13499 case OMPC_schedule: 13500 case OMPC_private: 13501 case OMPC_firstprivate: 13502 case OMPC_lastprivate: 13503 case OMPC_shared: 13504 case OMPC_reduction: 13505 case OMPC_task_reduction: 13506 case OMPC_in_reduction: 13507 case OMPC_linear: 13508 case OMPC_aligned: 13509 case OMPC_copyin: 13510 case OMPC_copyprivate: 13511 case OMPC_default: 13512 case OMPC_proc_bind: 13513 case OMPC_threadprivate: 13514 case OMPC_allocate: 13515 case OMPC_flush: 13516 case OMPC_depobj: 13517 case OMPC_depend: 13518 case OMPC_device: 13519 case OMPC_map: 13520 case OMPC_num_teams: 13521 case OMPC_thread_limit: 13522 case OMPC_priority: 13523 case OMPC_grainsize: 13524 case OMPC_num_tasks: 13525 case OMPC_hint: 13526 case OMPC_dist_schedule: 13527 case OMPC_defaultmap: 13528 case OMPC_unknown: 13529 case OMPC_uniform: 13530 case OMPC_to: 13531 case OMPC_from: 13532 case OMPC_use_device_ptr: 13533 case OMPC_use_device_addr: 13534 case OMPC_is_device_ptr: 13535 case OMPC_atomic_default_mem_order: 13536 case OMPC_device_type: 13537 case OMPC_match: 13538 case OMPC_nontemporal: 13539 case OMPC_order: 13540 case OMPC_detach: 13541 case OMPC_inclusive: 13542 case OMPC_exclusive: 13543 case OMPC_uses_allocators: 13544 case OMPC_affinity: 13545 default: 13546 llvm_unreachable("Clause is not allowed."); 13547 } 13548 return Res; 13549 } 13550 13551 OMPClause *Sema::ActOnOpenMPNowaitClause(SourceLocation StartLoc, 13552 SourceLocation EndLoc) { 13553 DSAStack->setNowaitRegion(); 13554 return new (Context) OMPNowaitClause(StartLoc, EndLoc); 13555 } 13556 13557 OMPClause *Sema::ActOnOpenMPUntiedClause(SourceLocation StartLoc, 13558 SourceLocation EndLoc) { 13559 return new (Context) OMPUntiedClause(StartLoc, EndLoc); 13560 } 13561 13562 OMPClause *Sema::ActOnOpenMPMergeableClause(SourceLocation StartLoc, 13563 SourceLocation EndLoc) { 13564 return new (Context) OMPMergeableClause(StartLoc, EndLoc); 13565 } 13566 13567 OMPClause *Sema::ActOnOpenMPReadClause(SourceLocation StartLoc, 13568 SourceLocation EndLoc) { 13569 return new (Context) OMPReadClause(StartLoc, EndLoc); 13570 } 13571 13572 OMPClause *Sema::ActOnOpenMPWriteClause(SourceLocation StartLoc, 13573 SourceLocation EndLoc) { 13574 return new (Context) OMPWriteClause(StartLoc, EndLoc); 13575 } 13576 13577 OMPClause *Sema::ActOnOpenMPUpdateClause(SourceLocation StartLoc, 13578 SourceLocation EndLoc) { 13579 return OMPUpdateClause::Create(Context, StartLoc, EndLoc); 13580 } 13581 13582 OMPClause *Sema::ActOnOpenMPCaptureClause(SourceLocation StartLoc, 13583 SourceLocation EndLoc) { 13584 return new (Context) OMPCaptureClause(StartLoc, EndLoc); 13585 } 13586 13587 OMPClause *Sema::ActOnOpenMPSeqCstClause(SourceLocation StartLoc, 13588 SourceLocation EndLoc) { 13589 return new (Context) OMPSeqCstClause(StartLoc, EndLoc); 13590 } 13591 13592 OMPClause *Sema::ActOnOpenMPAcqRelClause(SourceLocation StartLoc, 13593 SourceLocation EndLoc) { 13594 return new (Context) OMPAcqRelClause(StartLoc, EndLoc); 13595 } 13596 13597 OMPClause *Sema::ActOnOpenMPAcquireClause(SourceLocation StartLoc, 13598 SourceLocation EndLoc) { 13599 return new (Context) OMPAcquireClause(StartLoc, EndLoc); 13600 } 13601 13602 OMPClause *Sema::ActOnOpenMPReleaseClause(SourceLocation StartLoc, 13603 SourceLocation EndLoc) { 13604 return new (Context) OMPReleaseClause(StartLoc, EndLoc); 13605 } 13606 13607 OMPClause *Sema::ActOnOpenMPRelaxedClause(SourceLocation StartLoc, 13608 SourceLocation EndLoc) { 13609 return new (Context) OMPRelaxedClause(StartLoc, EndLoc); 13610 } 13611 13612 OMPClause *Sema::ActOnOpenMPThreadsClause(SourceLocation StartLoc, 13613 SourceLocation EndLoc) { 13614 return new (Context) OMPThreadsClause(StartLoc, EndLoc); 13615 } 13616 13617 OMPClause *Sema::ActOnOpenMPSIMDClause(SourceLocation StartLoc, 13618 SourceLocation EndLoc) { 13619 return new (Context) OMPSIMDClause(StartLoc, EndLoc); 13620 } 13621 13622 OMPClause *Sema::ActOnOpenMPNogroupClause(SourceLocation StartLoc, 13623 SourceLocation EndLoc) { 13624 return new (Context) OMPNogroupClause(StartLoc, EndLoc); 13625 } 13626 13627 OMPClause *Sema::ActOnOpenMPUnifiedAddressClause(SourceLocation StartLoc, 13628 SourceLocation EndLoc) { 13629 return new (Context) OMPUnifiedAddressClause(StartLoc, EndLoc); 13630 } 13631 13632 OMPClause *Sema::ActOnOpenMPUnifiedSharedMemoryClause(SourceLocation StartLoc, 13633 SourceLocation EndLoc) { 13634 return new (Context) OMPUnifiedSharedMemoryClause(StartLoc, EndLoc); 13635 } 13636 13637 OMPClause *Sema::ActOnOpenMPReverseOffloadClause(SourceLocation StartLoc, 13638 SourceLocation EndLoc) { 13639 return new (Context) OMPReverseOffloadClause(StartLoc, EndLoc); 13640 } 13641 13642 OMPClause *Sema::ActOnOpenMPDynamicAllocatorsClause(SourceLocation StartLoc, 13643 SourceLocation EndLoc) { 13644 return new (Context) OMPDynamicAllocatorsClause(StartLoc, EndLoc); 13645 } 13646 13647 OMPClause *Sema::ActOnOpenMPDestroyClause(SourceLocation StartLoc, 13648 SourceLocation EndLoc) { 13649 return new (Context) OMPDestroyClause(StartLoc, EndLoc); 13650 } 13651 13652 OMPClause *Sema::ActOnOpenMPVarListClause( 13653 OpenMPClauseKind Kind, ArrayRef<Expr *> VarList, Expr *DepModOrTailExpr, 13654 const OMPVarListLocTy &Locs, SourceLocation ColonLoc, 13655 CXXScopeSpec &ReductionOrMapperIdScopeSpec, 13656 DeclarationNameInfo &ReductionOrMapperId, int ExtraModifier, 13657 ArrayRef<OpenMPMapModifierKind> MapTypeModifiers, 13658 ArrayRef<SourceLocation> MapTypeModifiersLoc, bool IsMapTypeImplicit, 13659 SourceLocation ExtraModifierLoc, 13660 ArrayRef<OpenMPMotionModifierKind> MotionModifiers, 13661 ArrayRef<SourceLocation> MotionModifiersLoc) { 13662 SourceLocation StartLoc = Locs.StartLoc; 13663 SourceLocation LParenLoc = Locs.LParenLoc; 13664 SourceLocation EndLoc = Locs.EndLoc; 13665 OMPClause *Res = nullptr; 13666 switch (Kind) { 13667 case OMPC_private: 13668 Res = ActOnOpenMPPrivateClause(VarList, StartLoc, LParenLoc, EndLoc); 13669 break; 13670 case OMPC_firstprivate: 13671 Res = ActOnOpenMPFirstprivateClause(VarList, StartLoc, LParenLoc, EndLoc); 13672 break; 13673 case OMPC_lastprivate: 13674 assert(0 <= ExtraModifier && ExtraModifier <= OMPC_LASTPRIVATE_unknown && 13675 "Unexpected lastprivate modifier."); 13676 Res = ActOnOpenMPLastprivateClause( 13677 VarList, static_cast<OpenMPLastprivateModifier>(ExtraModifier), 13678 ExtraModifierLoc, ColonLoc, StartLoc, LParenLoc, EndLoc); 13679 break; 13680 case OMPC_shared: 13681 Res = ActOnOpenMPSharedClause(VarList, StartLoc, LParenLoc, EndLoc); 13682 break; 13683 case OMPC_reduction: 13684 assert(0 <= ExtraModifier && ExtraModifier <= OMPC_REDUCTION_unknown && 13685 "Unexpected lastprivate modifier."); 13686 Res = ActOnOpenMPReductionClause( 13687 VarList, static_cast<OpenMPReductionClauseModifier>(ExtraModifier), 13688 StartLoc, LParenLoc, ExtraModifierLoc, ColonLoc, EndLoc, 13689 ReductionOrMapperIdScopeSpec, ReductionOrMapperId); 13690 break; 13691 case OMPC_task_reduction: 13692 Res = ActOnOpenMPTaskReductionClause(VarList, StartLoc, LParenLoc, ColonLoc, 13693 EndLoc, ReductionOrMapperIdScopeSpec, 13694 ReductionOrMapperId); 13695 break; 13696 case OMPC_in_reduction: 13697 Res = ActOnOpenMPInReductionClause(VarList, StartLoc, LParenLoc, ColonLoc, 13698 EndLoc, ReductionOrMapperIdScopeSpec, 13699 ReductionOrMapperId); 13700 break; 13701 case OMPC_linear: 13702 assert(0 <= ExtraModifier && ExtraModifier <= OMPC_LINEAR_unknown && 13703 "Unexpected linear modifier."); 13704 Res = ActOnOpenMPLinearClause( 13705 VarList, DepModOrTailExpr, StartLoc, LParenLoc, 13706 static_cast<OpenMPLinearClauseKind>(ExtraModifier), ExtraModifierLoc, 13707 ColonLoc, EndLoc); 13708 break; 13709 case OMPC_aligned: 13710 Res = ActOnOpenMPAlignedClause(VarList, DepModOrTailExpr, StartLoc, 13711 LParenLoc, ColonLoc, EndLoc); 13712 break; 13713 case OMPC_copyin: 13714 Res = ActOnOpenMPCopyinClause(VarList, StartLoc, LParenLoc, EndLoc); 13715 break; 13716 case OMPC_copyprivate: 13717 Res = ActOnOpenMPCopyprivateClause(VarList, StartLoc, LParenLoc, EndLoc); 13718 break; 13719 case OMPC_flush: 13720 Res = ActOnOpenMPFlushClause(VarList, StartLoc, LParenLoc, EndLoc); 13721 break; 13722 case OMPC_depend: 13723 assert(0 <= ExtraModifier && ExtraModifier <= OMPC_DEPEND_unknown && 13724 "Unexpected depend modifier."); 13725 Res = ActOnOpenMPDependClause( 13726 DepModOrTailExpr, static_cast<OpenMPDependClauseKind>(ExtraModifier), 13727 ExtraModifierLoc, ColonLoc, VarList, StartLoc, LParenLoc, EndLoc); 13728 break; 13729 case OMPC_map: 13730 assert(0 <= ExtraModifier && ExtraModifier <= OMPC_MAP_unknown && 13731 "Unexpected map modifier."); 13732 Res = ActOnOpenMPMapClause( 13733 MapTypeModifiers, MapTypeModifiersLoc, ReductionOrMapperIdScopeSpec, 13734 ReductionOrMapperId, static_cast<OpenMPMapClauseKind>(ExtraModifier), 13735 IsMapTypeImplicit, ExtraModifierLoc, ColonLoc, VarList, Locs); 13736 break; 13737 case OMPC_to: 13738 Res = ActOnOpenMPToClause(MotionModifiers, MotionModifiersLoc, 13739 ReductionOrMapperIdScopeSpec, ReductionOrMapperId, 13740 ColonLoc, VarList, Locs); 13741 break; 13742 case OMPC_from: 13743 Res = ActOnOpenMPFromClause(MotionModifiers, MotionModifiersLoc, 13744 ReductionOrMapperIdScopeSpec, 13745 ReductionOrMapperId, ColonLoc, VarList, Locs); 13746 break; 13747 case OMPC_use_device_ptr: 13748 Res = ActOnOpenMPUseDevicePtrClause(VarList, Locs); 13749 break; 13750 case OMPC_use_device_addr: 13751 Res = ActOnOpenMPUseDeviceAddrClause(VarList, Locs); 13752 break; 13753 case OMPC_is_device_ptr: 13754 Res = ActOnOpenMPIsDevicePtrClause(VarList, Locs); 13755 break; 13756 case OMPC_allocate: 13757 Res = ActOnOpenMPAllocateClause(DepModOrTailExpr, VarList, StartLoc, 13758 LParenLoc, ColonLoc, EndLoc); 13759 break; 13760 case OMPC_nontemporal: 13761 Res = ActOnOpenMPNontemporalClause(VarList, StartLoc, LParenLoc, EndLoc); 13762 break; 13763 case OMPC_inclusive: 13764 Res = ActOnOpenMPInclusiveClause(VarList, StartLoc, LParenLoc, EndLoc); 13765 break; 13766 case OMPC_exclusive: 13767 Res = ActOnOpenMPExclusiveClause(VarList, StartLoc, LParenLoc, EndLoc); 13768 break; 13769 case OMPC_affinity: 13770 Res = ActOnOpenMPAffinityClause(StartLoc, LParenLoc, ColonLoc, EndLoc, 13771 DepModOrTailExpr, VarList); 13772 break; 13773 case OMPC_if: 13774 case OMPC_depobj: 13775 case OMPC_final: 13776 case OMPC_num_threads: 13777 case OMPC_safelen: 13778 case OMPC_simdlen: 13779 case OMPC_allocator: 13780 case OMPC_collapse: 13781 case OMPC_default: 13782 case OMPC_proc_bind: 13783 case OMPC_schedule: 13784 case OMPC_ordered: 13785 case OMPC_nowait: 13786 case OMPC_untied: 13787 case OMPC_mergeable: 13788 case OMPC_threadprivate: 13789 case OMPC_read: 13790 case OMPC_write: 13791 case OMPC_update: 13792 case OMPC_capture: 13793 case OMPC_seq_cst: 13794 case OMPC_acq_rel: 13795 case OMPC_acquire: 13796 case OMPC_release: 13797 case OMPC_relaxed: 13798 case OMPC_device: 13799 case OMPC_threads: 13800 case OMPC_simd: 13801 case OMPC_num_teams: 13802 case OMPC_thread_limit: 13803 case OMPC_priority: 13804 case OMPC_grainsize: 13805 case OMPC_nogroup: 13806 case OMPC_num_tasks: 13807 case OMPC_hint: 13808 case OMPC_dist_schedule: 13809 case OMPC_defaultmap: 13810 case OMPC_unknown: 13811 case OMPC_uniform: 13812 case OMPC_unified_address: 13813 case OMPC_unified_shared_memory: 13814 case OMPC_reverse_offload: 13815 case OMPC_dynamic_allocators: 13816 case OMPC_atomic_default_mem_order: 13817 case OMPC_device_type: 13818 case OMPC_match: 13819 case OMPC_order: 13820 case OMPC_destroy: 13821 case OMPC_detach: 13822 case OMPC_uses_allocators: 13823 default: 13824 llvm_unreachable("Clause is not allowed."); 13825 } 13826 return Res; 13827 } 13828 13829 ExprResult Sema::getOpenMPCapturedExpr(VarDecl *Capture, ExprValueKind VK, 13830 ExprObjectKind OK, SourceLocation Loc) { 13831 ExprResult Res = BuildDeclRefExpr( 13832 Capture, Capture->getType().getNonReferenceType(), VK_LValue, Loc); 13833 if (!Res.isUsable()) 13834 return ExprError(); 13835 if (OK == OK_Ordinary && !getLangOpts().CPlusPlus) { 13836 Res = CreateBuiltinUnaryOp(Loc, UO_Deref, Res.get()); 13837 if (!Res.isUsable()) 13838 return ExprError(); 13839 } 13840 if (VK != VK_LValue && Res.get()->isGLValue()) { 13841 Res = DefaultLvalueConversion(Res.get()); 13842 if (!Res.isUsable()) 13843 return ExprError(); 13844 } 13845 return Res; 13846 } 13847 13848 OMPClause *Sema::ActOnOpenMPPrivateClause(ArrayRef<Expr *> VarList, 13849 SourceLocation StartLoc, 13850 SourceLocation LParenLoc, 13851 SourceLocation EndLoc) { 13852 SmallVector<Expr *, 8> Vars; 13853 SmallVector<Expr *, 8> PrivateCopies; 13854 for (Expr *RefExpr : VarList) { 13855 assert(RefExpr && "NULL expr in OpenMP private clause."); 13856 SourceLocation ELoc; 13857 SourceRange ERange; 13858 Expr *SimpleRefExpr = RefExpr; 13859 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 13860 if (Res.second) { 13861 // It will be analyzed later. 13862 Vars.push_back(RefExpr); 13863 PrivateCopies.push_back(nullptr); 13864 } 13865 ValueDecl *D = Res.first; 13866 if (!D) 13867 continue; 13868 13869 QualType Type = D->getType(); 13870 auto *VD = dyn_cast<VarDecl>(D); 13871 13872 // OpenMP [2.9.3.3, Restrictions, C/C++, p.3] 13873 // A variable that appears in a private clause must not have an incomplete 13874 // type or a reference type. 13875 if (RequireCompleteType(ELoc, Type, diag::err_omp_private_incomplete_type)) 13876 continue; 13877 Type = Type.getNonReferenceType(); 13878 13879 // OpenMP 5.0 [2.19.3, List Item Privatization, Restrictions] 13880 // A variable that is privatized must not have a const-qualified type 13881 // unless it is of class type with a mutable member. This restriction does 13882 // not apply to the firstprivate clause. 13883 // 13884 // OpenMP 3.1 [2.9.3.3, private clause, Restrictions] 13885 // A variable that appears in a private clause must not have a 13886 // const-qualified type unless it is of class type with a mutable member. 13887 if (rejectConstNotMutableType(*this, D, Type, OMPC_private, ELoc)) 13888 continue; 13889 13890 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 13891 // in a Construct] 13892 // Variables with the predetermined data-sharing attributes may not be 13893 // listed in data-sharing attributes clauses, except for the cases 13894 // listed below. For these exceptions only, listing a predetermined 13895 // variable in a data-sharing attribute clause is allowed and overrides 13896 // the variable's predetermined data-sharing attributes. 13897 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false); 13898 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_private) { 13899 Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind) 13900 << getOpenMPClauseName(OMPC_private); 13901 reportOriginalDsa(*this, DSAStack, D, DVar); 13902 continue; 13903 } 13904 13905 OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective(); 13906 // Variably modified types are not supported for tasks. 13907 if (!Type->isAnyPointerType() && Type->isVariablyModifiedType() && 13908 isOpenMPTaskingDirective(CurrDir)) { 13909 Diag(ELoc, diag::err_omp_variably_modified_type_not_supported) 13910 << getOpenMPClauseName(OMPC_private) << Type 13911 << getOpenMPDirectiveName(CurrDir); 13912 bool IsDecl = 13913 !VD || 13914 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 13915 Diag(D->getLocation(), 13916 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 13917 << D; 13918 continue; 13919 } 13920 13921 // OpenMP 4.5 [2.15.5.1, Restrictions, p.3] 13922 // A list item cannot appear in both a map clause and a data-sharing 13923 // attribute clause on the same construct 13924 // 13925 // OpenMP 5.0 [2.19.7.1, Restrictions, p.7] 13926 // A list item cannot appear in both a map clause and a data-sharing 13927 // attribute clause on the same construct unless the construct is a 13928 // combined construct. 13929 if ((LangOpts.OpenMP <= 45 && isOpenMPTargetExecutionDirective(CurrDir)) || 13930 CurrDir == OMPD_target) { 13931 OpenMPClauseKind ConflictKind; 13932 if (DSAStack->checkMappableExprComponentListsForDecl( 13933 VD, /*CurrentRegionOnly=*/true, 13934 [&](OMPClauseMappableExprCommon::MappableExprComponentListRef, 13935 OpenMPClauseKind WhereFoundClauseKind) -> bool { 13936 ConflictKind = WhereFoundClauseKind; 13937 return true; 13938 })) { 13939 Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa) 13940 << getOpenMPClauseName(OMPC_private) 13941 << getOpenMPClauseName(ConflictKind) 13942 << getOpenMPDirectiveName(CurrDir); 13943 reportOriginalDsa(*this, DSAStack, D, DVar); 13944 continue; 13945 } 13946 } 13947 13948 // OpenMP [2.9.3.3, Restrictions, C/C++, p.1] 13949 // A variable of class type (or array thereof) that appears in a private 13950 // clause requires an accessible, unambiguous default constructor for the 13951 // class type. 13952 // Generate helper private variable and initialize it with the default 13953 // value. The address of the original variable is replaced by the address of 13954 // the new private variable in CodeGen. This new variable is not added to 13955 // IdResolver, so the code in the OpenMP region uses original variable for 13956 // proper diagnostics. 13957 Type = Type.getUnqualifiedType(); 13958 VarDecl *VDPrivate = 13959 buildVarDecl(*this, ELoc, Type, D->getName(), 13960 D->hasAttrs() ? &D->getAttrs() : nullptr, 13961 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr); 13962 ActOnUninitializedDecl(VDPrivate); 13963 if (VDPrivate->isInvalidDecl()) 13964 continue; 13965 DeclRefExpr *VDPrivateRefExpr = buildDeclRefExpr( 13966 *this, VDPrivate, RefExpr->getType().getUnqualifiedType(), ELoc); 13967 13968 DeclRefExpr *Ref = nullptr; 13969 if (!VD && !CurContext->isDependentContext()) 13970 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false); 13971 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_private, Ref); 13972 Vars.push_back((VD || CurContext->isDependentContext()) 13973 ? RefExpr->IgnoreParens() 13974 : Ref); 13975 PrivateCopies.push_back(VDPrivateRefExpr); 13976 } 13977 13978 if (Vars.empty()) 13979 return nullptr; 13980 13981 return OMPPrivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars, 13982 PrivateCopies); 13983 } 13984 13985 namespace { 13986 class DiagsUninitializedSeveretyRAII { 13987 private: 13988 DiagnosticsEngine &Diags; 13989 SourceLocation SavedLoc; 13990 bool IsIgnored = false; 13991 13992 public: 13993 DiagsUninitializedSeveretyRAII(DiagnosticsEngine &Diags, SourceLocation Loc, 13994 bool IsIgnored) 13995 : Diags(Diags), SavedLoc(Loc), IsIgnored(IsIgnored) { 13996 if (!IsIgnored) { 13997 Diags.setSeverity(/*Diag*/ diag::warn_uninit_self_reference_in_init, 13998 /*Map*/ diag::Severity::Ignored, Loc); 13999 } 14000 } 14001 ~DiagsUninitializedSeveretyRAII() { 14002 if (!IsIgnored) 14003 Diags.popMappings(SavedLoc); 14004 } 14005 }; 14006 } 14007 14008 OMPClause *Sema::ActOnOpenMPFirstprivateClause(ArrayRef<Expr *> VarList, 14009 SourceLocation StartLoc, 14010 SourceLocation LParenLoc, 14011 SourceLocation EndLoc) { 14012 SmallVector<Expr *, 8> Vars; 14013 SmallVector<Expr *, 8> PrivateCopies; 14014 SmallVector<Expr *, 8> Inits; 14015 SmallVector<Decl *, 4> ExprCaptures; 14016 bool IsImplicitClause = 14017 StartLoc.isInvalid() && LParenLoc.isInvalid() && EndLoc.isInvalid(); 14018 SourceLocation ImplicitClauseLoc = DSAStack->getConstructLoc(); 14019 14020 for (Expr *RefExpr : VarList) { 14021 assert(RefExpr && "NULL expr in OpenMP firstprivate clause."); 14022 SourceLocation ELoc; 14023 SourceRange ERange; 14024 Expr *SimpleRefExpr = RefExpr; 14025 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 14026 if (Res.second) { 14027 // It will be analyzed later. 14028 Vars.push_back(RefExpr); 14029 PrivateCopies.push_back(nullptr); 14030 Inits.push_back(nullptr); 14031 } 14032 ValueDecl *D = Res.first; 14033 if (!D) 14034 continue; 14035 14036 ELoc = IsImplicitClause ? ImplicitClauseLoc : ELoc; 14037 QualType Type = D->getType(); 14038 auto *VD = dyn_cast<VarDecl>(D); 14039 14040 // OpenMP [2.9.3.3, Restrictions, C/C++, p.3] 14041 // A variable that appears in a private clause must not have an incomplete 14042 // type or a reference type. 14043 if (RequireCompleteType(ELoc, Type, 14044 diag::err_omp_firstprivate_incomplete_type)) 14045 continue; 14046 Type = Type.getNonReferenceType(); 14047 14048 // OpenMP [2.9.3.4, Restrictions, C/C++, p.1] 14049 // A variable of class type (or array thereof) that appears in a private 14050 // clause requires an accessible, unambiguous copy constructor for the 14051 // class type. 14052 QualType ElemType = Context.getBaseElementType(Type).getNonReferenceType(); 14053 14054 // If an implicit firstprivate variable found it was checked already. 14055 DSAStackTy::DSAVarData TopDVar; 14056 if (!IsImplicitClause) { 14057 DSAStackTy::DSAVarData DVar = 14058 DSAStack->getTopDSA(D, /*FromParent=*/false); 14059 TopDVar = DVar; 14060 OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective(); 14061 bool IsConstant = ElemType.isConstant(Context); 14062 // OpenMP [2.4.13, Data-sharing Attribute Clauses] 14063 // A list item that specifies a given variable may not appear in more 14064 // than one clause on the same directive, except that a variable may be 14065 // specified in both firstprivate and lastprivate clauses. 14066 // OpenMP 4.5 [2.10.8, Distribute Construct, p.3] 14067 // A list item may appear in a firstprivate or lastprivate clause but not 14068 // both. 14069 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_firstprivate && 14070 (isOpenMPDistributeDirective(CurrDir) || 14071 DVar.CKind != OMPC_lastprivate) && 14072 DVar.RefExpr) { 14073 Diag(ELoc, diag::err_omp_wrong_dsa) 14074 << getOpenMPClauseName(DVar.CKind) 14075 << getOpenMPClauseName(OMPC_firstprivate); 14076 reportOriginalDsa(*this, DSAStack, D, DVar); 14077 continue; 14078 } 14079 14080 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 14081 // in a Construct] 14082 // Variables with the predetermined data-sharing attributes may not be 14083 // listed in data-sharing attributes clauses, except for the cases 14084 // listed below. For these exceptions only, listing a predetermined 14085 // variable in a data-sharing attribute clause is allowed and overrides 14086 // the variable's predetermined data-sharing attributes. 14087 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 14088 // in a Construct, C/C++, p.2] 14089 // Variables with const-qualified type having no mutable member may be 14090 // listed in a firstprivate clause, even if they are static data members. 14091 if (!(IsConstant || (VD && VD->isStaticDataMember())) && !DVar.RefExpr && 14092 DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_shared) { 14093 Diag(ELoc, diag::err_omp_wrong_dsa) 14094 << getOpenMPClauseName(DVar.CKind) 14095 << getOpenMPClauseName(OMPC_firstprivate); 14096 reportOriginalDsa(*this, DSAStack, D, DVar); 14097 continue; 14098 } 14099 14100 // OpenMP [2.9.3.4, Restrictions, p.2] 14101 // A list item that is private within a parallel region must not appear 14102 // in a firstprivate clause on a worksharing construct if any of the 14103 // worksharing regions arising from the worksharing construct ever bind 14104 // to any of the parallel regions arising from the parallel construct. 14105 // OpenMP 4.5 [2.15.3.4, Restrictions, p.3] 14106 // A list item that is private within a teams region must not appear in a 14107 // firstprivate clause on a distribute construct if any of the distribute 14108 // regions arising from the distribute construct ever bind to any of the 14109 // teams regions arising from the teams construct. 14110 // OpenMP 4.5 [2.15.3.4, Restrictions, p.3] 14111 // A list item that appears in a reduction clause of a teams construct 14112 // must not appear in a firstprivate clause on a distribute construct if 14113 // any of the distribute regions arising from the distribute construct 14114 // ever bind to any of the teams regions arising from the teams construct. 14115 if ((isOpenMPWorksharingDirective(CurrDir) || 14116 isOpenMPDistributeDirective(CurrDir)) && 14117 !isOpenMPParallelDirective(CurrDir) && 14118 !isOpenMPTeamsDirective(CurrDir)) { 14119 DVar = DSAStack->getImplicitDSA(D, true); 14120 if (DVar.CKind != OMPC_shared && 14121 (isOpenMPParallelDirective(DVar.DKind) || 14122 isOpenMPTeamsDirective(DVar.DKind) || 14123 DVar.DKind == OMPD_unknown)) { 14124 Diag(ELoc, diag::err_omp_required_access) 14125 << getOpenMPClauseName(OMPC_firstprivate) 14126 << getOpenMPClauseName(OMPC_shared); 14127 reportOriginalDsa(*this, DSAStack, D, DVar); 14128 continue; 14129 } 14130 } 14131 // OpenMP [2.9.3.4, Restrictions, p.3] 14132 // A list item that appears in a reduction clause of a parallel construct 14133 // must not appear in a firstprivate clause on a worksharing or task 14134 // construct if any of the worksharing or task regions arising from the 14135 // worksharing or task construct ever bind to any of the parallel regions 14136 // arising from the parallel construct. 14137 // OpenMP [2.9.3.4, Restrictions, p.4] 14138 // A list item that appears in a reduction clause in worksharing 14139 // construct must not appear in a firstprivate clause in a task construct 14140 // encountered during execution of any of the worksharing regions arising 14141 // from the worksharing construct. 14142 if (isOpenMPTaskingDirective(CurrDir)) { 14143 DVar = DSAStack->hasInnermostDSA( 14144 D, 14145 [](OpenMPClauseKind C, bool AppliedToPointee) { 14146 return C == OMPC_reduction && !AppliedToPointee; 14147 }, 14148 [](OpenMPDirectiveKind K) { 14149 return isOpenMPParallelDirective(K) || 14150 isOpenMPWorksharingDirective(K) || 14151 isOpenMPTeamsDirective(K); 14152 }, 14153 /*FromParent=*/true); 14154 if (DVar.CKind == OMPC_reduction && 14155 (isOpenMPParallelDirective(DVar.DKind) || 14156 isOpenMPWorksharingDirective(DVar.DKind) || 14157 isOpenMPTeamsDirective(DVar.DKind))) { 14158 Diag(ELoc, diag::err_omp_parallel_reduction_in_task_firstprivate) 14159 << getOpenMPDirectiveName(DVar.DKind); 14160 reportOriginalDsa(*this, DSAStack, D, DVar); 14161 continue; 14162 } 14163 } 14164 14165 // OpenMP 4.5 [2.15.5.1, Restrictions, p.3] 14166 // A list item cannot appear in both a map clause and a data-sharing 14167 // attribute clause on the same construct 14168 // 14169 // OpenMP 5.0 [2.19.7.1, Restrictions, p.7] 14170 // A list item cannot appear in both a map clause and a data-sharing 14171 // attribute clause on the same construct unless the construct is a 14172 // combined construct. 14173 if ((LangOpts.OpenMP <= 45 && 14174 isOpenMPTargetExecutionDirective(CurrDir)) || 14175 CurrDir == OMPD_target) { 14176 OpenMPClauseKind ConflictKind; 14177 if (DSAStack->checkMappableExprComponentListsForDecl( 14178 VD, /*CurrentRegionOnly=*/true, 14179 [&ConflictKind]( 14180 OMPClauseMappableExprCommon::MappableExprComponentListRef, 14181 OpenMPClauseKind WhereFoundClauseKind) { 14182 ConflictKind = WhereFoundClauseKind; 14183 return true; 14184 })) { 14185 Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa) 14186 << getOpenMPClauseName(OMPC_firstprivate) 14187 << getOpenMPClauseName(ConflictKind) 14188 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 14189 reportOriginalDsa(*this, DSAStack, D, DVar); 14190 continue; 14191 } 14192 } 14193 } 14194 14195 // Variably modified types are not supported for tasks. 14196 if (!Type->isAnyPointerType() && Type->isVariablyModifiedType() && 14197 isOpenMPTaskingDirective(DSAStack->getCurrentDirective())) { 14198 Diag(ELoc, diag::err_omp_variably_modified_type_not_supported) 14199 << getOpenMPClauseName(OMPC_firstprivate) << Type 14200 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 14201 bool IsDecl = 14202 !VD || 14203 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 14204 Diag(D->getLocation(), 14205 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 14206 << D; 14207 continue; 14208 } 14209 14210 Type = Type.getUnqualifiedType(); 14211 VarDecl *VDPrivate = 14212 buildVarDecl(*this, ELoc, Type, D->getName(), 14213 D->hasAttrs() ? &D->getAttrs() : nullptr, 14214 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr); 14215 // Generate helper private variable and initialize it with the value of the 14216 // original variable. The address of the original variable is replaced by 14217 // the address of the new private variable in the CodeGen. This new variable 14218 // is not added to IdResolver, so the code in the OpenMP region uses 14219 // original variable for proper diagnostics and variable capturing. 14220 Expr *VDInitRefExpr = nullptr; 14221 // For arrays generate initializer for single element and replace it by the 14222 // original array element in CodeGen. 14223 if (Type->isArrayType()) { 14224 VarDecl *VDInit = 14225 buildVarDecl(*this, RefExpr->getExprLoc(), ElemType, D->getName()); 14226 VDInitRefExpr = buildDeclRefExpr(*this, VDInit, ElemType, ELoc); 14227 Expr *Init = DefaultLvalueConversion(VDInitRefExpr).get(); 14228 ElemType = ElemType.getUnqualifiedType(); 14229 VarDecl *VDInitTemp = buildVarDecl(*this, RefExpr->getExprLoc(), ElemType, 14230 ".firstprivate.temp"); 14231 InitializedEntity Entity = 14232 InitializedEntity::InitializeVariable(VDInitTemp); 14233 InitializationKind Kind = InitializationKind::CreateCopy(ELoc, ELoc); 14234 14235 InitializationSequence InitSeq(*this, Entity, Kind, Init); 14236 ExprResult Result = InitSeq.Perform(*this, Entity, Kind, Init); 14237 if (Result.isInvalid()) 14238 VDPrivate->setInvalidDecl(); 14239 else 14240 VDPrivate->setInit(Result.getAs<Expr>()); 14241 // Remove temp variable declaration. 14242 Context.Deallocate(VDInitTemp); 14243 } else { 14244 VarDecl *VDInit = buildVarDecl(*this, RefExpr->getExprLoc(), Type, 14245 ".firstprivate.temp"); 14246 VDInitRefExpr = buildDeclRefExpr(*this, VDInit, RefExpr->getType(), 14247 RefExpr->getExprLoc()); 14248 AddInitializerToDecl(VDPrivate, 14249 DefaultLvalueConversion(VDInitRefExpr).get(), 14250 /*DirectInit=*/false); 14251 } 14252 if (VDPrivate->isInvalidDecl()) { 14253 if (IsImplicitClause) { 14254 Diag(RefExpr->getExprLoc(), 14255 diag::note_omp_task_predetermined_firstprivate_here); 14256 } 14257 continue; 14258 } 14259 CurContext->addDecl(VDPrivate); 14260 DeclRefExpr *VDPrivateRefExpr = buildDeclRefExpr( 14261 *this, VDPrivate, RefExpr->getType().getUnqualifiedType(), 14262 RefExpr->getExprLoc()); 14263 DeclRefExpr *Ref = nullptr; 14264 if (!VD && !CurContext->isDependentContext()) { 14265 if (TopDVar.CKind == OMPC_lastprivate) { 14266 Ref = TopDVar.PrivateCopy; 14267 } else { 14268 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true); 14269 if (!isOpenMPCapturedDecl(D)) 14270 ExprCaptures.push_back(Ref->getDecl()); 14271 } 14272 } 14273 if (!IsImplicitClause) 14274 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_firstprivate, Ref); 14275 Vars.push_back((VD || CurContext->isDependentContext()) 14276 ? RefExpr->IgnoreParens() 14277 : Ref); 14278 PrivateCopies.push_back(VDPrivateRefExpr); 14279 Inits.push_back(VDInitRefExpr); 14280 } 14281 14282 if (Vars.empty()) 14283 return nullptr; 14284 14285 return OMPFirstprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, 14286 Vars, PrivateCopies, Inits, 14287 buildPreInits(Context, ExprCaptures)); 14288 } 14289 14290 OMPClause *Sema::ActOnOpenMPLastprivateClause( 14291 ArrayRef<Expr *> VarList, OpenMPLastprivateModifier LPKind, 14292 SourceLocation LPKindLoc, SourceLocation ColonLoc, SourceLocation StartLoc, 14293 SourceLocation LParenLoc, SourceLocation EndLoc) { 14294 if (LPKind == OMPC_LASTPRIVATE_unknown && LPKindLoc.isValid()) { 14295 assert(ColonLoc.isValid() && "Colon location must be valid."); 14296 Diag(LPKindLoc, diag::err_omp_unexpected_clause_value) 14297 << getListOfPossibleValues(OMPC_lastprivate, /*First=*/0, 14298 /*Last=*/OMPC_LASTPRIVATE_unknown) 14299 << getOpenMPClauseName(OMPC_lastprivate); 14300 return nullptr; 14301 } 14302 14303 SmallVector<Expr *, 8> Vars; 14304 SmallVector<Expr *, 8> SrcExprs; 14305 SmallVector<Expr *, 8> DstExprs; 14306 SmallVector<Expr *, 8> AssignmentOps; 14307 SmallVector<Decl *, 4> ExprCaptures; 14308 SmallVector<Expr *, 4> ExprPostUpdates; 14309 for (Expr *RefExpr : VarList) { 14310 assert(RefExpr && "NULL expr in OpenMP lastprivate clause."); 14311 SourceLocation ELoc; 14312 SourceRange ERange; 14313 Expr *SimpleRefExpr = RefExpr; 14314 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 14315 if (Res.second) { 14316 // It will be analyzed later. 14317 Vars.push_back(RefExpr); 14318 SrcExprs.push_back(nullptr); 14319 DstExprs.push_back(nullptr); 14320 AssignmentOps.push_back(nullptr); 14321 } 14322 ValueDecl *D = Res.first; 14323 if (!D) 14324 continue; 14325 14326 QualType Type = D->getType(); 14327 auto *VD = dyn_cast<VarDecl>(D); 14328 14329 // OpenMP [2.14.3.5, Restrictions, C/C++, p.2] 14330 // A variable that appears in a lastprivate clause must not have an 14331 // incomplete type or a reference type. 14332 if (RequireCompleteType(ELoc, Type, 14333 diag::err_omp_lastprivate_incomplete_type)) 14334 continue; 14335 Type = Type.getNonReferenceType(); 14336 14337 // OpenMP 5.0 [2.19.3, List Item Privatization, Restrictions] 14338 // A variable that is privatized must not have a const-qualified type 14339 // unless it is of class type with a mutable member. This restriction does 14340 // not apply to the firstprivate clause. 14341 // 14342 // OpenMP 3.1 [2.9.3.5, lastprivate clause, Restrictions] 14343 // A variable that appears in a lastprivate clause must not have a 14344 // const-qualified type unless it is of class type with a mutable member. 14345 if (rejectConstNotMutableType(*this, D, Type, OMPC_lastprivate, ELoc)) 14346 continue; 14347 14348 // OpenMP 5.0 [2.19.4.5 lastprivate Clause, Restrictions] 14349 // A list item that appears in a lastprivate clause with the conditional 14350 // modifier must be a scalar variable. 14351 if (LPKind == OMPC_LASTPRIVATE_conditional && !Type->isScalarType()) { 14352 Diag(ELoc, diag::err_omp_lastprivate_conditional_non_scalar); 14353 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) == 14354 VarDecl::DeclarationOnly; 14355 Diag(D->getLocation(), 14356 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 14357 << D; 14358 continue; 14359 } 14360 14361 OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective(); 14362 // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables Referenced 14363 // in a Construct] 14364 // Variables with the predetermined data-sharing attributes may not be 14365 // listed in data-sharing attributes clauses, except for the cases 14366 // listed below. 14367 // OpenMP 4.5 [2.10.8, Distribute Construct, p.3] 14368 // A list item may appear in a firstprivate or lastprivate clause but not 14369 // both. 14370 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false); 14371 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_lastprivate && 14372 (isOpenMPDistributeDirective(CurrDir) || 14373 DVar.CKind != OMPC_firstprivate) && 14374 (DVar.CKind != OMPC_private || DVar.RefExpr != nullptr)) { 14375 Diag(ELoc, diag::err_omp_wrong_dsa) 14376 << getOpenMPClauseName(DVar.CKind) 14377 << getOpenMPClauseName(OMPC_lastprivate); 14378 reportOriginalDsa(*this, DSAStack, D, DVar); 14379 continue; 14380 } 14381 14382 // OpenMP [2.14.3.5, Restrictions, p.2] 14383 // A list item that is private within a parallel region, or that appears in 14384 // the reduction clause of a parallel construct, must not appear in a 14385 // lastprivate clause on a worksharing construct if any of the corresponding 14386 // worksharing regions ever binds to any of the corresponding parallel 14387 // regions. 14388 DSAStackTy::DSAVarData TopDVar = DVar; 14389 if (isOpenMPWorksharingDirective(CurrDir) && 14390 !isOpenMPParallelDirective(CurrDir) && 14391 !isOpenMPTeamsDirective(CurrDir)) { 14392 DVar = DSAStack->getImplicitDSA(D, true); 14393 if (DVar.CKind != OMPC_shared) { 14394 Diag(ELoc, diag::err_omp_required_access) 14395 << getOpenMPClauseName(OMPC_lastprivate) 14396 << getOpenMPClauseName(OMPC_shared); 14397 reportOriginalDsa(*this, DSAStack, D, DVar); 14398 continue; 14399 } 14400 } 14401 14402 // OpenMP [2.14.3.5, Restrictions, C++, p.1,2] 14403 // A variable of class type (or array thereof) that appears in a 14404 // lastprivate clause requires an accessible, unambiguous default 14405 // constructor for the class type, unless the list item is also specified 14406 // in a firstprivate clause. 14407 // A variable of class type (or array thereof) that appears in a 14408 // lastprivate clause requires an accessible, unambiguous copy assignment 14409 // operator for the class type. 14410 Type = Context.getBaseElementType(Type).getNonReferenceType(); 14411 VarDecl *SrcVD = buildVarDecl(*this, ERange.getBegin(), 14412 Type.getUnqualifiedType(), ".lastprivate.src", 14413 D->hasAttrs() ? &D->getAttrs() : nullptr); 14414 DeclRefExpr *PseudoSrcExpr = 14415 buildDeclRefExpr(*this, SrcVD, Type.getUnqualifiedType(), ELoc); 14416 VarDecl *DstVD = 14417 buildVarDecl(*this, ERange.getBegin(), Type, ".lastprivate.dst", 14418 D->hasAttrs() ? &D->getAttrs() : nullptr); 14419 DeclRefExpr *PseudoDstExpr = buildDeclRefExpr(*this, DstVD, Type, ELoc); 14420 // For arrays generate assignment operation for single element and replace 14421 // it by the original array element in CodeGen. 14422 ExprResult AssignmentOp = BuildBinOp(/*S=*/nullptr, ELoc, BO_Assign, 14423 PseudoDstExpr, PseudoSrcExpr); 14424 if (AssignmentOp.isInvalid()) 14425 continue; 14426 AssignmentOp = 14427 ActOnFinishFullExpr(AssignmentOp.get(), ELoc, /*DiscardedValue*/ false); 14428 if (AssignmentOp.isInvalid()) 14429 continue; 14430 14431 DeclRefExpr *Ref = nullptr; 14432 if (!VD && !CurContext->isDependentContext()) { 14433 if (TopDVar.CKind == OMPC_firstprivate) { 14434 Ref = TopDVar.PrivateCopy; 14435 } else { 14436 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false); 14437 if (!isOpenMPCapturedDecl(D)) 14438 ExprCaptures.push_back(Ref->getDecl()); 14439 } 14440 if ((TopDVar.CKind == OMPC_firstprivate && !TopDVar.PrivateCopy) || 14441 (!isOpenMPCapturedDecl(D) && 14442 Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>())) { 14443 ExprResult RefRes = DefaultLvalueConversion(Ref); 14444 if (!RefRes.isUsable()) 14445 continue; 14446 ExprResult PostUpdateRes = 14447 BuildBinOp(DSAStack->getCurScope(), ELoc, BO_Assign, SimpleRefExpr, 14448 RefRes.get()); 14449 if (!PostUpdateRes.isUsable()) 14450 continue; 14451 ExprPostUpdates.push_back( 14452 IgnoredValueConversions(PostUpdateRes.get()).get()); 14453 } 14454 } 14455 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_lastprivate, Ref); 14456 Vars.push_back((VD || CurContext->isDependentContext()) 14457 ? RefExpr->IgnoreParens() 14458 : Ref); 14459 SrcExprs.push_back(PseudoSrcExpr); 14460 DstExprs.push_back(PseudoDstExpr); 14461 AssignmentOps.push_back(AssignmentOp.get()); 14462 } 14463 14464 if (Vars.empty()) 14465 return nullptr; 14466 14467 return OMPLastprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, 14468 Vars, SrcExprs, DstExprs, AssignmentOps, 14469 LPKind, LPKindLoc, ColonLoc, 14470 buildPreInits(Context, ExprCaptures), 14471 buildPostUpdate(*this, ExprPostUpdates)); 14472 } 14473 14474 OMPClause *Sema::ActOnOpenMPSharedClause(ArrayRef<Expr *> VarList, 14475 SourceLocation StartLoc, 14476 SourceLocation LParenLoc, 14477 SourceLocation EndLoc) { 14478 SmallVector<Expr *, 8> Vars; 14479 for (Expr *RefExpr : VarList) { 14480 assert(RefExpr && "NULL expr in OpenMP lastprivate clause."); 14481 SourceLocation ELoc; 14482 SourceRange ERange; 14483 Expr *SimpleRefExpr = RefExpr; 14484 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 14485 if (Res.second) { 14486 // It will be analyzed later. 14487 Vars.push_back(RefExpr); 14488 } 14489 ValueDecl *D = Res.first; 14490 if (!D) 14491 continue; 14492 14493 auto *VD = dyn_cast<VarDecl>(D); 14494 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 14495 // in a Construct] 14496 // Variables with the predetermined data-sharing attributes may not be 14497 // listed in data-sharing attributes clauses, except for the cases 14498 // listed below. For these exceptions only, listing a predetermined 14499 // variable in a data-sharing attribute clause is allowed and overrides 14500 // the variable's predetermined data-sharing attributes. 14501 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false); 14502 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_shared && 14503 DVar.RefExpr) { 14504 Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind) 14505 << getOpenMPClauseName(OMPC_shared); 14506 reportOriginalDsa(*this, DSAStack, D, DVar); 14507 continue; 14508 } 14509 14510 DeclRefExpr *Ref = nullptr; 14511 if (!VD && isOpenMPCapturedDecl(D) && !CurContext->isDependentContext()) 14512 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true); 14513 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_shared, Ref); 14514 Vars.push_back((VD || !Ref || CurContext->isDependentContext()) 14515 ? RefExpr->IgnoreParens() 14516 : Ref); 14517 } 14518 14519 if (Vars.empty()) 14520 return nullptr; 14521 14522 return OMPSharedClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars); 14523 } 14524 14525 namespace { 14526 class DSARefChecker : public StmtVisitor<DSARefChecker, bool> { 14527 DSAStackTy *Stack; 14528 14529 public: 14530 bool VisitDeclRefExpr(DeclRefExpr *E) { 14531 if (auto *VD = dyn_cast<VarDecl>(E->getDecl())) { 14532 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(VD, /*FromParent=*/false); 14533 if (DVar.CKind == OMPC_shared && !DVar.RefExpr) 14534 return false; 14535 if (DVar.CKind != OMPC_unknown) 14536 return true; 14537 DSAStackTy::DSAVarData DVarPrivate = Stack->hasDSA( 14538 VD, 14539 [](OpenMPClauseKind C, bool AppliedToPointee) { 14540 return isOpenMPPrivate(C) && !AppliedToPointee; 14541 }, 14542 [](OpenMPDirectiveKind) { return true; }, 14543 /*FromParent=*/true); 14544 return DVarPrivate.CKind != OMPC_unknown; 14545 } 14546 return false; 14547 } 14548 bool VisitStmt(Stmt *S) { 14549 for (Stmt *Child : S->children()) { 14550 if (Child && Visit(Child)) 14551 return true; 14552 } 14553 return false; 14554 } 14555 explicit DSARefChecker(DSAStackTy *S) : Stack(S) {} 14556 }; 14557 } // namespace 14558 14559 namespace { 14560 // Transform MemberExpression for specified FieldDecl of current class to 14561 // DeclRefExpr to specified OMPCapturedExprDecl. 14562 class TransformExprToCaptures : public TreeTransform<TransformExprToCaptures> { 14563 typedef TreeTransform<TransformExprToCaptures> BaseTransform; 14564 ValueDecl *Field = nullptr; 14565 DeclRefExpr *CapturedExpr = nullptr; 14566 14567 public: 14568 TransformExprToCaptures(Sema &SemaRef, ValueDecl *FieldDecl) 14569 : BaseTransform(SemaRef), Field(FieldDecl), CapturedExpr(nullptr) {} 14570 14571 ExprResult TransformMemberExpr(MemberExpr *E) { 14572 if (isa<CXXThisExpr>(E->getBase()->IgnoreParenImpCasts()) && 14573 E->getMemberDecl() == Field) { 14574 CapturedExpr = buildCapture(SemaRef, Field, E, /*WithInit=*/false); 14575 return CapturedExpr; 14576 } 14577 return BaseTransform::TransformMemberExpr(E); 14578 } 14579 DeclRefExpr *getCapturedExpr() { return CapturedExpr; } 14580 }; 14581 } // namespace 14582 14583 template <typename T, typename U> 14584 static T filterLookupForUDReductionAndMapper( 14585 SmallVectorImpl<U> &Lookups, const llvm::function_ref<T(ValueDecl *)> Gen) { 14586 for (U &Set : Lookups) { 14587 for (auto *D : Set) { 14588 if (T Res = Gen(cast<ValueDecl>(D))) 14589 return Res; 14590 } 14591 } 14592 return T(); 14593 } 14594 14595 static NamedDecl *findAcceptableDecl(Sema &SemaRef, NamedDecl *D) { 14596 assert(!LookupResult::isVisible(SemaRef, D) && "not in slow case"); 14597 14598 for (auto RD : D->redecls()) { 14599 // Don't bother with extra checks if we already know this one isn't visible. 14600 if (RD == D) 14601 continue; 14602 14603 auto ND = cast<NamedDecl>(RD); 14604 if (LookupResult::isVisible(SemaRef, ND)) 14605 return ND; 14606 } 14607 14608 return nullptr; 14609 } 14610 14611 static void 14612 argumentDependentLookup(Sema &SemaRef, const DeclarationNameInfo &Id, 14613 SourceLocation Loc, QualType Ty, 14614 SmallVectorImpl<UnresolvedSet<8>> &Lookups) { 14615 // Find all of the associated namespaces and classes based on the 14616 // arguments we have. 14617 Sema::AssociatedNamespaceSet AssociatedNamespaces; 14618 Sema::AssociatedClassSet AssociatedClasses; 14619 OpaqueValueExpr OVE(Loc, Ty, VK_LValue); 14620 SemaRef.FindAssociatedClassesAndNamespaces(Loc, &OVE, AssociatedNamespaces, 14621 AssociatedClasses); 14622 14623 // C++ [basic.lookup.argdep]p3: 14624 // Let X be the lookup set produced by unqualified lookup (3.4.1) 14625 // and let Y be the lookup set produced by argument dependent 14626 // lookup (defined as follows). If X contains [...] then Y is 14627 // empty. Otherwise Y is the set of declarations found in the 14628 // namespaces associated with the argument types as described 14629 // below. The set of declarations found by the lookup of the name 14630 // is the union of X and Y. 14631 // 14632 // Here, we compute Y and add its members to the overloaded 14633 // candidate set. 14634 for (auto *NS : AssociatedNamespaces) { 14635 // When considering an associated namespace, the lookup is the 14636 // same as the lookup performed when the associated namespace is 14637 // used as a qualifier (3.4.3.2) except that: 14638 // 14639 // -- Any using-directives in the associated namespace are 14640 // ignored. 14641 // 14642 // -- Any namespace-scope friend functions declared in 14643 // associated classes are visible within their respective 14644 // namespaces even if they are not visible during an ordinary 14645 // lookup (11.4). 14646 DeclContext::lookup_result R = NS->lookup(Id.getName()); 14647 for (auto *D : R) { 14648 auto *Underlying = D; 14649 if (auto *USD = dyn_cast<UsingShadowDecl>(D)) 14650 Underlying = USD->getTargetDecl(); 14651 14652 if (!isa<OMPDeclareReductionDecl>(Underlying) && 14653 !isa<OMPDeclareMapperDecl>(Underlying)) 14654 continue; 14655 14656 if (!SemaRef.isVisible(D)) { 14657 D = findAcceptableDecl(SemaRef, D); 14658 if (!D) 14659 continue; 14660 if (auto *USD = dyn_cast<UsingShadowDecl>(D)) 14661 Underlying = USD->getTargetDecl(); 14662 } 14663 Lookups.emplace_back(); 14664 Lookups.back().addDecl(Underlying); 14665 } 14666 } 14667 } 14668 14669 static ExprResult 14670 buildDeclareReductionRef(Sema &SemaRef, SourceLocation Loc, SourceRange Range, 14671 Scope *S, CXXScopeSpec &ReductionIdScopeSpec, 14672 const DeclarationNameInfo &ReductionId, QualType Ty, 14673 CXXCastPath &BasePath, Expr *UnresolvedReduction) { 14674 if (ReductionIdScopeSpec.isInvalid()) 14675 return ExprError(); 14676 SmallVector<UnresolvedSet<8>, 4> Lookups; 14677 if (S) { 14678 LookupResult Lookup(SemaRef, ReductionId, Sema::LookupOMPReductionName); 14679 Lookup.suppressDiagnostics(); 14680 while (S && SemaRef.LookupParsedName(Lookup, S, &ReductionIdScopeSpec)) { 14681 NamedDecl *D = Lookup.getRepresentativeDecl(); 14682 do { 14683 S = S->getParent(); 14684 } while (S && !S->isDeclScope(D)); 14685 if (S) 14686 S = S->getParent(); 14687 Lookups.emplace_back(); 14688 Lookups.back().append(Lookup.begin(), Lookup.end()); 14689 Lookup.clear(); 14690 } 14691 } else if (auto *ULE = 14692 cast_or_null<UnresolvedLookupExpr>(UnresolvedReduction)) { 14693 Lookups.push_back(UnresolvedSet<8>()); 14694 Decl *PrevD = nullptr; 14695 for (NamedDecl *D : ULE->decls()) { 14696 if (D == PrevD) 14697 Lookups.push_back(UnresolvedSet<8>()); 14698 else if (auto *DRD = dyn_cast<OMPDeclareReductionDecl>(D)) 14699 Lookups.back().addDecl(DRD); 14700 PrevD = D; 14701 } 14702 } 14703 if (SemaRef.CurContext->isDependentContext() || Ty->isDependentType() || 14704 Ty->isInstantiationDependentType() || 14705 Ty->containsUnexpandedParameterPack() || 14706 filterLookupForUDReductionAndMapper<bool>(Lookups, [](ValueDecl *D) { 14707 return !D->isInvalidDecl() && 14708 (D->getType()->isDependentType() || 14709 D->getType()->isInstantiationDependentType() || 14710 D->getType()->containsUnexpandedParameterPack()); 14711 })) { 14712 UnresolvedSet<8> ResSet; 14713 for (const UnresolvedSet<8> &Set : Lookups) { 14714 if (Set.empty()) 14715 continue; 14716 ResSet.append(Set.begin(), Set.end()); 14717 // The last item marks the end of all declarations at the specified scope. 14718 ResSet.addDecl(Set[Set.size() - 1]); 14719 } 14720 return UnresolvedLookupExpr::Create( 14721 SemaRef.Context, /*NamingClass=*/nullptr, 14722 ReductionIdScopeSpec.getWithLocInContext(SemaRef.Context), ReductionId, 14723 /*ADL=*/true, /*Overloaded=*/true, ResSet.begin(), ResSet.end()); 14724 } 14725 // Lookup inside the classes. 14726 // C++ [over.match.oper]p3: 14727 // For a unary operator @ with an operand of a type whose 14728 // cv-unqualified version is T1, and for a binary operator @ with 14729 // a left operand of a type whose cv-unqualified version is T1 and 14730 // a right operand of a type whose cv-unqualified version is T2, 14731 // three sets of candidate functions, designated member 14732 // candidates, non-member candidates and built-in candidates, are 14733 // constructed as follows: 14734 // -- If T1 is a complete class type or a class currently being 14735 // defined, the set of member candidates is the result of the 14736 // qualified lookup of T1::operator@ (13.3.1.1.1); otherwise, 14737 // the set of member candidates is empty. 14738 LookupResult Lookup(SemaRef, ReductionId, Sema::LookupOMPReductionName); 14739 Lookup.suppressDiagnostics(); 14740 if (const auto *TyRec = Ty->getAs<RecordType>()) { 14741 // Complete the type if it can be completed. 14742 // If the type is neither complete nor being defined, bail out now. 14743 if (SemaRef.isCompleteType(Loc, Ty) || TyRec->isBeingDefined() || 14744 TyRec->getDecl()->getDefinition()) { 14745 Lookup.clear(); 14746 SemaRef.LookupQualifiedName(Lookup, TyRec->getDecl()); 14747 if (Lookup.empty()) { 14748 Lookups.emplace_back(); 14749 Lookups.back().append(Lookup.begin(), Lookup.end()); 14750 } 14751 } 14752 } 14753 // Perform ADL. 14754 if (SemaRef.getLangOpts().CPlusPlus) 14755 argumentDependentLookup(SemaRef, ReductionId, Loc, Ty, Lookups); 14756 if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>( 14757 Lookups, [&SemaRef, Ty](ValueDecl *D) -> ValueDecl * { 14758 if (!D->isInvalidDecl() && 14759 SemaRef.Context.hasSameType(D->getType(), Ty)) 14760 return D; 14761 return nullptr; 14762 })) 14763 return SemaRef.BuildDeclRefExpr(VD, VD->getType().getNonReferenceType(), 14764 VK_LValue, Loc); 14765 if (SemaRef.getLangOpts().CPlusPlus) { 14766 if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>( 14767 Lookups, [&SemaRef, Ty, Loc](ValueDecl *D) -> ValueDecl * { 14768 if (!D->isInvalidDecl() && 14769 SemaRef.IsDerivedFrom(Loc, Ty, D->getType()) && 14770 !Ty.isMoreQualifiedThan(D->getType())) 14771 return D; 14772 return nullptr; 14773 })) { 14774 CXXBasePaths Paths(/*FindAmbiguities=*/true, /*RecordPaths=*/true, 14775 /*DetectVirtual=*/false); 14776 if (SemaRef.IsDerivedFrom(Loc, Ty, VD->getType(), Paths)) { 14777 if (!Paths.isAmbiguous(SemaRef.Context.getCanonicalType( 14778 VD->getType().getUnqualifiedType()))) { 14779 if (SemaRef.CheckBaseClassAccess( 14780 Loc, VD->getType(), Ty, Paths.front(), 14781 /*DiagID=*/0) != Sema::AR_inaccessible) { 14782 SemaRef.BuildBasePathArray(Paths, BasePath); 14783 return SemaRef.BuildDeclRefExpr( 14784 VD, VD->getType().getNonReferenceType(), VK_LValue, Loc); 14785 } 14786 } 14787 } 14788 } 14789 } 14790 if (ReductionIdScopeSpec.isSet()) { 14791 SemaRef.Diag(Loc, diag::err_omp_not_resolved_reduction_identifier) 14792 << Ty << Range; 14793 return ExprError(); 14794 } 14795 return ExprEmpty(); 14796 } 14797 14798 namespace { 14799 /// Data for the reduction-based clauses. 14800 struct ReductionData { 14801 /// List of original reduction items. 14802 SmallVector<Expr *, 8> Vars; 14803 /// List of private copies of the reduction items. 14804 SmallVector<Expr *, 8> Privates; 14805 /// LHS expressions for the reduction_op expressions. 14806 SmallVector<Expr *, 8> LHSs; 14807 /// RHS expressions for the reduction_op expressions. 14808 SmallVector<Expr *, 8> RHSs; 14809 /// Reduction operation expression. 14810 SmallVector<Expr *, 8> ReductionOps; 14811 /// inscan copy operation expressions. 14812 SmallVector<Expr *, 8> InscanCopyOps; 14813 /// inscan copy temp array expressions for prefix sums. 14814 SmallVector<Expr *, 8> InscanCopyArrayTemps; 14815 /// inscan copy temp array element expressions for prefix sums. 14816 SmallVector<Expr *, 8> InscanCopyArrayElems; 14817 /// Taskgroup descriptors for the corresponding reduction items in 14818 /// in_reduction clauses. 14819 SmallVector<Expr *, 8> TaskgroupDescriptors; 14820 /// List of captures for clause. 14821 SmallVector<Decl *, 4> ExprCaptures; 14822 /// List of postupdate expressions. 14823 SmallVector<Expr *, 4> ExprPostUpdates; 14824 /// Reduction modifier. 14825 unsigned RedModifier = 0; 14826 ReductionData() = delete; 14827 /// Reserves required memory for the reduction data. 14828 ReductionData(unsigned Size, unsigned Modifier = 0) : RedModifier(Modifier) { 14829 Vars.reserve(Size); 14830 Privates.reserve(Size); 14831 LHSs.reserve(Size); 14832 RHSs.reserve(Size); 14833 ReductionOps.reserve(Size); 14834 if (RedModifier == OMPC_REDUCTION_inscan) { 14835 InscanCopyOps.reserve(Size); 14836 InscanCopyArrayTemps.reserve(Size); 14837 InscanCopyArrayElems.reserve(Size); 14838 } 14839 TaskgroupDescriptors.reserve(Size); 14840 ExprCaptures.reserve(Size); 14841 ExprPostUpdates.reserve(Size); 14842 } 14843 /// Stores reduction item and reduction operation only (required for dependent 14844 /// reduction item). 14845 void push(Expr *Item, Expr *ReductionOp) { 14846 Vars.emplace_back(Item); 14847 Privates.emplace_back(nullptr); 14848 LHSs.emplace_back(nullptr); 14849 RHSs.emplace_back(nullptr); 14850 ReductionOps.emplace_back(ReductionOp); 14851 TaskgroupDescriptors.emplace_back(nullptr); 14852 if (RedModifier == OMPC_REDUCTION_inscan) { 14853 InscanCopyOps.push_back(nullptr); 14854 InscanCopyArrayTemps.push_back(nullptr); 14855 InscanCopyArrayElems.push_back(nullptr); 14856 } 14857 } 14858 /// Stores reduction data. 14859 void push(Expr *Item, Expr *Private, Expr *LHS, Expr *RHS, Expr *ReductionOp, 14860 Expr *TaskgroupDescriptor, Expr *CopyOp, Expr *CopyArrayTemp, 14861 Expr *CopyArrayElem) { 14862 Vars.emplace_back(Item); 14863 Privates.emplace_back(Private); 14864 LHSs.emplace_back(LHS); 14865 RHSs.emplace_back(RHS); 14866 ReductionOps.emplace_back(ReductionOp); 14867 TaskgroupDescriptors.emplace_back(TaskgroupDescriptor); 14868 if (RedModifier == OMPC_REDUCTION_inscan) { 14869 InscanCopyOps.push_back(CopyOp); 14870 InscanCopyArrayTemps.push_back(CopyArrayTemp); 14871 InscanCopyArrayElems.push_back(CopyArrayElem); 14872 } else { 14873 assert(CopyOp == nullptr && CopyArrayTemp == nullptr && 14874 CopyArrayElem == nullptr && 14875 "Copy operation must be used for inscan reductions only."); 14876 } 14877 } 14878 }; 14879 } // namespace 14880 14881 static bool checkOMPArraySectionConstantForReduction( 14882 ASTContext &Context, const OMPArraySectionExpr *OASE, bool &SingleElement, 14883 SmallVectorImpl<llvm::APSInt> &ArraySizes) { 14884 const Expr *Length = OASE->getLength(); 14885 if (Length == nullptr) { 14886 // For array sections of the form [1:] or [:], we would need to analyze 14887 // the lower bound... 14888 if (OASE->getColonLocFirst().isValid()) 14889 return false; 14890 14891 // This is an array subscript which has implicit length 1! 14892 SingleElement = true; 14893 ArraySizes.push_back(llvm::APSInt::get(1)); 14894 } else { 14895 Expr::EvalResult Result; 14896 if (!Length->EvaluateAsInt(Result, Context)) 14897 return false; 14898 14899 llvm::APSInt ConstantLengthValue = Result.Val.getInt(); 14900 SingleElement = (ConstantLengthValue.getSExtValue() == 1); 14901 ArraySizes.push_back(ConstantLengthValue); 14902 } 14903 14904 // Get the base of this array section and walk up from there. 14905 const Expr *Base = OASE->getBase()->IgnoreParenImpCasts(); 14906 14907 // We require length = 1 for all array sections except the right-most to 14908 // guarantee that the memory region is contiguous and has no holes in it. 14909 while (const auto *TempOASE = dyn_cast<OMPArraySectionExpr>(Base)) { 14910 Length = TempOASE->getLength(); 14911 if (Length == nullptr) { 14912 // For array sections of the form [1:] or [:], we would need to analyze 14913 // the lower bound... 14914 if (OASE->getColonLocFirst().isValid()) 14915 return false; 14916 14917 // This is an array subscript which has implicit length 1! 14918 ArraySizes.push_back(llvm::APSInt::get(1)); 14919 } else { 14920 Expr::EvalResult Result; 14921 if (!Length->EvaluateAsInt(Result, Context)) 14922 return false; 14923 14924 llvm::APSInt ConstantLengthValue = Result.Val.getInt(); 14925 if (ConstantLengthValue.getSExtValue() != 1) 14926 return false; 14927 14928 ArraySizes.push_back(ConstantLengthValue); 14929 } 14930 Base = TempOASE->getBase()->IgnoreParenImpCasts(); 14931 } 14932 14933 // If we have a single element, we don't need to add the implicit lengths. 14934 if (!SingleElement) { 14935 while (const auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base)) { 14936 // Has implicit length 1! 14937 ArraySizes.push_back(llvm::APSInt::get(1)); 14938 Base = TempASE->getBase()->IgnoreParenImpCasts(); 14939 } 14940 } 14941 14942 // This array section can be privatized as a single value or as a constant 14943 // sized array. 14944 return true; 14945 } 14946 14947 static bool actOnOMPReductionKindClause( 14948 Sema &S, DSAStackTy *Stack, OpenMPClauseKind ClauseKind, 14949 ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, 14950 SourceLocation ColonLoc, SourceLocation EndLoc, 14951 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, 14952 ArrayRef<Expr *> UnresolvedReductions, ReductionData &RD) { 14953 DeclarationName DN = ReductionId.getName(); 14954 OverloadedOperatorKind OOK = DN.getCXXOverloadedOperator(); 14955 BinaryOperatorKind BOK = BO_Comma; 14956 14957 ASTContext &Context = S.Context; 14958 // OpenMP [2.14.3.6, reduction clause] 14959 // C 14960 // reduction-identifier is either an identifier or one of the following 14961 // operators: +, -, *, &, |, ^, && and || 14962 // C++ 14963 // reduction-identifier is either an id-expression or one of the following 14964 // operators: +, -, *, &, |, ^, && and || 14965 switch (OOK) { 14966 case OO_Plus: 14967 case OO_Minus: 14968 BOK = BO_Add; 14969 break; 14970 case OO_Star: 14971 BOK = BO_Mul; 14972 break; 14973 case OO_Amp: 14974 BOK = BO_And; 14975 break; 14976 case OO_Pipe: 14977 BOK = BO_Or; 14978 break; 14979 case OO_Caret: 14980 BOK = BO_Xor; 14981 break; 14982 case OO_AmpAmp: 14983 BOK = BO_LAnd; 14984 break; 14985 case OO_PipePipe: 14986 BOK = BO_LOr; 14987 break; 14988 case OO_New: 14989 case OO_Delete: 14990 case OO_Array_New: 14991 case OO_Array_Delete: 14992 case OO_Slash: 14993 case OO_Percent: 14994 case OO_Tilde: 14995 case OO_Exclaim: 14996 case OO_Equal: 14997 case OO_Less: 14998 case OO_Greater: 14999 case OO_LessEqual: 15000 case OO_GreaterEqual: 15001 case OO_PlusEqual: 15002 case OO_MinusEqual: 15003 case OO_StarEqual: 15004 case OO_SlashEqual: 15005 case OO_PercentEqual: 15006 case OO_CaretEqual: 15007 case OO_AmpEqual: 15008 case OO_PipeEqual: 15009 case OO_LessLess: 15010 case OO_GreaterGreater: 15011 case OO_LessLessEqual: 15012 case OO_GreaterGreaterEqual: 15013 case OO_EqualEqual: 15014 case OO_ExclaimEqual: 15015 case OO_Spaceship: 15016 case OO_PlusPlus: 15017 case OO_MinusMinus: 15018 case OO_Comma: 15019 case OO_ArrowStar: 15020 case OO_Arrow: 15021 case OO_Call: 15022 case OO_Subscript: 15023 case OO_Conditional: 15024 case OO_Coawait: 15025 case NUM_OVERLOADED_OPERATORS: 15026 llvm_unreachable("Unexpected reduction identifier"); 15027 case OO_None: 15028 if (IdentifierInfo *II = DN.getAsIdentifierInfo()) { 15029 if (II->isStr("max")) 15030 BOK = BO_GT; 15031 else if (II->isStr("min")) 15032 BOK = BO_LT; 15033 } 15034 break; 15035 } 15036 SourceRange ReductionIdRange; 15037 if (ReductionIdScopeSpec.isValid()) 15038 ReductionIdRange.setBegin(ReductionIdScopeSpec.getBeginLoc()); 15039 else 15040 ReductionIdRange.setBegin(ReductionId.getBeginLoc()); 15041 ReductionIdRange.setEnd(ReductionId.getEndLoc()); 15042 15043 auto IR = UnresolvedReductions.begin(), ER = UnresolvedReductions.end(); 15044 bool FirstIter = true; 15045 for (Expr *RefExpr : VarList) { 15046 assert(RefExpr && "nullptr expr in OpenMP reduction clause."); 15047 // OpenMP [2.1, C/C++] 15048 // A list item is a variable or array section, subject to the restrictions 15049 // specified in Section 2.4 on page 42 and in each of the sections 15050 // describing clauses and directives for which a list appears. 15051 // OpenMP [2.14.3.3, Restrictions, p.1] 15052 // A variable that is part of another variable (as an array or 15053 // structure element) cannot appear in a private clause. 15054 if (!FirstIter && IR != ER) 15055 ++IR; 15056 FirstIter = false; 15057 SourceLocation ELoc; 15058 SourceRange ERange; 15059 Expr *SimpleRefExpr = RefExpr; 15060 auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange, 15061 /*AllowArraySection=*/true); 15062 if (Res.second) { 15063 // Try to find 'declare reduction' corresponding construct before using 15064 // builtin/overloaded operators. 15065 QualType Type = Context.DependentTy; 15066 CXXCastPath BasePath; 15067 ExprResult DeclareReductionRef = buildDeclareReductionRef( 15068 S, ELoc, ERange, Stack->getCurScope(), ReductionIdScopeSpec, 15069 ReductionId, Type, BasePath, IR == ER ? nullptr : *IR); 15070 Expr *ReductionOp = nullptr; 15071 if (S.CurContext->isDependentContext() && 15072 (DeclareReductionRef.isUnset() || 15073 isa<UnresolvedLookupExpr>(DeclareReductionRef.get()))) 15074 ReductionOp = DeclareReductionRef.get(); 15075 // It will be analyzed later. 15076 RD.push(RefExpr, ReductionOp); 15077 } 15078 ValueDecl *D = Res.first; 15079 if (!D) 15080 continue; 15081 15082 Expr *TaskgroupDescriptor = nullptr; 15083 QualType Type; 15084 auto *ASE = dyn_cast<ArraySubscriptExpr>(RefExpr->IgnoreParens()); 15085 auto *OASE = dyn_cast<OMPArraySectionExpr>(RefExpr->IgnoreParens()); 15086 if (ASE) { 15087 Type = ASE->getType().getNonReferenceType(); 15088 } else if (OASE) { 15089 QualType BaseType = 15090 OMPArraySectionExpr::getBaseOriginalType(OASE->getBase()); 15091 if (const auto *ATy = BaseType->getAsArrayTypeUnsafe()) 15092 Type = ATy->getElementType(); 15093 else 15094 Type = BaseType->getPointeeType(); 15095 Type = Type.getNonReferenceType(); 15096 } else { 15097 Type = Context.getBaseElementType(D->getType().getNonReferenceType()); 15098 } 15099 auto *VD = dyn_cast<VarDecl>(D); 15100 15101 // OpenMP [2.9.3.3, Restrictions, C/C++, p.3] 15102 // A variable that appears in a private clause must not have an incomplete 15103 // type or a reference type. 15104 if (S.RequireCompleteType(ELoc, D->getType(), 15105 diag::err_omp_reduction_incomplete_type)) 15106 continue; 15107 // OpenMP [2.14.3.6, reduction clause, Restrictions] 15108 // A list item that appears in a reduction clause must not be 15109 // const-qualified. 15110 if (rejectConstNotMutableType(S, D, Type, ClauseKind, ELoc, 15111 /*AcceptIfMutable*/ false, ASE || OASE)) 15112 continue; 15113 15114 OpenMPDirectiveKind CurrDir = Stack->getCurrentDirective(); 15115 // OpenMP [2.9.3.6, Restrictions, C/C++, p.4] 15116 // If a list-item is a reference type then it must bind to the same object 15117 // for all threads of the team. 15118 if (!ASE && !OASE) { 15119 if (VD) { 15120 VarDecl *VDDef = VD->getDefinition(); 15121 if (VD->getType()->isReferenceType() && VDDef && VDDef->hasInit()) { 15122 DSARefChecker Check(Stack); 15123 if (Check.Visit(VDDef->getInit())) { 15124 S.Diag(ELoc, diag::err_omp_reduction_ref_type_arg) 15125 << getOpenMPClauseName(ClauseKind) << ERange; 15126 S.Diag(VDDef->getLocation(), diag::note_defined_here) << VDDef; 15127 continue; 15128 } 15129 } 15130 } 15131 15132 // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables Referenced 15133 // in a Construct] 15134 // Variables with the predetermined data-sharing attributes may not be 15135 // listed in data-sharing attributes clauses, except for the cases 15136 // listed below. For these exceptions only, listing a predetermined 15137 // variable in a data-sharing attribute clause is allowed and overrides 15138 // the variable's predetermined data-sharing attributes. 15139 // OpenMP [2.14.3.6, Restrictions, p.3] 15140 // Any number of reduction clauses can be specified on the directive, 15141 // but a list item can appear only once in the reduction clauses for that 15142 // directive. 15143 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(D, /*FromParent=*/false); 15144 if (DVar.CKind == OMPC_reduction) { 15145 S.Diag(ELoc, diag::err_omp_once_referenced) 15146 << getOpenMPClauseName(ClauseKind); 15147 if (DVar.RefExpr) 15148 S.Diag(DVar.RefExpr->getExprLoc(), diag::note_omp_referenced); 15149 continue; 15150 } 15151 if (DVar.CKind != OMPC_unknown) { 15152 S.Diag(ELoc, diag::err_omp_wrong_dsa) 15153 << getOpenMPClauseName(DVar.CKind) 15154 << getOpenMPClauseName(OMPC_reduction); 15155 reportOriginalDsa(S, Stack, D, DVar); 15156 continue; 15157 } 15158 15159 // OpenMP [2.14.3.6, Restrictions, p.1] 15160 // A list item that appears in a reduction clause of a worksharing 15161 // construct must be shared in the parallel regions to which any of the 15162 // worksharing regions arising from the worksharing construct bind. 15163 if (isOpenMPWorksharingDirective(CurrDir) && 15164 !isOpenMPParallelDirective(CurrDir) && 15165 !isOpenMPTeamsDirective(CurrDir)) { 15166 DVar = Stack->getImplicitDSA(D, true); 15167 if (DVar.CKind != OMPC_shared) { 15168 S.Diag(ELoc, diag::err_omp_required_access) 15169 << getOpenMPClauseName(OMPC_reduction) 15170 << getOpenMPClauseName(OMPC_shared); 15171 reportOriginalDsa(S, Stack, D, DVar); 15172 continue; 15173 } 15174 } 15175 } else { 15176 // Threadprivates cannot be shared between threads, so dignose if the base 15177 // is a threadprivate variable. 15178 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(D, /*FromParent=*/false); 15179 if (DVar.CKind == OMPC_threadprivate) { 15180 S.Diag(ELoc, diag::err_omp_wrong_dsa) 15181 << getOpenMPClauseName(DVar.CKind) 15182 << getOpenMPClauseName(OMPC_reduction); 15183 reportOriginalDsa(S, Stack, D, DVar); 15184 continue; 15185 } 15186 } 15187 15188 // Try to find 'declare reduction' corresponding construct before using 15189 // builtin/overloaded operators. 15190 CXXCastPath BasePath; 15191 ExprResult DeclareReductionRef = buildDeclareReductionRef( 15192 S, ELoc, ERange, Stack->getCurScope(), ReductionIdScopeSpec, 15193 ReductionId, Type, BasePath, IR == ER ? nullptr : *IR); 15194 if (DeclareReductionRef.isInvalid()) 15195 continue; 15196 if (S.CurContext->isDependentContext() && 15197 (DeclareReductionRef.isUnset() || 15198 isa<UnresolvedLookupExpr>(DeclareReductionRef.get()))) { 15199 RD.push(RefExpr, DeclareReductionRef.get()); 15200 continue; 15201 } 15202 if (BOK == BO_Comma && DeclareReductionRef.isUnset()) { 15203 // Not allowed reduction identifier is found. 15204 S.Diag(ReductionId.getBeginLoc(), 15205 diag::err_omp_unknown_reduction_identifier) 15206 << Type << ReductionIdRange; 15207 continue; 15208 } 15209 15210 // OpenMP [2.14.3.6, reduction clause, Restrictions] 15211 // The type of a list item that appears in a reduction clause must be valid 15212 // for the reduction-identifier. For a max or min reduction in C, the type 15213 // of the list item must be an allowed arithmetic data type: char, int, 15214 // float, double, or _Bool, possibly modified with long, short, signed, or 15215 // unsigned. For a max or min reduction in C++, the type of the list item 15216 // must be an allowed arithmetic data type: char, wchar_t, int, float, 15217 // double, or bool, possibly modified with long, short, signed, or unsigned. 15218 if (DeclareReductionRef.isUnset()) { 15219 if ((BOK == BO_GT || BOK == BO_LT) && 15220 !(Type->isScalarType() || 15221 (S.getLangOpts().CPlusPlus && Type->isArithmeticType()))) { 15222 S.Diag(ELoc, diag::err_omp_clause_not_arithmetic_type_arg) 15223 << getOpenMPClauseName(ClauseKind) << S.getLangOpts().CPlusPlus; 15224 if (!ASE && !OASE) { 15225 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) == 15226 VarDecl::DeclarationOnly; 15227 S.Diag(D->getLocation(), 15228 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 15229 << D; 15230 } 15231 continue; 15232 } 15233 if ((BOK == BO_OrAssign || BOK == BO_AndAssign || BOK == BO_XorAssign) && 15234 !S.getLangOpts().CPlusPlus && Type->isFloatingType()) { 15235 S.Diag(ELoc, diag::err_omp_clause_floating_type_arg) 15236 << getOpenMPClauseName(ClauseKind); 15237 if (!ASE && !OASE) { 15238 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) == 15239 VarDecl::DeclarationOnly; 15240 S.Diag(D->getLocation(), 15241 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 15242 << D; 15243 } 15244 continue; 15245 } 15246 } 15247 15248 Type = Type.getNonLValueExprType(Context).getUnqualifiedType(); 15249 VarDecl *LHSVD = buildVarDecl(S, ELoc, Type, ".reduction.lhs", 15250 D->hasAttrs() ? &D->getAttrs() : nullptr); 15251 VarDecl *RHSVD = buildVarDecl(S, ELoc, Type, D->getName(), 15252 D->hasAttrs() ? &D->getAttrs() : nullptr); 15253 QualType PrivateTy = Type; 15254 15255 // Try if we can determine constant lengths for all array sections and avoid 15256 // the VLA. 15257 bool ConstantLengthOASE = false; 15258 if (OASE) { 15259 bool SingleElement; 15260 llvm::SmallVector<llvm::APSInt, 4> ArraySizes; 15261 ConstantLengthOASE = checkOMPArraySectionConstantForReduction( 15262 Context, OASE, SingleElement, ArraySizes); 15263 15264 // If we don't have a single element, we must emit a constant array type. 15265 if (ConstantLengthOASE && !SingleElement) { 15266 for (llvm::APSInt &Size : ArraySizes) 15267 PrivateTy = Context.getConstantArrayType(PrivateTy, Size, nullptr, 15268 ArrayType::Normal, 15269 /*IndexTypeQuals=*/0); 15270 } 15271 } 15272 15273 if ((OASE && !ConstantLengthOASE) || 15274 (!OASE && !ASE && 15275 D->getType().getNonReferenceType()->isVariablyModifiedType())) { 15276 if (!Context.getTargetInfo().isVLASupported()) { 15277 if (isOpenMPTargetExecutionDirective(Stack->getCurrentDirective())) { 15278 S.Diag(ELoc, diag::err_omp_reduction_vla_unsupported) << !!OASE; 15279 S.Diag(ELoc, diag::note_vla_unsupported); 15280 continue; 15281 } else { 15282 S.targetDiag(ELoc, diag::err_omp_reduction_vla_unsupported) << !!OASE; 15283 S.targetDiag(ELoc, diag::note_vla_unsupported); 15284 } 15285 } 15286 // For arrays/array sections only: 15287 // Create pseudo array type for private copy. The size for this array will 15288 // be generated during codegen. 15289 // For array subscripts or single variables Private Ty is the same as Type 15290 // (type of the variable or single array element). 15291 PrivateTy = Context.getVariableArrayType( 15292 Type, 15293 new (Context) OpaqueValueExpr(ELoc, Context.getSizeType(), VK_RValue), 15294 ArrayType::Normal, /*IndexTypeQuals=*/0, SourceRange()); 15295 } else if (!ASE && !OASE && 15296 Context.getAsArrayType(D->getType().getNonReferenceType())) { 15297 PrivateTy = D->getType().getNonReferenceType(); 15298 } 15299 // Private copy. 15300 VarDecl *PrivateVD = 15301 buildVarDecl(S, ELoc, PrivateTy, D->getName(), 15302 D->hasAttrs() ? &D->getAttrs() : nullptr, 15303 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr); 15304 // Add initializer for private variable. 15305 Expr *Init = nullptr; 15306 DeclRefExpr *LHSDRE = buildDeclRefExpr(S, LHSVD, Type, ELoc); 15307 DeclRefExpr *RHSDRE = buildDeclRefExpr(S, RHSVD, Type, ELoc); 15308 if (DeclareReductionRef.isUsable()) { 15309 auto *DRDRef = DeclareReductionRef.getAs<DeclRefExpr>(); 15310 auto *DRD = cast<OMPDeclareReductionDecl>(DRDRef->getDecl()); 15311 if (DRD->getInitializer()) { 15312 S.ActOnUninitializedDecl(PrivateVD); 15313 Init = DRDRef; 15314 RHSVD->setInit(DRDRef); 15315 RHSVD->setInitStyle(VarDecl::CallInit); 15316 } 15317 } else { 15318 switch (BOK) { 15319 case BO_Add: 15320 case BO_Xor: 15321 case BO_Or: 15322 case BO_LOr: 15323 // '+', '-', '^', '|', '||' reduction ops - initializer is '0'. 15324 if (Type->isScalarType() || Type->isAnyComplexType()) 15325 Init = S.ActOnIntegerConstant(ELoc, /*Val=*/0).get(); 15326 break; 15327 case BO_Mul: 15328 case BO_LAnd: 15329 if (Type->isScalarType() || Type->isAnyComplexType()) { 15330 // '*' and '&&' reduction ops - initializer is '1'. 15331 Init = S.ActOnIntegerConstant(ELoc, /*Val=*/1).get(); 15332 } 15333 break; 15334 case BO_And: { 15335 // '&' reduction op - initializer is '~0'. 15336 QualType OrigType = Type; 15337 if (auto *ComplexTy = OrigType->getAs<ComplexType>()) 15338 Type = ComplexTy->getElementType(); 15339 if (Type->isRealFloatingType()) { 15340 llvm::APFloat InitValue = llvm::APFloat::getAllOnesValue( 15341 Context.getFloatTypeSemantics(Type), 15342 Context.getTypeSize(Type)); 15343 Init = FloatingLiteral::Create(Context, InitValue, /*isexact=*/true, 15344 Type, ELoc); 15345 } else if (Type->isScalarType()) { 15346 uint64_t Size = Context.getTypeSize(Type); 15347 QualType IntTy = Context.getIntTypeForBitwidth(Size, /*Signed=*/0); 15348 llvm::APInt InitValue = llvm::APInt::getAllOnesValue(Size); 15349 Init = IntegerLiteral::Create(Context, InitValue, IntTy, ELoc); 15350 } 15351 if (Init && OrigType->isAnyComplexType()) { 15352 // Init = 0xFFFF + 0xFFFFi; 15353 auto *Im = new (Context) ImaginaryLiteral(Init, OrigType); 15354 Init = S.CreateBuiltinBinOp(ELoc, BO_Add, Init, Im).get(); 15355 } 15356 Type = OrigType; 15357 break; 15358 } 15359 case BO_LT: 15360 case BO_GT: { 15361 // 'min' reduction op - initializer is 'Largest representable number in 15362 // the reduction list item type'. 15363 // 'max' reduction op - initializer is 'Least representable number in 15364 // the reduction list item type'. 15365 if (Type->isIntegerType() || Type->isPointerType()) { 15366 bool IsSigned = Type->hasSignedIntegerRepresentation(); 15367 uint64_t Size = Context.getTypeSize(Type); 15368 QualType IntTy = 15369 Context.getIntTypeForBitwidth(Size, /*Signed=*/IsSigned); 15370 llvm::APInt InitValue = 15371 (BOK != BO_LT) ? IsSigned ? llvm::APInt::getSignedMinValue(Size) 15372 : llvm::APInt::getMinValue(Size) 15373 : IsSigned ? llvm::APInt::getSignedMaxValue(Size) 15374 : llvm::APInt::getMaxValue(Size); 15375 Init = IntegerLiteral::Create(Context, InitValue, IntTy, ELoc); 15376 if (Type->isPointerType()) { 15377 // Cast to pointer type. 15378 ExprResult CastExpr = S.BuildCStyleCastExpr( 15379 ELoc, Context.getTrivialTypeSourceInfo(Type, ELoc), ELoc, Init); 15380 if (CastExpr.isInvalid()) 15381 continue; 15382 Init = CastExpr.get(); 15383 } 15384 } else if (Type->isRealFloatingType()) { 15385 llvm::APFloat InitValue = llvm::APFloat::getLargest( 15386 Context.getFloatTypeSemantics(Type), BOK != BO_LT); 15387 Init = FloatingLiteral::Create(Context, InitValue, /*isexact=*/true, 15388 Type, ELoc); 15389 } 15390 break; 15391 } 15392 case BO_PtrMemD: 15393 case BO_PtrMemI: 15394 case BO_MulAssign: 15395 case BO_Div: 15396 case BO_Rem: 15397 case BO_Sub: 15398 case BO_Shl: 15399 case BO_Shr: 15400 case BO_LE: 15401 case BO_GE: 15402 case BO_EQ: 15403 case BO_NE: 15404 case BO_Cmp: 15405 case BO_AndAssign: 15406 case BO_XorAssign: 15407 case BO_OrAssign: 15408 case BO_Assign: 15409 case BO_AddAssign: 15410 case BO_SubAssign: 15411 case BO_DivAssign: 15412 case BO_RemAssign: 15413 case BO_ShlAssign: 15414 case BO_ShrAssign: 15415 case BO_Comma: 15416 llvm_unreachable("Unexpected reduction operation"); 15417 } 15418 } 15419 if (Init && DeclareReductionRef.isUnset()) { 15420 S.AddInitializerToDecl(RHSVD, Init, /*DirectInit=*/false); 15421 // Store initializer for single element in private copy. Will be used 15422 // during codegen. 15423 PrivateVD->setInit(RHSVD->getInit()); 15424 PrivateVD->setInitStyle(RHSVD->getInitStyle()); 15425 } else if (!Init) { 15426 S.ActOnUninitializedDecl(RHSVD); 15427 // Store initializer for single element in private copy. Will be used 15428 // during codegen. 15429 PrivateVD->setInit(RHSVD->getInit()); 15430 PrivateVD->setInitStyle(RHSVD->getInitStyle()); 15431 } 15432 if (RHSVD->isInvalidDecl()) 15433 continue; 15434 if (!RHSVD->hasInit() && 15435 (DeclareReductionRef.isUnset() || !S.LangOpts.CPlusPlus)) { 15436 S.Diag(ELoc, diag::err_omp_reduction_id_not_compatible) 15437 << Type << ReductionIdRange; 15438 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) == 15439 VarDecl::DeclarationOnly; 15440 S.Diag(D->getLocation(), 15441 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 15442 << D; 15443 continue; 15444 } 15445 DeclRefExpr *PrivateDRE = buildDeclRefExpr(S, PrivateVD, PrivateTy, ELoc); 15446 ExprResult ReductionOp; 15447 if (DeclareReductionRef.isUsable()) { 15448 QualType RedTy = DeclareReductionRef.get()->getType(); 15449 QualType PtrRedTy = Context.getPointerType(RedTy); 15450 ExprResult LHS = S.CreateBuiltinUnaryOp(ELoc, UO_AddrOf, LHSDRE); 15451 ExprResult RHS = S.CreateBuiltinUnaryOp(ELoc, UO_AddrOf, RHSDRE); 15452 if (!BasePath.empty()) { 15453 LHS = S.DefaultLvalueConversion(LHS.get()); 15454 RHS = S.DefaultLvalueConversion(RHS.get()); 15455 LHS = ImplicitCastExpr::Create( 15456 Context, PtrRedTy, CK_UncheckedDerivedToBase, LHS.get(), &BasePath, 15457 LHS.get()->getValueKind(), FPOptionsOverride()); 15458 RHS = ImplicitCastExpr::Create( 15459 Context, PtrRedTy, CK_UncheckedDerivedToBase, RHS.get(), &BasePath, 15460 RHS.get()->getValueKind(), FPOptionsOverride()); 15461 } 15462 FunctionProtoType::ExtProtoInfo EPI; 15463 QualType Params[] = {PtrRedTy, PtrRedTy}; 15464 QualType FnTy = Context.getFunctionType(Context.VoidTy, Params, EPI); 15465 auto *OVE = new (Context) OpaqueValueExpr( 15466 ELoc, Context.getPointerType(FnTy), VK_RValue, OK_Ordinary, 15467 S.DefaultLvalueConversion(DeclareReductionRef.get()).get()); 15468 Expr *Args[] = {LHS.get(), RHS.get()}; 15469 ReductionOp = 15470 CallExpr::Create(Context, OVE, Args, Context.VoidTy, VK_RValue, ELoc, 15471 S.CurFPFeatureOverrides()); 15472 } else { 15473 ReductionOp = S.BuildBinOp( 15474 Stack->getCurScope(), ReductionId.getBeginLoc(), BOK, LHSDRE, RHSDRE); 15475 if (ReductionOp.isUsable()) { 15476 if (BOK != BO_LT && BOK != BO_GT) { 15477 ReductionOp = 15478 S.BuildBinOp(Stack->getCurScope(), ReductionId.getBeginLoc(), 15479 BO_Assign, LHSDRE, ReductionOp.get()); 15480 } else { 15481 auto *ConditionalOp = new (Context) 15482 ConditionalOperator(ReductionOp.get(), ELoc, LHSDRE, ELoc, RHSDRE, 15483 Type, VK_LValue, OK_Ordinary); 15484 ReductionOp = 15485 S.BuildBinOp(Stack->getCurScope(), ReductionId.getBeginLoc(), 15486 BO_Assign, LHSDRE, ConditionalOp); 15487 } 15488 if (ReductionOp.isUsable()) 15489 ReductionOp = S.ActOnFinishFullExpr(ReductionOp.get(), 15490 /*DiscardedValue*/ false); 15491 } 15492 if (!ReductionOp.isUsable()) 15493 continue; 15494 } 15495 15496 // Add copy operations for inscan reductions. 15497 // LHS = RHS; 15498 ExprResult CopyOpRes, TempArrayRes, TempArrayElem; 15499 if (ClauseKind == OMPC_reduction && 15500 RD.RedModifier == OMPC_REDUCTION_inscan) { 15501 ExprResult RHS = S.DefaultLvalueConversion(RHSDRE); 15502 CopyOpRes = S.BuildBinOp(Stack->getCurScope(), ELoc, BO_Assign, LHSDRE, 15503 RHS.get()); 15504 if (!CopyOpRes.isUsable()) 15505 continue; 15506 CopyOpRes = 15507 S.ActOnFinishFullExpr(CopyOpRes.get(), /*DiscardedValue=*/true); 15508 if (!CopyOpRes.isUsable()) 15509 continue; 15510 // For simd directive and simd-based directives in simd mode no need to 15511 // construct temp array, need just a single temp element. 15512 if (Stack->getCurrentDirective() == OMPD_simd || 15513 (S.getLangOpts().OpenMPSimd && 15514 isOpenMPSimdDirective(Stack->getCurrentDirective()))) { 15515 VarDecl *TempArrayVD = 15516 buildVarDecl(S, ELoc, PrivateTy, D->getName(), 15517 D->hasAttrs() ? &D->getAttrs() : nullptr); 15518 // Add a constructor to the temp decl. 15519 S.ActOnUninitializedDecl(TempArrayVD); 15520 TempArrayRes = buildDeclRefExpr(S, TempArrayVD, PrivateTy, ELoc); 15521 } else { 15522 // Build temp array for prefix sum. 15523 auto *Dim = new (S.Context) 15524 OpaqueValueExpr(ELoc, S.Context.getSizeType(), VK_RValue); 15525 QualType ArrayTy = 15526 S.Context.getVariableArrayType(PrivateTy, Dim, ArrayType::Normal, 15527 /*IndexTypeQuals=*/0, {ELoc, ELoc}); 15528 VarDecl *TempArrayVD = 15529 buildVarDecl(S, ELoc, ArrayTy, D->getName(), 15530 D->hasAttrs() ? &D->getAttrs() : nullptr); 15531 // Add a constructor to the temp decl. 15532 S.ActOnUninitializedDecl(TempArrayVD); 15533 TempArrayRes = buildDeclRefExpr(S, TempArrayVD, ArrayTy, ELoc); 15534 TempArrayElem = 15535 S.DefaultFunctionArrayLvalueConversion(TempArrayRes.get()); 15536 auto *Idx = new (S.Context) 15537 OpaqueValueExpr(ELoc, S.Context.getSizeType(), VK_RValue); 15538 TempArrayElem = S.CreateBuiltinArraySubscriptExpr(TempArrayElem.get(), 15539 ELoc, Idx, ELoc); 15540 } 15541 } 15542 15543 // OpenMP [2.15.4.6, Restrictions, p.2] 15544 // A list item that appears in an in_reduction clause of a task construct 15545 // must appear in a task_reduction clause of a construct associated with a 15546 // taskgroup region that includes the participating task in its taskgroup 15547 // set. The construct associated with the innermost region that meets this 15548 // condition must specify the same reduction-identifier as the in_reduction 15549 // clause. 15550 if (ClauseKind == OMPC_in_reduction) { 15551 SourceRange ParentSR; 15552 BinaryOperatorKind ParentBOK; 15553 const Expr *ParentReductionOp = nullptr; 15554 Expr *ParentBOKTD = nullptr, *ParentReductionOpTD = nullptr; 15555 DSAStackTy::DSAVarData ParentBOKDSA = 15556 Stack->getTopMostTaskgroupReductionData(D, ParentSR, ParentBOK, 15557 ParentBOKTD); 15558 DSAStackTy::DSAVarData ParentReductionOpDSA = 15559 Stack->getTopMostTaskgroupReductionData( 15560 D, ParentSR, ParentReductionOp, ParentReductionOpTD); 15561 bool IsParentBOK = ParentBOKDSA.DKind != OMPD_unknown; 15562 bool IsParentReductionOp = ParentReductionOpDSA.DKind != OMPD_unknown; 15563 if ((DeclareReductionRef.isUnset() && IsParentReductionOp) || 15564 (DeclareReductionRef.isUsable() && IsParentBOK) || 15565 (IsParentBOK && BOK != ParentBOK) || IsParentReductionOp) { 15566 bool EmitError = true; 15567 if (IsParentReductionOp && DeclareReductionRef.isUsable()) { 15568 llvm::FoldingSetNodeID RedId, ParentRedId; 15569 ParentReductionOp->Profile(ParentRedId, Context, /*Canonical=*/true); 15570 DeclareReductionRef.get()->Profile(RedId, Context, 15571 /*Canonical=*/true); 15572 EmitError = RedId != ParentRedId; 15573 } 15574 if (EmitError) { 15575 S.Diag(ReductionId.getBeginLoc(), 15576 diag::err_omp_reduction_identifier_mismatch) 15577 << ReductionIdRange << RefExpr->getSourceRange(); 15578 S.Diag(ParentSR.getBegin(), 15579 diag::note_omp_previous_reduction_identifier) 15580 << ParentSR 15581 << (IsParentBOK ? ParentBOKDSA.RefExpr 15582 : ParentReductionOpDSA.RefExpr) 15583 ->getSourceRange(); 15584 continue; 15585 } 15586 } 15587 TaskgroupDescriptor = IsParentBOK ? ParentBOKTD : ParentReductionOpTD; 15588 } 15589 15590 DeclRefExpr *Ref = nullptr; 15591 Expr *VarsExpr = RefExpr->IgnoreParens(); 15592 if (!VD && !S.CurContext->isDependentContext()) { 15593 if (ASE || OASE) { 15594 TransformExprToCaptures RebuildToCapture(S, D); 15595 VarsExpr = 15596 RebuildToCapture.TransformExpr(RefExpr->IgnoreParens()).get(); 15597 Ref = RebuildToCapture.getCapturedExpr(); 15598 } else { 15599 VarsExpr = Ref = buildCapture(S, D, SimpleRefExpr, /*WithInit=*/false); 15600 } 15601 if (!S.isOpenMPCapturedDecl(D)) { 15602 RD.ExprCaptures.emplace_back(Ref->getDecl()); 15603 if (Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>()) { 15604 ExprResult RefRes = S.DefaultLvalueConversion(Ref); 15605 if (!RefRes.isUsable()) 15606 continue; 15607 ExprResult PostUpdateRes = 15608 S.BuildBinOp(Stack->getCurScope(), ELoc, BO_Assign, SimpleRefExpr, 15609 RefRes.get()); 15610 if (!PostUpdateRes.isUsable()) 15611 continue; 15612 if (isOpenMPTaskingDirective(Stack->getCurrentDirective()) || 15613 Stack->getCurrentDirective() == OMPD_taskgroup) { 15614 S.Diag(RefExpr->getExprLoc(), 15615 diag::err_omp_reduction_non_addressable_expression) 15616 << RefExpr->getSourceRange(); 15617 continue; 15618 } 15619 RD.ExprPostUpdates.emplace_back( 15620 S.IgnoredValueConversions(PostUpdateRes.get()).get()); 15621 } 15622 } 15623 } 15624 // All reduction items are still marked as reduction (to do not increase 15625 // code base size). 15626 unsigned Modifier = RD.RedModifier; 15627 // Consider task_reductions as reductions with task modifier. Required for 15628 // correct analysis of in_reduction clauses. 15629 if (CurrDir == OMPD_taskgroup && ClauseKind == OMPC_task_reduction) 15630 Modifier = OMPC_REDUCTION_task; 15631 Stack->addDSA(D, RefExpr->IgnoreParens(), OMPC_reduction, Ref, Modifier, 15632 ASE || OASE); 15633 if (Modifier == OMPC_REDUCTION_task && 15634 (CurrDir == OMPD_taskgroup || 15635 ((isOpenMPParallelDirective(CurrDir) || 15636 isOpenMPWorksharingDirective(CurrDir)) && 15637 !isOpenMPSimdDirective(CurrDir)))) { 15638 if (DeclareReductionRef.isUsable()) 15639 Stack->addTaskgroupReductionData(D, ReductionIdRange, 15640 DeclareReductionRef.get()); 15641 else 15642 Stack->addTaskgroupReductionData(D, ReductionIdRange, BOK); 15643 } 15644 RD.push(VarsExpr, PrivateDRE, LHSDRE, RHSDRE, ReductionOp.get(), 15645 TaskgroupDescriptor, CopyOpRes.get(), TempArrayRes.get(), 15646 TempArrayElem.get()); 15647 } 15648 return RD.Vars.empty(); 15649 } 15650 15651 OMPClause *Sema::ActOnOpenMPReductionClause( 15652 ArrayRef<Expr *> VarList, OpenMPReductionClauseModifier Modifier, 15653 SourceLocation StartLoc, SourceLocation LParenLoc, 15654 SourceLocation ModifierLoc, SourceLocation ColonLoc, SourceLocation EndLoc, 15655 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, 15656 ArrayRef<Expr *> UnresolvedReductions) { 15657 if (ModifierLoc.isValid() && Modifier == OMPC_REDUCTION_unknown) { 15658 Diag(LParenLoc, diag::err_omp_unexpected_clause_value) 15659 << getListOfPossibleValues(OMPC_reduction, /*First=*/0, 15660 /*Last=*/OMPC_REDUCTION_unknown) 15661 << getOpenMPClauseName(OMPC_reduction); 15662 return nullptr; 15663 } 15664 // OpenMP 5.0, 2.19.5.4 reduction Clause, Restrictions 15665 // A reduction clause with the inscan reduction-modifier may only appear on a 15666 // worksharing-loop construct, a worksharing-loop SIMD construct, a simd 15667 // construct, a parallel worksharing-loop construct or a parallel 15668 // worksharing-loop SIMD construct. 15669 if (Modifier == OMPC_REDUCTION_inscan && 15670 (DSAStack->getCurrentDirective() != OMPD_for && 15671 DSAStack->getCurrentDirective() != OMPD_for_simd && 15672 DSAStack->getCurrentDirective() != OMPD_simd && 15673 DSAStack->getCurrentDirective() != OMPD_parallel_for && 15674 DSAStack->getCurrentDirective() != OMPD_parallel_for_simd)) { 15675 Diag(ModifierLoc, diag::err_omp_wrong_inscan_reduction); 15676 return nullptr; 15677 } 15678 15679 ReductionData RD(VarList.size(), Modifier); 15680 if (actOnOMPReductionKindClause(*this, DSAStack, OMPC_reduction, VarList, 15681 StartLoc, LParenLoc, ColonLoc, EndLoc, 15682 ReductionIdScopeSpec, ReductionId, 15683 UnresolvedReductions, RD)) 15684 return nullptr; 15685 15686 return OMPReductionClause::Create( 15687 Context, StartLoc, LParenLoc, ModifierLoc, ColonLoc, EndLoc, Modifier, 15688 RD.Vars, ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId, 15689 RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps, RD.InscanCopyOps, 15690 RD.InscanCopyArrayTemps, RD.InscanCopyArrayElems, 15691 buildPreInits(Context, RD.ExprCaptures), 15692 buildPostUpdate(*this, RD.ExprPostUpdates)); 15693 } 15694 15695 OMPClause *Sema::ActOnOpenMPTaskReductionClause( 15696 ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, 15697 SourceLocation ColonLoc, SourceLocation EndLoc, 15698 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, 15699 ArrayRef<Expr *> UnresolvedReductions) { 15700 ReductionData RD(VarList.size()); 15701 if (actOnOMPReductionKindClause(*this, DSAStack, OMPC_task_reduction, VarList, 15702 StartLoc, LParenLoc, ColonLoc, EndLoc, 15703 ReductionIdScopeSpec, ReductionId, 15704 UnresolvedReductions, RD)) 15705 return nullptr; 15706 15707 return OMPTaskReductionClause::Create( 15708 Context, StartLoc, LParenLoc, ColonLoc, EndLoc, RD.Vars, 15709 ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId, 15710 RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps, 15711 buildPreInits(Context, RD.ExprCaptures), 15712 buildPostUpdate(*this, RD.ExprPostUpdates)); 15713 } 15714 15715 OMPClause *Sema::ActOnOpenMPInReductionClause( 15716 ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, 15717 SourceLocation ColonLoc, SourceLocation EndLoc, 15718 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, 15719 ArrayRef<Expr *> UnresolvedReductions) { 15720 ReductionData RD(VarList.size()); 15721 if (actOnOMPReductionKindClause(*this, DSAStack, OMPC_in_reduction, VarList, 15722 StartLoc, LParenLoc, ColonLoc, EndLoc, 15723 ReductionIdScopeSpec, ReductionId, 15724 UnresolvedReductions, RD)) 15725 return nullptr; 15726 15727 return OMPInReductionClause::Create( 15728 Context, StartLoc, LParenLoc, ColonLoc, EndLoc, RD.Vars, 15729 ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId, 15730 RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps, RD.TaskgroupDescriptors, 15731 buildPreInits(Context, RD.ExprCaptures), 15732 buildPostUpdate(*this, RD.ExprPostUpdates)); 15733 } 15734 15735 bool Sema::CheckOpenMPLinearModifier(OpenMPLinearClauseKind LinKind, 15736 SourceLocation LinLoc) { 15737 if ((!LangOpts.CPlusPlus && LinKind != OMPC_LINEAR_val) || 15738 LinKind == OMPC_LINEAR_unknown) { 15739 Diag(LinLoc, diag::err_omp_wrong_linear_modifier) << LangOpts.CPlusPlus; 15740 return true; 15741 } 15742 return false; 15743 } 15744 15745 bool Sema::CheckOpenMPLinearDecl(const ValueDecl *D, SourceLocation ELoc, 15746 OpenMPLinearClauseKind LinKind, QualType Type, 15747 bool IsDeclareSimd) { 15748 const auto *VD = dyn_cast_or_null<VarDecl>(D); 15749 // A variable must not have an incomplete type or a reference type. 15750 if (RequireCompleteType(ELoc, Type, diag::err_omp_linear_incomplete_type)) 15751 return true; 15752 if ((LinKind == OMPC_LINEAR_uval || LinKind == OMPC_LINEAR_ref) && 15753 !Type->isReferenceType()) { 15754 Diag(ELoc, diag::err_omp_wrong_linear_modifier_non_reference) 15755 << Type << getOpenMPSimpleClauseTypeName(OMPC_linear, LinKind); 15756 return true; 15757 } 15758 Type = Type.getNonReferenceType(); 15759 15760 // OpenMP 5.0 [2.19.3, List Item Privatization, Restrictions] 15761 // A variable that is privatized must not have a const-qualified type 15762 // unless it is of class type with a mutable member. This restriction does 15763 // not apply to the firstprivate clause, nor to the linear clause on 15764 // declarative directives (like declare simd). 15765 if (!IsDeclareSimd && 15766 rejectConstNotMutableType(*this, D, Type, OMPC_linear, ELoc)) 15767 return true; 15768 15769 // A list item must be of integral or pointer type. 15770 Type = Type.getUnqualifiedType().getCanonicalType(); 15771 const auto *Ty = Type.getTypePtrOrNull(); 15772 if (!Ty || (LinKind != OMPC_LINEAR_ref && !Ty->isDependentType() && 15773 !Ty->isIntegralType(Context) && !Ty->isPointerType())) { 15774 Diag(ELoc, diag::err_omp_linear_expected_int_or_ptr) << Type; 15775 if (D) { 15776 bool IsDecl = 15777 !VD || 15778 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 15779 Diag(D->getLocation(), 15780 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 15781 << D; 15782 } 15783 return true; 15784 } 15785 return false; 15786 } 15787 15788 OMPClause *Sema::ActOnOpenMPLinearClause( 15789 ArrayRef<Expr *> VarList, Expr *Step, SourceLocation StartLoc, 15790 SourceLocation LParenLoc, OpenMPLinearClauseKind LinKind, 15791 SourceLocation LinLoc, SourceLocation ColonLoc, SourceLocation EndLoc) { 15792 SmallVector<Expr *, 8> Vars; 15793 SmallVector<Expr *, 8> Privates; 15794 SmallVector<Expr *, 8> Inits; 15795 SmallVector<Decl *, 4> ExprCaptures; 15796 SmallVector<Expr *, 4> ExprPostUpdates; 15797 if (CheckOpenMPLinearModifier(LinKind, LinLoc)) 15798 LinKind = OMPC_LINEAR_val; 15799 for (Expr *RefExpr : VarList) { 15800 assert(RefExpr && "NULL expr in OpenMP linear clause."); 15801 SourceLocation ELoc; 15802 SourceRange ERange; 15803 Expr *SimpleRefExpr = RefExpr; 15804 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 15805 if (Res.second) { 15806 // It will be analyzed later. 15807 Vars.push_back(RefExpr); 15808 Privates.push_back(nullptr); 15809 Inits.push_back(nullptr); 15810 } 15811 ValueDecl *D = Res.first; 15812 if (!D) 15813 continue; 15814 15815 QualType Type = D->getType(); 15816 auto *VD = dyn_cast<VarDecl>(D); 15817 15818 // OpenMP [2.14.3.7, linear clause] 15819 // A list-item cannot appear in more than one linear clause. 15820 // A list-item that appears in a linear clause cannot appear in any 15821 // other data-sharing attribute clause. 15822 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false); 15823 if (DVar.RefExpr) { 15824 Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind) 15825 << getOpenMPClauseName(OMPC_linear); 15826 reportOriginalDsa(*this, DSAStack, D, DVar); 15827 continue; 15828 } 15829 15830 if (CheckOpenMPLinearDecl(D, ELoc, LinKind, Type)) 15831 continue; 15832 Type = Type.getNonReferenceType().getUnqualifiedType().getCanonicalType(); 15833 15834 // Build private copy of original var. 15835 VarDecl *Private = 15836 buildVarDecl(*this, ELoc, Type, D->getName(), 15837 D->hasAttrs() ? &D->getAttrs() : nullptr, 15838 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr); 15839 DeclRefExpr *PrivateRef = buildDeclRefExpr(*this, Private, Type, ELoc); 15840 // Build var to save initial value. 15841 VarDecl *Init = buildVarDecl(*this, ELoc, Type, ".linear.start"); 15842 Expr *InitExpr; 15843 DeclRefExpr *Ref = nullptr; 15844 if (!VD && !CurContext->isDependentContext()) { 15845 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false); 15846 if (!isOpenMPCapturedDecl(D)) { 15847 ExprCaptures.push_back(Ref->getDecl()); 15848 if (Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>()) { 15849 ExprResult RefRes = DefaultLvalueConversion(Ref); 15850 if (!RefRes.isUsable()) 15851 continue; 15852 ExprResult PostUpdateRes = 15853 BuildBinOp(DSAStack->getCurScope(), ELoc, BO_Assign, 15854 SimpleRefExpr, RefRes.get()); 15855 if (!PostUpdateRes.isUsable()) 15856 continue; 15857 ExprPostUpdates.push_back( 15858 IgnoredValueConversions(PostUpdateRes.get()).get()); 15859 } 15860 } 15861 } 15862 if (LinKind == OMPC_LINEAR_uval) 15863 InitExpr = VD ? VD->getInit() : SimpleRefExpr; 15864 else 15865 InitExpr = VD ? SimpleRefExpr : Ref; 15866 AddInitializerToDecl(Init, DefaultLvalueConversion(InitExpr).get(), 15867 /*DirectInit=*/false); 15868 DeclRefExpr *InitRef = buildDeclRefExpr(*this, Init, Type, ELoc); 15869 15870 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_linear, Ref); 15871 Vars.push_back((VD || CurContext->isDependentContext()) 15872 ? RefExpr->IgnoreParens() 15873 : Ref); 15874 Privates.push_back(PrivateRef); 15875 Inits.push_back(InitRef); 15876 } 15877 15878 if (Vars.empty()) 15879 return nullptr; 15880 15881 Expr *StepExpr = Step; 15882 Expr *CalcStepExpr = nullptr; 15883 if (Step && !Step->isValueDependent() && !Step->isTypeDependent() && 15884 !Step->isInstantiationDependent() && 15885 !Step->containsUnexpandedParameterPack()) { 15886 SourceLocation StepLoc = Step->getBeginLoc(); 15887 ExprResult Val = PerformOpenMPImplicitIntegerConversion(StepLoc, Step); 15888 if (Val.isInvalid()) 15889 return nullptr; 15890 StepExpr = Val.get(); 15891 15892 // Build var to save the step value. 15893 VarDecl *SaveVar = 15894 buildVarDecl(*this, StepLoc, StepExpr->getType(), ".linear.step"); 15895 ExprResult SaveRef = 15896 buildDeclRefExpr(*this, SaveVar, StepExpr->getType(), StepLoc); 15897 ExprResult CalcStep = 15898 BuildBinOp(CurScope, StepLoc, BO_Assign, SaveRef.get(), StepExpr); 15899 CalcStep = ActOnFinishFullExpr(CalcStep.get(), /*DiscardedValue*/ false); 15900 15901 // Warn about zero linear step (it would be probably better specified as 15902 // making corresponding variables 'const'). 15903 if (Optional<llvm::APSInt> Result = 15904 StepExpr->getIntegerConstantExpr(Context)) { 15905 if (!Result->isNegative() && !Result->isStrictlyPositive()) 15906 Diag(StepLoc, diag::warn_omp_linear_step_zero) 15907 << Vars[0] << (Vars.size() > 1); 15908 } else if (CalcStep.isUsable()) { 15909 // Calculate the step beforehand instead of doing this on each iteration. 15910 // (This is not used if the number of iterations may be kfold-ed). 15911 CalcStepExpr = CalcStep.get(); 15912 } 15913 } 15914 15915 return OMPLinearClause::Create(Context, StartLoc, LParenLoc, LinKind, LinLoc, 15916 ColonLoc, EndLoc, Vars, Privates, Inits, 15917 StepExpr, CalcStepExpr, 15918 buildPreInits(Context, ExprCaptures), 15919 buildPostUpdate(*this, ExprPostUpdates)); 15920 } 15921 15922 static bool FinishOpenMPLinearClause(OMPLinearClause &Clause, DeclRefExpr *IV, 15923 Expr *NumIterations, Sema &SemaRef, 15924 Scope *S, DSAStackTy *Stack) { 15925 // Walk the vars and build update/final expressions for the CodeGen. 15926 SmallVector<Expr *, 8> Updates; 15927 SmallVector<Expr *, 8> Finals; 15928 SmallVector<Expr *, 8> UsedExprs; 15929 Expr *Step = Clause.getStep(); 15930 Expr *CalcStep = Clause.getCalcStep(); 15931 // OpenMP [2.14.3.7, linear clause] 15932 // If linear-step is not specified it is assumed to be 1. 15933 if (!Step) 15934 Step = SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get(); 15935 else if (CalcStep) 15936 Step = cast<BinaryOperator>(CalcStep)->getLHS(); 15937 bool HasErrors = false; 15938 auto CurInit = Clause.inits().begin(); 15939 auto CurPrivate = Clause.privates().begin(); 15940 OpenMPLinearClauseKind LinKind = Clause.getModifier(); 15941 for (Expr *RefExpr : Clause.varlists()) { 15942 SourceLocation ELoc; 15943 SourceRange ERange; 15944 Expr *SimpleRefExpr = RefExpr; 15945 auto Res = getPrivateItem(SemaRef, SimpleRefExpr, ELoc, ERange); 15946 ValueDecl *D = Res.first; 15947 if (Res.second || !D) { 15948 Updates.push_back(nullptr); 15949 Finals.push_back(nullptr); 15950 HasErrors = true; 15951 continue; 15952 } 15953 auto &&Info = Stack->isLoopControlVariable(D); 15954 // OpenMP [2.15.11, distribute simd Construct] 15955 // A list item may not appear in a linear clause, unless it is the loop 15956 // iteration variable. 15957 if (isOpenMPDistributeDirective(Stack->getCurrentDirective()) && 15958 isOpenMPSimdDirective(Stack->getCurrentDirective()) && !Info.first) { 15959 SemaRef.Diag(ELoc, 15960 diag::err_omp_linear_distribute_var_non_loop_iteration); 15961 Updates.push_back(nullptr); 15962 Finals.push_back(nullptr); 15963 HasErrors = true; 15964 continue; 15965 } 15966 Expr *InitExpr = *CurInit; 15967 15968 // Build privatized reference to the current linear var. 15969 auto *DE = cast<DeclRefExpr>(SimpleRefExpr); 15970 Expr *CapturedRef; 15971 if (LinKind == OMPC_LINEAR_uval) 15972 CapturedRef = cast<VarDecl>(DE->getDecl())->getInit(); 15973 else 15974 CapturedRef = 15975 buildDeclRefExpr(SemaRef, cast<VarDecl>(DE->getDecl()), 15976 DE->getType().getUnqualifiedType(), DE->getExprLoc(), 15977 /*RefersToCapture=*/true); 15978 15979 // Build update: Var = InitExpr + IV * Step 15980 ExprResult Update; 15981 if (!Info.first) 15982 Update = buildCounterUpdate( 15983 SemaRef, S, RefExpr->getExprLoc(), *CurPrivate, InitExpr, IV, Step, 15984 /*Subtract=*/false, /*IsNonRectangularLB=*/false); 15985 else 15986 Update = *CurPrivate; 15987 Update = SemaRef.ActOnFinishFullExpr(Update.get(), DE->getBeginLoc(), 15988 /*DiscardedValue*/ false); 15989 15990 // Build final: Var = InitExpr + NumIterations * Step 15991 ExprResult Final; 15992 if (!Info.first) 15993 Final = 15994 buildCounterUpdate(SemaRef, S, RefExpr->getExprLoc(), CapturedRef, 15995 InitExpr, NumIterations, Step, /*Subtract=*/false, 15996 /*IsNonRectangularLB=*/false); 15997 else 15998 Final = *CurPrivate; 15999 Final = SemaRef.ActOnFinishFullExpr(Final.get(), DE->getBeginLoc(), 16000 /*DiscardedValue*/ false); 16001 16002 if (!Update.isUsable() || !Final.isUsable()) { 16003 Updates.push_back(nullptr); 16004 Finals.push_back(nullptr); 16005 UsedExprs.push_back(nullptr); 16006 HasErrors = true; 16007 } else { 16008 Updates.push_back(Update.get()); 16009 Finals.push_back(Final.get()); 16010 if (!Info.first) 16011 UsedExprs.push_back(SimpleRefExpr); 16012 } 16013 ++CurInit; 16014 ++CurPrivate; 16015 } 16016 if (Expr *S = Clause.getStep()) 16017 UsedExprs.push_back(S); 16018 // Fill the remaining part with the nullptr. 16019 UsedExprs.append(Clause.varlist_size() + 1 - UsedExprs.size(), nullptr); 16020 Clause.setUpdates(Updates); 16021 Clause.setFinals(Finals); 16022 Clause.setUsedExprs(UsedExprs); 16023 return HasErrors; 16024 } 16025 16026 OMPClause *Sema::ActOnOpenMPAlignedClause( 16027 ArrayRef<Expr *> VarList, Expr *Alignment, SourceLocation StartLoc, 16028 SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc) { 16029 SmallVector<Expr *, 8> Vars; 16030 for (Expr *RefExpr : VarList) { 16031 assert(RefExpr && "NULL expr in OpenMP linear clause."); 16032 SourceLocation ELoc; 16033 SourceRange ERange; 16034 Expr *SimpleRefExpr = RefExpr; 16035 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 16036 if (Res.second) { 16037 // It will be analyzed later. 16038 Vars.push_back(RefExpr); 16039 } 16040 ValueDecl *D = Res.first; 16041 if (!D) 16042 continue; 16043 16044 QualType QType = D->getType(); 16045 auto *VD = dyn_cast<VarDecl>(D); 16046 16047 // OpenMP [2.8.1, simd construct, Restrictions] 16048 // The type of list items appearing in the aligned clause must be 16049 // array, pointer, reference to array, or reference to pointer. 16050 QType = QType.getNonReferenceType().getUnqualifiedType().getCanonicalType(); 16051 const Type *Ty = QType.getTypePtrOrNull(); 16052 if (!Ty || (!Ty->isArrayType() && !Ty->isPointerType())) { 16053 Diag(ELoc, diag::err_omp_aligned_expected_array_or_ptr) 16054 << QType << getLangOpts().CPlusPlus << ERange; 16055 bool IsDecl = 16056 !VD || 16057 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 16058 Diag(D->getLocation(), 16059 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 16060 << D; 16061 continue; 16062 } 16063 16064 // OpenMP [2.8.1, simd construct, Restrictions] 16065 // A list-item cannot appear in more than one aligned clause. 16066 if (const Expr *PrevRef = DSAStack->addUniqueAligned(D, SimpleRefExpr)) { 16067 Diag(ELoc, diag::err_omp_used_in_clause_twice) 16068 << 0 << getOpenMPClauseName(OMPC_aligned) << ERange; 16069 Diag(PrevRef->getExprLoc(), diag::note_omp_explicit_dsa) 16070 << getOpenMPClauseName(OMPC_aligned); 16071 continue; 16072 } 16073 16074 DeclRefExpr *Ref = nullptr; 16075 if (!VD && isOpenMPCapturedDecl(D)) 16076 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true); 16077 Vars.push_back(DefaultFunctionArrayConversion( 16078 (VD || !Ref) ? RefExpr->IgnoreParens() : Ref) 16079 .get()); 16080 } 16081 16082 // OpenMP [2.8.1, simd construct, Description] 16083 // The parameter of the aligned clause, alignment, must be a constant 16084 // positive integer expression. 16085 // If no optional parameter is specified, implementation-defined default 16086 // alignments for SIMD instructions on the target platforms are assumed. 16087 if (Alignment != nullptr) { 16088 ExprResult AlignResult = 16089 VerifyPositiveIntegerConstantInClause(Alignment, OMPC_aligned); 16090 if (AlignResult.isInvalid()) 16091 return nullptr; 16092 Alignment = AlignResult.get(); 16093 } 16094 if (Vars.empty()) 16095 return nullptr; 16096 16097 return OMPAlignedClause::Create(Context, StartLoc, LParenLoc, ColonLoc, 16098 EndLoc, Vars, Alignment); 16099 } 16100 16101 OMPClause *Sema::ActOnOpenMPCopyinClause(ArrayRef<Expr *> VarList, 16102 SourceLocation StartLoc, 16103 SourceLocation LParenLoc, 16104 SourceLocation EndLoc) { 16105 SmallVector<Expr *, 8> Vars; 16106 SmallVector<Expr *, 8> SrcExprs; 16107 SmallVector<Expr *, 8> DstExprs; 16108 SmallVector<Expr *, 8> AssignmentOps; 16109 for (Expr *RefExpr : VarList) { 16110 assert(RefExpr && "NULL expr in OpenMP copyin clause."); 16111 if (isa<DependentScopeDeclRefExpr>(RefExpr)) { 16112 // It will be analyzed later. 16113 Vars.push_back(RefExpr); 16114 SrcExprs.push_back(nullptr); 16115 DstExprs.push_back(nullptr); 16116 AssignmentOps.push_back(nullptr); 16117 continue; 16118 } 16119 16120 SourceLocation ELoc = RefExpr->getExprLoc(); 16121 // OpenMP [2.1, C/C++] 16122 // A list item is a variable name. 16123 // OpenMP [2.14.4.1, Restrictions, p.1] 16124 // A list item that appears in a copyin clause must be threadprivate. 16125 auto *DE = dyn_cast<DeclRefExpr>(RefExpr); 16126 if (!DE || !isa<VarDecl>(DE->getDecl())) { 16127 Diag(ELoc, diag::err_omp_expected_var_name_member_expr) 16128 << 0 << RefExpr->getSourceRange(); 16129 continue; 16130 } 16131 16132 Decl *D = DE->getDecl(); 16133 auto *VD = cast<VarDecl>(D); 16134 16135 QualType Type = VD->getType(); 16136 if (Type->isDependentType() || Type->isInstantiationDependentType()) { 16137 // It will be analyzed later. 16138 Vars.push_back(DE); 16139 SrcExprs.push_back(nullptr); 16140 DstExprs.push_back(nullptr); 16141 AssignmentOps.push_back(nullptr); 16142 continue; 16143 } 16144 16145 // OpenMP [2.14.4.1, Restrictions, C/C++, p.1] 16146 // A list item that appears in a copyin clause must be threadprivate. 16147 if (!DSAStack->isThreadPrivate(VD)) { 16148 Diag(ELoc, diag::err_omp_required_access) 16149 << getOpenMPClauseName(OMPC_copyin) 16150 << getOpenMPDirectiveName(OMPD_threadprivate); 16151 continue; 16152 } 16153 16154 // OpenMP [2.14.4.1, Restrictions, C/C++, p.2] 16155 // A variable of class type (or array thereof) that appears in a 16156 // copyin clause requires an accessible, unambiguous copy assignment 16157 // operator for the class type. 16158 QualType ElemType = Context.getBaseElementType(Type).getNonReferenceType(); 16159 VarDecl *SrcVD = 16160 buildVarDecl(*this, DE->getBeginLoc(), ElemType.getUnqualifiedType(), 16161 ".copyin.src", VD->hasAttrs() ? &VD->getAttrs() : nullptr); 16162 DeclRefExpr *PseudoSrcExpr = buildDeclRefExpr( 16163 *this, SrcVD, ElemType.getUnqualifiedType(), DE->getExprLoc()); 16164 VarDecl *DstVD = 16165 buildVarDecl(*this, DE->getBeginLoc(), ElemType, ".copyin.dst", 16166 VD->hasAttrs() ? &VD->getAttrs() : nullptr); 16167 DeclRefExpr *PseudoDstExpr = 16168 buildDeclRefExpr(*this, DstVD, ElemType, DE->getExprLoc()); 16169 // For arrays generate assignment operation for single element and replace 16170 // it by the original array element in CodeGen. 16171 ExprResult AssignmentOp = 16172 BuildBinOp(/*S=*/nullptr, DE->getExprLoc(), BO_Assign, PseudoDstExpr, 16173 PseudoSrcExpr); 16174 if (AssignmentOp.isInvalid()) 16175 continue; 16176 AssignmentOp = ActOnFinishFullExpr(AssignmentOp.get(), DE->getExprLoc(), 16177 /*DiscardedValue*/ false); 16178 if (AssignmentOp.isInvalid()) 16179 continue; 16180 16181 DSAStack->addDSA(VD, DE, OMPC_copyin); 16182 Vars.push_back(DE); 16183 SrcExprs.push_back(PseudoSrcExpr); 16184 DstExprs.push_back(PseudoDstExpr); 16185 AssignmentOps.push_back(AssignmentOp.get()); 16186 } 16187 16188 if (Vars.empty()) 16189 return nullptr; 16190 16191 return OMPCopyinClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars, 16192 SrcExprs, DstExprs, AssignmentOps); 16193 } 16194 16195 OMPClause *Sema::ActOnOpenMPCopyprivateClause(ArrayRef<Expr *> VarList, 16196 SourceLocation StartLoc, 16197 SourceLocation LParenLoc, 16198 SourceLocation EndLoc) { 16199 SmallVector<Expr *, 8> Vars; 16200 SmallVector<Expr *, 8> SrcExprs; 16201 SmallVector<Expr *, 8> DstExprs; 16202 SmallVector<Expr *, 8> AssignmentOps; 16203 for (Expr *RefExpr : VarList) { 16204 assert(RefExpr && "NULL expr in OpenMP linear clause."); 16205 SourceLocation ELoc; 16206 SourceRange ERange; 16207 Expr *SimpleRefExpr = RefExpr; 16208 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 16209 if (Res.second) { 16210 // It will be analyzed later. 16211 Vars.push_back(RefExpr); 16212 SrcExprs.push_back(nullptr); 16213 DstExprs.push_back(nullptr); 16214 AssignmentOps.push_back(nullptr); 16215 } 16216 ValueDecl *D = Res.first; 16217 if (!D) 16218 continue; 16219 16220 QualType Type = D->getType(); 16221 auto *VD = dyn_cast<VarDecl>(D); 16222 16223 // OpenMP [2.14.4.2, Restrictions, p.2] 16224 // A list item that appears in a copyprivate clause may not appear in a 16225 // private or firstprivate clause on the single construct. 16226 if (!VD || !DSAStack->isThreadPrivate(VD)) { 16227 DSAStackTy::DSAVarData DVar = 16228 DSAStack->getTopDSA(D, /*FromParent=*/false); 16229 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_copyprivate && 16230 DVar.RefExpr) { 16231 Diag(ELoc, diag::err_omp_wrong_dsa) 16232 << getOpenMPClauseName(DVar.CKind) 16233 << getOpenMPClauseName(OMPC_copyprivate); 16234 reportOriginalDsa(*this, DSAStack, D, DVar); 16235 continue; 16236 } 16237 16238 // OpenMP [2.11.4.2, Restrictions, p.1] 16239 // All list items that appear in a copyprivate clause must be either 16240 // threadprivate or private in the enclosing context. 16241 if (DVar.CKind == OMPC_unknown) { 16242 DVar = DSAStack->getImplicitDSA(D, false); 16243 if (DVar.CKind == OMPC_shared) { 16244 Diag(ELoc, diag::err_omp_required_access) 16245 << getOpenMPClauseName(OMPC_copyprivate) 16246 << "threadprivate or private in the enclosing context"; 16247 reportOriginalDsa(*this, DSAStack, D, DVar); 16248 continue; 16249 } 16250 } 16251 } 16252 16253 // Variably modified types are not supported. 16254 if (!Type->isAnyPointerType() && Type->isVariablyModifiedType()) { 16255 Diag(ELoc, diag::err_omp_variably_modified_type_not_supported) 16256 << getOpenMPClauseName(OMPC_copyprivate) << Type 16257 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 16258 bool IsDecl = 16259 !VD || 16260 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 16261 Diag(D->getLocation(), 16262 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 16263 << D; 16264 continue; 16265 } 16266 16267 // OpenMP [2.14.4.1, Restrictions, C/C++, p.2] 16268 // A variable of class type (or array thereof) that appears in a 16269 // copyin clause requires an accessible, unambiguous copy assignment 16270 // operator for the class type. 16271 Type = Context.getBaseElementType(Type.getNonReferenceType()) 16272 .getUnqualifiedType(); 16273 VarDecl *SrcVD = 16274 buildVarDecl(*this, RefExpr->getBeginLoc(), Type, ".copyprivate.src", 16275 D->hasAttrs() ? &D->getAttrs() : nullptr); 16276 DeclRefExpr *PseudoSrcExpr = buildDeclRefExpr(*this, SrcVD, Type, ELoc); 16277 VarDecl *DstVD = 16278 buildVarDecl(*this, RefExpr->getBeginLoc(), Type, ".copyprivate.dst", 16279 D->hasAttrs() ? &D->getAttrs() : nullptr); 16280 DeclRefExpr *PseudoDstExpr = buildDeclRefExpr(*this, DstVD, Type, ELoc); 16281 ExprResult AssignmentOp = BuildBinOp( 16282 DSAStack->getCurScope(), ELoc, BO_Assign, PseudoDstExpr, PseudoSrcExpr); 16283 if (AssignmentOp.isInvalid()) 16284 continue; 16285 AssignmentOp = 16286 ActOnFinishFullExpr(AssignmentOp.get(), ELoc, /*DiscardedValue*/ false); 16287 if (AssignmentOp.isInvalid()) 16288 continue; 16289 16290 // No need to mark vars as copyprivate, they are already threadprivate or 16291 // implicitly private. 16292 assert(VD || isOpenMPCapturedDecl(D)); 16293 Vars.push_back( 16294 VD ? RefExpr->IgnoreParens() 16295 : buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false)); 16296 SrcExprs.push_back(PseudoSrcExpr); 16297 DstExprs.push_back(PseudoDstExpr); 16298 AssignmentOps.push_back(AssignmentOp.get()); 16299 } 16300 16301 if (Vars.empty()) 16302 return nullptr; 16303 16304 return OMPCopyprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, 16305 Vars, SrcExprs, DstExprs, AssignmentOps); 16306 } 16307 16308 OMPClause *Sema::ActOnOpenMPFlushClause(ArrayRef<Expr *> VarList, 16309 SourceLocation StartLoc, 16310 SourceLocation LParenLoc, 16311 SourceLocation EndLoc) { 16312 if (VarList.empty()) 16313 return nullptr; 16314 16315 return OMPFlushClause::Create(Context, StartLoc, LParenLoc, EndLoc, VarList); 16316 } 16317 16318 /// Tries to find omp_depend_t. type. 16319 static bool findOMPDependT(Sema &S, SourceLocation Loc, DSAStackTy *Stack, 16320 bool Diagnose = true) { 16321 QualType OMPDependT = Stack->getOMPDependT(); 16322 if (!OMPDependT.isNull()) 16323 return true; 16324 IdentifierInfo *II = &S.PP.getIdentifierTable().get("omp_depend_t"); 16325 ParsedType PT = S.getTypeName(*II, Loc, S.getCurScope()); 16326 if (!PT.getAsOpaquePtr() || PT.get().isNull()) { 16327 if (Diagnose) 16328 S.Diag(Loc, diag::err_omp_implied_type_not_found) << "omp_depend_t"; 16329 return false; 16330 } 16331 Stack->setOMPDependT(PT.get()); 16332 return true; 16333 } 16334 16335 OMPClause *Sema::ActOnOpenMPDepobjClause(Expr *Depobj, SourceLocation StartLoc, 16336 SourceLocation LParenLoc, 16337 SourceLocation EndLoc) { 16338 if (!Depobj) 16339 return nullptr; 16340 16341 bool OMPDependTFound = findOMPDependT(*this, StartLoc, DSAStack); 16342 16343 // OpenMP 5.0, 2.17.10.1 depobj Construct 16344 // depobj is an lvalue expression of type omp_depend_t. 16345 if (!Depobj->isTypeDependent() && !Depobj->isValueDependent() && 16346 !Depobj->isInstantiationDependent() && 16347 !Depobj->containsUnexpandedParameterPack() && 16348 (OMPDependTFound && 16349 !Context.typesAreCompatible(DSAStack->getOMPDependT(), Depobj->getType(), 16350 /*CompareUnqualified=*/true))) { 16351 Diag(Depobj->getExprLoc(), diag::err_omp_expected_omp_depend_t_lvalue) 16352 << 0 << Depobj->getType() << Depobj->getSourceRange(); 16353 } 16354 16355 if (!Depobj->isLValue()) { 16356 Diag(Depobj->getExprLoc(), diag::err_omp_expected_omp_depend_t_lvalue) 16357 << 1 << Depobj->getSourceRange(); 16358 } 16359 16360 return OMPDepobjClause::Create(Context, StartLoc, LParenLoc, EndLoc, Depobj); 16361 } 16362 16363 OMPClause * 16364 Sema::ActOnOpenMPDependClause(Expr *DepModifier, OpenMPDependClauseKind DepKind, 16365 SourceLocation DepLoc, SourceLocation ColonLoc, 16366 ArrayRef<Expr *> VarList, SourceLocation StartLoc, 16367 SourceLocation LParenLoc, SourceLocation EndLoc) { 16368 if (DSAStack->getCurrentDirective() == OMPD_ordered && 16369 DepKind != OMPC_DEPEND_source && DepKind != OMPC_DEPEND_sink) { 16370 Diag(DepLoc, diag::err_omp_unexpected_clause_value) 16371 << "'source' or 'sink'" << getOpenMPClauseName(OMPC_depend); 16372 return nullptr; 16373 } 16374 if ((DSAStack->getCurrentDirective() != OMPD_ordered || 16375 DSAStack->getCurrentDirective() == OMPD_depobj) && 16376 (DepKind == OMPC_DEPEND_unknown || DepKind == OMPC_DEPEND_source || 16377 DepKind == OMPC_DEPEND_sink || 16378 ((LangOpts.OpenMP < 50 || 16379 DSAStack->getCurrentDirective() == OMPD_depobj) && 16380 DepKind == OMPC_DEPEND_depobj))) { 16381 SmallVector<unsigned, 3> Except; 16382 Except.push_back(OMPC_DEPEND_source); 16383 Except.push_back(OMPC_DEPEND_sink); 16384 if (LangOpts.OpenMP < 50 || DSAStack->getCurrentDirective() == OMPD_depobj) 16385 Except.push_back(OMPC_DEPEND_depobj); 16386 std::string Expected = (LangOpts.OpenMP >= 50 && !DepModifier) 16387 ? "depend modifier(iterator) or " 16388 : ""; 16389 Diag(DepLoc, diag::err_omp_unexpected_clause_value) 16390 << Expected + getListOfPossibleValues(OMPC_depend, /*First=*/0, 16391 /*Last=*/OMPC_DEPEND_unknown, 16392 Except) 16393 << getOpenMPClauseName(OMPC_depend); 16394 return nullptr; 16395 } 16396 if (DepModifier && 16397 (DepKind == OMPC_DEPEND_source || DepKind == OMPC_DEPEND_sink)) { 16398 Diag(DepModifier->getExprLoc(), 16399 diag::err_omp_depend_sink_source_with_modifier); 16400 return nullptr; 16401 } 16402 if (DepModifier && 16403 !DepModifier->getType()->isSpecificBuiltinType(BuiltinType::OMPIterator)) 16404 Diag(DepModifier->getExprLoc(), diag::err_omp_depend_modifier_not_iterator); 16405 16406 SmallVector<Expr *, 8> Vars; 16407 DSAStackTy::OperatorOffsetTy OpsOffs; 16408 llvm::APSInt DepCounter(/*BitWidth=*/32); 16409 llvm::APSInt TotalDepCount(/*BitWidth=*/32); 16410 if (DepKind == OMPC_DEPEND_sink || DepKind == OMPC_DEPEND_source) { 16411 if (const Expr *OrderedCountExpr = 16412 DSAStack->getParentOrderedRegionParam().first) { 16413 TotalDepCount = OrderedCountExpr->EvaluateKnownConstInt(Context); 16414 TotalDepCount.setIsUnsigned(/*Val=*/true); 16415 } 16416 } 16417 for (Expr *RefExpr : VarList) { 16418 assert(RefExpr && "NULL expr in OpenMP shared clause."); 16419 if (isa<DependentScopeDeclRefExpr>(RefExpr)) { 16420 // It will be analyzed later. 16421 Vars.push_back(RefExpr); 16422 continue; 16423 } 16424 16425 SourceLocation ELoc = RefExpr->getExprLoc(); 16426 Expr *SimpleExpr = RefExpr->IgnoreParenCasts(); 16427 if (DepKind == OMPC_DEPEND_sink) { 16428 if (DSAStack->getParentOrderedRegionParam().first && 16429 DepCounter >= TotalDepCount) { 16430 Diag(ELoc, diag::err_omp_depend_sink_unexpected_expr); 16431 continue; 16432 } 16433 ++DepCounter; 16434 // OpenMP [2.13.9, Summary] 16435 // depend(dependence-type : vec), where dependence-type is: 16436 // 'sink' and where vec is the iteration vector, which has the form: 16437 // x1 [+- d1], x2 [+- d2 ], . . . , xn [+- dn] 16438 // where n is the value specified by the ordered clause in the loop 16439 // directive, xi denotes the loop iteration variable of the i-th nested 16440 // loop associated with the loop directive, and di is a constant 16441 // non-negative integer. 16442 if (CurContext->isDependentContext()) { 16443 // It will be analyzed later. 16444 Vars.push_back(RefExpr); 16445 continue; 16446 } 16447 SimpleExpr = SimpleExpr->IgnoreImplicit(); 16448 OverloadedOperatorKind OOK = OO_None; 16449 SourceLocation OOLoc; 16450 Expr *LHS = SimpleExpr; 16451 Expr *RHS = nullptr; 16452 if (auto *BO = dyn_cast<BinaryOperator>(SimpleExpr)) { 16453 OOK = BinaryOperator::getOverloadedOperator(BO->getOpcode()); 16454 OOLoc = BO->getOperatorLoc(); 16455 LHS = BO->getLHS()->IgnoreParenImpCasts(); 16456 RHS = BO->getRHS()->IgnoreParenImpCasts(); 16457 } else if (auto *OCE = dyn_cast<CXXOperatorCallExpr>(SimpleExpr)) { 16458 OOK = OCE->getOperator(); 16459 OOLoc = OCE->getOperatorLoc(); 16460 LHS = OCE->getArg(/*Arg=*/0)->IgnoreParenImpCasts(); 16461 RHS = OCE->getArg(/*Arg=*/1)->IgnoreParenImpCasts(); 16462 } else if (auto *MCE = dyn_cast<CXXMemberCallExpr>(SimpleExpr)) { 16463 OOK = MCE->getMethodDecl() 16464 ->getNameInfo() 16465 .getName() 16466 .getCXXOverloadedOperator(); 16467 OOLoc = MCE->getCallee()->getExprLoc(); 16468 LHS = MCE->getImplicitObjectArgument()->IgnoreParenImpCasts(); 16469 RHS = MCE->getArg(/*Arg=*/0)->IgnoreParenImpCasts(); 16470 } 16471 SourceLocation ELoc; 16472 SourceRange ERange; 16473 auto Res = getPrivateItem(*this, LHS, ELoc, ERange); 16474 if (Res.second) { 16475 // It will be analyzed later. 16476 Vars.push_back(RefExpr); 16477 } 16478 ValueDecl *D = Res.first; 16479 if (!D) 16480 continue; 16481 16482 if (OOK != OO_Plus && OOK != OO_Minus && (RHS || OOK != OO_None)) { 16483 Diag(OOLoc, diag::err_omp_depend_sink_expected_plus_minus); 16484 continue; 16485 } 16486 if (RHS) { 16487 ExprResult RHSRes = VerifyPositiveIntegerConstantInClause( 16488 RHS, OMPC_depend, /*StrictlyPositive=*/false); 16489 if (RHSRes.isInvalid()) 16490 continue; 16491 } 16492 if (!CurContext->isDependentContext() && 16493 DSAStack->getParentOrderedRegionParam().first && 16494 DepCounter != DSAStack->isParentLoopControlVariable(D).first) { 16495 const ValueDecl *VD = 16496 DSAStack->getParentLoopControlVariable(DepCounter.getZExtValue()); 16497 if (VD) 16498 Diag(ELoc, diag::err_omp_depend_sink_expected_loop_iteration) 16499 << 1 << VD; 16500 else 16501 Diag(ELoc, diag::err_omp_depend_sink_expected_loop_iteration) << 0; 16502 continue; 16503 } 16504 OpsOffs.emplace_back(RHS, OOK); 16505 } else { 16506 bool OMPDependTFound = LangOpts.OpenMP >= 50; 16507 if (OMPDependTFound) 16508 OMPDependTFound = findOMPDependT(*this, StartLoc, DSAStack, 16509 DepKind == OMPC_DEPEND_depobj); 16510 if (DepKind == OMPC_DEPEND_depobj) { 16511 // OpenMP 5.0, 2.17.11 depend Clause, Restrictions, C/C++ 16512 // List items used in depend clauses with the depobj dependence type 16513 // must be expressions of the omp_depend_t type. 16514 if (!RefExpr->isValueDependent() && !RefExpr->isTypeDependent() && 16515 !RefExpr->isInstantiationDependent() && 16516 !RefExpr->containsUnexpandedParameterPack() && 16517 (OMPDependTFound && 16518 !Context.hasSameUnqualifiedType(DSAStack->getOMPDependT(), 16519 RefExpr->getType()))) { 16520 Diag(ELoc, diag::err_omp_expected_omp_depend_t_lvalue) 16521 << 0 << RefExpr->getType() << RefExpr->getSourceRange(); 16522 continue; 16523 } 16524 if (!RefExpr->isLValue()) { 16525 Diag(ELoc, diag::err_omp_expected_omp_depend_t_lvalue) 16526 << 1 << RefExpr->getType() << RefExpr->getSourceRange(); 16527 continue; 16528 } 16529 } else { 16530 // OpenMP 5.0 [2.17.11, Restrictions] 16531 // List items used in depend clauses cannot be zero-length array 16532 // sections. 16533 QualType ExprTy = RefExpr->getType().getNonReferenceType(); 16534 const auto *OASE = dyn_cast<OMPArraySectionExpr>(SimpleExpr); 16535 if (OASE) { 16536 QualType BaseType = 16537 OMPArraySectionExpr::getBaseOriginalType(OASE->getBase()); 16538 if (const auto *ATy = BaseType->getAsArrayTypeUnsafe()) 16539 ExprTy = ATy->getElementType(); 16540 else 16541 ExprTy = BaseType->getPointeeType(); 16542 ExprTy = ExprTy.getNonReferenceType(); 16543 const Expr *Length = OASE->getLength(); 16544 Expr::EvalResult Result; 16545 if (Length && !Length->isValueDependent() && 16546 Length->EvaluateAsInt(Result, Context) && 16547 Result.Val.getInt().isNullValue()) { 16548 Diag(ELoc, 16549 diag::err_omp_depend_zero_length_array_section_not_allowed) 16550 << SimpleExpr->getSourceRange(); 16551 continue; 16552 } 16553 } 16554 16555 // OpenMP 5.0, 2.17.11 depend Clause, Restrictions, C/C++ 16556 // List items used in depend clauses with the in, out, inout or 16557 // mutexinoutset dependence types cannot be expressions of the 16558 // omp_depend_t type. 16559 if (!RefExpr->isValueDependent() && !RefExpr->isTypeDependent() && 16560 !RefExpr->isInstantiationDependent() && 16561 !RefExpr->containsUnexpandedParameterPack() && 16562 (OMPDependTFound && 16563 DSAStack->getOMPDependT().getTypePtr() == ExprTy.getTypePtr())) { 16564 Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item) 16565 << (LangOpts.OpenMP >= 50 ? 1 : 0) << 1 16566 << RefExpr->getSourceRange(); 16567 continue; 16568 } 16569 16570 auto *ASE = dyn_cast<ArraySubscriptExpr>(SimpleExpr); 16571 if (!RefExpr->IgnoreParenImpCasts()->isLValue() || 16572 (ASE && !ASE->getBase()->isTypeDependent() && 16573 !ASE->getBase() 16574 ->getType() 16575 .getNonReferenceType() 16576 ->isPointerType() && 16577 !ASE->getBase()->getType().getNonReferenceType()->isArrayType())) { 16578 Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item) 16579 << (LangOpts.OpenMP >= 50 ? 1 : 0) 16580 << (LangOpts.OpenMP >= 50 ? 1 : 0) << RefExpr->getSourceRange(); 16581 continue; 16582 } 16583 16584 ExprResult Res; 16585 { 16586 Sema::TentativeAnalysisScope Trap(*this); 16587 Res = CreateBuiltinUnaryOp(ELoc, UO_AddrOf, 16588 RefExpr->IgnoreParenImpCasts()); 16589 } 16590 if (!Res.isUsable() && !isa<OMPArraySectionExpr>(SimpleExpr) && 16591 !isa<OMPArrayShapingExpr>(SimpleExpr)) { 16592 Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item) 16593 << (LangOpts.OpenMP >= 50 ? 1 : 0) 16594 << (LangOpts.OpenMP >= 50 ? 1 : 0) << RefExpr->getSourceRange(); 16595 continue; 16596 } 16597 } 16598 } 16599 Vars.push_back(RefExpr->IgnoreParenImpCasts()); 16600 } 16601 16602 if (!CurContext->isDependentContext() && DepKind == OMPC_DEPEND_sink && 16603 TotalDepCount > VarList.size() && 16604 DSAStack->getParentOrderedRegionParam().first && 16605 DSAStack->getParentLoopControlVariable(VarList.size() + 1)) { 16606 Diag(EndLoc, diag::err_omp_depend_sink_expected_loop_iteration) 16607 << 1 << DSAStack->getParentLoopControlVariable(VarList.size() + 1); 16608 } 16609 if (DepKind != OMPC_DEPEND_source && DepKind != OMPC_DEPEND_sink && 16610 Vars.empty()) 16611 return nullptr; 16612 16613 auto *C = OMPDependClause::Create(Context, StartLoc, LParenLoc, EndLoc, 16614 DepModifier, DepKind, DepLoc, ColonLoc, 16615 Vars, TotalDepCount.getZExtValue()); 16616 if ((DepKind == OMPC_DEPEND_sink || DepKind == OMPC_DEPEND_source) && 16617 DSAStack->isParentOrderedRegion()) 16618 DSAStack->addDoacrossDependClause(C, OpsOffs); 16619 return C; 16620 } 16621 16622 OMPClause *Sema::ActOnOpenMPDeviceClause(OpenMPDeviceClauseModifier Modifier, 16623 Expr *Device, SourceLocation StartLoc, 16624 SourceLocation LParenLoc, 16625 SourceLocation ModifierLoc, 16626 SourceLocation EndLoc) { 16627 assert((ModifierLoc.isInvalid() || LangOpts.OpenMP >= 50) && 16628 "Unexpected device modifier in OpenMP < 50."); 16629 16630 bool ErrorFound = false; 16631 if (ModifierLoc.isValid() && Modifier == OMPC_DEVICE_unknown) { 16632 std::string Values = 16633 getListOfPossibleValues(OMPC_device, /*First=*/0, OMPC_DEVICE_unknown); 16634 Diag(ModifierLoc, diag::err_omp_unexpected_clause_value) 16635 << Values << getOpenMPClauseName(OMPC_device); 16636 ErrorFound = true; 16637 } 16638 16639 Expr *ValExpr = Device; 16640 Stmt *HelperValStmt = nullptr; 16641 16642 // OpenMP [2.9.1, Restrictions] 16643 // The device expression must evaluate to a non-negative integer value. 16644 ErrorFound = !isNonNegativeIntegerValue(ValExpr, *this, OMPC_device, 16645 /*StrictlyPositive=*/false) || 16646 ErrorFound; 16647 if (ErrorFound) 16648 return nullptr; 16649 16650 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 16651 OpenMPDirectiveKind CaptureRegion = 16652 getOpenMPCaptureRegionForClause(DKind, OMPC_device, LangOpts.OpenMP); 16653 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 16654 ValExpr = MakeFullExpr(ValExpr).get(); 16655 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 16656 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 16657 HelperValStmt = buildPreInits(Context, Captures); 16658 } 16659 16660 return new (Context) 16661 OMPDeviceClause(Modifier, ValExpr, HelperValStmt, CaptureRegion, StartLoc, 16662 LParenLoc, ModifierLoc, EndLoc); 16663 } 16664 16665 static bool checkTypeMappable(SourceLocation SL, SourceRange SR, Sema &SemaRef, 16666 DSAStackTy *Stack, QualType QTy, 16667 bool FullCheck = true) { 16668 NamedDecl *ND; 16669 if (QTy->isIncompleteType(&ND)) { 16670 SemaRef.Diag(SL, diag::err_incomplete_type) << QTy << SR; 16671 return false; 16672 } 16673 if (FullCheck && !SemaRef.CurContext->isDependentContext() && 16674 !QTy.isTriviallyCopyableType(SemaRef.Context)) 16675 SemaRef.Diag(SL, diag::warn_omp_non_trivial_type_mapped) << QTy << SR; 16676 return true; 16677 } 16678 16679 /// Return true if it can be proven that the provided array expression 16680 /// (array section or array subscript) does NOT specify the whole size of the 16681 /// array whose base type is \a BaseQTy. 16682 static bool checkArrayExpressionDoesNotReferToWholeSize(Sema &SemaRef, 16683 const Expr *E, 16684 QualType BaseQTy) { 16685 const auto *OASE = dyn_cast<OMPArraySectionExpr>(E); 16686 16687 // If this is an array subscript, it refers to the whole size if the size of 16688 // the dimension is constant and equals 1. Also, an array section assumes the 16689 // format of an array subscript if no colon is used. 16690 if (isa<ArraySubscriptExpr>(E) || 16691 (OASE && OASE->getColonLocFirst().isInvalid())) { 16692 if (const auto *ATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr())) 16693 return ATy->getSize().getSExtValue() != 1; 16694 // Size can't be evaluated statically. 16695 return false; 16696 } 16697 16698 assert(OASE && "Expecting array section if not an array subscript."); 16699 const Expr *LowerBound = OASE->getLowerBound(); 16700 const Expr *Length = OASE->getLength(); 16701 16702 // If there is a lower bound that does not evaluates to zero, we are not 16703 // covering the whole dimension. 16704 if (LowerBound) { 16705 Expr::EvalResult Result; 16706 if (!LowerBound->EvaluateAsInt(Result, SemaRef.getASTContext())) 16707 return false; // Can't get the integer value as a constant. 16708 16709 llvm::APSInt ConstLowerBound = Result.Val.getInt(); 16710 if (ConstLowerBound.getSExtValue()) 16711 return true; 16712 } 16713 16714 // If we don't have a length we covering the whole dimension. 16715 if (!Length) 16716 return false; 16717 16718 // If the base is a pointer, we don't have a way to get the size of the 16719 // pointee. 16720 if (BaseQTy->isPointerType()) 16721 return false; 16722 16723 // We can only check if the length is the same as the size of the dimension 16724 // if we have a constant array. 16725 const auto *CATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr()); 16726 if (!CATy) 16727 return false; 16728 16729 Expr::EvalResult Result; 16730 if (!Length->EvaluateAsInt(Result, SemaRef.getASTContext())) 16731 return false; // Can't get the integer value as a constant. 16732 16733 llvm::APSInt ConstLength = Result.Val.getInt(); 16734 return CATy->getSize().getSExtValue() != ConstLength.getSExtValue(); 16735 } 16736 16737 // Return true if it can be proven that the provided array expression (array 16738 // section or array subscript) does NOT specify a single element of the array 16739 // whose base type is \a BaseQTy. 16740 static bool checkArrayExpressionDoesNotReferToUnitySize(Sema &SemaRef, 16741 const Expr *E, 16742 QualType BaseQTy) { 16743 const auto *OASE = dyn_cast<OMPArraySectionExpr>(E); 16744 16745 // An array subscript always refer to a single element. Also, an array section 16746 // assumes the format of an array subscript if no colon is used. 16747 if (isa<ArraySubscriptExpr>(E) || 16748 (OASE && OASE->getColonLocFirst().isInvalid())) 16749 return false; 16750 16751 assert(OASE && "Expecting array section if not an array subscript."); 16752 const Expr *Length = OASE->getLength(); 16753 16754 // If we don't have a length we have to check if the array has unitary size 16755 // for this dimension. Also, we should always expect a length if the base type 16756 // is pointer. 16757 if (!Length) { 16758 if (const auto *ATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr())) 16759 return ATy->getSize().getSExtValue() != 1; 16760 // We cannot assume anything. 16761 return false; 16762 } 16763 16764 // Check if the length evaluates to 1. 16765 Expr::EvalResult Result; 16766 if (!Length->EvaluateAsInt(Result, SemaRef.getASTContext())) 16767 return false; // Can't get the integer value as a constant. 16768 16769 llvm::APSInt ConstLength = Result.Val.getInt(); 16770 return ConstLength.getSExtValue() != 1; 16771 } 16772 16773 // The base of elements of list in a map clause have to be either: 16774 // - a reference to variable or field. 16775 // - a member expression. 16776 // - an array expression. 16777 // 16778 // E.g. if we have the expression 'r.S.Arr[:12]', we want to retrieve the 16779 // reference to 'r'. 16780 // 16781 // If we have: 16782 // 16783 // struct SS { 16784 // Bla S; 16785 // foo() { 16786 // #pragma omp target map (S.Arr[:12]); 16787 // } 16788 // } 16789 // 16790 // We want to retrieve the member expression 'this->S'; 16791 16792 // OpenMP 5.0 [2.19.7.1, map Clause, Restrictions, p.2] 16793 // If a list item is an array section, it must specify contiguous storage. 16794 // 16795 // For this restriction it is sufficient that we make sure only references 16796 // to variables or fields and array expressions, and that no array sections 16797 // exist except in the rightmost expression (unless they cover the whole 16798 // dimension of the array). E.g. these would be invalid: 16799 // 16800 // r.ArrS[3:5].Arr[6:7] 16801 // 16802 // r.ArrS[3:5].x 16803 // 16804 // but these would be valid: 16805 // r.ArrS[3].Arr[6:7] 16806 // 16807 // r.ArrS[3].x 16808 namespace { 16809 class MapBaseChecker final : public StmtVisitor<MapBaseChecker, bool> { 16810 Sema &SemaRef; 16811 OpenMPClauseKind CKind = OMPC_unknown; 16812 OpenMPDirectiveKind DKind = OMPD_unknown; 16813 OMPClauseMappableExprCommon::MappableExprComponentList &Components; 16814 bool IsNonContiguous = false; 16815 bool NoDiagnose = false; 16816 const Expr *RelevantExpr = nullptr; 16817 bool AllowUnitySizeArraySection = true; 16818 bool AllowWholeSizeArraySection = true; 16819 bool AllowAnotherPtr = true; 16820 SourceLocation ELoc; 16821 SourceRange ERange; 16822 16823 void emitErrorMsg() { 16824 // If nothing else worked, this is not a valid map clause expression. 16825 if (SemaRef.getLangOpts().OpenMP < 50) { 16826 SemaRef.Diag(ELoc, 16827 diag::err_omp_expected_named_var_member_or_array_expression) 16828 << ERange; 16829 } else { 16830 SemaRef.Diag(ELoc, diag::err_omp_non_lvalue_in_map_or_motion_clauses) 16831 << getOpenMPClauseName(CKind) << ERange; 16832 } 16833 } 16834 16835 public: 16836 bool VisitDeclRefExpr(DeclRefExpr *DRE) { 16837 if (!isa<VarDecl>(DRE->getDecl())) { 16838 emitErrorMsg(); 16839 return false; 16840 } 16841 assert(!RelevantExpr && "RelevantExpr is expected to be nullptr"); 16842 RelevantExpr = DRE; 16843 // Record the component. 16844 Components.emplace_back(DRE, DRE->getDecl(), IsNonContiguous); 16845 return true; 16846 } 16847 16848 bool VisitMemberExpr(MemberExpr *ME) { 16849 Expr *E = ME; 16850 Expr *BaseE = ME->getBase()->IgnoreParenCasts(); 16851 16852 if (isa<CXXThisExpr>(BaseE)) { 16853 assert(!RelevantExpr && "RelevantExpr is expected to be nullptr"); 16854 // We found a base expression: this->Val. 16855 RelevantExpr = ME; 16856 } else { 16857 E = BaseE; 16858 } 16859 16860 if (!isa<FieldDecl>(ME->getMemberDecl())) { 16861 if (!NoDiagnose) { 16862 SemaRef.Diag(ELoc, diag::err_omp_expected_access_to_data_field) 16863 << ME->getSourceRange(); 16864 return false; 16865 } 16866 if (RelevantExpr) 16867 return false; 16868 return Visit(E); 16869 } 16870 16871 auto *FD = cast<FieldDecl>(ME->getMemberDecl()); 16872 16873 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.3] 16874 // A bit-field cannot appear in a map clause. 16875 // 16876 if (FD->isBitField()) { 16877 if (!NoDiagnose) { 16878 SemaRef.Diag(ELoc, diag::err_omp_bit_fields_forbidden_in_clause) 16879 << ME->getSourceRange() << getOpenMPClauseName(CKind); 16880 return false; 16881 } 16882 if (RelevantExpr) 16883 return false; 16884 return Visit(E); 16885 } 16886 16887 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1] 16888 // If the type of a list item is a reference to a type T then the type 16889 // will be considered to be T for all purposes of this clause. 16890 QualType CurType = BaseE->getType().getNonReferenceType(); 16891 16892 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.2] 16893 // A list item cannot be a variable that is a member of a structure with 16894 // a union type. 16895 // 16896 if (CurType->isUnionType()) { 16897 if (!NoDiagnose) { 16898 SemaRef.Diag(ELoc, diag::err_omp_union_type_not_allowed) 16899 << ME->getSourceRange(); 16900 return false; 16901 } 16902 return RelevantExpr || Visit(E); 16903 } 16904 16905 // If we got a member expression, we should not expect any array section 16906 // before that: 16907 // 16908 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.7] 16909 // If a list item is an element of a structure, only the rightmost symbol 16910 // of the variable reference can be an array section. 16911 // 16912 AllowUnitySizeArraySection = false; 16913 AllowWholeSizeArraySection = false; 16914 16915 // Record the component. 16916 Components.emplace_back(ME, FD, IsNonContiguous); 16917 return RelevantExpr || Visit(E); 16918 } 16919 16920 bool VisitArraySubscriptExpr(ArraySubscriptExpr *AE) { 16921 Expr *E = AE->getBase()->IgnoreParenImpCasts(); 16922 16923 if (!E->getType()->isAnyPointerType() && !E->getType()->isArrayType()) { 16924 if (!NoDiagnose) { 16925 SemaRef.Diag(ELoc, diag::err_omp_expected_base_var_name) 16926 << 0 << AE->getSourceRange(); 16927 return false; 16928 } 16929 return RelevantExpr || Visit(E); 16930 } 16931 16932 // If we got an array subscript that express the whole dimension we 16933 // can have any array expressions before. If it only expressing part of 16934 // the dimension, we can only have unitary-size array expressions. 16935 if (checkArrayExpressionDoesNotReferToWholeSize(SemaRef, AE, 16936 E->getType())) 16937 AllowWholeSizeArraySection = false; 16938 16939 if (const auto *TE = dyn_cast<CXXThisExpr>(E->IgnoreParenCasts())) { 16940 Expr::EvalResult Result; 16941 if (!AE->getIdx()->isValueDependent() && 16942 AE->getIdx()->EvaluateAsInt(Result, SemaRef.getASTContext()) && 16943 !Result.Val.getInt().isNullValue()) { 16944 SemaRef.Diag(AE->getIdx()->getExprLoc(), 16945 diag::err_omp_invalid_map_this_expr); 16946 SemaRef.Diag(AE->getIdx()->getExprLoc(), 16947 diag::note_omp_invalid_subscript_on_this_ptr_map); 16948 } 16949 assert(!RelevantExpr && "RelevantExpr is expected to be nullptr"); 16950 RelevantExpr = TE; 16951 } 16952 16953 // Record the component - we don't have any declaration associated. 16954 Components.emplace_back(AE, nullptr, IsNonContiguous); 16955 16956 return RelevantExpr || Visit(E); 16957 } 16958 16959 bool VisitOMPArraySectionExpr(OMPArraySectionExpr *OASE) { 16960 assert(!NoDiagnose && "Array sections cannot be implicitly mapped."); 16961 Expr *E = OASE->getBase()->IgnoreParenImpCasts(); 16962 QualType CurType = 16963 OMPArraySectionExpr::getBaseOriginalType(E).getCanonicalType(); 16964 16965 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1] 16966 // If the type of a list item is a reference to a type T then the type 16967 // will be considered to be T for all purposes of this clause. 16968 if (CurType->isReferenceType()) 16969 CurType = CurType->getPointeeType(); 16970 16971 bool IsPointer = CurType->isAnyPointerType(); 16972 16973 if (!IsPointer && !CurType->isArrayType()) { 16974 SemaRef.Diag(ELoc, diag::err_omp_expected_base_var_name) 16975 << 0 << OASE->getSourceRange(); 16976 return false; 16977 } 16978 16979 bool NotWhole = 16980 checkArrayExpressionDoesNotReferToWholeSize(SemaRef, OASE, CurType); 16981 bool NotUnity = 16982 checkArrayExpressionDoesNotReferToUnitySize(SemaRef, OASE, CurType); 16983 16984 if (AllowWholeSizeArraySection) { 16985 // Any array section is currently allowed. Allowing a whole size array 16986 // section implies allowing a unity array section as well. 16987 // 16988 // If this array section refers to the whole dimension we can still 16989 // accept other array sections before this one, except if the base is a 16990 // pointer. Otherwise, only unitary sections are accepted. 16991 if (NotWhole || IsPointer) 16992 AllowWholeSizeArraySection = false; 16993 } else if (DKind == OMPD_target_update && 16994 SemaRef.getLangOpts().OpenMP >= 50) { 16995 if (IsPointer && !AllowAnotherPtr) 16996 SemaRef.Diag(ELoc, diag::err_omp_section_length_undefined) 16997 << /*array of unknown bound */ 1; 16998 else 16999 IsNonContiguous = true; 17000 } else if (AllowUnitySizeArraySection && NotUnity) { 17001 // A unity or whole array section is not allowed and that is not 17002 // compatible with the properties of the current array section. 17003 SemaRef.Diag( 17004 ELoc, diag::err_array_section_does_not_specify_contiguous_storage) 17005 << OASE->getSourceRange(); 17006 return false; 17007 } 17008 17009 if (IsPointer) 17010 AllowAnotherPtr = false; 17011 17012 if (const auto *TE = dyn_cast<CXXThisExpr>(E)) { 17013 Expr::EvalResult ResultR; 17014 Expr::EvalResult ResultL; 17015 if (!OASE->getLength()->isValueDependent() && 17016 OASE->getLength()->EvaluateAsInt(ResultR, SemaRef.getASTContext()) && 17017 !ResultR.Val.getInt().isOneValue()) { 17018 SemaRef.Diag(OASE->getLength()->getExprLoc(), 17019 diag::err_omp_invalid_map_this_expr); 17020 SemaRef.Diag(OASE->getLength()->getExprLoc(), 17021 diag::note_omp_invalid_length_on_this_ptr_mapping); 17022 } 17023 if (OASE->getLowerBound() && !OASE->getLowerBound()->isValueDependent() && 17024 OASE->getLowerBound()->EvaluateAsInt(ResultL, 17025 SemaRef.getASTContext()) && 17026 !ResultL.Val.getInt().isNullValue()) { 17027 SemaRef.Diag(OASE->getLowerBound()->getExprLoc(), 17028 diag::err_omp_invalid_map_this_expr); 17029 SemaRef.Diag(OASE->getLowerBound()->getExprLoc(), 17030 diag::note_omp_invalid_lower_bound_on_this_ptr_mapping); 17031 } 17032 assert(!RelevantExpr && "RelevantExpr is expected to be nullptr"); 17033 RelevantExpr = TE; 17034 } 17035 17036 // Record the component - we don't have any declaration associated. 17037 Components.emplace_back(OASE, nullptr, /*IsNonContiguous=*/false); 17038 return RelevantExpr || Visit(E); 17039 } 17040 bool VisitOMPArrayShapingExpr(OMPArrayShapingExpr *E) { 17041 Expr *Base = E->getBase(); 17042 17043 // Record the component - we don't have any declaration associated. 17044 Components.emplace_back(E, nullptr, IsNonContiguous); 17045 17046 return Visit(Base->IgnoreParenImpCasts()); 17047 } 17048 17049 bool VisitUnaryOperator(UnaryOperator *UO) { 17050 if (SemaRef.getLangOpts().OpenMP < 50 || !UO->isLValue() || 17051 UO->getOpcode() != UO_Deref) { 17052 emitErrorMsg(); 17053 return false; 17054 } 17055 if (!RelevantExpr) { 17056 // Record the component if haven't found base decl. 17057 Components.emplace_back(UO, nullptr, /*IsNonContiguous=*/false); 17058 } 17059 return RelevantExpr || Visit(UO->getSubExpr()->IgnoreParenImpCasts()); 17060 } 17061 bool VisitBinaryOperator(BinaryOperator *BO) { 17062 if (SemaRef.getLangOpts().OpenMP < 50 || !BO->getType()->isPointerType()) { 17063 emitErrorMsg(); 17064 return false; 17065 } 17066 17067 // Pointer arithmetic is the only thing we expect to happen here so after we 17068 // make sure the binary operator is a pointer type, the we only thing need 17069 // to to is to visit the subtree that has the same type as root (so that we 17070 // know the other subtree is just an offset) 17071 Expr *LE = BO->getLHS()->IgnoreParenImpCasts(); 17072 Expr *RE = BO->getRHS()->IgnoreParenImpCasts(); 17073 Components.emplace_back(BO, nullptr, false); 17074 assert((LE->getType().getTypePtr() == BO->getType().getTypePtr() || 17075 RE->getType().getTypePtr() == BO->getType().getTypePtr()) && 17076 "Either LHS or RHS have base decl inside"); 17077 if (BO->getType().getTypePtr() == LE->getType().getTypePtr()) 17078 return RelevantExpr || Visit(LE); 17079 return RelevantExpr || Visit(RE); 17080 } 17081 bool VisitCXXThisExpr(CXXThisExpr *CTE) { 17082 assert(!RelevantExpr && "RelevantExpr is expected to be nullptr"); 17083 RelevantExpr = CTE; 17084 Components.emplace_back(CTE, nullptr, IsNonContiguous); 17085 return true; 17086 } 17087 bool VisitCXXOperatorCallExpr(CXXOperatorCallExpr *COCE) { 17088 assert(!RelevantExpr && "RelevantExpr is expected to be nullptr"); 17089 Components.emplace_back(COCE, nullptr, IsNonContiguous); 17090 return true; 17091 } 17092 bool VisitStmt(Stmt *) { 17093 emitErrorMsg(); 17094 return false; 17095 } 17096 const Expr *getFoundBase() const { 17097 return RelevantExpr; 17098 } 17099 explicit MapBaseChecker( 17100 Sema &SemaRef, OpenMPClauseKind CKind, OpenMPDirectiveKind DKind, 17101 OMPClauseMappableExprCommon::MappableExprComponentList &Components, 17102 bool NoDiagnose, SourceLocation &ELoc, SourceRange &ERange) 17103 : SemaRef(SemaRef), CKind(CKind), DKind(DKind), Components(Components), 17104 NoDiagnose(NoDiagnose), ELoc(ELoc), ERange(ERange) {} 17105 }; 17106 } // namespace 17107 17108 /// Return the expression of the base of the mappable expression or null if it 17109 /// cannot be determined and do all the necessary checks to see if the expression 17110 /// is valid as a standalone mappable expression. In the process, record all the 17111 /// components of the expression. 17112 static const Expr *checkMapClauseExpressionBase( 17113 Sema &SemaRef, Expr *E, 17114 OMPClauseMappableExprCommon::MappableExprComponentList &CurComponents, 17115 OpenMPClauseKind CKind, OpenMPDirectiveKind DKind, bool NoDiagnose) { 17116 SourceLocation ELoc = E->getExprLoc(); 17117 SourceRange ERange = E->getSourceRange(); 17118 MapBaseChecker Checker(SemaRef, CKind, DKind, CurComponents, NoDiagnose, ELoc, 17119 ERange); 17120 if (Checker.Visit(E->IgnoreParens())) { 17121 // Check if the highest dimension array section has length specified 17122 if (SemaRef.getLangOpts().OpenMP >= 50 && !CurComponents.empty() && 17123 (CKind == OMPC_to || CKind == OMPC_from)) { 17124 auto CI = CurComponents.rbegin(); 17125 auto CE = CurComponents.rend(); 17126 for (; CI != CE; ++CI) { 17127 const auto *OASE = 17128 dyn_cast<OMPArraySectionExpr>(CI->getAssociatedExpression()); 17129 if (!OASE) 17130 continue; 17131 if (OASE && OASE->getLength()) 17132 break; 17133 SemaRef.Diag(ELoc, diag::err_array_section_does_not_specify_length) 17134 << ERange; 17135 } 17136 } 17137 return Checker.getFoundBase(); 17138 } 17139 return nullptr; 17140 } 17141 17142 // Return true if expression E associated with value VD has conflicts with other 17143 // map information. 17144 static bool checkMapConflicts( 17145 Sema &SemaRef, DSAStackTy *DSAS, const ValueDecl *VD, const Expr *E, 17146 bool CurrentRegionOnly, 17147 OMPClauseMappableExprCommon::MappableExprComponentListRef CurComponents, 17148 OpenMPClauseKind CKind) { 17149 assert(VD && E); 17150 SourceLocation ELoc = E->getExprLoc(); 17151 SourceRange ERange = E->getSourceRange(); 17152 17153 // In order to easily check the conflicts we need to match each component of 17154 // the expression under test with the components of the expressions that are 17155 // already in the stack. 17156 17157 assert(!CurComponents.empty() && "Map clause expression with no components!"); 17158 assert(CurComponents.back().getAssociatedDeclaration() == VD && 17159 "Map clause expression with unexpected base!"); 17160 17161 // Variables to help detecting enclosing problems in data environment nests. 17162 bool IsEnclosedByDataEnvironmentExpr = false; 17163 const Expr *EnclosingExpr = nullptr; 17164 17165 bool FoundError = DSAS->checkMappableExprComponentListsForDecl( 17166 VD, CurrentRegionOnly, 17167 [&IsEnclosedByDataEnvironmentExpr, &SemaRef, VD, CurrentRegionOnly, ELoc, 17168 ERange, CKind, &EnclosingExpr, 17169 CurComponents](OMPClauseMappableExprCommon::MappableExprComponentListRef 17170 StackComponents, 17171 OpenMPClauseKind) { 17172 assert(!StackComponents.empty() && 17173 "Map clause expression with no components!"); 17174 assert(StackComponents.back().getAssociatedDeclaration() == VD && 17175 "Map clause expression with unexpected base!"); 17176 (void)VD; 17177 17178 // The whole expression in the stack. 17179 const Expr *RE = StackComponents.front().getAssociatedExpression(); 17180 17181 // Expressions must start from the same base. Here we detect at which 17182 // point both expressions diverge from each other and see if we can 17183 // detect if the memory referred to both expressions is contiguous and 17184 // do not overlap. 17185 auto CI = CurComponents.rbegin(); 17186 auto CE = CurComponents.rend(); 17187 auto SI = StackComponents.rbegin(); 17188 auto SE = StackComponents.rend(); 17189 for (; CI != CE && SI != SE; ++CI, ++SI) { 17190 17191 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.3] 17192 // At most one list item can be an array item derived from a given 17193 // variable in map clauses of the same construct. 17194 if (CurrentRegionOnly && 17195 (isa<ArraySubscriptExpr>(CI->getAssociatedExpression()) || 17196 isa<OMPArraySectionExpr>(CI->getAssociatedExpression()) || 17197 isa<OMPArrayShapingExpr>(CI->getAssociatedExpression())) && 17198 (isa<ArraySubscriptExpr>(SI->getAssociatedExpression()) || 17199 isa<OMPArraySectionExpr>(SI->getAssociatedExpression()) || 17200 isa<OMPArrayShapingExpr>(SI->getAssociatedExpression()))) { 17201 SemaRef.Diag(CI->getAssociatedExpression()->getExprLoc(), 17202 diag::err_omp_multiple_array_items_in_map_clause) 17203 << CI->getAssociatedExpression()->getSourceRange(); 17204 SemaRef.Diag(SI->getAssociatedExpression()->getExprLoc(), 17205 diag::note_used_here) 17206 << SI->getAssociatedExpression()->getSourceRange(); 17207 return true; 17208 } 17209 17210 // Do both expressions have the same kind? 17211 if (CI->getAssociatedExpression()->getStmtClass() != 17212 SI->getAssociatedExpression()->getStmtClass()) 17213 break; 17214 17215 // Are we dealing with different variables/fields? 17216 if (CI->getAssociatedDeclaration() != SI->getAssociatedDeclaration()) 17217 break; 17218 } 17219 // Check if the extra components of the expressions in the enclosing 17220 // data environment are redundant for the current base declaration. 17221 // If they are, the maps completely overlap, which is legal. 17222 for (; SI != SE; ++SI) { 17223 QualType Type; 17224 if (const auto *ASE = 17225 dyn_cast<ArraySubscriptExpr>(SI->getAssociatedExpression())) { 17226 Type = ASE->getBase()->IgnoreParenImpCasts()->getType(); 17227 } else if (const auto *OASE = dyn_cast<OMPArraySectionExpr>( 17228 SI->getAssociatedExpression())) { 17229 const Expr *E = OASE->getBase()->IgnoreParenImpCasts(); 17230 Type = 17231 OMPArraySectionExpr::getBaseOriginalType(E).getCanonicalType(); 17232 } else if (const auto *OASE = dyn_cast<OMPArrayShapingExpr>( 17233 SI->getAssociatedExpression())) { 17234 Type = OASE->getBase()->getType()->getPointeeType(); 17235 } 17236 if (Type.isNull() || Type->isAnyPointerType() || 17237 checkArrayExpressionDoesNotReferToWholeSize( 17238 SemaRef, SI->getAssociatedExpression(), Type)) 17239 break; 17240 } 17241 17242 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.4] 17243 // List items of map clauses in the same construct must not share 17244 // original storage. 17245 // 17246 // If the expressions are exactly the same or one is a subset of the 17247 // other, it means they are sharing storage. 17248 if (CI == CE && SI == SE) { 17249 if (CurrentRegionOnly) { 17250 if (CKind == OMPC_map) { 17251 SemaRef.Diag(ELoc, diag::err_omp_map_shared_storage) << ERange; 17252 } else { 17253 assert(CKind == OMPC_to || CKind == OMPC_from); 17254 SemaRef.Diag(ELoc, diag::err_omp_once_referenced_in_target_update) 17255 << ERange; 17256 } 17257 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here) 17258 << RE->getSourceRange(); 17259 return true; 17260 } 17261 // If we find the same expression in the enclosing data environment, 17262 // that is legal. 17263 IsEnclosedByDataEnvironmentExpr = true; 17264 return false; 17265 } 17266 17267 QualType DerivedType = 17268 std::prev(CI)->getAssociatedDeclaration()->getType(); 17269 SourceLocation DerivedLoc = 17270 std::prev(CI)->getAssociatedExpression()->getExprLoc(); 17271 17272 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1] 17273 // If the type of a list item is a reference to a type T then the type 17274 // will be considered to be T for all purposes of this clause. 17275 DerivedType = DerivedType.getNonReferenceType(); 17276 17277 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.1] 17278 // A variable for which the type is pointer and an array section 17279 // derived from that variable must not appear as list items of map 17280 // clauses of the same construct. 17281 // 17282 // Also, cover one of the cases in: 17283 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.5] 17284 // If any part of the original storage of a list item has corresponding 17285 // storage in the device data environment, all of the original storage 17286 // must have corresponding storage in the device data environment. 17287 // 17288 if (DerivedType->isAnyPointerType()) { 17289 if (CI == CE || SI == SE) { 17290 SemaRef.Diag( 17291 DerivedLoc, 17292 diag::err_omp_pointer_mapped_along_with_derived_section) 17293 << DerivedLoc; 17294 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here) 17295 << RE->getSourceRange(); 17296 return true; 17297 } 17298 if (CI->getAssociatedExpression()->getStmtClass() != 17299 SI->getAssociatedExpression()->getStmtClass() || 17300 CI->getAssociatedDeclaration()->getCanonicalDecl() == 17301 SI->getAssociatedDeclaration()->getCanonicalDecl()) { 17302 assert(CI != CE && SI != SE); 17303 SemaRef.Diag(DerivedLoc, diag::err_omp_same_pointer_dereferenced) 17304 << DerivedLoc; 17305 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here) 17306 << RE->getSourceRange(); 17307 return true; 17308 } 17309 } 17310 17311 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.4] 17312 // List items of map clauses in the same construct must not share 17313 // original storage. 17314 // 17315 // An expression is a subset of the other. 17316 if (CurrentRegionOnly && (CI == CE || SI == SE)) { 17317 if (CKind == OMPC_map) { 17318 if (CI != CE || SI != SE) { 17319 // Allow constructs like this: map(s, s.ptr[0:1]), where s.ptr is 17320 // a pointer. 17321 auto Begin = 17322 CI != CE ? CurComponents.begin() : StackComponents.begin(); 17323 auto End = CI != CE ? CurComponents.end() : StackComponents.end(); 17324 auto It = Begin; 17325 while (It != End && !It->getAssociatedDeclaration()) 17326 std::advance(It, 1); 17327 assert(It != End && 17328 "Expected at least one component with the declaration."); 17329 if (It != Begin && It->getAssociatedDeclaration() 17330 ->getType() 17331 .getCanonicalType() 17332 ->isAnyPointerType()) { 17333 IsEnclosedByDataEnvironmentExpr = false; 17334 EnclosingExpr = nullptr; 17335 return false; 17336 } 17337 } 17338 SemaRef.Diag(ELoc, diag::err_omp_map_shared_storage) << ERange; 17339 } else { 17340 assert(CKind == OMPC_to || CKind == OMPC_from); 17341 SemaRef.Diag(ELoc, diag::err_omp_once_referenced_in_target_update) 17342 << ERange; 17343 } 17344 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here) 17345 << RE->getSourceRange(); 17346 return true; 17347 } 17348 17349 // The current expression uses the same base as other expression in the 17350 // data environment but does not contain it completely. 17351 if (!CurrentRegionOnly && SI != SE) 17352 EnclosingExpr = RE; 17353 17354 // The current expression is a subset of the expression in the data 17355 // environment. 17356 IsEnclosedByDataEnvironmentExpr |= 17357 (!CurrentRegionOnly && CI != CE && SI == SE); 17358 17359 return false; 17360 }); 17361 17362 if (CurrentRegionOnly) 17363 return FoundError; 17364 17365 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.5] 17366 // If any part of the original storage of a list item has corresponding 17367 // storage in the device data environment, all of the original storage must 17368 // have corresponding storage in the device data environment. 17369 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.6] 17370 // If a list item is an element of a structure, and a different element of 17371 // the structure has a corresponding list item in the device data environment 17372 // prior to a task encountering the construct associated with the map clause, 17373 // then the list item must also have a corresponding list item in the device 17374 // data environment prior to the task encountering the construct. 17375 // 17376 if (EnclosingExpr && !IsEnclosedByDataEnvironmentExpr) { 17377 SemaRef.Diag(ELoc, 17378 diag::err_omp_original_storage_is_shared_and_does_not_contain) 17379 << ERange; 17380 SemaRef.Diag(EnclosingExpr->getExprLoc(), diag::note_used_here) 17381 << EnclosingExpr->getSourceRange(); 17382 return true; 17383 } 17384 17385 return FoundError; 17386 } 17387 17388 // Look up the user-defined mapper given the mapper name and mapped type, and 17389 // build a reference to it. 17390 static ExprResult buildUserDefinedMapperRef(Sema &SemaRef, Scope *S, 17391 CXXScopeSpec &MapperIdScopeSpec, 17392 const DeclarationNameInfo &MapperId, 17393 QualType Type, 17394 Expr *UnresolvedMapper) { 17395 if (MapperIdScopeSpec.isInvalid()) 17396 return ExprError(); 17397 // Get the actual type for the array type. 17398 if (Type->isArrayType()) { 17399 assert(Type->getAsArrayTypeUnsafe() && "Expect to get a valid array type"); 17400 Type = Type->getAsArrayTypeUnsafe()->getElementType().getCanonicalType(); 17401 } 17402 // Find all user-defined mappers with the given MapperId. 17403 SmallVector<UnresolvedSet<8>, 4> Lookups; 17404 LookupResult Lookup(SemaRef, MapperId, Sema::LookupOMPMapperName); 17405 Lookup.suppressDiagnostics(); 17406 if (S) { 17407 while (S && SemaRef.LookupParsedName(Lookup, S, &MapperIdScopeSpec)) { 17408 NamedDecl *D = Lookup.getRepresentativeDecl(); 17409 while (S && !S->isDeclScope(D)) 17410 S = S->getParent(); 17411 if (S) 17412 S = S->getParent(); 17413 Lookups.emplace_back(); 17414 Lookups.back().append(Lookup.begin(), Lookup.end()); 17415 Lookup.clear(); 17416 } 17417 } else if (auto *ULE = cast_or_null<UnresolvedLookupExpr>(UnresolvedMapper)) { 17418 // Extract the user-defined mappers with the given MapperId. 17419 Lookups.push_back(UnresolvedSet<8>()); 17420 for (NamedDecl *D : ULE->decls()) { 17421 auto *DMD = cast<OMPDeclareMapperDecl>(D); 17422 assert(DMD && "Expect valid OMPDeclareMapperDecl during instantiation."); 17423 Lookups.back().addDecl(DMD); 17424 } 17425 } 17426 // Defer the lookup for dependent types. The results will be passed through 17427 // UnresolvedMapper on instantiation. 17428 if (SemaRef.CurContext->isDependentContext() || Type->isDependentType() || 17429 Type->isInstantiationDependentType() || 17430 Type->containsUnexpandedParameterPack() || 17431 filterLookupForUDReductionAndMapper<bool>(Lookups, [](ValueDecl *D) { 17432 return !D->isInvalidDecl() && 17433 (D->getType()->isDependentType() || 17434 D->getType()->isInstantiationDependentType() || 17435 D->getType()->containsUnexpandedParameterPack()); 17436 })) { 17437 UnresolvedSet<8> URS; 17438 for (const UnresolvedSet<8> &Set : Lookups) { 17439 if (Set.empty()) 17440 continue; 17441 URS.append(Set.begin(), Set.end()); 17442 } 17443 return UnresolvedLookupExpr::Create( 17444 SemaRef.Context, /*NamingClass=*/nullptr, 17445 MapperIdScopeSpec.getWithLocInContext(SemaRef.Context), MapperId, 17446 /*ADL=*/false, /*Overloaded=*/true, URS.begin(), URS.end()); 17447 } 17448 SourceLocation Loc = MapperId.getLoc(); 17449 // [OpenMP 5.0], 2.19.7.3 declare mapper Directive, Restrictions 17450 // The type must be of struct, union or class type in C and C++ 17451 if (!Type->isStructureOrClassType() && !Type->isUnionType() && 17452 (MapperIdScopeSpec.isSet() || MapperId.getAsString() != "default")) { 17453 SemaRef.Diag(Loc, diag::err_omp_mapper_wrong_type); 17454 return ExprError(); 17455 } 17456 // Perform argument dependent lookup. 17457 if (SemaRef.getLangOpts().CPlusPlus && !MapperIdScopeSpec.isSet()) 17458 argumentDependentLookup(SemaRef, MapperId, Loc, Type, Lookups); 17459 // Return the first user-defined mapper with the desired type. 17460 if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>( 17461 Lookups, [&SemaRef, Type](ValueDecl *D) -> ValueDecl * { 17462 if (!D->isInvalidDecl() && 17463 SemaRef.Context.hasSameType(D->getType(), Type)) 17464 return D; 17465 return nullptr; 17466 })) 17467 return SemaRef.BuildDeclRefExpr(VD, Type, VK_LValue, Loc); 17468 // Find the first user-defined mapper with a type derived from the desired 17469 // type. 17470 if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>( 17471 Lookups, [&SemaRef, Type, Loc](ValueDecl *D) -> ValueDecl * { 17472 if (!D->isInvalidDecl() && 17473 SemaRef.IsDerivedFrom(Loc, Type, D->getType()) && 17474 !Type.isMoreQualifiedThan(D->getType())) 17475 return D; 17476 return nullptr; 17477 })) { 17478 CXXBasePaths Paths(/*FindAmbiguities=*/true, /*RecordPaths=*/true, 17479 /*DetectVirtual=*/false); 17480 if (SemaRef.IsDerivedFrom(Loc, Type, VD->getType(), Paths)) { 17481 if (!Paths.isAmbiguous(SemaRef.Context.getCanonicalType( 17482 VD->getType().getUnqualifiedType()))) { 17483 if (SemaRef.CheckBaseClassAccess( 17484 Loc, VD->getType(), Type, Paths.front(), 17485 /*DiagID=*/0) != Sema::AR_inaccessible) { 17486 return SemaRef.BuildDeclRefExpr(VD, Type, VK_LValue, Loc); 17487 } 17488 } 17489 } 17490 } 17491 // Report error if a mapper is specified, but cannot be found. 17492 if (MapperIdScopeSpec.isSet() || MapperId.getAsString() != "default") { 17493 SemaRef.Diag(Loc, diag::err_omp_invalid_mapper) 17494 << Type << MapperId.getName(); 17495 return ExprError(); 17496 } 17497 return ExprEmpty(); 17498 } 17499 17500 namespace { 17501 // Utility struct that gathers all the related lists associated with a mappable 17502 // expression. 17503 struct MappableVarListInfo { 17504 // The list of expressions. 17505 ArrayRef<Expr *> VarList; 17506 // The list of processed expressions. 17507 SmallVector<Expr *, 16> ProcessedVarList; 17508 // The mappble components for each expression. 17509 OMPClauseMappableExprCommon::MappableExprComponentLists VarComponents; 17510 // The base declaration of the variable. 17511 SmallVector<ValueDecl *, 16> VarBaseDeclarations; 17512 // The reference to the user-defined mapper associated with every expression. 17513 SmallVector<Expr *, 16> UDMapperList; 17514 17515 MappableVarListInfo(ArrayRef<Expr *> VarList) : VarList(VarList) { 17516 // We have a list of components and base declarations for each entry in the 17517 // variable list. 17518 VarComponents.reserve(VarList.size()); 17519 VarBaseDeclarations.reserve(VarList.size()); 17520 } 17521 }; 17522 } 17523 17524 // Check the validity of the provided variable list for the provided clause kind 17525 // \a CKind. In the check process the valid expressions, mappable expression 17526 // components, variables, and user-defined mappers are extracted and used to 17527 // fill \a ProcessedVarList, \a VarComponents, \a VarBaseDeclarations, and \a 17528 // UDMapperList in MVLI. \a MapType, \a IsMapTypeImplicit, \a MapperIdScopeSpec, 17529 // and \a MapperId are expected to be valid if the clause kind is 'map'. 17530 static void checkMappableExpressionList( 17531 Sema &SemaRef, DSAStackTy *DSAS, OpenMPClauseKind CKind, 17532 MappableVarListInfo &MVLI, SourceLocation StartLoc, 17533 CXXScopeSpec &MapperIdScopeSpec, DeclarationNameInfo MapperId, 17534 ArrayRef<Expr *> UnresolvedMappers, 17535 OpenMPMapClauseKind MapType = OMPC_MAP_unknown, 17536 bool IsMapTypeImplicit = false) { 17537 // We only expect mappable expressions in 'to', 'from', and 'map' clauses. 17538 assert((CKind == OMPC_map || CKind == OMPC_to || CKind == OMPC_from) && 17539 "Unexpected clause kind with mappable expressions!"); 17540 17541 // If the identifier of user-defined mapper is not specified, it is "default". 17542 // We do not change the actual name in this clause to distinguish whether a 17543 // mapper is specified explicitly, i.e., it is not explicitly specified when 17544 // MapperId.getName() is empty. 17545 if (!MapperId.getName() || MapperId.getName().isEmpty()) { 17546 auto &DeclNames = SemaRef.getASTContext().DeclarationNames; 17547 MapperId.setName(DeclNames.getIdentifier( 17548 &SemaRef.getASTContext().Idents.get("default"))); 17549 } 17550 17551 // Iterators to find the current unresolved mapper expression. 17552 auto UMIt = UnresolvedMappers.begin(), UMEnd = UnresolvedMappers.end(); 17553 bool UpdateUMIt = false; 17554 Expr *UnresolvedMapper = nullptr; 17555 17556 // Keep track of the mappable components and base declarations in this clause. 17557 // Each entry in the list is going to have a list of components associated. We 17558 // record each set of the components so that we can build the clause later on. 17559 // In the end we should have the same amount of declarations and component 17560 // lists. 17561 17562 for (Expr *RE : MVLI.VarList) { 17563 assert(RE && "Null expr in omp to/from/map clause"); 17564 SourceLocation ELoc = RE->getExprLoc(); 17565 17566 // Find the current unresolved mapper expression. 17567 if (UpdateUMIt && UMIt != UMEnd) { 17568 UMIt++; 17569 assert( 17570 UMIt != UMEnd && 17571 "Expect the size of UnresolvedMappers to match with that of VarList"); 17572 } 17573 UpdateUMIt = true; 17574 if (UMIt != UMEnd) 17575 UnresolvedMapper = *UMIt; 17576 17577 const Expr *VE = RE->IgnoreParenLValueCasts(); 17578 17579 if (VE->isValueDependent() || VE->isTypeDependent() || 17580 VE->isInstantiationDependent() || 17581 VE->containsUnexpandedParameterPack()) { 17582 // Try to find the associated user-defined mapper. 17583 ExprResult ER = buildUserDefinedMapperRef( 17584 SemaRef, DSAS->getCurScope(), MapperIdScopeSpec, MapperId, 17585 VE->getType().getCanonicalType(), UnresolvedMapper); 17586 if (ER.isInvalid()) 17587 continue; 17588 MVLI.UDMapperList.push_back(ER.get()); 17589 // We can only analyze this information once the missing information is 17590 // resolved. 17591 MVLI.ProcessedVarList.push_back(RE); 17592 continue; 17593 } 17594 17595 Expr *SimpleExpr = RE->IgnoreParenCasts(); 17596 17597 if (!RE->isLValue()) { 17598 if (SemaRef.getLangOpts().OpenMP < 50) { 17599 SemaRef.Diag( 17600 ELoc, diag::err_omp_expected_named_var_member_or_array_expression) 17601 << RE->getSourceRange(); 17602 } else { 17603 SemaRef.Diag(ELoc, diag::err_omp_non_lvalue_in_map_or_motion_clauses) 17604 << getOpenMPClauseName(CKind) << RE->getSourceRange(); 17605 } 17606 continue; 17607 } 17608 17609 OMPClauseMappableExprCommon::MappableExprComponentList CurComponents; 17610 ValueDecl *CurDeclaration = nullptr; 17611 17612 // Obtain the array or member expression bases if required. Also, fill the 17613 // components array with all the components identified in the process. 17614 const Expr *BE = checkMapClauseExpressionBase( 17615 SemaRef, SimpleExpr, CurComponents, CKind, DSAS->getCurrentDirective(), 17616 /*NoDiagnose=*/false); 17617 if (!BE) 17618 continue; 17619 17620 assert(!CurComponents.empty() && 17621 "Invalid mappable expression information."); 17622 17623 if (const auto *TE = dyn_cast<CXXThisExpr>(BE)) { 17624 // Add store "this" pointer to class in DSAStackTy for future checking 17625 DSAS->addMappedClassesQualTypes(TE->getType()); 17626 // Try to find the associated user-defined mapper. 17627 ExprResult ER = buildUserDefinedMapperRef( 17628 SemaRef, DSAS->getCurScope(), MapperIdScopeSpec, MapperId, 17629 VE->getType().getCanonicalType(), UnresolvedMapper); 17630 if (ER.isInvalid()) 17631 continue; 17632 MVLI.UDMapperList.push_back(ER.get()); 17633 // Skip restriction checking for variable or field declarations 17634 MVLI.ProcessedVarList.push_back(RE); 17635 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1); 17636 MVLI.VarComponents.back().append(CurComponents.begin(), 17637 CurComponents.end()); 17638 MVLI.VarBaseDeclarations.push_back(nullptr); 17639 continue; 17640 } 17641 17642 // For the following checks, we rely on the base declaration which is 17643 // expected to be associated with the last component. The declaration is 17644 // expected to be a variable or a field (if 'this' is being mapped). 17645 CurDeclaration = CurComponents.back().getAssociatedDeclaration(); 17646 assert(CurDeclaration && "Null decl on map clause."); 17647 assert( 17648 CurDeclaration->isCanonicalDecl() && 17649 "Expecting components to have associated only canonical declarations."); 17650 17651 auto *VD = dyn_cast<VarDecl>(CurDeclaration); 17652 const auto *FD = dyn_cast<FieldDecl>(CurDeclaration); 17653 17654 assert((VD || FD) && "Only variables or fields are expected here!"); 17655 (void)FD; 17656 17657 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.10] 17658 // threadprivate variables cannot appear in a map clause. 17659 // OpenMP 4.5 [2.10.5, target update Construct] 17660 // threadprivate variables cannot appear in a from clause. 17661 if (VD && DSAS->isThreadPrivate(VD)) { 17662 DSAStackTy::DSAVarData DVar = DSAS->getTopDSA(VD, /*FromParent=*/false); 17663 SemaRef.Diag(ELoc, diag::err_omp_threadprivate_in_clause) 17664 << getOpenMPClauseName(CKind); 17665 reportOriginalDsa(SemaRef, DSAS, VD, DVar); 17666 continue; 17667 } 17668 17669 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.9] 17670 // A list item cannot appear in both a map clause and a data-sharing 17671 // attribute clause on the same construct. 17672 17673 // Check conflicts with other map clause expressions. We check the conflicts 17674 // with the current construct separately from the enclosing data 17675 // environment, because the restrictions are different. We only have to 17676 // check conflicts across regions for the map clauses. 17677 if (checkMapConflicts(SemaRef, DSAS, CurDeclaration, SimpleExpr, 17678 /*CurrentRegionOnly=*/true, CurComponents, CKind)) 17679 break; 17680 if (CKind == OMPC_map && 17681 (SemaRef.getLangOpts().OpenMP <= 45 || StartLoc.isValid()) && 17682 checkMapConflicts(SemaRef, DSAS, CurDeclaration, SimpleExpr, 17683 /*CurrentRegionOnly=*/false, CurComponents, CKind)) 17684 break; 17685 17686 // OpenMP 4.5 [2.10.5, target update Construct] 17687 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1] 17688 // If the type of a list item is a reference to a type T then the type will 17689 // be considered to be T for all purposes of this clause. 17690 auto I = llvm::find_if( 17691 CurComponents, 17692 [](const OMPClauseMappableExprCommon::MappableComponent &MC) { 17693 return MC.getAssociatedDeclaration(); 17694 }); 17695 assert(I != CurComponents.end() && "Null decl on map clause."); 17696 QualType Type; 17697 auto *ASE = dyn_cast<ArraySubscriptExpr>(VE->IgnoreParens()); 17698 auto *OASE = dyn_cast<OMPArraySectionExpr>(VE->IgnoreParens()); 17699 auto *OAShE = dyn_cast<OMPArrayShapingExpr>(VE->IgnoreParens()); 17700 if (ASE) { 17701 Type = ASE->getType().getNonReferenceType(); 17702 } else if (OASE) { 17703 QualType BaseType = 17704 OMPArraySectionExpr::getBaseOriginalType(OASE->getBase()); 17705 if (const auto *ATy = BaseType->getAsArrayTypeUnsafe()) 17706 Type = ATy->getElementType(); 17707 else 17708 Type = BaseType->getPointeeType(); 17709 Type = Type.getNonReferenceType(); 17710 } else if (OAShE) { 17711 Type = OAShE->getBase()->getType()->getPointeeType(); 17712 } else { 17713 Type = VE->getType(); 17714 } 17715 17716 // OpenMP 4.5 [2.10.5, target update Construct, Restrictions, p.4] 17717 // A list item in a to or from clause must have a mappable type. 17718 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.9] 17719 // A list item must have a mappable type. 17720 if (!checkTypeMappable(VE->getExprLoc(), VE->getSourceRange(), SemaRef, 17721 DSAS, Type)) 17722 continue; 17723 17724 Type = I->getAssociatedDeclaration()->getType().getNonReferenceType(); 17725 17726 if (CKind == OMPC_map) { 17727 // target enter data 17728 // OpenMP [2.10.2, Restrictions, p. 99] 17729 // A map-type must be specified in all map clauses and must be either 17730 // to or alloc. 17731 OpenMPDirectiveKind DKind = DSAS->getCurrentDirective(); 17732 if (DKind == OMPD_target_enter_data && 17733 !(MapType == OMPC_MAP_to || MapType == OMPC_MAP_alloc)) { 17734 SemaRef.Diag(StartLoc, diag::err_omp_invalid_map_type_for_directive) 17735 << (IsMapTypeImplicit ? 1 : 0) 17736 << getOpenMPSimpleClauseTypeName(OMPC_map, MapType) 17737 << getOpenMPDirectiveName(DKind); 17738 continue; 17739 } 17740 17741 // target exit_data 17742 // OpenMP [2.10.3, Restrictions, p. 102] 17743 // A map-type must be specified in all map clauses and must be either 17744 // from, release, or delete. 17745 if (DKind == OMPD_target_exit_data && 17746 !(MapType == OMPC_MAP_from || MapType == OMPC_MAP_release || 17747 MapType == OMPC_MAP_delete)) { 17748 SemaRef.Diag(StartLoc, diag::err_omp_invalid_map_type_for_directive) 17749 << (IsMapTypeImplicit ? 1 : 0) 17750 << getOpenMPSimpleClauseTypeName(OMPC_map, MapType) 17751 << getOpenMPDirectiveName(DKind); 17752 continue; 17753 } 17754 17755 // target, target data 17756 // OpenMP 5.0 [2.12.2, Restrictions, p. 163] 17757 // OpenMP 5.0 [2.12.5, Restrictions, p. 174] 17758 // A map-type in a map clause must be to, from, tofrom or alloc 17759 if ((DKind == OMPD_target_data || 17760 isOpenMPTargetExecutionDirective(DKind)) && 17761 !(MapType == OMPC_MAP_to || MapType == OMPC_MAP_from || 17762 MapType == OMPC_MAP_tofrom || MapType == OMPC_MAP_alloc)) { 17763 SemaRef.Diag(StartLoc, diag::err_omp_invalid_map_type_for_directive) 17764 << (IsMapTypeImplicit ? 1 : 0) 17765 << getOpenMPSimpleClauseTypeName(OMPC_map, MapType) 17766 << getOpenMPDirectiveName(DKind); 17767 continue; 17768 } 17769 17770 // OpenMP 4.5 [2.15.5.1, Restrictions, p.3] 17771 // A list item cannot appear in both a map clause and a data-sharing 17772 // attribute clause on the same construct 17773 // 17774 // OpenMP 5.0 [2.19.7.1, Restrictions, p.7] 17775 // A list item cannot appear in both a map clause and a data-sharing 17776 // attribute clause on the same construct unless the construct is a 17777 // combined construct. 17778 if (VD && ((SemaRef.LangOpts.OpenMP <= 45 && 17779 isOpenMPTargetExecutionDirective(DKind)) || 17780 DKind == OMPD_target)) { 17781 DSAStackTy::DSAVarData DVar = DSAS->getTopDSA(VD, /*FromParent=*/false); 17782 if (isOpenMPPrivate(DVar.CKind)) { 17783 SemaRef.Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa) 17784 << getOpenMPClauseName(DVar.CKind) 17785 << getOpenMPClauseName(OMPC_map) 17786 << getOpenMPDirectiveName(DSAS->getCurrentDirective()); 17787 reportOriginalDsa(SemaRef, DSAS, CurDeclaration, DVar); 17788 continue; 17789 } 17790 } 17791 } 17792 17793 // Try to find the associated user-defined mapper. 17794 ExprResult ER = buildUserDefinedMapperRef( 17795 SemaRef, DSAS->getCurScope(), MapperIdScopeSpec, MapperId, 17796 Type.getCanonicalType(), UnresolvedMapper); 17797 if (ER.isInvalid()) 17798 continue; 17799 MVLI.UDMapperList.push_back(ER.get()); 17800 17801 // Save the current expression. 17802 MVLI.ProcessedVarList.push_back(RE); 17803 17804 // Store the components in the stack so that they can be used to check 17805 // against other clauses later on. 17806 DSAS->addMappableExpressionComponents(CurDeclaration, CurComponents, 17807 /*WhereFoundClauseKind=*/OMPC_map); 17808 17809 // Save the components and declaration to create the clause. For purposes of 17810 // the clause creation, any component list that has has base 'this' uses 17811 // null as base declaration. 17812 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1); 17813 MVLI.VarComponents.back().append(CurComponents.begin(), 17814 CurComponents.end()); 17815 MVLI.VarBaseDeclarations.push_back(isa<MemberExpr>(BE) ? nullptr 17816 : CurDeclaration); 17817 } 17818 } 17819 17820 OMPClause *Sema::ActOnOpenMPMapClause( 17821 ArrayRef<OpenMPMapModifierKind> MapTypeModifiers, 17822 ArrayRef<SourceLocation> MapTypeModifiersLoc, 17823 CXXScopeSpec &MapperIdScopeSpec, DeclarationNameInfo &MapperId, 17824 OpenMPMapClauseKind MapType, bool IsMapTypeImplicit, SourceLocation MapLoc, 17825 SourceLocation ColonLoc, ArrayRef<Expr *> VarList, 17826 const OMPVarListLocTy &Locs, ArrayRef<Expr *> UnresolvedMappers) { 17827 OpenMPMapModifierKind Modifiers[] = { 17828 OMPC_MAP_MODIFIER_unknown, OMPC_MAP_MODIFIER_unknown, 17829 OMPC_MAP_MODIFIER_unknown, OMPC_MAP_MODIFIER_unknown}; 17830 SourceLocation ModifiersLoc[NumberOfOMPMapClauseModifiers]; 17831 17832 // Process map-type-modifiers, flag errors for duplicate modifiers. 17833 unsigned Count = 0; 17834 for (unsigned I = 0, E = MapTypeModifiers.size(); I < E; ++I) { 17835 if (MapTypeModifiers[I] != OMPC_MAP_MODIFIER_unknown && 17836 llvm::find(Modifiers, MapTypeModifiers[I]) != std::end(Modifiers)) { 17837 Diag(MapTypeModifiersLoc[I], diag::err_omp_duplicate_map_type_modifier); 17838 continue; 17839 } 17840 assert(Count < NumberOfOMPMapClauseModifiers && 17841 "Modifiers exceed the allowed number of map type modifiers"); 17842 Modifiers[Count] = MapTypeModifiers[I]; 17843 ModifiersLoc[Count] = MapTypeModifiersLoc[I]; 17844 ++Count; 17845 } 17846 17847 MappableVarListInfo MVLI(VarList); 17848 checkMappableExpressionList(*this, DSAStack, OMPC_map, MVLI, Locs.StartLoc, 17849 MapperIdScopeSpec, MapperId, UnresolvedMappers, 17850 MapType, IsMapTypeImplicit); 17851 17852 // We need to produce a map clause even if we don't have variables so that 17853 // other diagnostics related with non-existing map clauses are accurate. 17854 return OMPMapClause::Create(Context, Locs, MVLI.ProcessedVarList, 17855 MVLI.VarBaseDeclarations, MVLI.VarComponents, 17856 MVLI.UDMapperList, Modifiers, ModifiersLoc, 17857 MapperIdScopeSpec.getWithLocInContext(Context), 17858 MapperId, MapType, IsMapTypeImplicit, MapLoc); 17859 } 17860 17861 QualType Sema::ActOnOpenMPDeclareReductionType(SourceLocation TyLoc, 17862 TypeResult ParsedType) { 17863 assert(ParsedType.isUsable()); 17864 17865 QualType ReductionType = GetTypeFromParser(ParsedType.get()); 17866 if (ReductionType.isNull()) 17867 return QualType(); 17868 17869 // [OpenMP 4.0], 2.15 declare reduction Directive, Restrictions, C\C++ 17870 // A type name in a declare reduction directive cannot be a function type, an 17871 // array type, a reference type, or a type qualified with const, volatile or 17872 // restrict. 17873 if (ReductionType.hasQualifiers()) { 17874 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 0; 17875 return QualType(); 17876 } 17877 17878 if (ReductionType->isFunctionType()) { 17879 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 1; 17880 return QualType(); 17881 } 17882 if (ReductionType->isReferenceType()) { 17883 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 2; 17884 return QualType(); 17885 } 17886 if (ReductionType->isArrayType()) { 17887 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 3; 17888 return QualType(); 17889 } 17890 return ReductionType; 17891 } 17892 17893 Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareReductionDirectiveStart( 17894 Scope *S, DeclContext *DC, DeclarationName Name, 17895 ArrayRef<std::pair<QualType, SourceLocation>> ReductionTypes, 17896 AccessSpecifier AS, Decl *PrevDeclInScope) { 17897 SmallVector<Decl *, 8> Decls; 17898 Decls.reserve(ReductionTypes.size()); 17899 17900 LookupResult Lookup(*this, Name, SourceLocation(), LookupOMPReductionName, 17901 forRedeclarationInCurContext()); 17902 // [OpenMP 4.0], 2.15 declare reduction Directive, Restrictions 17903 // A reduction-identifier may not be re-declared in the current scope for the 17904 // same type or for a type that is compatible according to the base language 17905 // rules. 17906 llvm::DenseMap<QualType, SourceLocation> PreviousRedeclTypes; 17907 OMPDeclareReductionDecl *PrevDRD = nullptr; 17908 bool InCompoundScope = true; 17909 if (S != nullptr) { 17910 // Find previous declaration with the same name not referenced in other 17911 // declarations. 17912 FunctionScopeInfo *ParentFn = getEnclosingFunction(); 17913 InCompoundScope = 17914 (ParentFn != nullptr) && !ParentFn->CompoundScopes.empty(); 17915 LookupName(Lookup, S); 17916 FilterLookupForScope(Lookup, DC, S, /*ConsiderLinkage=*/false, 17917 /*AllowInlineNamespace=*/false); 17918 llvm::DenseMap<OMPDeclareReductionDecl *, bool> UsedAsPrevious; 17919 LookupResult::Filter Filter = Lookup.makeFilter(); 17920 while (Filter.hasNext()) { 17921 auto *PrevDecl = cast<OMPDeclareReductionDecl>(Filter.next()); 17922 if (InCompoundScope) { 17923 auto I = UsedAsPrevious.find(PrevDecl); 17924 if (I == UsedAsPrevious.end()) 17925 UsedAsPrevious[PrevDecl] = false; 17926 if (OMPDeclareReductionDecl *D = PrevDecl->getPrevDeclInScope()) 17927 UsedAsPrevious[D] = true; 17928 } 17929 PreviousRedeclTypes[PrevDecl->getType().getCanonicalType()] = 17930 PrevDecl->getLocation(); 17931 } 17932 Filter.done(); 17933 if (InCompoundScope) { 17934 for (const auto &PrevData : UsedAsPrevious) { 17935 if (!PrevData.second) { 17936 PrevDRD = PrevData.first; 17937 break; 17938 } 17939 } 17940 } 17941 } else if (PrevDeclInScope != nullptr) { 17942 auto *PrevDRDInScope = PrevDRD = 17943 cast<OMPDeclareReductionDecl>(PrevDeclInScope); 17944 do { 17945 PreviousRedeclTypes[PrevDRDInScope->getType().getCanonicalType()] = 17946 PrevDRDInScope->getLocation(); 17947 PrevDRDInScope = PrevDRDInScope->getPrevDeclInScope(); 17948 } while (PrevDRDInScope != nullptr); 17949 } 17950 for (const auto &TyData : ReductionTypes) { 17951 const auto I = PreviousRedeclTypes.find(TyData.first.getCanonicalType()); 17952 bool Invalid = false; 17953 if (I != PreviousRedeclTypes.end()) { 17954 Diag(TyData.second, diag::err_omp_declare_reduction_redefinition) 17955 << TyData.first; 17956 Diag(I->second, diag::note_previous_definition); 17957 Invalid = true; 17958 } 17959 PreviousRedeclTypes[TyData.first.getCanonicalType()] = TyData.second; 17960 auto *DRD = OMPDeclareReductionDecl::Create(Context, DC, TyData.second, 17961 Name, TyData.first, PrevDRD); 17962 DC->addDecl(DRD); 17963 DRD->setAccess(AS); 17964 Decls.push_back(DRD); 17965 if (Invalid) 17966 DRD->setInvalidDecl(); 17967 else 17968 PrevDRD = DRD; 17969 } 17970 17971 return DeclGroupPtrTy::make( 17972 DeclGroupRef::Create(Context, Decls.begin(), Decls.size())); 17973 } 17974 17975 void Sema::ActOnOpenMPDeclareReductionCombinerStart(Scope *S, Decl *D) { 17976 auto *DRD = cast<OMPDeclareReductionDecl>(D); 17977 17978 // Enter new function scope. 17979 PushFunctionScope(); 17980 setFunctionHasBranchProtectedScope(); 17981 getCurFunction()->setHasOMPDeclareReductionCombiner(); 17982 17983 if (S != nullptr) 17984 PushDeclContext(S, DRD); 17985 else 17986 CurContext = DRD; 17987 17988 PushExpressionEvaluationContext( 17989 ExpressionEvaluationContext::PotentiallyEvaluated); 17990 17991 QualType ReductionType = DRD->getType(); 17992 // Create 'T* omp_parm;T omp_in;'. All references to 'omp_in' will 17993 // be replaced by '*omp_parm' during codegen. This required because 'omp_in' 17994 // uses semantics of argument handles by value, but it should be passed by 17995 // reference. C lang does not support references, so pass all parameters as 17996 // pointers. 17997 // Create 'T omp_in;' variable. 17998 VarDecl *OmpInParm = 17999 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_in"); 18000 // Create 'T* omp_parm;T omp_out;'. All references to 'omp_out' will 18001 // be replaced by '*omp_parm' during codegen. This required because 'omp_out' 18002 // uses semantics of argument handles by value, but it should be passed by 18003 // reference. C lang does not support references, so pass all parameters as 18004 // pointers. 18005 // Create 'T omp_out;' variable. 18006 VarDecl *OmpOutParm = 18007 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_out"); 18008 if (S != nullptr) { 18009 PushOnScopeChains(OmpInParm, S); 18010 PushOnScopeChains(OmpOutParm, S); 18011 } else { 18012 DRD->addDecl(OmpInParm); 18013 DRD->addDecl(OmpOutParm); 18014 } 18015 Expr *InE = 18016 ::buildDeclRefExpr(*this, OmpInParm, ReductionType, D->getLocation()); 18017 Expr *OutE = 18018 ::buildDeclRefExpr(*this, OmpOutParm, ReductionType, D->getLocation()); 18019 DRD->setCombinerData(InE, OutE); 18020 } 18021 18022 void Sema::ActOnOpenMPDeclareReductionCombinerEnd(Decl *D, Expr *Combiner) { 18023 auto *DRD = cast<OMPDeclareReductionDecl>(D); 18024 DiscardCleanupsInEvaluationContext(); 18025 PopExpressionEvaluationContext(); 18026 18027 PopDeclContext(); 18028 PopFunctionScopeInfo(); 18029 18030 if (Combiner != nullptr) 18031 DRD->setCombiner(Combiner); 18032 else 18033 DRD->setInvalidDecl(); 18034 } 18035 18036 VarDecl *Sema::ActOnOpenMPDeclareReductionInitializerStart(Scope *S, Decl *D) { 18037 auto *DRD = cast<OMPDeclareReductionDecl>(D); 18038 18039 // Enter new function scope. 18040 PushFunctionScope(); 18041 setFunctionHasBranchProtectedScope(); 18042 18043 if (S != nullptr) 18044 PushDeclContext(S, DRD); 18045 else 18046 CurContext = DRD; 18047 18048 PushExpressionEvaluationContext( 18049 ExpressionEvaluationContext::PotentiallyEvaluated); 18050 18051 QualType ReductionType = DRD->getType(); 18052 // Create 'T* omp_parm;T omp_priv;'. All references to 'omp_priv' will 18053 // be replaced by '*omp_parm' during codegen. This required because 'omp_priv' 18054 // uses semantics of argument handles by value, but it should be passed by 18055 // reference. C lang does not support references, so pass all parameters as 18056 // pointers. 18057 // Create 'T omp_priv;' variable. 18058 VarDecl *OmpPrivParm = 18059 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_priv"); 18060 // Create 'T* omp_parm;T omp_orig;'. All references to 'omp_orig' will 18061 // be replaced by '*omp_parm' during codegen. This required because 'omp_orig' 18062 // uses semantics of argument handles by value, but it should be passed by 18063 // reference. C lang does not support references, so pass all parameters as 18064 // pointers. 18065 // Create 'T omp_orig;' variable. 18066 VarDecl *OmpOrigParm = 18067 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_orig"); 18068 if (S != nullptr) { 18069 PushOnScopeChains(OmpPrivParm, S); 18070 PushOnScopeChains(OmpOrigParm, S); 18071 } else { 18072 DRD->addDecl(OmpPrivParm); 18073 DRD->addDecl(OmpOrigParm); 18074 } 18075 Expr *OrigE = 18076 ::buildDeclRefExpr(*this, OmpOrigParm, ReductionType, D->getLocation()); 18077 Expr *PrivE = 18078 ::buildDeclRefExpr(*this, OmpPrivParm, ReductionType, D->getLocation()); 18079 DRD->setInitializerData(OrigE, PrivE); 18080 return OmpPrivParm; 18081 } 18082 18083 void Sema::ActOnOpenMPDeclareReductionInitializerEnd(Decl *D, Expr *Initializer, 18084 VarDecl *OmpPrivParm) { 18085 auto *DRD = cast<OMPDeclareReductionDecl>(D); 18086 DiscardCleanupsInEvaluationContext(); 18087 PopExpressionEvaluationContext(); 18088 18089 PopDeclContext(); 18090 PopFunctionScopeInfo(); 18091 18092 if (Initializer != nullptr) { 18093 DRD->setInitializer(Initializer, OMPDeclareReductionDecl::CallInit); 18094 } else if (OmpPrivParm->hasInit()) { 18095 DRD->setInitializer(OmpPrivParm->getInit(), 18096 OmpPrivParm->isDirectInit() 18097 ? OMPDeclareReductionDecl::DirectInit 18098 : OMPDeclareReductionDecl::CopyInit); 18099 } else { 18100 DRD->setInvalidDecl(); 18101 } 18102 } 18103 18104 Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareReductionDirectiveEnd( 18105 Scope *S, DeclGroupPtrTy DeclReductions, bool IsValid) { 18106 for (Decl *D : DeclReductions.get()) { 18107 if (IsValid) { 18108 if (S) 18109 PushOnScopeChains(cast<OMPDeclareReductionDecl>(D), S, 18110 /*AddToContext=*/false); 18111 } else { 18112 D->setInvalidDecl(); 18113 } 18114 } 18115 return DeclReductions; 18116 } 18117 18118 TypeResult Sema::ActOnOpenMPDeclareMapperVarDecl(Scope *S, Declarator &D) { 18119 TypeSourceInfo *TInfo = GetTypeForDeclarator(D, S); 18120 QualType T = TInfo->getType(); 18121 if (D.isInvalidType()) 18122 return true; 18123 18124 if (getLangOpts().CPlusPlus) { 18125 // Check that there are no default arguments (C++ only). 18126 CheckExtraCXXDefaultArguments(D); 18127 } 18128 18129 return CreateParsedType(T, TInfo); 18130 } 18131 18132 QualType Sema::ActOnOpenMPDeclareMapperType(SourceLocation TyLoc, 18133 TypeResult ParsedType) { 18134 assert(ParsedType.isUsable() && "Expect usable parsed mapper type"); 18135 18136 QualType MapperType = GetTypeFromParser(ParsedType.get()); 18137 assert(!MapperType.isNull() && "Expect valid mapper type"); 18138 18139 // [OpenMP 5.0], 2.19.7.3 declare mapper Directive, Restrictions 18140 // The type must be of struct, union or class type in C and C++ 18141 if (!MapperType->isStructureOrClassType() && !MapperType->isUnionType()) { 18142 Diag(TyLoc, diag::err_omp_mapper_wrong_type); 18143 return QualType(); 18144 } 18145 return MapperType; 18146 } 18147 18148 Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareMapperDirective( 18149 Scope *S, DeclContext *DC, DeclarationName Name, QualType MapperType, 18150 SourceLocation StartLoc, DeclarationName VN, AccessSpecifier AS, 18151 Expr *MapperVarRef, ArrayRef<OMPClause *> Clauses, Decl *PrevDeclInScope) { 18152 LookupResult Lookup(*this, Name, SourceLocation(), LookupOMPMapperName, 18153 forRedeclarationInCurContext()); 18154 // [OpenMP 5.0], 2.19.7.3 declare mapper Directive, Restrictions 18155 // A mapper-identifier may not be redeclared in the current scope for the 18156 // same type or for a type that is compatible according to the base language 18157 // rules. 18158 llvm::DenseMap<QualType, SourceLocation> PreviousRedeclTypes; 18159 OMPDeclareMapperDecl *PrevDMD = nullptr; 18160 bool InCompoundScope = true; 18161 if (S != nullptr) { 18162 // Find previous declaration with the same name not referenced in other 18163 // declarations. 18164 FunctionScopeInfo *ParentFn = getEnclosingFunction(); 18165 InCompoundScope = 18166 (ParentFn != nullptr) && !ParentFn->CompoundScopes.empty(); 18167 LookupName(Lookup, S); 18168 FilterLookupForScope(Lookup, DC, S, /*ConsiderLinkage=*/false, 18169 /*AllowInlineNamespace=*/false); 18170 llvm::DenseMap<OMPDeclareMapperDecl *, bool> UsedAsPrevious; 18171 LookupResult::Filter Filter = Lookup.makeFilter(); 18172 while (Filter.hasNext()) { 18173 auto *PrevDecl = cast<OMPDeclareMapperDecl>(Filter.next()); 18174 if (InCompoundScope) { 18175 auto I = UsedAsPrevious.find(PrevDecl); 18176 if (I == UsedAsPrevious.end()) 18177 UsedAsPrevious[PrevDecl] = false; 18178 if (OMPDeclareMapperDecl *D = PrevDecl->getPrevDeclInScope()) 18179 UsedAsPrevious[D] = true; 18180 } 18181 PreviousRedeclTypes[PrevDecl->getType().getCanonicalType()] = 18182 PrevDecl->getLocation(); 18183 } 18184 Filter.done(); 18185 if (InCompoundScope) { 18186 for (const auto &PrevData : UsedAsPrevious) { 18187 if (!PrevData.second) { 18188 PrevDMD = PrevData.first; 18189 break; 18190 } 18191 } 18192 } 18193 } else if (PrevDeclInScope) { 18194 auto *PrevDMDInScope = PrevDMD = 18195 cast<OMPDeclareMapperDecl>(PrevDeclInScope); 18196 do { 18197 PreviousRedeclTypes[PrevDMDInScope->getType().getCanonicalType()] = 18198 PrevDMDInScope->getLocation(); 18199 PrevDMDInScope = PrevDMDInScope->getPrevDeclInScope(); 18200 } while (PrevDMDInScope != nullptr); 18201 } 18202 const auto I = PreviousRedeclTypes.find(MapperType.getCanonicalType()); 18203 bool Invalid = false; 18204 if (I != PreviousRedeclTypes.end()) { 18205 Diag(StartLoc, diag::err_omp_declare_mapper_redefinition) 18206 << MapperType << Name; 18207 Diag(I->second, diag::note_previous_definition); 18208 Invalid = true; 18209 } 18210 auto *DMD = OMPDeclareMapperDecl::Create(Context, DC, StartLoc, Name, 18211 MapperType, VN, Clauses, PrevDMD); 18212 if (S) 18213 PushOnScopeChains(DMD, S); 18214 else 18215 DC->addDecl(DMD); 18216 DMD->setAccess(AS); 18217 if (Invalid) 18218 DMD->setInvalidDecl(); 18219 18220 auto *VD = cast<DeclRefExpr>(MapperVarRef)->getDecl(); 18221 VD->setDeclContext(DMD); 18222 VD->setLexicalDeclContext(DMD); 18223 DMD->addDecl(VD); 18224 DMD->setMapperVarRef(MapperVarRef); 18225 18226 return DeclGroupPtrTy::make(DeclGroupRef(DMD)); 18227 } 18228 18229 ExprResult 18230 Sema::ActOnOpenMPDeclareMapperDirectiveVarDecl(Scope *S, QualType MapperType, 18231 SourceLocation StartLoc, 18232 DeclarationName VN) { 18233 TypeSourceInfo *TInfo = 18234 Context.getTrivialTypeSourceInfo(MapperType, StartLoc); 18235 auto *VD = VarDecl::Create(Context, Context.getTranslationUnitDecl(), 18236 StartLoc, StartLoc, VN.getAsIdentifierInfo(), 18237 MapperType, TInfo, SC_None); 18238 if (S) 18239 PushOnScopeChains(VD, S, /*AddToContext=*/false); 18240 Expr *E = buildDeclRefExpr(*this, VD, MapperType, StartLoc); 18241 DSAStack->addDeclareMapperVarRef(E); 18242 return E; 18243 } 18244 18245 bool Sema::isOpenMPDeclareMapperVarDeclAllowed(const VarDecl *VD) const { 18246 assert(LangOpts.OpenMP && "Expected OpenMP mode."); 18247 const Expr *Ref = DSAStack->getDeclareMapperVarRef(); 18248 if (const auto *DRE = cast_or_null<DeclRefExpr>(Ref)) 18249 return VD->getCanonicalDecl() == DRE->getDecl()->getCanonicalDecl(); 18250 return true; 18251 } 18252 18253 const ValueDecl *Sema::getOpenMPDeclareMapperVarName() const { 18254 assert(LangOpts.OpenMP && "Expected OpenMP mode."); 18255 return cast<DeclRefExpr>(DSAStack->getDeclareMapperVarRef())->getDecl(); 18256 } 18257 18258 OMPClause *Sema::ActOnOpenMPNumTeamsClause(Expr *NumTeams, 18259 SourceLocation StartLoc, 18260 SourceLocation LParenLoc, 18261 SourceLocation EndLoc) { 18262 Expr *ValExpr = NumTeams; 18263 Stmt *HelperValStmt = nullptr; 18264 18265 // OpenMP [teams Constrcut, Restrictions] 18266 // The num_teams expression must evaluate to a positive integer value. 18267 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_num_teams, 18268 /*StrictlyPositive=*/true)) 18269 return nullptr; 18270 18271 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 18272 OpenMPDirectiveKind CaptureRegion = 18273 getOpenMPCaptureRegionForClause(DKind, OMPC_num_teams, LangOpts.OpenMP); 18274 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 18275 ValExpr = MakeFullExpr(ValExpr).get(); 18276 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 18277 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 18278 HelperValStmt = buildPreInits(Context, Captures); 18279 } 18280 18281 return new (Context) OMPNumTeamsClause(ValExpr, HelperValStmt, CaptureRegion, 18282 StartLoc, LParenLoc, EndLoc); 18283 } 18284 18285 OMPClause *Sema::ActOnOpenMPThreadLimitClause(Expr *ThreadLimit, 18286 SourceLocation StartLoc, 18287 SourceLocation LParenLoc, 18288 SourceLocation EndLoc) { 18289 Expr *ValExpr = ThreadLimit; 18290 Stmt *HelperValStmt = nullptr; 18291 18292 // OpenMP [teams Constrcut, Restrictions] 18293 // The thread_limit expression must evaluate to a positive integer value. 18294 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_thread_limit, 18295 /*StrictlyPositive=*/true)) 18296 return nullptr; 18297 18298 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 18299 OpenMPDirectiveKind CaptureRegion = getOpenMPCaptureRegionForClause( 18300 DKind, OMPC_thread_limit, LangOpts.OpenMP); 18301 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 18302 ValExpr = MakeFullExpr(ValExpr).get(); 18303 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 18304 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 18305 HelperValStmt = buildPreInits(Context, Captures); 18306 } 18307 18308 return new (Context) OMPThreadLimitClause( 18309 ValExpr, HelperValStmt, CaptureRegion, StartLoc, LParenLoc, EndLoc); 18310 } 18311 18312 OMPClause *Sema::ActOnOpenMPPriorityClause(Expr *Priority, 18313 SourceLocation StartLoc, 18314 SourceLocation LParenLoc, 18315 SourceLocation EndLoc) { 18316 Expr *ValExpr = Priority; 18317 Stmt *HelperValStmt = nullptr; 18318 OpenMPDirectiveKind CaptureRegion = OMPD_unknown; 18319 18320 // OpenMP [2.9.1, task Constrcut] 18321 // The priority-value is a non-negative numerical scalar expression. 18322 if (!isNonNegativeIntegerValue( 18323 ValExpr, *this, OMPC_priority, 18324 /*StrictlyPositive=*/false, /*BuildCapture=*/true, 18325 DSAStack->getCurrentDirective(), &CaptureRegion, &HelperValStmt)) 18326 return nullptr; 18327 18328 return new (Context) OMPPriorityClause(ValExpr, HelperValStmt, CaptureRegion, 18329 StartLoc, LParenLoc, EndLoc); 18330 } 18331 18332 OMPClause *Sema::ActOnOpenMPGrainsizeClause(Expr *Grainsize, 18333 SourceLocation StartLoc, 18334 SourceLocation LParenLoc, 18335 SourceLocation EndLoc) { 18336 Expr *ValExpr = Grainsize; 18337 Stmt *HelperValStmt = nullptr; 18338 OpenMPDirectiveKind CaptureRegion = OMPD_unknown; 18339 18340 // OpenMP [2.9.2, taskloop Constrcut] 18341 // The parameter of the grainsize clause must be a positive integer 18342 // expression. 18343 if (!isNonNegativeIntegerValue( 18344 ValExpr, *this, OMPC_grainsize, 18345 /*StrictlyPositive=*/true, /*BuildCapture=*/true, 18346 DSAStack->getCurrentDirective(), &CaptureRegion, &HelperValStmt)) 18347 return nullptr; 18348 18349 return new (Context) OMPGrainsizeClause(ValExpr, HelperValStmt, CaptureRegion, 18350 StartLoc, LParenLoc, EndLoc); 18351 } 18352 18353 OMPClause *Sema::ActOnOpenMPNumTasksClause(Expr *NumTasks, 18354 SourceLocation StartLoc, 18355 SourceLocation LParenLoc, 18356 SourceLocation EndLoc) { 18357 Expr *ValExpr = NumTasks; 18358 Stmt *HelperValStmt = nullptr; 18359 OpenMPDirectiveKind CaptureRegion = OMPD_unknown; 18360 18361 // OpenMP [2.9.2, taskloop Constrcut] 18362 // The parameter of the num_tasks clause must be a positive integer 18363 // expression. 18364 if (!isNonNegativeIntegerValue( 18365 ValExpr, *this, OMPC_num_tasks, 18366 /*StrictlyPositive=*/true, /*BuildCapture=*/true, 18367 DSAStack->getCurrentDirective(), &CaptureRegion, &HelperValStmt)) 18368 return nullptr; 18369 18370 return new (Context) OMPNumTasksClause(ValExpr, HelperValStmt, CaptureRegion, 18371 StartLoc, LParenLoc, EndLoc); 18372 } 18373 18374 OMPClause *Sema::ActOnOpenMPHintClause(Expr *Hint, SourceLocation StartLoc, 18375 SourceLocation LParenLoc, 18376 SourceLocation EndLoc) { 18377 // OpenMP [2.13.2, critical construct, Description] 18378 // ... where hint-expression is an integer constant expression that evaluates 18379 // to a valid lock hint. 18380 ExprResult HintExpr = VerifyPositiveIntegerConstantInClause(Hint, OMPC_hint); 18381 if (HintExpr.isInvalid()) 18382 return nullptr; 18383 return new (Context) 18384 OMPHintClause(HintExpr.get(), StartLoc, LParenLoc, EndLoc); 18385 } 18386 18387 /// Tries to find omp_event_handle_t type. 18388 static bool findOMPEventHandleT(Sema &S, SourceLocation Loc, 18389 DSAStackTy *Stack) { 18390 QualType OMPEventHandleT = Stack->getOMPEventHandleT(); 18391 if (!OMPEventHandleT.isNull()) 18392 return true; 18393 IdentifierInfo *II = &S.PP.getIdentifierTable().get("omp_event_handle_t"); 18394 ParsedType PT = S.getTypeName(*II, Loc, S.getCurScope()); 18395 if (!PT.getAsOpaquePtr() || PT.get().isNull()) { 18396 S.Diag(Loc, diag::err_omp_implied_type_not_found) << "omp_event_handle_t"; 18397 return false; 18398 } 18399 Stack->setOMPEventHandleT(PT.get()); 18400 return true; 18401 } 18402 18403 OMPClause *Sema::ActOnOpenMPDetachClause(Expr *Evt, SourceLocation StartLoc, 18404 SourceLocation LParenLoc, 18405 SourceLocation EndLoc) { 18406 if (!Evt->isValueDependent() && !Evt->isTypeDependent() && 18407 !Evt->isInstantiationDependent() && 18408 !Evt->containsUnexpandedParameterPack()) { 18409 if (!findOMPEventHandleT(*this, Evt->getExprLoc(), DSAStack)) 18410 return nullptr; 18411 // OpenMP 5.0, 2.10.1 task Construct. 18412 // event-handle is a variable of the omp_event_handle_t type. 18413 auto *Ref = dyn_cast<DeclRefExpr>(Evt->IgnoreParenImpCasts()); 18414 if (!Ref) { 18415 Diag(Evt->getExprLoc(), diag::err_omp_var_expected) 18416 << "omp_event_handle_t" << 0 << Evt->getSourceRange(); 18417 return nullptr; 18418 } 18419 auto *VD = dyn_cast_or_null<VarDecl>(Ref->getDecl()); 18420 if (!VD) { 18421 Diag(Evt->getExprLoc(), diag::err_omp_var_expected) 18422 << "omp_event_handle_t" << 0 << Evt->getSourceRange(); 18423 return nullptr; 18424 } 18425 if (!Context.hasSameUnqualifiedType(DSAStack->getOMPEventHandleT(), 18426 VD->getType()) || 18427 VD->getType().isConstant(Context)) { 18428 Diag(Evt->getExprLoc(), diag::err_omp_var_expected) 18429 << "omp_event_handle_t" << 1 << VD->getType() 18430 << Evt->getSourceRange(); 18431 return nullptr; 18432 } 18433 // OpenMP 5.0, 2.10.1 task Construct 18434 // [detach clause]... The event-handle will be considered as if it was 18435 // specified on a firstprivate clause. 18436 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(VD, /*FromParent=*/false); 18437 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_firstprivate && 18438 DVar.RefExpr) { 18439 Diag(Evt->getExprLoc(), diag::err_omp_wrong_dsa) 18440 << getOpenMPClauseName(DVar.CKind) 18441 << getOpenMPClauseName(OMPC_firstprivate); 18442 reportOriginalDsa(*this, DSAStack, VD, DVar); 18443 return nullptr; 18444 } 18445 } 18446 18447 return new (Context) OMPDetachClause(Evt, StartLoc, LParenLoc, EndLoc); 18448 } 18449 18450 OMPClause *Sema::ActOnOpenMPDistScheduleClause( 18451 OpenMPDistScheduleClauseKind Kind, Expr *ChunkSize, SourceLocation StartLoc, 18452 SourceLocation LParenLoc, SourceLocation KindLoc, SourceLocation CommaLoc, 18453 SourceLocation EndLoc) { 18454 if (Kind == OMPC_DIST_SCHEDULE_unknown) { 18455 std::string Values; 18456 Values += "'"; 18457 Values += getOpenMPSimpleClauseTypeName(OMPC_dist_schedule, 0); 18458 Values += "'"; 18459 Diag(KindLoc, diag::err_omp_unexpected_clause_value) 18460 << Values << getOpenMPClauseName(OMPC_dist_schedule); 18461 return nullptr; 18462 } 18463 Expr *ValExpr = ChunkSize; 18464 Stmt *HelperValStmt = nullptr; 18465 if (ChunkSize) { 18466 if (!ChunkSize->isValueDependent() && !ChunkSize->isTypeDependent() && 18467 !ChunkSize->isInstantiationDependent() && 18468 !ChunkSize->containsUnexpandedParameterPack()) { 18469 SourceLocation ChunkSizeLoc = ChunkSize->getBeginLoc(); 18470 ExprResult Val = 18471 PerformOpenMPImplicitIntegerConversion(ChunkSizeLoc, ChunkSize); 18472 if (Val.isInvalid()) 18473 return nullptr; 18474 18475 ValExpr = Val.get(); 18476 18477 // OpenMP [2.7.1, Restrictions] 18478 // chunk_size must be a loop invariant integer expression with a positive 18479 // value. 18480 if (Optional<llvm::APSInt> Result = 18481 ValExpr->getIntegerConstantExpr(Context)) { 18482 if (Result->isSigned() && !Result->isStrictlyPositive()) { 18483 Diag(ChunkSizeLoc, diag::err_omp_negative_expression_in_clause) 18484 << "dist_schedule" << ChunkSize->getSourceRange(); 18485 return nullptr; 18486 } 18487 } else if (getOpenMPCaptureRegionForClause( 18488 DSAStack->getCurrentDirective(), OMPC_dist_schedule, 18489 LangOpts.OpenMP) != OMPD_unknown && 18490 !CurContext->isDependentContext()) { 18491 ValExpr = MakeFullExpr(ValExpr).get(); 18492 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 18493 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 18494 HelperValStmt = buildPreInits(Context, Captures); 18495 } 18496 } 18497 } 18498 18499 return new (Context) 18500 OMPDistScheduleClause(StartLoc, LParenLoc, KindLoc, CommaLoc, EndLoc, 18501 Kind, ValExpr, HelperValStmt); 18502 } 18503 18504 OMPClause *Sema::ActOnOpenMPDefaultmapClause( 18505 OpenMPDefaultmapClauseModifier M, OpenMPDefaultmapClauseKind Kind, 18506 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation MLoc, 18507 SourceLocation KindLoc, SourceLocation EndLoc) { 18508 if (getLangOpts().OpenMP < 50) { 18509 if (M != OMPC_DEFAULTMAP_MODIFIER_tofrom || 18510 Kind != OMPC_DEFAULTMAP_scalar) { 18511 std::string Value; 18512 SourceLocation Loc; 18513 Value += "'"; 18514 if (M != OMPC_DEFAULTMAP_MODIFIER_tofrom) { 18515 Value += getOpenMPSimpleClauseTypeName(OMPC_defaultmap, 18516 OMPC_DEFAULTMAP_MODIFIER_tofrom); 18517 Loc = MLoc; 18518 } else { 18519 Value += getOpenMPSimpleClauseTypeName(OMPC_defaultmap, 18520 OMPC_DEFAULTMAP_scalar); 18521 Loc = KindLoc; 18522 } 18523 Value += "'"; 18524 Diag(Loc, diag::err_omp_unexpected_clause_value) 18525 << Value << getOpenMPClauseName(OMPC_defaultmap); 18526 return nullptr; 18527 } 18528 } else { 18529 bool isDefaultmapModifier = (M != OMPC_DEFAULTMAP_MODIFIER_unknown); 18530 bool isDefaultmapKind = (Kind != OMPC_DEFAULTMAP_unknown) || 18531 (LangOpts.OpenMP >= 50 && KindLoc.isInvalid()); 18532 if (!isDefaultmapKind || !isDefaultmapModifier) { 18533 std::string ModifierValue = "'alloc', 'from', 'to', 'tofrom', " 18534 "'firstprivate', 'none', 'default'"; 18535 std::string KindValue = "'scalar', 'aggregate', 'pointer'"; 18536 if (!isDefaultmapKind && isDefaultmapModifier) { 18537 Diag(KindLoc, diag::err_omp_unexpected_clause_value) 18538 << KindValue << getOpenMPClauseName(OMPC_defaultmap); 18539 } else if (isDefaultmapKind && !isDefaultmapModifier) { 18540 Diag(MLoc, diag::err_omp_unexpected_clause_value) 18541 << ModifierValue << getOpenMPClauseName(OMPC_defaultmap); 18542 } else { 18543 Diag(MLoc, diag::err_omp_unexpected_clause_value) 18544 << ModifierValue << getOpenMPClauseName(OMPC_defaultmap); 18545 Diag(KindLoc, diag::err_omp_unexpected_clause_value) 18546 << KindValue << getOpenMPClauseName(OMPC_defaultmap); 18547 } 18548 return nullptr; 18549 } 18550 18551 // OpenMP [5.0, 2.12.5, Restrictions, p. 174] 18552 // At most one defaultmap clause for each category can appear on the 18553 // directive. 18554 if (DSAStack->checkDefaultmapCategory(Kind)) { 18555 Diag(StartLoc, diag::err_omp_one_defaultmap_each_category); 18556 return nullptr; 18557 } 18558 } 18559 if (Kind == OMPC_DEFAULTMAP_unknown) { 18560 // Variable category is not specified - mark all categories. 18561 DSAStack->setDefaultDMAAttr(M, OMPC_DEFAULTMAP_aggregate, StartLoc); 18562 DSAStack->setDefaultDMAAttr(M, OMPC_DEFAULTMAP_scalar, StartLoc); 18563 DSAStack->setDefaultDMAAttr(M, OMPC_DEFAULTMAP_pointer, StartLoc); 18564 } else { 18565 DSAStack->setDefaultDMAAttr(M, Kind, StartLoc); 18566 } 18567 18568 return new (Context) 18569 OMPDefaultmapClause(StartLoc, LParenLoc, MLoc, KindLoc, EndLoc, Kind, M); 18570 } 18571 18572 bool Sema::ActOnStartOpenMPDeclareTargetDirective(SourceLocation Loc) { 18573 DeclContext *CurLexicalContext = getCurLexicalContext(); 18574 if (!CurLexicalContext->isFileContext() && 18575 !CurLexicalContext->isExternCContext() && 18576 !CurLexicalContext->isExternCXXContext() && 18577 !isa<CXXRecordDecl>(CurLexicalContext) && 18578 !isa<ClassTemplateDecl>(CurLexicalContext) && 18579 !isa<ClassTemplatePartialSpecializationDecl>(CurLexicalContext) && 18580 !isa<ClassTemplateSpecializationDecl>(CurLexicalContext)) { 18581 Diag(Loc, diag::err_omp_region_not_file_context); 18582 return false; 18583 } 18584 DeclareTargetNesting.push_back(Loc); 18585 return true; 18586 } 18587 18588 void Sema::ActOnFinishOpenMPDeclareTargetDirective() { 18589 assert(!DeclareTargetNesting.empty() && 18590 "Unexpected ActOnFinishOpenMPDeclareTargetDirective"); 18591 DeclareTargetNesting.pop_back(); 18592 } 18593 18594 NamedDecl * 18595 Sema::lookupOpenMPDeclareTargetName(Scope *CurScope, CXXScopeSpec &ScopeSpec, 18596 const DeclarationNameInfo &Id, 18597 NamedDeclSetType &SameDirectiveDecls) { 18598 LookupResult Lookup(*this, Id, LookupOrdinaryName); 18599 LookupParsedName(Lookup, CurScope, &ScopeSpec, true); 18600 18601 if (Lookup.isAmbiguous()) 18602 return nullptr; 18603 Lookup.suppressDiagnostics(); 18604 18605 if (!Lookup.isSingleResult()) { 18606 VarOrFuncDeclFilterCCC CCC(*this); 18607 if (TypoCorrection Corrected = 18608 CorrectTypo(Id, LookupOrdinaryName, CurScope, nullptr, CCC, 18609 CTK_ErrorRecovery)) { 18610 diagnoseTypo(Corrected, PDiag(diag::err_undeclared_var_use_suggest) 18611 << Id.getName()); 18612 checkDeclIsAllowedInOpenMPTarget(nullptr, Corrected.getCorrectionDecl()); 18613 return nullptr; 18614 } 18615 18616 Diag(Id.getLoc(), diag::err_undeclared_var_use) << Id.getName(); 18617 return nullptr; 18618 } 18619 18620 NamedDecl *ND = Lookup.getAsSingle<NamedDecl>(); 18621 if (!isa<VarDecl>(ND) && !isa<FunctionDecl>(ND) && 18622 !isa<FunctionTemplateDecl>(ND)) { 18623 Diag(Id.getLoc(), diag::err_omp_invalid_target_decl) << Id.getName(); 18624 return nullptr; 18625 } 18626 if (!SameDirectiveDecls.insert(cast<NamedDecl>(ND->getCanonicalDecl()))) 18627 Diag(Id.getLoc(), diag::err_omp_declare_target_multiple) << Id.getName(); 18628 return ND; 18629 } 18630 18631 void Sema::ActOnOpenMPDeclareTargetName( 18632 NamedDecl *ND, SourceLocation Loc, OMPDeclareTargetDeclAttr::MapTypeTy MT, 18633 OMPDeclareTargetDeclAttr::DevTypeTy DT) { 18634 assert((isa<VarDecl>(ND) || isa<FunctionDecl>(ND) || 18635 isa<FunctionTemplateDecl>(ND)) && 18636 "Expected variable, function or function template."); 18637 18638 // Diagnose marking after use as it may lead to incorrect diagnosis and 18639 // codegen. 18640 if (LangOpts.OpenMP >= 50 && 18641 (ND->isUsed(/*CheckUsedAttr=*/false) || ND->isReferenced())) 18642 Diag(Loc, diag::warn_omp_declare_target_after_first_use); 18643 18644 auto *VD = cast<ValueDecl>(ND); 18645 Optional<OMPDeclareTargetDeclAttr::DevTypeTy> DevTy = 18646 OMPDeclareTargetDeclAttr::getDeviceType(VD); 18647 Optional<SourceLocation> AttrLoc = OMPDeclareTargetDeclAttr::getLocation(VD); 18648 if (DevTy.hasValue() && *DevTy != DT && 18649 (DeclareTargetNesting.empty() || 18650 *AttrLoc != DeclareTargetNesting.back())) { 18651 Diag(Loc, diag::err_omp_device_type_mismatch) 18652 << OMPDeclareTargetDeclAttr::ConvertDevTypeTyToStr(DT) 18653 << OMPDeclareTargetDeclAttr::ConvertDevTypeTyToStr(*DevTy); 18654 return; 18655 } 18656 Optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res = 18657 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD); 18658 if (!Res || (!DeclareTargetNesting.empty() && 18659 *AttrLoc == DeclareTargetNesting.back())) { 18660 auto *A = OMPDeclareTargetDeclAttr::CreateImplicit( 18661 Context, MT, DT, DeclareTargetNesting.size() + 1, 18662 SourceRange(Loc, Loc)); 18663 ND->addAttr(A); 18664 if (ASTMutationListener *ML = Context.getASTMutationListener()) 18665 ML->DeclarationMarkedOpenMPDeclareTarget(ND, A); 18666 checkDeclIsAllowedInOpenMPTarget(nullptr, ND, Loc); 18667 } else if (*Res != MT) { 18668 Diag(Loc, diag::err_omp_declare_target_to_and_link) << ND; 18669 } 18670 } 18671 18672 static void checkDeclInTargetContext(SourceLocation SL, SourceRange SR, 18673 Sema &SemaRef, Decl *D) { 18674 if (!D || !isa<VarDecl>(D)) 18675 return; 18676 auto *VD = cast<VarDecl>(D); 18677 Optional<OMPDeclareTargetDeclAttr::MapTypeTy> MapTy = 18678 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD); 18679 if (SemaRef.LangOpts.OpenMP >= 50 && 18680 (SemaRef.getCurLambda(/*IgnoreNonLambdaCapturingScope=*/true) || 18681 SemaRef.getCurBlock() || SemaRef.getCurCapturedRegion()) && 18682 VD->hasGlobalStorage()) { 18683 llvm::Optional<OMPDeclareTargetDeclAttr::MapTypeTy> MapTy = 18684 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD); 18685 if (!MapTy || *MapTy != OMPDeclareTargetDeclAttr::MT_To) { 18686 // OpenMP 5.0, 2.12.7 declare target Directive, Restrictions 18687 // If a lambda declaration and definition appears between a 18688 // declare target directive and the matching end declare target 18689 // directive, all variables that are captured by the lambda 18690 // expression must also appear in a to clause. 18691 SemaRef.Diag(VD->getLocation(), 18692 diag::err_omp_lambda_capture_in_declare_target_not_to); 18693 SemaRef.Diag(SL, diag::note_var_explicitly_captured_here) 18694 << VD << 0 << SR; 18695 return; 18696 } 18697 } 18698 if (MapTy.hasValue()) 18699 return; 18700 SemaRef.Diag(VD->getLocation(), diag::warn_omp_not_in_target_context); 18701 SemaRef.Diag(SL, diag::note_used_here) << SR; 18702 } 18703 18704 static bool checkValueDeclInTarget(SourceLocation SL, SourceRange SR, 18705 Sema &SemaRef, DSAStackTy *Stack, 18706 ValueDecl *VD) { 18707 return OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD) || 18708 checkTypeMappable(SL, SR, SemaRef, Stack, VD->getType(), 18709 /*FullCheck=*/false); 18710 } 18711 18712 void Sema::checkDeclIsAllowedInOpenMPTarget(Expr *E, Decl *D, 18713 SourceLocation IdLoc) { 18714 if (!D || D->isInvalidDecl()) 18715 return; 18716 SourceRange SR = E ? E->getSourceRange() : D->getSourceRange(); 18717 SourceLocation SL = E ? E->getBeginLoc() : D->getLocation(); 18718 if (auto *VD = dyn_cast<VarDecl>(D)) { 18719 // Only global variables can be marked as declare target. 18720 if (!VD->isFileVarDecl() && !VD->isStaticLocal() && 18721 !VD->isStaticDataMember()) 18722 return; 18723 // 2.10.6: threadprivate variable cannot appear in a declare target 18724 // directive. 18725 if (DSAStack->isThreadPrivate(VD)) { 18726 Diag(SL, diag::err_omp_threadprivate_in_target); 18727 reportOriginalDsa(*this, DSAStack, VD, DSAStack->getTopDSA(VD, false)); 18728 return; 18729 } 18730 } 18731 if (const auto *FTD = dyn_cast<FunctionTemplateDecl>(D)) 18732 D = FTD->getTemplatedDecl(); 18733 if (auto *FD = dyn_cast<FunctionDecl>(D)) { 18734 llvm::Optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res = 18735 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(FD); 18736 if (IdLoc.isValid() && Res && *Res == OMPDeclareTargetDeclAttr::MT_Link) { 18737 Diag(IdLoc, diag::err_omp_function_in_link_clause); 18738 Diag(FD->getLocation(), diag::note_defined_here) << FD; 18739 return; 18740 } 18741 } 18742 if (auto *VD = dyn_cast<ValueDecl>(D)) { 18743 // Problem if any with var declared with incomplete type will be reported 18744 // as normal, so no need to check it here. 18745 if ((E || !VD->getType()->isIncompleteType()) && 18746 !checkValueDeclInTarget(SL, SR, *this, DSAStack, VD)) 18747 return; 18748 if (!E && !OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD)) { 18749 // Checking declaration inside declare target region. 18750 if (isa<VarDecl>(D) || isa<FunctionDecl>(D) || 18751 isa<FunctionTemplateDecl>(D)) { 18752 auto *A = OMPDeclareTargetDeclAttr::CreateImplicit( 18753 Context, OMPDeclareTargetDeclAttr::MT_To, 18754 OMPDeclareTargetDeclAttr::DT_Any, DeclareTargetNesting.size(), 18755 SourceRange(DeclareTargetNesting.back(), 18756 DeclareTargetNesting.back())); 18757 D->addAttr(A); 18758 if (ASTMutationListener *ML = Context.getASTMutationListener()) 18759 ML->DeclarationMarkedOpenMPDeclareTarget(D, A); 18760 } 18761 return; 18762 } 18763 } 18764 if (!E) 18765 return; 18766 checkDeclInTargetContext(E->getExprLoc(), E->getSourceRange(), *this, D); 18767 } 18768 18769 OMPClause *Sema::ActOnOpenMPToClause( 18770 ArrayRef<OpenMPMotionModifierKind> MotionModifiers, 18771 ArrayRef<SourceLocation> MotionModifiersLoc, 18772 CXXScopeSpec &MapperIdScopeSpec, DeclarationNameInfo &MapperId, 18773 SourceLocation ColonLoc, ArrayRef<Expr *> VarList, 18774 const OMPVarListLocTy &Locs, ArrayRef<Expr *> UnresolvedMappers) { 18775 OpenMPMotionModifierKind Modifiers[] = {OMPC_MOTION_MODIFIER_unknown, 18776 OMPC_MOTION_MODIFIER_unknown}; 18777 SourceLocation ModifiersLoc[NumberOfOMPMotionModifiers]; 18778 18779 // Process motion-modifiers, flag errors for duplicate modifiers. 18780 unsigned Count = 0; 18781 for (unsigned I = 0, E = MotionModifiers.size(); I < E; ++I) { 18782 if (MotionModifiers[I] != OMPC_MOTION_MODIFIER_unknown && 18783 llvm::find(Modifiers, MotionModifiers[I]) != std::end(Modifiers)) { 18784 Diag(MotionModifiersLoc[I], diag::err_omp_duplicate_motion_modifier); 18785 continue; 18786 } 18787 assert(Count < NumberOfOMPMotionModifiers && 18788 "Modifiers exceed the allowed number of motion modifiers"); 18789 Modifiers[Count] = MotionModifiers[I]; 18790 ModifiersLoc[Count] = MotionModifiersLoc[I]; 18791 ++Count; 18792 } 18793 18794 MappableVarListInfo MVLI(VarList); 18795 checkMappableExpressionList(*this, DSAStack, OMPC_to, MVLI, Locs.StartLoc, 18796 MapperIdScopeSpec, MapperId, UnresolvedMappers); 18797 if (MVLI.ProcessedVarList.empty()) 18798 return nullptr; 18799 18800 return OMPToClause::Create( 18801 Context, Locs, MVLI.ProcessedVarList, MVLI.VarBaseDeclarations, 18802 MVLI.VarComponents, MVLI.UDMapperList, Modifiers, ModifiersLoc, 18803 MapperIdScopeSpec.getWithLocInContext(Context), MapperId); 18804 } 18805 18806 OMPClause *Sema::ActOnOpenMPFromClause( 18807 ArrayRef<OpenMPMotionModifierKind> MotionModifiers, 18808 ArrayRef<SourceLocation> MotionModifiersLoc, 18809 CXXScopeSpec &MapperIdScopeSpec, DeclarationNameInfo &MapperId, 18810 SourceLocation ColonLoc, ArrayRef<Expr *> VarList, 18811 const OMPVarListLocTy &Locs, ArrayRef<Expr *> UnresolvedMappers) { 18812 OpenMPMotionModifierKind Modifiers[] = {OMPC_MOTION_MODIFIER_unknown, 18813 OMPC_MOTION_MODIFIER_unknown}; 18814 SourceLocation ModifiersLoc[NumberOfOMPMotionModifiers]; 18815 18816 // Process motion-modifiers, flag errors for duplicate modifiers. 18817 unsigned Count = 0; 18818 for (unsigned I = 0, E = MotionModifiers.size(); I < E; ++I) { 18819 if (MotionModifiers[I] != OMPC_MOTION_MODIFIER_unknown && 18820 llvm::find(Modifiers, MotionModifiers[I]) != std::end(Modifiers)) { 18821 Diag(MotionModifiersLoc[I], diag::err_omp_duplicate_motion_modifier); 18822 continue; 18823 } 18824 assert(Count < NumberOfOMPMotionModifiers && 18825 "Modifiers exceed the allowed number of motion modifiers"); 18826 Modifiers[Count] = MotionModifiers[I]; 18827 ModifiersLoc[Count] = MotionModifiersLoc[I]; 18828 ++Count; 18829 } 18830 18831 MappableVarListInfo MVLI(VarList); 18832 checkMappableExpressionList(*this, DSAStack, OMPC_from, MVLI, Locs.StartLoc, 18833 MapperIdScopeSpec, MapperId, UnresolvedMappers); 18834 if (MVLI.ProcessedVarList.empty()) 18835 return nullptr; 18836 18837 return OMPFromClause::Create( 18838 Context, Locs, MVLI.ProcessedVarList, MVLI.VarBaseDeclarations, 18839 MVLI.VarComponents, MVLI.UDMapperList, Modifiers, ModifiersLoc, 18840 MapperIdScopeSpec.getWithLocInContext(Context), MapperId); 18841 } 18842 18843 OMPClause *Sema::ActOnOpenMPUseDevicePtrClause(ArrayRef<Expr *> VarList, 18844 const OMPVarListLocTy &Locs) { 18845 MappableVarListInfo MVLI(VarList); 18846 SmallVector<Expr *, 8> PrivateCopies; 18847 SmallVector<Expr *, 8> Inits; 18848 18849 for (Expr *RefExpr : VarList) { 18850 assert(RefExpr && "NULL expr in OpenMP use_device_ptr clause."); 18851 SourceLocation ELoc; 18852 SourceRange ERange; 18853 Expr *SimpleRefExpr = RefExpr; 18854 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 18855 if (Res.second) { 18856 // It will be analyzed later. 18857 MVLI.ProcessedVarList.push_back(RefExpr); 18858 PrivateCopies.push_back(nullptr); 18859 Inits.push_back(nullptr); 18860 } 18861 ValueDecl *D = Res.first; 18862 if (!D) 18863 continue; 18864 18865 QualType Type = D->getType(); 18866 Type = Type.getNonReferenceType().getUnqualifiedType(); 18867 18868 auto *VD = dyn_cast<VarDecl>(D); 18869 18870 // Item should be a pointer or reference to pointer. 18871 if (!Type->isPointerType()) { 18872 Diag(ELoc, diag::err_omp_usedeviceptr_not_a_pointer) 18873 << 0 << RefExpr->getSourceRange(); 18874 continue; 18875 } 18876 18877 // Build the private variable and the expression that refers to it. 18878 auto VDPrivate = 18879 buildVarDecl(*this, ELoc, Type, D->getName(), 18880 D->hasAttrs() ? &D->getAttrs() : nullptr, 18881 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr); 18882 if (VDPrivate->isInvalidDecl()) 18883 continue; 18884 18885 CurContext->addDecl(VDPrivate); 18886 DeclRefExpr *VDPrivateRefExpr = buildDeclRefExpr( 18887 *this, VDPrivate, RefExpr->getType().getUnqualifiedType(), ELoc); 18888 18889 // Add temporary variable to initialize the private copy of the pointer. 18890 VarDecl *VDInit = 18891 buildVarDecl(*this, RefExpr->getExprLoc(), Type, ".devptr.temp"); 18892 DeclRefExpr *VDInitRefExpr = buildDeclRefExpr( 18893 *this, VDInit, RefExpr->getType(), RefExpr->getExprLoc()); 18894 AddInitializerToDecl(VDPrivate, 18895 DefaultLvalueConversion(VDInitRefExpr).get(), 18896 /*DirectInit=*/false); 18897 18898 // If required, build a capture to implement the privatization initialized 18899 // with the current list item value. 18900 DeclRefExpr *Ref = nullptr; 18901 if (!VD) 18902 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true); 18903 MVLI.ProcessedVarList.push_back(VD ? RefExpr->IgnoreParens() : Ref); 18904 PrivateCopies.push_back(VDPrivateRefExpr); 18905 Inits.push_back(VDInitRefExpr); 18906 18907 // We need to add a data sharing attribute for this variable to make sure it 18908 // is correctly captured. A variable that shows up in a use_device_ptr has 18909 // similar properties of a first private variable. 18910 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_firstprivate, Ref); 18911 18912 // Create a mappable component for the list item. List items in this clause 18913 // only need a component. 18914 MVLI.VarBaseDeclarations.push_back(D); 18915 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1); 18916 MVLI.VarComponents.back().emplace_back(SimpleRefExpr, D, 18917 /*IsNonContiguous=*/false); 18918 } 18919 18920 if (MVLI.ProcessedVarList.empty()) 18921 return nullptr; 18922 18923 return OMPUseDevicePtrClause::Create( 18924 Context, Locs, MVLI.ProcessedVarList, PrivateCopies, Inits, 18925 MVLI.VarBaseDeclarations, MVLI.VarComponents); 18926 } 18927 18928 OMPClause *Sema::ActOnOpenMPUseDeviceAddrClause(ArrayRef<Expr *> VarList, 18929 const OMPVarListLocTy &Locs) { 18930 MappableVarListInfo MVLI(VarList); 18931 18932 for (Expr *RefExpr : VarList) { 18933 assert(RefExpr && "NULL expr in OpenMP use_device_addr clause."); 18934 SourceLocation ELoc; 18935 SourceRange ERange; 18936 Expr *SimpleRefExpr = RefExpr; 18937 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange, 18938 /*AllowArraySection=*/true); 18939 if (Res.second) { 18940 // It will be analyzed later. 18941 MVLI.ProcessedVarList.push_back(RefExpr); 18942 } 18943 ValueDecl *D = Res.first; 18944 if (!D) 18945 continue; 18946 auto *VD = dyn_cast<VarDecl>(D); 18947 18948 // If required, build a capture to implement the privatization initialized 18949 // with the current list item value. 18950 DeclRefExpr *Ref = nullptr; 18951 if (!VD) 18952 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true); 18953 MVLI.ProcessedVarList.push_back(VD ? RefExpr->IgnoreParens() : Ref); 18954 18955 // We need to add a data sharing attribute for this variable to make sure it 18956 // is correctly captured. A variable that shows up in a use_device_addr has 18957 // similar properties of a first private variable. 18958 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_firstprivate, Ref); 18959 18960 // Create a mappable component for the list item. List items in this clause 18961 // only need a component. 18962 MVLI.VarBaseDeclarations.push_back(D); 18963 MVLI.VarComponents.emplace_back(); 18964 Expr *Component = SimpleRefExpr; 18965 if (VD && (isa<OMPArraySectionExpr>(RefExpr->IgnoreParenImpCasts()) || 18966 isa<ArraySubscriptExpr>(RefExpr->IgnoreParenImpCasts()))) 18967 Component = DefaultFunctionArrayLvalueConversion(SimpleRefExpr).get(); 18968 MVLI.VarComponents.back().emplace_back(Component, D, 18969 /*IsNonContiguous=*/false); 18970 } 18971 18972 if (MVLI.ProcessedVarList.empty()) 18973 return nullptr; 18974 18975 return OMPUseDeviceAddrClause::Create(Context, Locs, MVLI.ProcessedVarList, 18976 MVLI.VarBaseDeclarations, 18977 MVLI.VarComponents); 18978 } 18979 18980 OMPClause *Sema::ActOnOpenMPIsDevicePtrClause(ArrayRef<Expr *> VarList, 18981 const OMPVarListLocTy &Locs) { 18982 MappableVarListInfo MVLI(VarList); 18983 for (Expr *RefExpr : VarList) { 18984 assert(RefExpr && "NULL expr in OpenMP is_device_ptr clause."); 18985 SourceLocation ELoc; 18986 SourceRange ERange; 18987 Expr *SimpleRefExpr = RefExpr; 18988 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 18989 if (Res.second) { 18990 // It will be analyzed later. 18991 MVLI.ProcessedVarList.push_back(RefExpr); 18992 } 18993 ValueDecl *D = Res.first; 18994 if (!D) 18995 continue; 18996 18997 QualType Type = D->getType(); 18998 // item should be a pointer or array or reference to pointer or array 18999 if (!Type.getNonReferenceType()->isPointerType() && 19000 !Type.getNonReferenceType()->isArrayType()) { 19001 Diag(ELoc, diag::err_omp_argument_type_isdeviceptr) 19002 << 0 << RefExpr->getSourceRange(); 19003 continue; 19004 } 19005 19006 // Check if the declaration in the clause does not show up in any data 19007 // sharing attribute. 19008 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false); 19009 if (isOpenMPPrivate(DVar.CKind)) { 19010 Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa) 19011 << getOpenMPClauseName(DVar.CKind) 19012 << getOpenMPClauseName(OMPC_is_device_ptr) 19013 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 19014 reportOriginalDsa(*this, DSAStack, D, DVar); 19015 continue; 19016 } 19017 19018 const Expr *ConflictExpr; 19019 if (DSAStack->checkMappableExprComponentListsForDecl( 19020 D, /*CurrentRegionOnly=*/true, 19021 [&ConflictExpr]( 19022 OMPClauseMappableExprCommon::MappableExprComponentListRef R, 19023 OpenMPClauseKind) -> bool { 19024 ConflictExpr = R.front().getAssociatedExpression(); 19025 return true; 19026 })) { 19027 Diag(ELoc, diag::err_omp_map_shared_storage) << RefExpr->getSourceRange(); 19028 Diag(ConflictExpr->getExprLoc(), diag::note_used_here) 19029 << ConflictExpr->getSourceRange(); 19030 continue; 19031 } 19032 19033 // Store the components in the stack so that they can be used to check 19034 // against other clauses later on. 19035 OMPClauseMappableExprCommon::MappableComponent MC( 19036 SimpleRefExpr, D, /*IsNonContiguous=*/false); 19037 DSAStack->addMappableExpressionComponents( 19038 D, MC, /*WhereFoundClauseKind=*/OMPC_is_device_ptr); 19039 19040 // Record the expression we've just processed. 19041 MVLI.ProcessedVarList.push_back(SimpleRefExpr); 19042 19043 // Create a mappable component for the list item. List items in this clause 19044 // only need a component. We use a null declaration to signal fields in 19045 // 'this'. 19046 assert((isa<DeclRefExpr>(SimpleRefExpr) || 19047 isa<CXXThisExpr>(cast<MemberExpr>(SimpleRefExpr)->getBase())) && 19048 "Unexpected device pointer expression!"); 19049 MVLI.VarBaseDeclarations.push_back( 19050 isa<DeclRefExpr>(SimpleRefExpr) ? D : nullptr); 19051 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1); 19052 MVLI.VarComponents.back().push_back(MC); 19053 } 19054 19055 if (MVLI.ProcessedVarList.empty()) 19056 return nullptr; 19057 19058 return OMPIsDevicePtrClause::Create(Context, Locs, MVLI.ProcessedVarList, 19059 MVLI.VarBaseDeclarations, 19060 MVLI.VarComponents); 19061 } 19062 19063 OMPClause *Sema::ActOnOpenMPAllocateClause( 19064 Expr *Allocator, ArrayRef<Expr *> VarList, SourceLocation StartLoc, 19065 SourceLocation ColonLoc, SourceLocation LParenLoc, SourceLocation EndLoc) { 19066 if (Allocator) { 19067 // OpenMP [2.11.4 allocate Clause, Description] 19068 // allocator is an expression of omp_allocator_handle_t type. 19069 if (!findOMPAllocatorHandleT(*this, Allocator->getExprLoc(), DSAStack)) 19070 return nullptr; 19071 19072 ExprResult AllocatorRes = DefaultLvalueConversion(Allocator); 19073 if (AllocatorRes.isInvalid()) 19074 return nullptr; 19075 AllocatorRes = PerformImplicitConversion(AllocatorRes.get(), 19076 DSAStack->getOMPAllocatorHandleT(), 19077 Sema::AA_Initializing, 19078 /*AllowExplicit=*/true); 19079 if (AllocatorRes.isInvalid()) 19080 return nullptr; 19081 Allocator = AllocatorRes.get(); 19082 } else { 19083 // OpenMP 5.0, 2.11.4 allocate Clause, Restrictions. 19084 // allocate clauses that appear on a target construct or on constructs in a 19085 // target region must specify an allocator expression unless a requires 19086 // directive with the dynamic_allocators clause is present in the same 19087 // compilation unit. 19088 if (LangOpts.OpenMPIsDevice && 19089 !DSAStack->hasRequiresDeclWithClause<OMPDynamicAllocatorsClause>()) 19090 targetDiag(StartLoc, diag::err_expected_allocator_expression); 19091 } 19092 // Analyze and build list of variables. 19093 SmallVector<Expr *, 8> Vars; 19094 for (Expr *RefExpr : VarList) { 19095 assert(RefExpr && "NULL expr in OpenMP private clause."); 19096 SourceLocation ELoc; 19097 SourceRange ERange; 19098 Expr *SimpleRefExpr = RefExpr; 19099 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 19100 if (Res.second) { 19101 // It will be analyzed later. 19102 Vars.push_back(RefExpr); 19103 } 19104 ValueDecl *D = Res.first; 19105 if (!D) 19106 continue; 19107 19108 auto *VD = dyn_cast<VarDecl>(D); 19109 DeclRefExpr *Ref = nullptr; 19110 if (!VD && !CurContext->isDependentContext()) 19111 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false); 19112 Vars.push_back((VD || CurContext->isDependentContext()) 19113 ? RefExpr->IgnoreParens() 19114 : Ref); 19115 } 19116 19117 if (Vars.empty()) 19118 return nullptr; 19119 19120 if (Allocator) 19121 DSAStack->addInnerAllocatorExpr(Allocator); 19122 return OMPAllocateClause::Create(Context, StartLoc, LParenLoc, Allocator, 19123 ColonLoc, EndLoc, Vars); 19124 } 19125 19126 OMPClause *Sema::ActOnOpenMPNontemporalClause(ArrayRef<Expr *> VarList, 19127 SourceLocation StartLoc, 19128 SourceLocation LParenLoc, 19129 SourceLocation EndLoc) { 19130 SmallVector<Expr *, 8> Vars; 19131 for (Expr *RefExpr : VarList) { 19132 assert(RefExpr && "NULL expr in OpenMP nontemporal clause."); 19133 SourceLocation ELoc; 19134 SourceRange ERange; 19135 Expr *SimpleRefExpr = RefExpr; 19136 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 19137 if (Res.second) 19138 // It will be analyzed later. 19139 Vars.push_back(RefExpr); 19140 ValueDecl *D = Res.first; 19141 if (!D) 19142 continue; 19143 19144 // OpenMP 5.0, 2.9.3.1 simd Construct, Restrictions. 19145 // A list-item cannot appear in more than one nontemporal clause. 19146 if (const Expr *PrevRef = 19147 DSAStack->addUniqueNontemporal(D, SimpleRefExpr)) { 19148 Diag(ELoc, diag::err_omp_used_in_clause_twice) 19149 << 0 << getOpenMPClauseName(OMPC_nontemporal) << ERange; 19150 Diag(PrevRef->getExprLoc(), diag::note_omp_explicit_dsa) 19151 << getOpenMPClauseName(OMPC_nontemporal); 19152 continue; 19153 } 19154 19155 Vars.push_back(RefExpr); 19156 } 19157 19158 if (Vars.empty()) 19159 return nullptr; 19160 19161 return OMPNontemporalClause::Create(Context, StartLoc, LParenLoc, EndLoc, 19162 Vars); 19163 } 19164 19165 OMPClause *Sema::ActOnOpenMPInclusiveClause(ArrayRef<Expr *> VarList, 19166 SourceLocation StartLoc, 19167 SourceLocation LParenLoc, 19168 SourceLocation EndLoc) { 19169 SmallVector<Expr *, 8> Vars; 19170 for (Expr *RefExpr : VarList) { 19171 assert(RefExpr && "NULL expr in OpenMP nontemporal clause."); 19172 SourceLocation ELoc; 19173 SourceRange ERange; 19174 Expr *SimpleRefExpr = RefExpr; 19175 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange, 19176 /*AllowArraySection=*/true); 19177 if (Res.second) 19178 // It will be analyzed later. 19179 Vars.push_back(RefExpr); 19180 ValueDecl *D = Res.first; 19181 if (!D) 19182 continue; 19183 19184 const DSAStackTy::DSAVarData DVar = 19185 DSAStack->getTopDSA(D, /*FromParent=*/true); 19186 // OpenMP 5.0, 2.9.6, scan Directive, Restrictions. 19187 // A list item that appears in the inclusive or exclusive clause must appear 19188 // in a reduction clause with the inscan modifier on the enclosing 19189 // worksharing-loop, worksharing-loop SIMD, or simd construct. 19190 if (DVar.CKind != OMPC_reduction || 19191 DVar.Modifier != OMPC_REDUCTION_inscan) 19192 Diag(ELoc, diag::err_omp_inclusive_exclusive_not_reduction) 19193 << RefExpr->getSourceRange(); 19194 19195 if (DSAStack->getParentDirective() != OMPD_unknown) 19196 DSAStack->markDeclAsUsedInScanDirective(D); 19197 Vars.push_back(RefExpr); 19198 } 19199 19200 if (Vars.empty()) 19201 return nullptr; 19202 19203 return OMPInclusiveClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars); 19204 } 19205 19206 OMPClause *Sema::ActOnOpenMPExclusiveClause(ArrayRef<Expr *> VarList, 19207 SourceLocation StartLoc, 19208 SourceLocation LParenLoc, 19209 SourceLocation EndLoc) { 19210 SmallVector<Expr *, 8> Vars; 19211 for (Expr *RefExpr : VarList) { 19212 assert(RefExpr && "NULL expr in OpenMP nontemporal clause."); 19213 SourceLocation ELoc; 19214 SourceRange ERange; 19215 Expr *SimpleRefExpr = RefExpr; 19216 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange, 19217 /*AllowArraySection=*/true); 19218 if (Res.second) 19219 // It will be analyzed later. 19220 Vars.push_back(RefExpr); 19221 ValueDecl *D = Res.first; 19222 if (!D) 19223 continue; 19224 19225 OpenMPDirectiveKind ParentDirective = DSAStack->getParentDirective(); 19226 DSAStackTy::DSAVarData DVar; 19227 if (ParentDirective != OMPD_unknown) 19228 DVar = DSAStack->getTopDSA(D, /*FromParent=*/true); 19229 // OpenMP 5.0, 2.9.6, scan Directive, Restrictions. 19230 // A list item that appears in the inclusive or exclusive clause must appear 19231 // in a reduction clause with the inscan modifier on the enclosing 19232 // worksharing-loop, worksharing-loop SIMD, or simd construct. 19233 if (ParentDirective == OMPD_unknown || DVar.CKind != OMPC_reduction || 19234 DVar.Modifier != OMPC_REDUCTION_inscan) { 19235 Diag(ELoc, diag::err_omp_inclusive_exclusive_not_reduction) 19236 << RefExpr->getSourceRange(); 19237 } else { 19238 DSAStack->markDeclAsUsedInScanDirective(D); 19239 } 19240 Vars.push_back(RefExpr); 19241 } 19242 19243 if (Vars.empty()) 19244 return nullptr; 19245 19246 return OMPExclusiveClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars); 19247 } 19248 19249 /// Tries to find omp_alloctrait_t type. 19250 static bool findOMPAlloctraitT(Sema &S, SourceLocation Loc, DSAStackTy *Stack) { 19251 QualType OMPAlloctraitT = Stack->getOMPAlloctraitT(); 19252 if (!OMPAlloctraitT.isNull()) 19253 return true; 19254 IdentifierInfo &II = S.PP.getIdentifierTable().get("omp_alloctrait_t"); 19255 ParsedType PT = S.getTypeName(II, Loc, S.getCurScope()); 19256 if (!PT.getAsOpaquePtr() || PT.get().isNull()) { 19257 S.Diag(Loc, diag::err_omp_implied_type_not_found) << "omp_alloctrait_t"; 19258 return false; 19259 } 19260 Stack->setOMPAlloctraitT(PT.get()); 19261 return true; 19262 } 19263 19264 OMPClause *Sema::ActOnOpenMPUsesAllocatorClause( 19265 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc, 19266 ArrayRef<UsesAllocatorsData> Data) { 19267 // OpenMP [2.12.5, target Construct] 19268 // allocator is an identifier of omp_allocator_handle_t type. 19269 if (!findOMPAllocatorHandleT(*this, StartLoc, DSAStack)) 19270 return nullptr; 19271 // OpenMP [2.12.5, target Construct] 19272 // allocator-traits-array is an identifier of const omp_alloctrait_t * type. 19273 if (llvm::any_of( 19274 Data, 19275 [](const UsesAllocatorsData &D) { return D.AllocatorTraits; }) && 19276 !findOMPAlloctraitT(*this, StartLoc, DSAStack)) 19277 return nullptr; 19278 llvm::SmallPtrSet<CanonicalDeclPtr<Decl>, 4> PredefinedAllocators; 19279 for (int I = 0; I < OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; ++I) { 19280 auto AllocatorKind = static_cast<OMPAllocateDeclAttr::AllocatorTypeTy>(I); 19281 StringRef Allocator = 19282 OMPAllocateDeclAttr::ConvertAllocatorTypeTyToStr(AllocatorKind); 19283 DeclarationName AllocatorName = &Context.Idents.get(Allocator); 19284 PredefinedAllocators.insert(LookupSingleName( 19285 TUScope, AllocatorName, StartLoc, Sema::LookupAnyName)); 19286 } 19287 19288 SmallVector<OMPUsesAllocatorsClause::Data, 4> NewData; 19289 for (const UsesAllocatorsData &D : Data) { 19290 Expr *AllocatorExpr = nullptr; 19291 // Check allocator expression. 19292 if (D.Allocator->isTypeDependent()) { 19293 AllocatorExpr = D.Allocator; 19294 } else { 19295 // Traits were specified - need to assign new allocator to the specified 19296 // allocator, so it must be an lvalue. 19297 AllocatorExpr = D.Allocator->IgnoreParenImpCasts(); 19298 auto *DRE = dyn_cast<DeclRefExpr>(AllocatorExpr); 19299 bool IsPredefinedAllocator = false; 19300 if (DRE) 19301 IsPredefinedAllocator = PredefinedAllocators.count(DRE->getDecl()); 19302 if (!DRE || 19303 !(Context.hasSameUnqualifiedType( 19304 AllocatorExpr->getType(), DSAStack->getOMPAllocatorHandleT()) || 19305 Context.typesAreCompatible(AllocatorExpr->getType(), 19306 DSAStack->getOMPAllocatorHandleT(), 19307 /*CompareUnqualified=*/true)) || 19308 (!IsPredefinedAllocator && 19309 (AllocatorExpr->getType().isConstant(Context) || 19310 !AllocatorExpr->isLValue()))) { 19311 Diag(D.Allocator->getExprLoc(), diag::err_omp_var_expected) 19312 << "omp_allocator_handle_t" << (DRE ? 1 : 0) 19313 << AllocatorExpr->getType() << D.Allocator->getSourceRange(); 19314 continue; 19315 } 19316 // OpenMP [2.12.5, target Construct] 19317 // Predefined allocators appearing in a uses_allocators clause cannot have 19318 // traits specified. 19319 if (IsPredefinedAllocator && D.AllocatorTraits) { 19320 Diag(D.AllocatorTraits->getExprLoc(), 19321 diag::err_omp_predefined_allocator_with_traits) 19322 << D.AllocatorTraits->getSourceRange(); 19323 Diag(D.Allocator->getExprLoc(), diag::note_omp_predefined_allocator) 19324 << cast<NamedDecl>(DRE->getDecl())->getName() 19325 << D.Allocator->getSourceRange(); 19326 continue; 19327 } 19328 // OpenMP [2.12.5, target Construct] 19329 // Non-predefined allocators appearing in a uses_allocators clause must 19330 // have traits specified. 19331 if (!IsPredefinedAllocator && !D.AllocatorTraits) { 19332 Diag(D.Allocator->getExprLoc(), 19333 diag::err_omp_nonpredefined_allocator_without_traits); 19334 continue; 19335 } 19336 // No allocator traits - just convert it to rvalue. 19337 if (!D.AllocatorTraits) 19338 AllocatorExpr = DefaultLvalueConversion(AllocatorExpr).get(); 19339 DSAStack->addUsesAllocatorsDecl( 19340 DRE->getDecl(), 19341 IsPredefinedAllocator 19342 ? DSAStackTy::UsesAllocatorsDeclKind::PredefinedAllocator 19343 : DSAStackTy::UsesAllocatorsDeclKind::UserDefinedAllocator); 19344 } 19345 Expr *AllocatorTraitsExpr = nullptr; 19346 if (D.AllocatorTraits) { 19347 if (D.AllocatorTraits->isTypeDependent()) { 19348 AllocatorTraitsExpr = D.AllocatorTraits; 19349 } else { 19350 // OpenMP [2.12.5, target Construct] 19351 // Arrays that contain allocator traits that appear in a uses_allocators 19352 // clause must be constant arrays, have constant values and be defined 19353 // in the same scope as the construct in which the clause appears. 19354 AllocatorTraitsExpr = D.AllocatorTraits->IgnoreParenImpCasts(); 19355 // Check that traits expr is a constant array. 19356 QualType TraitTy; 19357 if (const ArrayType *Ty = 19358 AllocatorTraitsExpr->getType()->getAsArrayTypeUnsafe()) 19359 if (const auto *ConstArrayTy = dyn_cast<ConstantArrayType>(Ty)) 19360 TraitTy = ConstArrayTy->getElementType(); 19361 if (TraitTy.isNull() || 19362 !(Context.hasSameUnqualifiedType(TraitTy, 19363 DSAStack->getOMPAlloctraitT()) || 19364 Context.typesAreCompatible(TraitTy, DSAStack->getOMPAlloctraitT(), 19365 /*CompareUnqualified=*/true))) { 19366 Diag(D.AllocatorTraits->getExprLoc(), 19367 diag::err_omp_expected_array_alloctraits) 19368 << AllocatorTraitsExpr->getType(); 19369 continue; 19370 } 19371 // Do not map by default allocator traits if it is a standalone 19372 // variable. 19373 if (auto *DRE = dyn_cast<DeclRefExpr>(AllocatorTraitsExpr)) 19374 DSAStack->addUsesAllocatorsDecl( 19375 DRE->getDecl(), 19376 DSAStackTy::UsesAllocatorsDeclKind::AllocatorTrait); 19377 } 19378 } 19379 OMPUsesAllocatorsClause::Data &NewD = NewData.emplace_back(); 19380 NewD.Allocator = AllocatorExpr; 19381 NewD.AllocatorTraits = AllocatorTraitsExpr; 19382 NewD.LParenLoc = D.LParenLoc; 19383 NewD.RParenLoc = D.RParenLoc; 19384 } 19385 return OMPUsesAllocatorsClause::Create(Context, StartLoc, LParenLoc, EndLoc, 19386 NewData); 19387 } 19388 19389 OMPClause *Sema::ActOnOpenMPAffinityClause( 19390 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation ColonLoc, 19391 SourceLocation EndLoc, Expr *Modifier, ArrayRef<Expr *> Locators) { 19392 SmallVector<Expr *, 8> Vars; 19393 for (Expr *RefExpr : Locators) { 19394 assert(RefExpr && "NULL expr in OpenMP shared clause."); 19395 if (isa<DependentScopeDeclRefExpr>(RefExpr) || RefExpr->isTypeDependent()) { 19396 // It will be analyzed later. 19397 Vars.push_back(RefExpr); 19398 continue; 19399 } 19400 19401 SourceLocation ELoc = RefExpr->getExprLoc(); 19402 Expr *SimpleExpr = RefExpr->IgnoreParenImpCasts(); 19403 19404 if (!SimpleExpr->isLValue()) { 19405 Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item) 19406 << 1 << 0 << RefExpr->getSourceRange(); 19407 continue; 19408 } 19409 19410 ExprResult Res; 19411 { 19412 Sema::TentativeAnalysisScope Trap(*this); 19413 Res = CreateBuiltinUnaryOp(ELoc, UO_AddrOf, SimpleExpr); 19414 } 19415 if (!Res.isUsable() && !isa<OMPArraySectionExpr>(SimpleExpr) && 19416 !isa<OMPArrayShapingExpr>(SimpleExpr)) { 19417 Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item) 19418 << 1 << 0 << RefExpr->getSourceRange(); 19419 continue; 19420 } 19421 Vars.push_back(SimpleExpr); 19422 } 19423 19424 return OMPAffinityClause::Create(Context, StartLoc, LParenLoc, ColonLoc, 19425 EndLoc, Modifier, Vars); 19426 } 19427