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/ADT/SmallSet.h" 39 #include "llvm/ADT/StringExtras.h" 40 #include "llvm/Frontend/OpenMP/OMPAssume.h" 41 #include "llvm/Frontend/OpenMP/OMPConstants.h" 42 #include <set> 43 44 using namespace clang; 45 using namespace llvm::omp; 46 47 //===----------------------------------------------------------------------===// 48 // Stack of data-sharing attributes for variables 49 //===----------------------------------------------------------------------===// 50 51 static const Expr *checkMapClauseExpressionBase( 52 Sema &SemaRef, Expr *E, 53 OMPClauseMappableExprCommon::MappableExprComponentList &CurComponents, 54 OpenMPClauseKind CKind, OpenMPDirectiveKind DKind, bool NoDiagnose); 55 56 namespace { 57 /// Default data sharing attributes, which can be applied to directive. 58 enum DefaultDataSharingAttributes { 59 DSA_unspecified = 0, /// Data sharing attribute not specified. 60 DSA_none = 1 << 0, /// Default data sharing attribute 'none'. 61 DSA_shared = 1 << 1, /// Default data sharing attribute 'shared'. 62 DSA_private = 1 << 2, /// Default data sharing attribute 'private'. 63 DSA_firstprivate = 1 << 3, /// Default data sharing attribute 'firstprivate'. 64 }; 65 66 /// Stack for tracking declarations used in OpenMP directives and 67 /// clauses and their data-sharing attributes. 68 class DSAStackTy { 69 public: 70 struct DSAVarData { 71 OpenMPDirectiveKind DKind = OMPD_unknown; 72 OpenMPClauseKind CKind = OMPC_unknown; 73 unsigned Modifier = 0; 74 const Expr *RefExpr = nullptr; 75 DeclRefExpr *PrivateCopy = nullptr; 76 SourceLocation ImplicitDSALoc; 77 bool AppliedToPointee = false; 78 DSAVarData() = default; 79 DSAVarData(OpenMPDirectiveKind DKind, OpenMPClauseKind CKind, 80 const Expr *RefExpr, DeclRefExpr *PrivateCopy, 81 SourceLocation ImplicitDSALoc, unsigned Modifier, 82 bool AppliedToPointee) 83 : DKind(DKind), CKind(CKind), Modifier(Modifier), RefExpr(RefExpr), 84 PrivateCopy(PrivateCopy), ImplicitDSALoc(ImplicitDSALoc), 85 AppliedToPointee(AppliedToPointee) {} 86 }; 87 using OperatorOffsetTy = 88 llvm::SmallVector<std::pair<Expr *, OverloadedOperatorKind>, 4>; 89 using DoacrossDependMapTy = 90 llvm::DenseMap<OMPDependClause *, OperatorOffsetTy>; 91 /// Kind of the declaration used in the uses_allocators clauses. 92 enum class UsesAllocatorsDeclKind { 93 /// Predefined allocator 94 PredefinedAllocator, 95 /// User-defined allocator 96 UserDefinedAllocator, 97 /// The declaration that represent allocator trait 98 AllocatorTrait, 99 }; 100 101 private: 102 struct DSAInfo { 103 OpenMPClauseKind Attributes = OMPC_unknown; 104 unsigned Modifier = 0; 105 /// Pointer to a reference expression and a flag which shows that the 106 /// variable is marked as lastprivate(true) or not (false). 107 llvm::PointerIntPair<const Expr *, 1, bool> RefExpr; 108 DeclRefExpr *PrivateCopy = nullptr; 109 /// true if the attribute is applied to the pointee, not the variable 110 /// itself. 111 bool AppliedToPointee = false; 112 }; 113 using DeclSAMapTy = llvm::SmallDenseMap<const ValueDecl *, DSAInfo, 8>; 114 using UsedRefMapTy = llvm::SmallDenseMap<const ValueDecl *, const Expr *, 8>; 115 using LCDeclInfo = std::pair<unsigned, VarDecl *>; 116 using LoopControlVariablesMapTy = 117 llvm::SmallDenseMap<const ValueDecl *, LCDeclInfo, 8>; 118 /// Struct that associates a component with the clause kind where they are 119 /// found. 120 struct MappedExprComponentTy { 121 OMPClauseMappableExprCommon::MappableExprComponentLists Components; 122 OpenMPClauseKind Kind = OMPC_unknown; 123 }; 124 using MappedExprComponentsTy = 125 llvm::DenseMap<const ValueDecl *, MappedExprComponentTy>; 126 using CriticalsWithHintsTy = 127 llvm::StringMap<std::pair<const OMPCriticalDirective *, llvm::APSInt>>; 128 struct ReductionData { 129 using BOKPtrType = llvm::PointerEmbeddedInt<BinaryOperatorKind, 16>; 130 SourceRange ReductionRange; 131 llvm::PointerUnion<const Expr *, BOKPtrType> ReductionOp; 132 ReductionData() = default; 133 void set(BinaryOperatorKind BO, SourceRange RR) { 134 ReductionRange = RR; 135 ReductionOp = BO; 136 } 137 void set(const Expr *RefExpr, SourceRange RR) { 138 ReductionRange = RR; 139 ReductionOp = RefExpr; 140 } 141 }; 142 using DeclReductionMapTy = 143 llvm::SmallDenseMap<const ValueDecl *, ReductionData, 4>; 144 struct DefaultmapInfo { 145 OpenMPDefaultmapClauseModifier ImplicitBehavior = 146 OMPC_DEFAULTMAP_MODIFIER_unknown; 147 SourceLocation SLoc; 148 DefaultmapInfo() = default; 149 DefaultmapInfo(OpenMPDefaultmapClauseModifier M, SourceLocation Loc) 150 : ImplicitBehavior(M), SLoc(Loc) {} 151 }; 152 153 struct SharingMapTy { 154 DeclSAMapTy SharingMap; 155 DeclReductionMapTy ReductionMap; 156 UsedRefMapTy AlignedMap; 157 UsedRefMapTy NontemporalMap; 158 MappedExprComponentsTy MappedExprComponents; 159 LoopControlVariablesMapTy LCVMap; 160 DefaultDataSharingAttributes DefaultAttr = DSA_unspecified; 161 SourceLocation DefaultAttrLoc; 162 DefaultmapInfo DefaultmapMap[OMPC_DEFAULTMAP_unknown]; 163 OpenMPDirectiveKind Directive = OMPD_unknown; 164 DeclarationNameInfo DirectiveName; 165 Scope *CurScope = nullptr; 166 DeclContext *Context = nullptr; 167 SourceLocation ConstructLoc; 168 /// Set of 'depend' clauses with 'sink|source' dependence kind. Required to 169 /// get the data (loop counters etc.) about enclosing loop-based construct. 170 /// This data is required during codegen. 171 DoacrossDependMapTy DoacrossDepends; 172 /// First argument (Expr *) contains optional argument of the 173 /// 'ordered' clause, the second one is true if the regions has 'ordered' 174 /// clause, false otherwise. 175 llvm::Optional<std::pair<const Expr *, OMPOrderedClause *>> OrderedRegion; 176 unsigned AssociatedLoops = 1; 177 bool HasMutipleLoops = false; 178 const Decl *PossiblyLoopCounter = nullptr; 179 bool NowaitRegion = false; 180 bool UntiedRegion = false; 181 bool CancelRegion = false; 182 bool LoopStart = false; 183 bool BodyComplete = false; 184 SourceLocation PrevScanLocation; 185 SourceLocation PrevOrderedLocation; 186 SourceLocation InnerTeamsRegionLoc; 187 /// Reference to the taskgroup task_reduction reference expression. 188 Expr *TaskgroupReductionRef = nullptr; 189 llvm::DenseSet<QualType> MappedClassesQualTypes; 190 SmallVector<Expr *, 4> InnerUsedAllocators; 191 llvm::DenseSet<CanonicalDeclPtr<Decl>> ImplicitTaskFirstprivates; 192 /// List of globals marked as declare target link in this target region 193 /// (isOpenMPTargetExecutionDirective(Directive) == true). 194 llvm::SmallVector<DeclRefExpr *, 4> DeclareTargetLinkVarDecls; 195 /// List of decls used in inclusive/exclusive clauses of the scan directive. 196 llvm::DenseSet<CanonicalDeclPtr<Decl>> UsedInScanDirective; 197 llvm::DenseMap<CanonicalDeclPtr<const Decl>, UsesAllocatorsDeclKind> 198 UsesAllocatorsDecls; 199 Expr *DeclareMapperVar = nullptr; 200 SharingMapTy(OpenMPDirectiveKind DKind, DeclarationNameInfo Name, 201 Scope *CurScope, SourceLocation Loc) 202 : Directive(DKind), DirectiveName(Name), CurScope(CurScope), 203 ConstructLoc(Loc) {} 204 SharingMapTy() = default; 205 }; 206 207 using StackTy = SmallVector<SharingMapTy, 4>; 208 209 /// Stack of used declaration and their data-sharing attributes. 210 DeclSAMapTy Threadprivates; 211 const FunctionScopeInfo *CurrentNonCapturingFunctionScope = nullptr; 212 SmallVector<std::pair<StackTy, const FunctionScopeInfo *>, 4> Stack; 213 /// true, if check for DSA must be from parent directive, false, if 214 /// from current directive. 215 OpenMPClauseKind ClauseKindMode = OMPC_unknown; 216 Sema &SemaRef; 217 bool ForceCapturing = false; 218 /// true if all the variables in the target executable directives must be 219 /// captured by reference. 220 bool ForceCaptureByReferenceInTargetExecutable = false; 221 CriticalsWithHintsTy Criticals; 222 unsigned IgnoredStackElements = 0; 223 224 /// Iterators over the stack iterate in order from innermost to outermost 225 /// directive. 226 using const_iterator = StackTy::const_reverse_iterator; 227 const_iterator begin() const { 228 return Stack.empty() ? const_iterator() 229 : Stack.back().first.rbegin() + IgnoredStackElements; 230 } 231 const_iterator end() const { 232 return Stack.empty() ? const_iterator() : Stack.back().first.rend(); 233 } 234 using iterator = StackTy::reverse_iterator; 235 iterator begin() { 236 return Stack.empty() ? iterator() 237 : Stack.back().first.rbegin() + IgnoredStackElements; 238 } 239 iterator end() { 240 return Stack.empty() ? iterator() : Stack.back().first.rend(); 241 } 242 243 // Convenience operations to get at the elements of the stack. 244 245 bool isStackEmpty() const { 246 return Stack.empty() || 247 Stack.back().second != CurrentNonCapturingFunctionScope || 248 Stack.back().first.size() <= IgnoredStackElements; 249 } 250 size_t getStackSize() const { 251 return isStackEmpty() ? 0 252 : Stack.back().first.size() - IgnoredStackElements; 253 } 254 255 SharingMapTy *getTopOfStackOrNull() { 256 size_t Size = getStackSize(); 257 if (Size == 0) 258 return nullptr; 259 return &Stack.back().first[Size - 1]; 260 } 261 const SharingMapTy *getTopOfStackOrNull() const { 262 return const_cast<DSAStackTy &>(*this).getTopOfStackOrNull(); 263 } 264 SharingMapTy &getTopOfStack() { 265 assert(!isStackEmpty() && "no current directive"); 266 return *getTopOfStackOrNull(); 267 } 268 const SharingMapTy &getTopOfStack() const { 269 return const_cast<DSAStackTy &>(*this).getTopOfStack(); 270 } 271 272 SharingMapTy *getSecondOnStackOrNull() { 273 size_t Size = getStackSize(); 274 if (Size <= 1) 275 return nullptr; 276 return &Stack.back().first[Size - 2]; 277 } 278 const SharingMapTy *getSecondOnStackOrNull() const { 279 return const_cast<DSAStackTy &>(*this).getSecondOnStackOrNull(); 280 } 281 282 /// Get the stack element at a certain level (previously returned by 283 /// \c getNestingLevel). 284 /// 285 /// Note that nesting levels count from outermost to innermost, and this is 286 /// the reverse of our iteration order where new inner levels are pushed at 287 /// the front of the stack. 288 SharingMapTy &getStackElemAtLevel(unsigned Level) { 289 assert(Level < getStackSize() && "no such stack element"); 290 return Stack.back().first[Level]; 291 } 292 const SharingMapTy &getStackElemAtLevel(unsigned Level) const { 293 return const_cast<DSAStackTy &>(*this).getStackElemAtLevel(Level); 294 } 295 296 DSAVarData getDSA(const_iterator &Iter, ValueDecl *D) const; 297 298 /// Checks if the variable is a local for OpenMP region. 299 bool isOpenMPLocal(VarDecl *D, const_iterator Iter) const; 300 301 /// Vector of previously declared requires directives 302 SmallVector<const OMPRequiresDecl *, 2> RequiresDecls; 303 /// omp_allocator_handle_t type. 304 QualType OMPAllocatorHandleT; 305 /// omp_depend_t type. 306 QualType OMPDependT; 307 /// omp_event_handle_t type. 308 QualType OMPEventHandleT; 309 /// omp_alloctrait_t type. 310 QualType OMPAlloctraitT; 311 /// Expression for the predefined allocators. 312 Expr *OMPPredefinedAllocators[OMPAllocateDeclAttr::OMPUserDefinedMemAlloc] = { 313 nullptr}; 314 /// Vector of previously encountered target directives 315 SmallVector<SourceLocation, 2> TargetLocations; 316 SourceLocation AtomicLocation; 317 /// Vector of declare variant construct traits. 318 SmallVector<llvm::omp::TraitProperty, 8> ConstructTraits; 319 320 public: 321 explicit DSAStackTy(Sema &S) : SemaRef(S) {} 322 323 /// Sets omp_allocator_handle_t type. 324 void setOMPAllocatorHandleT(QualType Ty) { OMPAllocatorHandleT = Ty; } 325 /// Gets omp_allocator_handle_t type. 326 QualType getOMPAllocatorHandleT() const { return OMPAllocatorHandleT; } 327 /// Sets omp_alloctrait_t type. 328 void setOMPAlloctraitT(QualType Ty) { OMPAlloctraitT = Ty; } 329 /// Gets omp_alloctrait_t type. 330 QualType getOMPAlloctraitT() const { return OMPAlloctraitT; } 331 /// Sets the given default allocator. 332 void setAllocator(OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind, 333 Expr *Allocator) { 334 OMPPredefinedAllocators[AllocatorKind] = Allocator; 335 } 336 /// Returns the specified default allocator. 337 Expr *getAllocator(OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind) const { 338 return OMPPredefinedAllocators[AllocatorKind]; 339 } 340 /// Sets omp_depend_t type. 341 void setOMPDependT(QualType Ty) { OMPDependT = Ty; } 342 /// Gets omp_depend_t type. 343 QualType getOMPDependT() const { return OMPDependT; } 344 345 /// Sets omp_event_handle_t type. 346 void setOMPEventHandleT(QualType Ty) { OMPEventHandleT = Ty; } 347 /// Gets omp_event_handle_t type. 348 QualType getOMPEventHandleT() const { return OMPEventHandleT; } 349 350 bool isClauseParsingMode() const { return ClauseKindMode != OMPC_unknown; } 351 OpenMPClauseKind getClauseParsingMode() const { 352 assert(isClauseParsingMode() && "Must be in clause parsing mode."); 353 return ClauseKindMode; 354 } 355 void setClauseParsingMode(OpenMPClauseKind K) { ClauseKindMode = K; } 356 357 bool isBodyComplete() const { 358 const SharingMapTy *Top = getTopOfStackOrNull(); 359 return Top && Top->BodyComplete; 360 } 361 void setBodyComplete() { getTopOfStack().BodyComplete = true; } 362 363 bool isForceVarCapturing() const { return ForceCapturing; } 364 void setForceVarCapturing(bool V) { ForceCapturing = V; } 365 366 void setForceCaptureByReferenceInTargetExecutable(bool V) { 367 ForceCaptureByReferenceInTargetExecutable = V; 368 } 369 bool isForceCaptureByReferenceInTargetExecutable() const { 370 return ForceCaptureByReferenceInTargetExecutable; 371 } 372 373 void push(OpenMPDirectiveKind DKind, const DeclarationNameInfo &DirName, 374 Scope *CurScope, SourceLocation Loc) { 375 assert(!IgnoredStackElements && 376 "cannot change stack while ignoring elements"); 377 if (Stack.empty() || 378 Stack.back().second != CurrentNonCapturingFunctionScope) 379 Stack.emplace_back(StackTy(), CurrentNonCapturingFunctionScope); 380 Stack.back().first.emplace_back(DKind, DirName, CurScope, Loc); 381 Stack.back().first.back().DefaultAttrLoc = Loc; 382 } 383 384 void pop() { 385 assert(!IgnoredStackElements && 386 "cannot change stack while ignoring elements"); 387 assert(!Stack.back().first.empty() && 388 "Data-sharing attributes stack is empty!"); 389 Stack.back().first.pop_back(); 390 } 391 392 /// RAII object to temporarily leave the scope of a directive when we want to 393 /// logically operate in its parent. 394 class ParentDirectiveScope { 395 DSAStackTy &Self; 396 bool Active; 397 398 public: 399 ParentDirectiveScope(DSAStackTy &Self, bool Activate) 400 : Self(Self), Active(false) { 401 if (Activate) 402 enable(); 403 } 404 ~ParentDirectiveScope() { disable(); } 405 void disable() { 406 if (Active) { 407 --Self.IgnoredStackElements; 408 Active = false; 409 } 410 } 411 void enable() { 412 if (!Active) { 413 ++Self.IgnoredStackElements; 414 Active = true; 415 } 416 } 417 }; 418 419 /// Marks that we're started loop parsing. 420 void loopInit() { 421 assert(isOpenMPLoopDirective(getCurrentDirective()) && 422 "Expected loop-based directive."); 423 getTopOfStack().LoopStart = true; 424 } 425 /// Start capturing of the variables in the loop context. 426 void loopStart() { 427 assert(isOpenMPLoopDirective(getCurrentDirective()) && 428 "Expected loop-based directive."); 429 getTopOfStack().LoopStart = false; 430 } 431 /// true, if variables are captured, false otherwise. 432 bool isLoopStarted() const { 433 assert(isOpenMPLoopDirective(getCurrentDirective()) && 434 "Expected loop-based directive."); 435 return !getTopOfStack().LoopStart; 436 } 437 /// Marks (or clears) declaration as possibly loop counter. 438 void resetPossibleLoopCounter(const Decl *D = nullptr) { 439 getTopOfStack().PossiblyLoopCounter = D ? D->getCanonicalDecl() : D; 440 } 441 /// Gets the possible loop counter decl. 442 const Decl *getPossiblyLoopCunter() const { 443 return getTopOfStack().PossiblyLoopCounter; 444 } 445 /// Start new OpenMP region stack in new non-capturing function. 446 void pushFunction() { 447 assert(!IgnoredStackElements && 448 "cannot change stack while ignoring elements"); 449 const FunctionScopeInfo *CurFnScope = SemaRef.getCurFunction(); 450 assert(!isa<CapturingScopeInfo>(CurFnScope)); 451 CurrentNonCapturingFunctionScope = CurFnScope; 452 } 453 /// Pop region stack for non-capturing function. 454 void popFunction(const FunctionScopeInfo *OldFSI) { 455 assert(!IgnoredStackElements && 456 "cannot change stack while ignoring elements"); 457 if (!Stack.empty() && Stack.back().second == OldFSI) { 458 assert(Stack.back().first.empty()); 459 Stack.pop_back(); 460 } 461 CurrentNonCapturingFunctionScope = nullptr; 462 for (const FunctionScopeInfo *FSI : llvm::reverse(SemaRef.FunctionScopes)) { 463 if (!isa<CapturingScopeInfo>(FSI)) { 464 CurrentNonCapturingFunctionScope = FSI; 465 break; 466 } 467 } 468 } 469 470 void addCriticalWithHint(const OMPCriticalDirective *D, llvm::APSInt Hint) { 471 Criticals.try_emplace(D->getDirectiveName().getAsString(), D, Hint); 472 } 473 const std::pair<const OMPCriticalDirective *, llvm::APSInt> 474 getCriticalWithHint(const DeclarationNameInfo &Name) const { 475 auto I = Criticals.find(Name.getAsString()); 476 if (I != Criticals.end()) 477 return I->second; 478 return std::make_pair(nullptr, llvm::APSInt()); 479 } 480 /// If 'aligned' declaration for given variable \a D was not seen yet, 481 /// add it and return NULL; otherwise return previous occurrence's expression 482 /// for diagnostics. 483 const Expr *addUniqueAligned(const ValueDecl *D, const Expr *NewDE); 484 /// If 'nontemporal' declaration for given variable \a D was not seen yet, 485 /// add it and return NULL; otherwise return previous occurrence's expression 486 /// for diagnostics. 487 const Expr *addUniqueNontemporal(const ValueDecl *D, const Expr *NewDE); 488 489 /// Register specified variable as loop control variable. 490 void addLoopControlVariable(const ValueDecl *D, VarDecl *Capture); 491 /// Check if the specified variable is a loop control variable for 492 /// current 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 isLoopControlVariable(const ValueDecl *D) const; 496 /// Check if the specified variable is a loop control variable for 497 /// parent 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 isParentLoopControlVariable(const ValueDecl *D) const; 501 /// Check if the specified variable is a loop control variable for 502 /// current region. 503 /// \return The index of the loop control variable in the list of associated 504 /// for-loops (from outer to inner). 505 const LCDeclInfo isLoopControlVariable(const ValueDecl *D, 506 unsigned Level) const; 507 /// Get the loop control variable for the I-th loop (or nullptr) in 508 /// parent directive. 509 const ValueDecl *getParentLoopControlVariable(unsigned I) const; 510 511 /// Marks the specified decl \p D as used in scan directive. 512 void markDeclAsUsedInScanDirective(ValueDecl *D) { 513 if (SharingMapTy *Stack = getSecondOnStackOrNull()) 514 Stack->UsedInScanDirective.insert(D); 515 } 516 517 /// Checks if the specified declaration was used in the inner scan directive. 518 bool isUsedInScanDirective(ValueDecl *D) const { 519 if (const SharingMapTy *Stack = getTopOfStackOrNull()) 520 return Stack->UsedInScanDirective.contains(D); 521 return false; 522 } 523 524 /// Adds explicit data sharing attribute to the specified declaration. 525 void addDSA(const ValueDecl *D, const Expr *E, OpenMPClauseKind A, 526 DeclRefExpr *PrivateCopy = nullptr, unsigned Modifier = 0, 527 bool AppliedToPointee = false); 528 529 /// Adds additional information for the reduction items with the reduction id 530 /// represented as an operator. 531 void addTaskgroupReductionData(const ValueDecl *D, SourceRange SR, 532 BinaryOperatorKind BOK); 533 /// Adds additional information for the reduction items with the reduction id 534 /// represented as reduction identifier. 535 void addTaskgroupReductionData(const ValueDecl *D, SourceRange SR, 536 const Expr *ReductionRef); 537 /// Returns the location and reduction operation from the innermost parent 538 /// region for the given \p D. 539 const DSAVarData 540 getTopMostTaskgroupReductionData(const ValueDecl *D, SourceRange &SR, 541 BinaryOperatorKind &BOK, 542 Expr *&TaskgroupDescriptor) const; 543 /// Returns the location and reduction operation from the innermost parent 544 /// region for the given \p D. 545 const DSAVarData 546 getTopMostTaskgroupReductionData(const ValueDecl *D, SourceRange &SR, 547 const Expr *&ReductionRef, 548 Expr *&TaskgroupDescriptor) const; 549 /// Return reduction reference expression for the current taskgroup or 550 /// parallel/worksharing directives with task reductions. 551 Expr *getTaskgroupReductionRef() const { 552 assert((getTopOfStack().Directive == OMPD_taskgroup || 553 ((isOpenMPParallelDirective(getTopOfStack().Directive) || 554 isOpenMPWorksharingDirective(getTopOfStack().Directive)) && 555 !isOpenMPSimdDirective(getTopOfStack().Directive))) && 556 "taskgroup reference expression requested for non taskgroup or " 557 "parallel/worksharing directive."); 558 return getTopOfStack().TaskgroupReductionRef; 559 } 560 /// Checks if the given \p VD declaration is actually a taskgroup reduction 561 /// descriptor variable at the \p Level of OpenMP regions. 562 bool isTaskgroupReductionRef(const ValueDecl *VD, unsigned Level) const { 563 return getStackElemAtLevel(Level).TaskgroupReductionRef && 564 cast<DeclRefExpr>(getStackElemAtLevel(Level).TaskgroupReductionRef) 565 ->getDecl() == VD; 566 } 567 568 /// Returns data sharing attributes from top of the stack for the 569 /// specified declaration. 570 const DSAVarData getTopDSA(ValueDecl *D, bool FromParent); 571 /// Returns data-sharing attributes for the specified declaration. 572 const DSAVarData getImplicitDSA(ValueDecl *D, bool FromParent) const; 573 /// Returns data-sharing attributes for the specified declaration. 574 const DSAVarData getImplicitDSA(ValueDecl *D, unsigned Level) const; 575 /// Checks if the specified variables has data-sharing attributes which 576 /// match specified \a CPred predicate in any directive which matches \a DPred 577 /// predicate. 578 const DSAVarData 579 hasDSA(ValueDecl *D, 580 const llvm::function_ref<bool(OpenMPClauseKind, bool)> CPred, 581 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred, 582 bool FromParent) const; 583 /// Checks if the specified variables has data-sharing attributes which 584 /// match specified \a CPred predicate in any innermost directive which 585 /// matches \a DPred predicate. 586 const DSAVarData 587 hasInnermostDSA(ValueDecl *D, 588 const llvm::function_ref<bool(OpenMPClauseKind, bool)> CPred, 589 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred, 590 bool FromParent) const; 591 /// Checks if the specified variables has explicit data-sharing 592 /// attributes which match specified \a CPred predicate at the specified 593 /// OpenMP region. 594 bool 595 hasExplicitDSA(const ValueDecl *D, 596 const llvm::function_ref<bool(OpenMPClauseKind, bool)> CPred, 597 unsigned Level, bool NotLastprivate = false) const; 598 599 /// Returns true if the directive at level \Level matches in the 600 /// specified \a DPred predicate. 601 bool hasExplicitDirective( 602 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred, 603 unsigned Level) const; 604 605 /// Finds a directive which matches specified \a DPred predicate. 606 bool hasDirective( 607 const llvm::function_ref<bool( 608 OpenMPDirectiveKind, const DeclarationNameInfo &, SourceLocation)> 609 DPred, 610 bool FromParent) const; 611 612 /// Returns currently analyzed directive. 613 OpenMPDirectiveKind getCurrentDirective() const { 614 const SharingMapTy *Top = getTopOfStackOrNull(); 615 return Top ? Top->Directive : OMPD_unknown; 616 } 617 /// Returns directive kind at specified level. 618 OpenMPDirectiveKind getDirective(unsigned Level) const { 619 assert(!isStackEmpty() && "No directive at specified level."); 620 return getStackElemAtLevel(Level).Directive; 621 } 622 /// Returns the capture region at the specified level. 623 OpenMPDirectiveKind getCaptureRegion(unsigned Level, 624 unsigned OpenMPCaptureLevel) const { 625 SmallVector<OpenMPDirectiveKind, 4> CaptureRegions; 626 getOpenMPCaptureRegions(CaptureRegions, getDirective(Level)); 627 return CaptureRegions[OpenMPCaptureLevel]; 628 } 629 /// Returns parent directive. 630 OpenMPDirectiveKind getParentDirective() const { 631 const SharingMapTy *Parent = getSecondOnStackOrNull(); 632 return Parent ? Parent->Directive : OMPD_unknown; 633 } 634 635 /// Add requires decl to internal vector 636 void addRequiresDecl(OMPRequiresDecl *RD) { RequiresDecls.push_back(RD); } 637 638 /// Checks if the defined 'requires' directive has specified type of clause. 639 template <typename ClauseType> bool hasRequiresDeclWithClause() const { 640 return llvm::any_of(RequiresDecls, [](const OMPRequiresDecl *D) { 641 return llvm::any_of(D->clauselists(), [](const OMPClause *C) { 642 return isa<ClauseType>(C); 643 }); 644 }); 645 } 646 647 /// Checks for a duplicate clause amongst previously declared requires 648 /// directives 649 bool hasDuplicateRequiresClause(ArrayRef<OMPClause *> ClauseList) const { 650 bool IsDuplicate = false; 651 for (OMPClause *CNew : ClauseList) { 652 for (const OMPRequiresDecl *D : RequiresDecls) { 653 for (const OMPClause *CPrev : D->clauselists()) { 654 if (CNew->getClauseKind() == CPrev->getClauseKind()) { 655 SemaRef.Diag(CNew->getBeginLoc(), 656 diag::err_omp_requires_clause_redeclaration) 657 << getOpenMPClauseName(CNew->getClauseKind()); 658 SemaRef.Diag(CPrev->getBeginLoc(), 659 diag::note_omp_requires_previous_clause) 660 << getOpenMPClauseName(CPrev->getClauseKind()); 661 IsDuplicate = true; 662 } 663 } 664 } 665 } 666 return IsDuplicate; 667 } 668 669 /// Add location of previously encountered target to internal vector 670 void addTargetDirLocation(SourceLocation LocStart) { 671 TargetLocations.push_back(LocStart); 672 } 673 674 /// Add location for the first encountered atomicc directive. 675 void addAtomicDirectiveLoc(SourceLocation Loc) { 676 if (AtomicLocation.isInvalid()) 677 AtomicLocation = Loc; 678 } 679 680 /// Returns the location of the first encountered atomic directive in the 681 /// module. 682 SourceLocation getAtomicDirectiveLoc() const { return AtomicLocation; } 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 private. 700 void setDefaultDSAPrivate(SourceLocation Loc) { 701 getTopOfStack().DefaultAttr = DSA_private; 702 getTopOfStack().DefaultAttrLoc = Loc; 703 } 704 /// Set default data sharing attribute to firstprivate. 705 void setDefaultDSAFirstPrivate(SourceLocation Loc) { 706 getTopOfStack().DefaultAttr = DSA_firstprivate; 707 getTopOfStack().DefaultAttrLoc = Loc; 708 } 709 /// Set default data mapping attribute to Modifier:Kind 710 void setDefaultDMAAttr(OpenMPDefaultmapClauseModifier M, 711 OpenMPDefaultmapClauseKind Kind, SourceLocation Loc) { 712 DefaultmapInfo &DMI = getTopOfStack().DefaultmapMap[Kind]; 713 DMI.ImplicitBehavior = M; 714 DMI.SLoc = Loc; 715 } 716 /// Check whether the implicit-behavior has been set in defaultmap 717 bool checkDefaultmapCategory(OpenMPDefaultmapClauseKind VariableCategory) { 718 if (VariableCategory == OMPC_DEFAULTMAP_unknown) 719 return getTopOfStack() 720 .DefaultmapMap[OMPC_DEFAULTMAP_aggregate] 721 .ImplicitBehavior != OMPC_DEFAULTMAP_MODIFIER_unknown || 722 getTopOfStack() 723 .DefaultmapMap[OMPC_DEFAULTMAP_scalar] 724 .ImplicitBehavior != OMPC_DEFAULTMAP_MODIFIER_unknown || 725 getTopOfStack() 726 .DefaultmapMap[OMPC_DEFAULTMAP_pointer] 727 .ImplicitBehavior != OMPC_DEFAULTMAP_MODIFIER_unknown; 728 return getTopOfStack().DefaultmapMap[VariableCategory].ImplicitBehavior != 729 OMPC_DEFAULTMAP_MODIFIER_unknown; 730 } 731 732 ArrayRef<llvm::omp::TraitProperty> getConstructTraits() { 733 return ConstructTraits; 734 } 735 void handleConstructTrait(ArrayRef<llvm::omp::TraitProperty> Traits, 736 bool ScopeEntry) { 737 if (ScopeEntry) 738 ConstructTraits.append(Traits.begin(), Traits.end()); 739 else 740 for (llvm::omp::TraitProperty Trait : llvm::reverse(Traits)) { 741 llvm::omp::TraitProperty Top = ConstructTraits.pop_back_val(); 742 assert(Top == Trait && "Something left a trait on the stack!"); 743 (void)Trait; 744 (void)Top; 745 } 746 } 747 748 DefaultDataSharingAttributes getDefaultDSA(unsigned Level) const { 749 return getStackSize() <= Level ? DSA_unspecified 750 : getStackElemAtLevel(Level).DefaultAttr; 751 } 752 DefaultDataSharingAttributes getDefaultDSA() const { 753 return isStackEmpty() ? DSA_unspecified : getTopOfStack().DefaultAttr; 754 } 755 SourceLocation getDefaultDSALocation() const { 756 return isStackEmpty() ? SourceLocation() : getTopOfStack().DefaultAttrLoc; 757 } 758 OpenMPDefaultmapClauseModifier 759 getDefaultmapModifier(OpenMPDefaultmapClauseKind Kind) const { 760 return isStackEmpty() 761 ? OMPC_DEFAULTMAP_MODIFIER_unknown 762 : getTopOfStack().DefaultmapMap[Kind].ImplicitBehavior; 763 } 764 OpenMPDefaultmapClauseModifier 765 getDefaultmapModifierAtLevel(unsigned Level, 766 OpenMPDefaultmapClauseKind Kind) const { 767 return getStackElemAtLevel(Level).DefaultmapMap[Kind].ImplicitBehavior; 768 } 769 bool isDefaultmapCapturedByRef(unsigned Level, 770 OpenMPDefaultmapClauseKind Kind) const { 771 OpenMPDefaultmapClauseModifier M = 772 getDefaultmapModifierAtLevel(Level, Kind); 773 if (Kind == OMPC_DEFAULTMAP_scalar || Kind == OMPC_DEFAULTMAP_pointer) { 774 return (M == OMPC_DEFAULTMAP_MODIFIER_alloc) || 775 (M == OMPC_DEFAULTMAP_MODIFIER_to) || 776 (M == OMPC_DEFAULTMAP_MODIFIER_from) || 777 (M == OMPC_DEFAULTMAP_MODIFIER_tofrom); 778 } 779 return true; 780 } 781 static bool mustBeFirstprivateBase(OpenMPDefaultmapClauseModifier M, 782 OpenMPDefaultmapClauseKind Kind) { 783 switch (Kind) { 784 case OMPC_DEFAULTMAP_scalar: 785 case OMPC_DEFAULTMAP_pointer: 786 return (M == OMPC_DEFAULTMAP_MODIFIER_unknown) || 787 (M == OMPC_DEFAULTMAP_MODIFIER_firstprivate) || 788 (M == OMPC_DEFAULTMAP_MODIFIER_default); 789 case OMPC_DEFAULTMAP_aggregate: 790 return M == OMPC_DEFAULTMAP_MODIFIER_firstprivate; 791 default: 792 break; 793 } 794 llvm_unreachable("Unexpected OpenMPDefaultmapClauseKind enum"); 795 } 796 bool mustBeFirstprivateAtLevel(unsigned Level, 797 OpenMPDefaultmapClauseKind Kind) const { 798 OpenMPDefaultmapClauseModifier M = 799 getDefaultmapModifierAtLevel(Level, Kind); 800 return mustBeFirstprivateBase(M, Kind); 801 } 802 bool mustBeFirstprivate(OpenMPDefaultmapClauseKind Kind) const { 803 OpenMPDefaultmapClauseModifier M = getDefaultmapModifier(Kind); 804 return mustBeFirstprivateBase(M, Kind); 805 } 806 807 /// Checks if the specified variable is a threadprivate. 808 bool isThreadPrivate(VarDecl *D) { 809 const DSAVarData DVar = getTopDSA(D, false); 810 return isOpenMPThreadPrivate(DVar.CKind); 811 } 812 813 /// Marks current region as ordered (it has an 'ordered' clause). 814 void setOrderedRegion(bool IsOrdered, const Expr *Param, 815 OMPOrderedClause *Clause) { 816 if (IsOrdered) 817 getTopOfStack().OrderedRegion.emplace(Param, Clause); 818 else 819 getTopOfStack().OrderedRegion.reset(); 820 } 821 /// Returns true, if region is ordered (has associated 'ordered' clause), 822 /// false - otherwise. 823 bool isOrderedRegion() const { 824 if (const SharingMapTy *Top = getTopOfStackOrNull()) 825 return Top->OrderedRegion.hasValue(); 826 return false; 827 } 828 /// Returns optional parameter for the ordered region. 829 std::pair<const Expr *, OMPOrderedClause *> getOrderedRegionParam() const { 830 if (const SharingMapTy *Top = getTopOfStackOrNull()) 831 if (Top->OrderedRegion) 832 return Top->OrderedRegion.getValue(); 833 return std::make_pair(nullptr, nullptr); 834 } 835 /// Returns true, if parent region is ordered (has associated 836 /// 'ordered' clause), false - otherwise. 837 bool isParentOrderedRegion() const { 838 if (const SharingMapTy *Parent = getSecondOnStackOrNull()) 839 return Parent->OrderedRegion.hasValue(); 840 return false; 841 } 842 /// Returns optional parameter for the ordered region. 843 std::pair<const Expr *, OMPOrderedClause *> 844 getParentOrderedRegionParam() const { 845 if (const SharingMapTy *Parent = getSecondOnStackOrNull()) 846 if (Parent->OrderedRegion) 847 return Parent->OrderedRegion.getValue(); 848 return std::make_pair(nullptr, nullptr); 849 } 850 /// Marks current region as nowait (it has a 'nowait' clause). 851 void setNowaitRegion(bool IsNowait = true) { 852 getTopOfStack().NowaitRegion = IsNowait; 853 } 854 /// Returns true, if parent region is nowait (has associated 855 /// 'nowait' clause), false - otherwise. 856 bool isParentNowaitRegion() const { 857 if (const SharingMapTy *Parent = getSecondOnStackOrNull()) 858 return Parent->NowaitRegion; 859 return false; 860 } 861 /// Marks current region as untied (it has a 'untied' clause). 862 void setUntiedRegion(bool IsUntied = true) { 863 getTopOfStack().UntiedRegion = IsUntied; 864 } 865 /// Return true if current region is untied. 866 bool isUntiedRegion() const { 867 const SharingMapTy *Top = getTopOfStackOrNull(); 868 return Top ? Top->UntiedRegion : false; 869 } 870 /// Marks parent region as cancel region. 871 void setParentCancelRegion(bool Cancel = true) { 872 if (SharingMapTy *Parent = getSecondOnStackOrNull()) 873 Parent->CancelRegion |= Cancel; 874 } 875 /// Return true if current region has inner cancel construct. 876 bool isCancelRegion() const { 877 const SharingMapTy *Top = getTopOfStackOrNull(); 878 return Top ? Top->CancelRegion : false; 879 } 880 881 /// Mark that parent region already has scan directive. 882 void setParentHasScanDirective(SourceLocation Loc) { 883 if (SharingMapTy *Parent = getSecondOnStackOrNull()) 884 Parent->PrevScanLocation = Loc; 885 } 886 /// Return true if current region has inner cancel construct. 887 bool doesParentHasScanDirective() const { 888 const SharingMapTy *Top = getSecondOnStackOrNull(); 889 return Top ? Top->PrevScanLocation.isValid() : false; 890 } 891 /// Return true if current region has inner cancel construct. 892 SourceLocation getParentScanDirectiveLoc() const { 893 const SharingMapTy *Top = getSecondOnStackOrNull(); 894 return Top ? Top->PrevScanLocation : SourceLocation(); 895 } 896 /// Mark that parent region already has ordered directive. 897 void setParentHasOrderedDirective(SourceLocation Loc) { 898 if (SharingMapTy *Parent = getSecondOnStackOrNull()) 899 Parent->PrevOrderedLocation = Loc; 900 } 901 /// Return true if current region has inner ordered construct. 902 bool doesParentHasOrderedDirective() const { 903 const SharingMapTy *Top = getSecondOnStackOrNull(); 904 return Top ? Top->PrevOrderedLocation.isValid() : false; 905 } 906 /// Returns the location of the previously specified ordered directive. 907 SourceLocation getParentOrderedDirectiveLoc() const { 908 const SharingMapTy *Top = getSecondOnStackOrNull(); 909 return Top ? Top->PrevOrderedLocation : SourceLocation(); 910 } 911 912 /// Set collapse value for the region. 913 void setAssociatedLoops(unsigned Val) { 914 getTopOfStack().AssociatedLoops = Val; 915 if (Val > 1) 916 getTopOfStack().HasMutipleLoops = true; 917 } 918 /// Return collapse value for region. 919 unsigned getAssociatedLoops() const { 920 const SharingMapTy *Top = getTopOfStackOrNull(); 921 return Top ? Top->AssociatedLoops : 0; 922 } 923 /// Returns true if the construct is associated with multiple loops. 924 bool hasMutipleLoops() const { 925 const SharingMapTy *Top = getTopOfStackOrNull(); 926 return Top ? Top->HasMutipleLoops : false; 927 } 928 929 /// Marks current target region as one with closely nested teams 930 /// region. 931 void setParentTeamsRegionLoc(SourceLocation TeamsRegionLoc) { 932 if (SharingMapTy *Parent = getSecondOnStackOrNull()) 933 Parent->InnerTeamsRegionLoc = TeamsRegionLoc; 934 } 935 /// Returns true, if current region has closely nested teams region. 936 bool hasInnerTeamsRegion() const { 937 return getInnerTeamsRegionLoc().isValid(); 938 } 939 /// Returns location of the nested teams region (if any). 940 SourceLocation getInnerTeamsRegionLoc() const { 941 const SharingMapTy *Top = getTopOfStackOrNull(); 942 return Top ? Top->InnerTeamsRegionLoc : SourceLocation(); 943 } 944 945 Scope *getCurScope() const { 946 const SharingMapTy *Top = getTopOfStackOrNull(); 947 return Top ? Top->CurScope : nullptr; 948 } 949 void setContext(DeclContext *DC) { getTopOfStack().Context = DC; } 950 SourceLocation getConstructLoc() const { 951 const SharingMapTy *Top = getTopOfStackOrNull(); 952 return Top ? Top->ConstructLoc : SourceLocation(); 953 } 954 955 /// Do the check specified in \a Check to all component lists and return true 956 /// if any issue is found. 957 bool checkMappableExprComponentListsForDecl( 958 const ValueDecl *VD, bool CurrentRegionOnly, 959 const llvm::function_ref< 960 bool(OMPClauseMappableExprCommon::MappableExprComponentListRef, 961 OpenMPClauseKind)> 962 Check) const { 963 if (isStackEmpty()) 964 return false; 965 auto SI = begin(); 966 auto SE = end(); 967 968 if (SI == SE) 969 return false; 970 971 if (CurrentRegionOnly) 972 SE = std::next(SI); 973 else 974 std::advance(SI, 1); 975 976 for (; SI != SE; ++SI) { 977 auto MI = SI->MappedExprComponents.find(VD); 978 if (MI != SI->MappedExprComponents.end()) 979 for (OMPClauseMappableExprCommon::MappableExprComponentListRef L : 980 MI->second.Components) 981 if (Check(L, MI->second.Kind)) 982 return true; 983 } 984 return false; 985 } 986 987 /// Do the check specified in \a Check to all component lists at a given level 988 /// and return true if any issue is found. 989 bool checkMappableExprComponentListsForDeclAtLevel( 990 const ValueDecl *VD, unsigned Level, 991 const llvm::function_ref< 992 bool(OMPClauseMappableExprCommon::MappableExprComponentListRef, 993 OpenMPClauseKind)> 994 Check) const { 995 if (getStackSize() <= Level) 996 return false; 997 998 const SharingMapTy &StackElem = getStackElemAtLevel(Level); 999 auto MI = StackElem.MappedExprComponents.find(VD); 1000 if (MI != StackElem.MappedExprComponents.end()) 1001 for (OMPClauseMappableExprCommon::MappableExprComponentListRef L : 1002 MI->second.Components) 1003 if (Check(L, MI->second.Kind)) 1004 return true; 1005 return false; 1006 } 1007 1008 /// Create a new mappable expression component list associated with a given 1009 /// declaration and initialize it with the provided list of components. 1010 void addMappableExpressionComponents( 1011 const ValueDecl *VD, 1012 OMPClauseMappableExprCommon::MappableExprComponentListRef Components, 1013 OpenMPClauseKind WhereFoundClauseKind) { 1014 MappedExprComponentTy &MEC = getTopOfStack().MappedExprComponents[VD]; 1015 // Create new entry and append the new components there. 1016 MEC.Components.resize(MEC.Components.size() + 1); 1017 MEC.Components.back().append(Components.begin(), Components.end()); 1018 MEC.Kind = WhereFoundClauseKind; 1019 } 1020 1021 unsigned getNestingLevel() const { 1022 assert(!isStackEmpty()); 1023 return getStackSize() - 1; 1024 } 1025 void addDoacrossDependClause(OMPDependClause *C, 1026 const OperatorOffsetTy &OpsOffs) { 1027 SharingMapTy *Parent = getSecondOnStackOrNull(); 1028 assert(Parent && isOpenMPWorksharingDirective(Parent->Directive)); 1029 Parent->DoacrossDepends.try_emplace(C, OpsOffs); 1030 } 1031 llvm::iterator_range<DoacrossDependMapTy::const_iterator> 1032 getDoacrossDependClauses() const { 1033 const SharingMapTy &StackElem = getTopOfStack(); 1034 if (isOpenMPWorksharingDirective(StackElem.Directive)) { 1035 const DoacrossDependMapTy &Ref = StackElem.DoacrossDepends; 1036 return llvm::make_range(Ref.begin(), Ref.end()); 1037 } 1038 return llvm::make_range(StackElem.DoacrossDepends.end(), 1039 StackElem.DoacrossDepends.end()); 1040 } 1041 1042 // Store types of classes which have been explicitly mapped 1043 void addMappedClassesQualTypes(QualType QT) { 1044 SharingMapTy &StackElem = getTopOfStack(); 1045 StackElem.MappedClassesQualTypes.insert(QT); 1046 } 1047 1048 // Return set of mapped classes types 1049 bool isClassPreviouslyMapped(QualType QT) const { 1050 const SharingMapTy &StackElem = getTopOfStack(); 1051 return StackElem.MappedClassesQualTypes.contains(QT); 1052 } 1053 1054 /// Adds global declare target to the parent target region. 1055 void addToParentTargetRegionLinkGlobals(DeclRefExpr *E) { 1056 assert(*OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration( 1057 E->getDecl()) == OMPDeclareTargetDeclAttr::MT_Link && 1058 "Expected declare target link global."); 1059 for (auto &Elem : *this) { 1060 if (isOpenMPTargetExecutionDirective(Elem.Directive)) { 1061 Elem.DeclareTargetLinkVarDecls.push_back(E); 1062 return; 1063 } 1064 } 1065 } 1066 1067 /// Returns the list of globals with declare target link if current directive 1068 /// is target. 1069 ArrayRef<DeclRefExpr *> getLinkGlobals() const { 1070 assert(isOpenMPTargetExecutionDirective(getCurrentDirective()) && 1071 "Expected target executable directive."); 1072 return getTopOfStack().DeclareTargetLinkVarDecls; 1073 } 1074 1075 /// Adds list of allocators expressions. 1076 void addInnerAllocatorExpr(Expr *E) { 1077 getTopOfStack().InnerUsedAllocators.push_back(E); 1078 } 1079 /// Return list of used allocators. 1080 ArrayRef<Expr *> getInnerAllocators() const { 1081 return getTopOfStack().InnerUsedAllocators; 1082 } 1083 /// Marks the declaration as implicitly firstprivate nin the task-based 1084 /// regions. 1085 void addImplicitTaskFirstprivate(unsigned Level, Decl *D) { 1086 getStackElemAtLevel(Level).ImplicitTaskFirstprivates.insert(D); 1087 } 1088 /// Checks if the decl is implicitly firstprivate in the task-based region. 1089 bool isImplicitTaskFirstprivate(Decl *D) const { 1090 return getTopOfStack().ImplicitTaskFirstprivates.contains(D); 1091 } 1092 1093 /// Marks decl as used in uses_allocators clause as the allocator. 1094 void addUsesAllocatorsDecl(const Decl *D, UsesAllocatorsDeclKind Kind) { 1095 getTopOfStack().UsesAllocatorsDecls.try_emplace(D, Kind); 1096 } 1097 /// Checks if specified decl is used in uses allocator clause as the 1098 /// allocator. 1099 Optional<UsesAllocatorsDeclKind> isUsesAllocatorsDecl(unsigned Level, 1100 const Decl *D) const { 1101 const SharingMapTy &StackElem = getTopOfStack(); 1102 auto I = StackElem.UsesAllocatorsDecls.find(D); 1103 if (I == StackElem.UsesAllocatorsDecls.end()) 1104 return None; 1105 return I->getSecond(); 1106 } 1107 Optional<UsesAllocatorsDeclKind> isUsesAllocatorsDecl(const Decl *D) const { 1108 const SharingMapTy &StackElem = getTopOfStack(); 1109 auto I = StackElem.UsesAllocatorsDecls.find(D); 1110 if (I == StackElem.UsesAllocatorsDecls.end()) 1111 return None; 1112 return I->getSecond(); 1113 } 1114 1115 void addDeclareMapperVarRef(Expr *Ref) { 1116 SharingMapTy &StackElem = getTopOfStack(); 1117 StackElem.DeclareMapperVar = Ref; 1118 } 1119 const Expr *getDeclareMapperVarRef() const { 1120 const SharingMapTy *Top = getTopOfStackOrNull(); 1121 return Top ? Top->DeclareMapperVar : nullptr; 1122 } 1123 }; 1124 1125 bool isImplicitTaskingRegion(OpenMPDirectiveKind DKind) { 1126 return isOpenMPParallelDirective(DKind) || isOpenMPTeamsDirective(DKind); 1127 } 1128 1129 bool isImplicitOrExplicitTaskingRegion(OpenMPDirectiveKind DKind) { 1130 return isImplicitTaskingRegion(DKind) || isOpenMPTaskingDirective(DKind) || 1131 DKind == OMPD_unknown; 1132 } 1133 1134 } // namespace 1135 1136 static const Expr *getExprAsWritten(const Expr *E) { 1137 if (const auto *FE = dyn_cast<FullExpr>(E)) 1138 E = FE->getSubExpr(); 1139 1140 if (const auto *MTE = dyn_cast<MaterializeTemporaryExpr>(E)) 1141 E = MTE->getSubExpr(); 1142 1143 while (const auto *Binder = dyn_cast<CXXBindTemporaryExpr>(E)) 1144 E = Binder->getSubExpr(); 1145 1146 if (const auto *ICE = dyn_cast<ImplicitCastExpr>(E)) 1147 E = ICE->getSubExprAsWritten(); 1148 return E->IgnoreParens(); 1149 } 1150 1151 static Expr *getExprAsWritten(Expr *E) { 1152 return const_cast<Expr *>(getExprAsWritten(const_cast<const Expr *>(E))); 1153 } 1154 1155 static const ValueDecl *getCanonicalDecl(const ValueDecl *D) { 1156 if (const auto *CED = dyn_cast<OMPCapturedExprDecl>(D)) 1157 if (const auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit()))) 1158 D = ME->getMemberDecl(); 1159 const auto *VD = dyn_cast<VarDecl>(D); 1160 const auto *FD = dyn_cast<FieldDecl>(D); 1161 if (VD != nullptr) { 1162 VD = VD->getCanonicalDecl(); 1163 D = VD; 1164 } else { 1165 assert(FD); 1166 FD = FD->getCanonicalDecl(); 1167 D = FD; 1168 } 1169 return D; 1170 } 1171 1172 static ValueDecl *getCanonicalDecl(ValueDecl *D) { 1173 return const_cast<ValueDecl *>( 1174 getCanonicalDecl(const_cast<const ValueDecl *>(D))); 1175 } 1176 1177 DSAStackTy::DSAVarData DSAStackTy::getDSA(const_iterator &Iter, 1178 ValueDecl *D) const { 1179 D = getCanonicalDecl(D); 1180 auto *VD = dyn_cast<VarDecl>(D); 1181 const auto *FD = dyn_cast<FieldDecl>(D); 1182 DSAVarData DVar; 1183 if (Iter == end()) { 1184 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 1185 // in a region but not in construct] 1186 // File-scope or namespace-scope variables referenced in called routines 1187 // in the region are shared unless they appear in a threadprivate 1188 // directive. 1189 if (VD && !VD->isFunctionOrMethodVarDecl() && !isa<ParmVarDecl>(VD)) 1190 DVar.CKind = OMPC_shared; 1191 1192 // OpenMP [2.9.1.2, Data-sharing Attribute Rules for Variables Referenced 1193 // in a region but not in construct] 1194 // Variables with static storage duration that are declared in called 1195 // routines in the region are shared. 1196 if (VD && VD->hasGlobalStorage()) 1197 DVar.CKind = OMPC_shared; 1198 1199 // Non-static data members are shared by default. 1200 if (FD) 1201 DVar.CKind = OMPC_shared; 1202 1203 return DVar; 1204 } 1205 1206 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 1207 // in a Construct, C/C++, predetermined, p.1] 1208 // Variables with automatic storage duration that are declared in a scope 1209 // inside the construct are private. 1210 if (VD && isOpenMPLocal(VD, Iter) && VD->isLocalVarDecl() && 1211 (VD->getStorageClass() == SC_Auto || VD->getStorageClass() == SC_None)) { 1212 DVar.CKind = OMPC_private; 1213 return DVar; 1214 } 1215 1216 DVar.DKind = Iter->Directive; 1217 // Explicitly specified attributes and local variables with predetermined 1218 // attributes. 1219 if (Iter->SharingMap.count(D)) { 1220 const DSAInfo &Data = Iter->SharingMap.lookup(D); 1221 DVar.RefExpr = Data.RefExpr.getPointer(); 1222 DVar.PrivateCopy = Data.PrivateCopy; 1223 DVar.CKind = Data.Attributes; 1224 DVar.ImplicitDSALoc = Iter->DefaultAttrLoc; 1225 DVar.Modifier = Data.Modifier; 1226 DVar.AppliedToPointee = Data.AppliedToPointee; 1227 return DVar; 1228 } 1229 1230 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 1231 // in a Construct, C/C++, implicitly determined, p.1] 1232 // In a parallel or task construct, the data-sharing attributes of these 1233 // variables are determined by the default clause, if present. 1234 switch (Iter->DefaultAttr) { 1235 case DSA_shared: 1236 DVar.CKind = OMPC_shared; 1237 DVar.ImplicitDSALoc = Iter->DefaultAttrLoc; 1238 return DVar; 1239 case DSA_none: 1240 return DVar; 1241 case DSA_firstprivate: 1242 if (VD && VD->getStorageDuration() == SD_Static && 1243 VD->getDeclContext()->isFileContext()) { 1244 DVar.CKind = OMPC_unknown; 1245 } else { 1246 DVar.CKind = OMPC_firstprivate; 1247 } 1248 DVar.ImplicitDSALoc = Iter->DefaultAttrLoc; 1249 return DVar; 1250 case DSA_private: 1251 // each variable with static storage duration that is declared 1252 // in a namespace or global scope and referenced in the construct, 1253 // and that does not have a predetermined data-sharing attribute 1254 if (VD && VD->getStorageDuration() == SD_Static && 1255 VD->getDeclContext()->isFileContext()) { 1256 DVar.CKind = OMPC_unknown; 1257 } else { 1258 DVar.CKind = OMPC_private; 1259 } 1260 DVar.ImplicitDSALoc = Iter->DefaultAttrLoc; 1261 return DVar; 1262 case DSA_unspecified: 1263 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 1264 // in a Construct, implicitly determined, p.2] 1265 // In a parallel construct, if no default clause is present, these 1266 // variables are shared. 1267 DVar.ImplicitDSALoc = Iter->DefaultAttrLoc; 1268 if ((isOpenMPParallelDirective(DVar.DKind) && 1269 !isOpenMPTaskLoopDirective(DVar.DKind)) || 1270 isOpenMPTeamsDirective(DVar.DKind)) { 1271 DVar.CKind = OMPC_shared; 1272 return DVar; 1273 } 1274 1275 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 1276 // in a Construct, implicitly determined, p.4] 1277 // In a task construct, if no default clause is present, a variable that in 1278 // the enclosing context is determined to be shared by all implicit tasks 1279 // bound to the current team is shared. 1280 if (isOpenMPTaskingDirective(DVar.DKind)) { 1281 DSAVarData DVarTemp; 1282 const_iterator I = Iter, E = end(); 1283 do { 1284 ++I; 1285 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables 1286 // Referenced in a Construct, implicitly determined, p.6] 1287 // In a task construct, if no default clause is present, a variable 1288 // whose data-sharing attribute is not determined by the rules above is 1289 // firstprivate. 1290 DVarTemp = getDSA(I, D); 1291 if (DVarTemp.CKind != OMPC_shared) { 1292 DVar.RefExpr = nullptr; 1293 DVar.CKind = OMPC_firstprivate; 1294 return DVar; 1295 } 1296 } while (I != E && !isImplicitTaskingRegion(I->Directive)); 1297 DVar.CKind = 1298 (DVarTemp.CKind == OMPC_unknown) ? OMPC_firstprivate : OMPC_shared; 1299 return DVar; 1300 } 1301 } 1302 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 1303 // in a Construct, implicitly determined, p.3] 1304 // For constructs other than task, if no default clause is present, these 1305 // variables inherit their data-sharing attributes from the enclosing 1306 // context. 1307 return getDSA(++Iter, D); 1308 } 1309 1310 const Expr *DSAStackTy::addUniqueAligned(const ValueDecl *D, 1311 const Expr *NewDE) { 1312 assert(!isStackEmpty() && "Data sharing attributes stack is empty"); 1313 D = getCanonicalDecl(D); 1314 SharingMapTy &StackElem = getTopOfStack(); 1315 auto It = StackElem.AlignedMap.find(D); 1316 if (It == StackElem.AlignedMap.end()) { 1317 assert(NewDE && "Unexpected nullptr expr to be added into aligned map"); 1318 StackElem.AlignedMap[D] = NewDE; 1319 return nullptr; 1320 } 1321 assert(It->second && "Unexpected nullptr expr in the aligned map"); 1322 return It->second; 1323 } 1324 1325 const Expr *DSAStackTy::addUniqueNontemporal(const ValueDecl *D, 1326 const Expr *NewDE) { 1327 assert(!isStackEmpty() && "Data sharing attributes stack is empty"); 1328 D = getCanonicalDecl(D); 1329 SharingMapTy &StackElem = getTopOfStack(); 1330 auto It = StackElem.NontemporalMap.find(D); 1331 if (It == StackElem.NontemporalMap.end()) { 1332 assert(NewDE && "Unexpected nullptr expr to be added into aligned map"); 1333 StackElem.NontemporalMap[D] = NewDE; 1334 return nullptr; 1335 } 1336 assert(It->second && "Unexpected nullptr expr in the aligned map"); 1337 return It->second; 1338 } 1339 1340 void DSAStackTy::addLoopControlVariable(const ValueDecl *D, VarDecl *Capture) { 1341 assert(!isStackEmpty() && "Data-sharing attributes stack is empty"); 1342 D = getCanonicalDecl(D); 1343 SharingMapTy &StackElem = getTopOfStack(); 1344 StackElem.LCVMap.try_emplace( 1345 D, LCDeclInfo(StackElem.LCVMap.size() + 1, Capture)); 1346 } 1347 1348 const DSAStackTy::LCDeclInfo 1349 DSAStackTy::isLoopControlVariable(const ValueDecl *D) const { 1350 assert(!isStackEmpty() && "Data-sharing attributes stack is empty"); 1351 D = getCanonicalDecl(D); 1352 const SharingMapTy &StackElem = getTopOfStack(); 1353 auto It = StackElem.LCVMap.find(D); 1354 if (It != StackElem.LCVMap.end()) 1355 return It->second; 1356 return {0, nullptr}; 1357 } 1358 1359 const DSAStackTy::LCDeclInfo 1360 DSAStackTy::isLoopControlVariable(const ValueDecl *D, unsigned Level) const { 1361 assert(!isStackEmpty() && "Data-sharing attributes stack is empty"); 1362 D = getCanonicalDecl(D); 1363 for (unsigned I = Level + 1; I > 0; --I) { 1364 const SharingMapTy &StackElem = getStackElemAtLevel(I - 1); 1365 auto It = StackElem.LCVMap.find(D); 1366 if (It != StackElem.LCVMap.end()) 1367 return It->second; 1368 } 1369 return {0, nullptr}; 1370 } 1371 1372 const DSAStackTy::LCDeclInfo 1373 DSAStackTy::isParentLoopControlVariable(const ValueDecl *D) const { 1374 const SharingMapTy *Parent = getSecondOnStackOrNull(); 1375 assert(Parent && "Data-sharing attributes stack is empty"); 1376 D = getCanonicalDecl(D); 1377 auto It = Parent->LCVMap.find(D); 1378 if (It != Parent->LCVMap.end()) 1379 return It->second; 1380 return {0, nullptr}; 1381 } 1382 1383 const ValueDecl *DSAStackTy::getParentLoopControlVariable(unsigned I) const { 1384 const SharingMapTy *Parent = getSecondOnStackOrNull(); 1385 assert(Parent && "Data-sharing attributes stack is empty"); 1386 if (Parent->LCVMap.size() < I) 1387 return nullptr; 1388 for (const auto &Pair : Parent->LCVMap) 1389 if (Pair.second.first == I) 1390 return Pair.first; 1391 return nullptr; 1392 } 1393 1394 void DSAStackTy::addDSA(const ValueDecl *D, const Expr *E, OpenMPClauseKind A, 1395 DeclRefExpr *PrivateCopy, unsigned Modifier, 1396 bool AppliedToPointee) { 1397 D = getCanonicalDecl(D); 1398 if (A == OMPC_threadprivate) { 1399 DSAInfo &Data = Threadprivates[D]; 1400 Data.Attributes = A; 1401 Data.RefExpr.setPointer(E); 1402 Data.PrivateCopy = nullptr; 1403 Data.Modifier = Modifier; 1404 } else { 1405 DSAInfo &Data = getTopOfStack().SharingMap[D]; 1406 assert(Data.Attributes == OMPC_unknown || (A == Data.Attributes) || 1407 (A == OMPC_firstprivate && Data.Attributes == OMPC_lastprivate) || 1408 (A == OMPC_lastprivate && Data.Attributes == OMPC_firstprivate) || 1409 (isLoopControlVariable(D).first && A == OMPC_private)); 1410 Data.Modifier = Modifier; 1411 if (A == OMPC_lastprivate && Data.Attributes == OMPC_firstprivate) { 1412 Data.RefExpr.setInt(/*IntVal=*/true); 1413 return; 1414 } 1415 const bool IsLastprivate = 1416 A == OMPC_lastprivate || Data.Attributes == OMPC_lastprivate; 1417 Data.Attributes = A; 1418 Data.RefExpr.setPointerAndInt(E, IsLastprivate); 1419 Data.PrivateCopy = PrivateCopy; 1420 Data.AppliedToPointee = AppliedToPointee; 1421 if (PrivateCopy) { 1422 DSAInfo &Data = getTopOfStack().SharingMap[PrivateCopy->getDecl()]; 1423 Data.Modifier = Modifier; 1424 Data.Attributes = A; 1425 Data.RefExpr.setPointerAndInt(PrivateCopy, IsLastprivate); 1426 Data.PrivateCopy = nullptr; 1427 Data.AppliedToPointee = AppliedToPointee; 1428 } 1429 } 1430 } 1431 1432 /// Build a variable declaration for OpenMP loop iteration variable. 1433 static VarDecl *buildVarDecl(Sema &SemaRef, SourceLocation Loc, QualType Type, 1434 StringRef Name, const AttrVec *Attrs = nullptr, 1435 DeclRefExpr *OrigRef = nullptr) { 1436 DeclContext *DC = SemaRef.CurContext; 1437 IdentifierInfo *II = &SemaRef.PP.getIdentifierTable().get(Name); 1438 TypeSourceInfo *TInfo = SemaRef.Context.getTrivialTypeSourceInfo(Type, Loc); 1439 auto *Decl = 1440 VarDecl::Create(SemaRef.Context, DC, Loc, Loc, II, Type, TInfo, SC_None); 1441 if (Attrs) { 1442 for (specific_attr_iterator<AlignedAttr> I(Attrs->begin()), E(Attrs->end()); 1443 I != E; ++I) 1444 Decl->addAttr(*I); 1445 } 1446 Decl->setImplicit(); 1447 if (OrigRef) { 1448 Decl->addAttr( 1449 OMPReferencedVarAttr::CreateImplicit(SemaRef.Context, OrigRef)); 1450 } 1451 return Decl; 1452 } 1453 1454 static DeclRefExpr *buildDeclRefExpr(Sema &S, VarDecl *D, QualType Ty, 1455 SourceLocation Loc, 1456 bool RefersToCapture = false) { 1457 D->setReferenced(); 1458 D->markUsed(S.Context); 1459 return DeclRefExpr::Create(S.getASTContext(), NestedNameSpecifierLoc(), 1460 SourceLocation(), D, RefersToCapture, Loc, Ty, 1461 VK_LValue); 1462 } 1463 1464 void DSAStackTy::addTaskgroupReductionData(const ValueDecl *D, SourceRange SR, 1465 BinaryOperatorKind BOK) { 1466 D = getCanonicalDecl(D); 1467 assert(!isStackEmpty() && "Data-sharing attributes stack is empty"); 1468 assert( 1469 getTopOfStack().SharingMap[D].Attributes == OMPC_reduction && 1470 "Additional reduction info may be specified only for reduction items."); 1471 ReductionData &ReductionData = getTopOfStack().ReductionMap[D]; 1472 assert(ReductionData.ReductionRange.isInvalid() && 1473 (getTopOfStack().Directive == OMPD_taskgroup || 1474 ((isOpenMPParallelDirective(getTopOfStack().Directive) || 1475 isOpenMPWorksharingDirective(getTopOfStack().Directive)) && 1476 !isOpenMPSimdDirective(getTopOfStack().Directive))) && 1477 "Additional reduction info may be specified only once for reduction " 1478 "items."); 1479 ReductionData.set(BOK, SR); 1480 Expr *&TaskgroupReductionRef = getTopOfStack().TaskgroupReductionRef; 1481 if (!TaskgroupReductionRef) { 1482 VarDecl *VD = buildVarDecl(SemaRef, SR.getBegin(), 1483 SemaRef.Context.VoidPtrTy, ".task_red."); 1484 TaskgroupReductionRef = 1485 buildDeclRefExpr(SemaRef, VD, SemaRef.Context.VoidPtrTy, SR.getBegin()); 1486 } 1487 } 1488 1489 void DSAStackTy::addTaskgroupReductionData(const ValueDecl *D, SourceRange SR, 1490 const Expr *ReductionRef) { 1491 D = getCanonicalDecl(D); 1492 assert(!isStackEmpty() && "Data-sharing attributes stack is empty"); 1493 assert( 1494 getTopOfStack().SharingMap[D].Attributes == OMPC_reduction && 1495 "Additional reduction info may be specified only for reduction items."); 1496 ReductionData &ReductionData = getTopOfStack().ReductionMap[D]; 1497 assert(ReductionData.ReductionRange.isInvalid() && 1498 (getTopOfStack().Directive == OMPD_taskgroup || 1499 ((isOpenMPParallelDirective(getTopOfStack().Directive) || 1500 isOpenMPWorksharingDirective(getTopOfStack().Directive)) && 1501 !isOpenMPSimdDirective(getTopOfStack().Directive))) && 1502 "Additional reduction info may be specified only once for reduction " 1503 "items."); 1504 ReductionData.set(ReductionRef, SR); 1505 Expr *&TaskgroupReductionRef = getTopOfStack().TaskgroupReductionRef; 1506 if (!TaskgroupReductionRef) { 1507 VarDecl *VD = buildVarDecl(SemaRef, SR.getBegin(), 1508 SemaRef.Context.VoidPtrTy, ".task_red."); 1509 TaskgroupReductionRef = 1510 buildDeclRefExpr(SemaRef, VD, SemaRef.Context.VoidPtrTy, SR.getBegin()); 1511 } 1512 } 1513 1514 const DSAStackTy::DSAVarData DSAStackTy::getTopMostTaskgroupReductionData( 1515 const ValueDecl *D, SourceRange &SR, BinaryOperatorKind &BOK, 1516 Expr *&TaskgroupDescriptor) const { 1517 D = getCanonicalDecl(D); 1518 assert(!isStackEmpty() && "Data-sharing attributes stack is empty."); 1519 for (const_iterator I = begin() + 1, E = end(); I != E; ++I) { 1520 const DSAInfo &Data = I->SharingMap.lookup(D); 1521 if (Data.Attributes != OMPC_reduction || 1522 Data.Modifier != OMPC_REDUCTION_task) 1523 continue; 1524 const ReductionData &ReductionData = I->ReductionMap.lookup(D); 1525 if (!ReductionData.ReductionOp || 1526 ReductionData.ReductionOp.is<const Expr *>()) 1527 return DSAVarData(); 1528 SR = ReductionData.ReductionRange; 1529 BOK = ReductionData.ReductionOp.get<ReductionData::BOKPtrType>(); 1530 assert(I->TaskgroupReductionRef && "taskgroup reduction reference " 1531 "expression for the descriptor is not " 1532 "set."); 1533 TaskgroupDescriptor = I->TaskgroupReductionRef; 1534 return DSAVarData(I->Directive, OMPC_reduction, Data.RefExpr.getPointer(), 1535 Data.PrivateCopy, I->DefaultAttrLoc, OMPC_REDUCTION_task, 1536 /*AppliedToPointee=*/false); 1537 } 1538 return DSAVarData(); 1539 } 1540 1541 const DSAStackTy::DSAVarData DSAStackTy::getTopMostTaskgroupReductionData( 1542 const ValueDecl *D, SourceRange &SR, const Expr *&ReductionRef, 1543 Expr *&TaskgroupDescriptor) const { 1544 D = getCanonicalDecl(D); 1545 assert(!isStackEmpty() && "Data-sharing attributes stack is empty."); 1546 for (const_iterator I = begin() + 1, E = end(); I != E; ++I) { 1547 const DSAInfo &Data = I->SharingMap.lookup(D); 1548 if (Data.Attributes != OMPC_reduction || 1549 Data.Modifier != OMPC_REDUCTION_task) 1550 continue; 1551 const ReductionData &ReductionData = I->ReductionMap.lookup(D); 1552 if (!ReductionData.ReductionOp || 1553 !ReductionData.ReductionOp.is<const Expr *>()) 1554 return DSAVarData(); 1555 SR = ReductionData.ReductionRange; 1556 ReductionRef = ReductionData.ReductionOp.get<const Expr *>(); 1557 assert(I->TaskgroupReductionRef && "taskgroup reduction reference " 1558 "expression for the descriptor is not " 1559 "set."); 1560 TaskgroupDescriptor = I->TaskgroupReductionRef; 1561 return DSAVarData(I->Directive, OMPC_reduction, Data.RefExpr.getPointer(), 1562 Data.PrivateCopy, I->DefaultAttrLoc, OMPC_REDUCTION_task, 1563 /*AppliedToPointee=*/false); 1564 } 1565 return DSAVarData(); 1566 } 1567 1568 bool DSAStackTy::isOpenMPLocal(VarDecl *D, const_iterator I) const { 1569 D = D->getCanonicalDecl(); 1570 for (const_iterator E = end(); I != E; ++I) { 1571 if (isImplicitOrExplicitTaskingRegion(I->Directive) || 1572 isOpenMPTargetExecutionDirective(I->Directive)) { 1573 if (I->CurScope) { 1574 Scope *TopScope = I->CurScope->getParent(); 1575 Scope *CurScope = getCurScope(); 1576 while (CurScope && CurScope != TopScope && !CurScope->isDeclScope(D)) 1577 CurScope = CurScope->getParent(); 1578 return CurScope != TopScope; 1579 } 1580 for (DeclContext *DC = D->getDeclContext(); DC; DC = DC->getParent()) 1581 if (I->Context == DC) 1582 return true; 1583 return false; 1584 } 1585 } 1586 return false; 1587 } 1588 1589 static bool isConstNotMutableType(Sema &SemaRef, QualType Type, 1590 bool AcceptIfMutable = true, 1591 bool *IsClassType = nullptr) { 1592 ASTContext &Context = SemaRef.getASTContext(); 1593 Type = Type.getNonReferenceType().getCanonicalType(); 1594 bool IsConstant = Type.isConstant(Context); 1595 Type = Context.getBaseElementType(Type); 1596 const CXXRecordDecl *RD = AcceptIfMutable && SemaRef.getLangOpts().CPlusPlus 1597 ? Type->getAsCXXRecordDecl() 1598 : nullptr; 1599 if (const auto *CTSD = dyn_cast_or_null<ClassTemplateSpecializationDecl>(RD)) 1600 if (const ClassTemplateDecl *CTD = CTSD->getSpecializedTemplate()) 1601 RD = CTD->getTemplatedDecl(); 1602 if (IsClassType) 1603 *IsClassType = RD; 1604 return IsConstant && !(SemaRef.getLangOpts().CPlusPlus && RD && 1605 RD->hasDefinition() && RD->hasMutableFields()); 1606 } 1607 1608 static bool rejectConstNotMutableType(Sema &SemaRef, const ValueDecl *D, 1609 QualType Type, OpenMPClauseKind CKind, 1610 SourceLocation ELoc, 1611 bool AcceptIfMutable = true, 1612 bool ListItemNotVar = false) { 1613 ASTContext &Context = SemaRef.getASTContext(); 1614 bool IsClassType; 1615 if (isConstNotMutableType(SemaRef, Type, AcceptIfMutable, &IsClassType)) { 1616 unsigned Diag = ListItemNotVar ? diag::err_omp_const_list_item 1617 : IsClassType ? diag::err_omp_const_not_mutable_variable 1618 : diag::err_omp_const_variable; 1619 SemaRef.Diag(ELoc, Diag) << getOpenMPClauseName(CKind); 1620 if (!ListItemNotVar && D) { 1621 const VarDecl *VD = dyn_cast<VarDecl>(D); 1622 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) == 1623 VarDecl::DeclarationOnly; 1624 SemaRef.Diag(D->getLocation(), 1625 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 1626 << D; 1627 } 1628 return true; 1629 } 1630 return false; 1631 } 1632 1633 const DSAStackTy::DSAVarData DSAStackTy::getTopDSA(ValueDecl *D, 1634 bool FromParent) { 1635 D = getCanonicalDecl(D); 1636 DSAVarData DVar; 1637 1638 auto *VD = dyn_cast<VarDecl>(D); 1639 auto TI = Threadprivates.find(D); 1640 if (TI != Threadprivates.end()) { 1641 DVar.RefExpr = TI->getSecond().RefExpr.getPointer(); 1642 DVar.CKind = OMPC_threadprivate; 1643 DVar.Modifier = TI->getSecond().Modifier; 1644 return DVar; 1645 } 1646 if (VD && VD->hasAttr<OMPThreadPrivateDeclAttr>()) { 1647 DVar.RefExpr = buildDeclRefExpr( 1648 SemaRef, VD, D->getType().getNonReferenceType(), 1649 VD->getAttr<OMPThreadPrivateDeclAttr>()->getLocation()); 1650 DVar.CKind = OMPC_threadprivate; 1651 addDSA(D, DVar.RefExpr, OMPC_threadprivate); 1652 return DVar; 1653 } 1654 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 1655 // in a Construct, C/C++, predetermined, p.1] 1656 // Variables appearing in threadprivate directives are threadprivate. 1657 if ((VD && VD->getTLSKind() != VarDecl::TLS_None && 1658 !(VD->hasAttr<OMPThreadPrivateDeclAttr>() && 1659 SemaRef.getLangOpts().OpenMPUseTLS && 1660 SemaRef.getASTContext().getTargetInfo().isTLSSupported())) || 1661 (VD && VD->getStorageClass() == SC_Register && 1662 VD->hasAttr<AsmLabelAttr>() && !VD->isLocalVarDecl())) { 1663 DVar.RefExpr = buildDeclRefExpr( 1664 SemaRef, VD, D->getType().getNonReferenceType(), D->getLocation()); 1665 DVar.CKind = OMPC_threadprivate; 1666 addDSA(D, DVar.RefExpr, OMPC_threadprivate); 1667 return DVar; 1668 } 1669 if (SemaRef.getLangOpts().OpenMPCUDAMode && VD && 1670 VD->isLocalVarDeclOrParm() && !isStackEmpty() && 1671 !isLoopControlVariable(D).first) { 1672 const_iterator IterTarget = 1673 std::find_if(begin(), end(), [](const SharingMapTy &Data) { 1674 return isOpenMPTargetExecutionDirective(Data.Directive); 1675 }); 1676 if (IterTarget != end()) { 1677 const_iterator ParentIterTarget = IterTarget + 1; 1678 for (const_iterator Iter = begin(); Iter != ParentIterTarget; ++Iter) { 1679 if (isOpenMPLocal(VD, Iter)) { 1680 DVar.RefExpr = 1681 buildDeclRefExpr(SemaRef, VD, D->getType().getNonReferenceType(), 1682 D->getLocation()); 1683 DVar.CKind = OMPC_threadprivate; 1684 return DVar; 1685 } 1686 } 1687 if (!isClauseParsingMode() || IterTarget != begin()) { 1688 auto DSAIter = IterTarget->SharingMap.find(D); 1689 if (DSAIter != IterTarget->SharingMap.end() && 1690 isOpenMPPrivate(DSAIter->getSecond().Attributes)) { 1691 DVar.RefExpr = DSAIter->getSecond().RefExpr.getPointer(); 1692 DVar.CKind = OMPC_threadprivate; 1693 return DVar; 1694 } 1695 const_iterator End = end(); 1696 if (!SemaRef.isOpenMPCapturedByRef(D, 1697 std::distance(ParentIterTarget, End), 1698 /*OpenMPCaptureLevel=*/0)) { 1699 DVar.RefExpr = 1700 buildDeclRefExpr(SemaRef, VD, D->getType().getNonReferenceType(), 1701 IterTarget->ConstructLoc); 1702 DVar.CKind = OMPC_threadprivate; 1703 return DVar; 1704 } 1705 } 1706 } 1707 } 1708 1709 if (isStackEmpty()) 1710 // Not in OpenMP execution region and top scope was already checked. 1711 return DVar; 1712 1713 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 1714 // in a Construct, C/C++, predetermined, p.4] 1715 // Static data members are shared. 1716 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 1717 // in a Construct, C/C++, predetermined, p.7] 1718 // Variables with static storage duration that are declared in a scope 1719 // inside the construct are shared. 1720 if (VD && VD->isStaticDataMember()) { 1721 // Check for explicitly specified attributes. 1722 const_iterator I = begin(); 1723 const_iterator EndI = end(); 1724 if (FromParent && I != EndI) 1725 ++I; 1726 if (I != EndI) { 1727 auto It = I->SharingMap.find(D); 1728 if (It != I->SharingMap.end()) { 1729 const DSAInfo &Data = It->getSecond(); 1730 DVar.RefExpr = Data.RefExpr.getPointer(); 1731 DVar.PrivateCopy = Data.PrivateCopy; 1732 DVar.CKind = Data.Attributes; 1733 DVar.ImplicitDSALoc = I->DefaultAttrLoc; 1734 DVar.DKind = I->Directive; 1735 DVar.Modifier = Data.Modifier; 1736 DVar.AppliedToPointee = Data.AppliedToPointee; 1737 return DVar; 1738 } 1739 } 1740 1741 DVar.CKind = OMPC_shared; 1742 return DVar; 1743 } 1744 1745 auto &&MatchesAlways = [](OpenMPDirectiveKind) { return true; }; 1746 // The predetermined shared attribute for const-qualified types having no 1747 // mutable members was removed after OpenMP 3.1. 1748 if (SemaRef.LangOpts.OpenMP <= 31) { 1749 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 1750 // in a Construct, C/C++, predetermined, p.6] 1751 // Variables with const qualified type having no mutable member are 1752 // shared. 1753 if (isConstNotMutableType(SemaRef, D->getType())) { 1754 // Variables with const-qualified type having no mutable member may be 1755 // listed in a firstprivate clause, even if they are static data members. 1756 DSAVarData DVarTemp = hasInnermostDSA( 1757 D, 1758 [](OpenMPClauseKind C, bool) { 1759 return C == OMPC_firstprivate || C == OMPC_shared; 1760 }, 1761 MatchesAlways, FromParent); 1762 if (DVarTemp.CKind != OMPC_unknown && DVarTemp.RefExpr) 1763 return DVarTemp; 1764 1765 DVar.CKind = OMPC_shared; 1766 return DVar; 1767 } 1768 } 1769 1770 // Explicitly specified attributes and local variables with predetermined 1771 // attributes. 1772 const_iterator I = begin(); 1773 const_iterator EndI = end(); 1774 if (FromParent && I != EndI) 1775 ++I; 1776 if (I == EndI) 1777 return DVar; 1778 auto It = I->SharingMap.find(D); 1779 if (It != I->SharingMap.end()) { 1780 const DSAInfo &Data = It->getSecond(); 1781 DVar.RefExpr = Data.RefExpr.getPointer(); 1782 DVar.PrivateCopy = Data.PrivateCopy; 1783 DVar.CKind = Data.Attributes; 1784 DVar.ImplicitDSALoc = I->DefaultAttrLoc; 1785 DVar.DKind = I->Directive; 1786 DVar.Modifier = Data.Modifier; 1787 DVar.AppliedToPointee = Data.AppliedToPointee; 1788 } 1789 1790 return DVar; 1791 } 1792 1793 const DSAStackTy::DSAVarData DSAStackTy::getImplicitDSA(ValueDecl *D, 1794 bool FromParent) const { 1795 if (isStackEmpty()) { 1796 const_iterator I; 1797 return getDSA(I, D); 1798 } 1799 D = getCanonicalDecl(D); 1800 const_iterator StartI = begin(); 1801 const_iterator EndI = end(); 1802 if (FromParent && StartI != EndI) 1803 ++StartI; 1804 return getDSA(StartI, D); 1805 } 1806 1807 const DSAStackTy::DSAVarData DSAStackTy::getImplicitDSA(ValueDecl *D, 1808 unsigned Level) const { 1809 if (getStackSize() <= Level) 1810 return DSAVarData(); 1811 D = getCanonicalDecl(D); 1812 const_iterator StartI = std::next(begin(), getStackSize() - 1 - Level); 1813 return getDSA(StartI, D); 1814 } 1815 1816 const DSAStackTy::DSAVarData 1817 DSAStackTy::hasDSA(ValueDecl *D, 1818 const llvm::function_ref<bool(OpenMPClauseKind, bool)> CPred, 1819 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred, 1820 bool FromParent) const { 1821 if (isStackEmpty()) 1822 return {}; 1823 D = getCanonicalDecl(D); 1824 const_iterator I = begin(); 1825 const_iterator EndI = end(); 1826 if (FromParent && I != EndI) 1827 ++I; 1828 for (; I != EndI; ++I) { 1829 if (!DPred(I->Directive) && 1830 !isImplicitOrExplicitTaskingRegion(I->Directive)) 1831 continue; 1832 const_iterator NewI = I; 1833 DSAVarData DVar = getDSA(NewI, D); 1834 if (I == NewI && CPred(DVar.CKind, DVar.AppliedToPointee)) 1835 return DVar; 1836 } 1837 return {}; 1838 } 1839 1840 const DSAStackTy::DSAVarData DSAStackTy::hasInnermostDSA( 1841 ValueDecl *D, const llvm::function_ref<bool(OpenMPClauseKind, bool)> CPred, 1842 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred, 1843 bool FromParent) const { 1844 if (isStackEmpty()) 1845 return {}; 1846 D = getCanonicalDecl(D); 1847 const_iterator StartI = begin(); 1848 const_iterator EndI = end(); 1849 if (FromParent && StartI != EndI) 1850 ++StartI; 1851 if (StartI == EndI || !DPred(StartI->Directive)) 1852 return {}; 1853 const_iterator NewI = StartI; 1854 DSAVarData DVar = getDSA(NewI, D); 1855 return (NewI == StartI && CPred(DVar.CKind, DVar.AppliedToPointee)) 1856 ? DVar 1857 : DSAVarData(); 1858 } 1859 1860 bool DSAStackTy::hasExplicitDSA( 1861 const ValueDecl *D, 1862 const llvm::function_ref<bool(OpenMPClauseKind, bool)> CPred, 1863 unsigned Level, bool NotLastprivate) const { 1864 if (getStackSize() <= Level) 1865 return false; 1866 D = getCanonicalDecl(D); 1867 const SharingMapTy &StackElem = getStackElemAtLevel(Level); 1868 auto I = StackElem.SharingMap.find(D); 1869 if (I != StackElem.SharingMap.end() && I->getSecond().RefExpr.getPointer() && 1870 CPred(I->getSecond().Attributes, I->getSecond().AppliedToPointee) && 1871 (!NotLastprivate || !I->getSecond().RefExpr.getInt())) 1872 return true; 1873 // Check predetermined rules for the loop control variables. 1874 auto LI = StackElem.LCVMap.find(D); 1875 if (LI != StackElem.LCVMap.end()) 1876 return CPred(OMPC_private, /*AppliedToPointee=*/false); 1877 return false; 1878 } 1879 1880 bool DSAStackTy::hasExplicitDirective( 1881 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred, 1882 unsigned Level) const { 1883 if (getStackSize() <= Level) 1884 return false; 1885 const SharingMapTy &StackElem = getStackElemAtLevel(Level); 1886 return DPred(StackElem.Directive); 1887 } 1888 1889 bool DSAStackTy::hasDirective( 1890 const llvm::function_ref<bool(OpenMPDirectiveKind, 1891 const DeclarationNameInfo &, SourceLocation)> 1892 DPred, 1893 bool FromParent) const { 1894 // We look only in the enclosing region. 1895 size_t Skip = FromParent ? 2 : 1; 1896 for (const_iterator I = begin() + std::min(Skip, getStackSize()), E = end(); 1897 I != E; ++I) { 1898 if (DPred(I->Directive, I->DirectiveName, I->ConstructLoc)) 1899 return true; 1900 } 1901 return false; 1902 } 1903 1904 void Sema::InitDataSharingAttributesStack() { 1905 VarDataSharingAttributesStack = new DSAStackTy(*this); 1906 } 1907 1908 #define DSAStack static_cast<DSAStackTy *>(VarDataSharingAttributesStack) 1909 1910 void Sema::pushOpenMPFunctionRegion() { DSAStack->pushFunction(); } 1911 1912 void Sema::popOpenMPFunctionRegion(const FunctionScopeInfo *OldFSI) { 1913 DSAStack->popFunction(OldFSI); 1914 } 1915 1916 static bool isOpenMPDeviceDelayedContext(Sema &S) { 1917 assert(S.LangOpts.OpenMP && S.LangOpts.OpenMPIsDevice && 1918 "Expected OpenMP device compilation."); 1919 return !S.isInOpenMPTargetExecutionDirective(); 1920 } 1921 1922 namespace { 1923 /// Status of the function emission on the host/device. 1924 enum class FunctionEmissionStatus { 1925 Emitted, 1926 Discarded, 1927 Unknown, 1928 }; 1929 } // anonymous namespace 1930 1931 Sema::SemaDiagnosticBuilder Sema::diagIfOpenMPDeviceCode(SourceLocation Loc, 1932 unsigned DiagID, 1933 FunctionDecl *FD) { 1934 assert(LangOpts.OpenMP && LangOpts.OpenMPIsDevice && 1935 "Expected OpenMP device compilation."); 1936 1937 SemaDiagnosticBuilder::Kind Kind = SemaDiagnosticBuilder::K_Nop; 1938 if (FD) { 1939 FunctionEmissionStatus FES = getEmissionStatus(FD); 1940 switch (FES) { 1941 case FunctionEmissionStatus::Emitted: 1942 Kind = SemaDiagnosticBuilder::K_Immediate; 1943 break; 1944 case FunctionEmissionStatus::Unknown: 1945 // TODO: We should always delay diagnostics here in case a target 1946 // region is in a function we do not emit. However, as the 1947 // current diagnostics are associated with the function containing 1948 // the target region and we do not emit that one, we would miss out 1949 // on diagnostics for the target region itself. We need to anchor 1950 // the diagnostics with the new generated function *or* ensure we 1951 // emit diagnostics associated with the surrounding function. 1952 Kind = isOpenMPDeviceDelayedContext(*this) 1953 ? SemaDiagnosticBuilder::K_Deferred 1954 : SemaDiagnosticBuilder::K_Immediate; 1955 break; 1956 case FunctionEmissionStatus::TemplateDiscarded: 1957 case FunctionEmissionStatus::OMPDiscarded: 1958 Kind = SemaDiagnosticBuilder::K_Nop; 1959 break; 1960 case FunctionEmissionStatus::CUDADiscarded: 1961 llvm_unreachable("CUDADiscarded unexpected in OpenMP device compilation"); 1962 break; 1963 } 1964 } 1965 1966 return SemaDiagnosticBuilder(Kind, Loc, DiagID, FD, *this); 1967 } 1968 1969 Sema::SemaDiagnosticBuilder Sema::diagIfOpenMPHostCode(SourceLocation Loc, 1970 unsigned DiagID, 1971 FunctionDecl *FD) { 1972 assert(LangOpts.OpenMP && !LangOpts.OpenMPIsDevice && 1973 "Expected OpenMP host compilation."); 1974 1975 SemaDiagnosticBuilder::Kind Kind = SemaDiagnosticBuilder::K_Nop; 1976 if (FD) { 1977 FunctionEmissionStatus FES = getEmissionStatus(FD); 1978 switch (FES) { 1979 case FunctionEmissionStatus::Emitted: 1980 Kind = SemaDiagnosticBuilder::K_Immediate; 1981 break; 1982 case FunctionEmissionStatus::Unknown: 1983 Kind = SemaDiagnosticBuilder::K_Deferred; 1984 break; 1985 case FunctionEmissionStatus::TemplateDiscarded: 1986 case FunctionEmissionStatus::OMPDiscarded: 1987 case FunctionEmissionStatus::CUDADiscarded: 1988 Kind = SemaDiagnosticBuilder::K_Nop; 1989 break; 1990 } 1991 } 1992 1993 return SemaDiagnosticBuilder(Kind, Loc, DiagID, FD, *this); 1994 } 1995 1996 static OpenMPDefaultmapClauseKind 1997 getVariableCategoryFromDecl(const LangOptions &LO, const ValueDecl *VD) { 1998 if (LO.OpenMP <= 45) { 1999 if (VD->getType().getNonReferenceType()->isScalarType()) 2000 return OMPC_DEFAULTMAP_scalar; 2001 return OMPC_DEFAULTMAP_aggregate; 2002 } 2003 if (VD->getType().getNonReferenceType()->isAnyPointerType()) 2004 return OMPC_DEFAULTMAP_pointer; 2005 if (VD->getType().getNonReferenceType()->isScalarType()) 2006 return OMPC_DEFAULTMAP_scalar; 2007 return OMPC_DEFAULTMAP_aggregate; 2008 } 2009 2010 bool Sema::isOpenMPCapturedByRef(const ValueDecl *D, unsigned Level, 2011 unsigned OpenMPCaptureLevel) const { 2012 assert(LangOpts.OpenMP && "OpenMP is not allowed"); 2013 2014 ASTContext &Ctx = getASTContext(); 2015 bool IsByRef = true; 2016 2017 // Find the directive that is associated with the provided scope. 2018 D = cast<ValueDecl>(D->getCanonicalDecl()); 2019 QualType Ty = D->getType(); 2020 2021 bool IsVariableUsedInMapClause = false; 2022 if (DSAStack->hasExplicitDirective(isOpenMPTargetExecutionDirective, Level)) { 2023 // This table summarizes how a given variable should be passed to the device 2024 // given its type and the clauses where it appears. This table is based on 2025 // the description in OpenMP 4.5 [2.10.4, target Construct] and 2026 // OpenMP 4.5 [2.15.5, Data-mapping Attribute Rules and Clauses]. 2027 // 2028 // ========================================================================= 2029 // | type | defaultmap | pvt | first | is_device_ptr | map | res. | 2030 // | |(tofrom:scalar)| | pvt | | | | 2031 // ========================================================================= 2032 // | scl | | | | - | | bycopy| 2033 // | scl | | - | x | - | - | bycopy| 2034 // | scl | | x | - | - | - | null | 2035 // | scl | x | | | - | | byref | 2036 // | scl | x | - | x | - | - | bycopy| 2037 // | scl | x | x | - | - | - | null | 2038 // | scl | | - | - | - | x | byref | 2039 // | scl | x | - | - | - | x | byref | 2040 // 2041 // | agg | n.a. | | | - | | byref | 2042 // | agg | n.a. | - | x | - | - | byref | 2043 // | agg | n.a. | x | - | - | - | null | 2044 // | agg | n.a. | - | - | - | x | byref | 2045 // | agg | n.a. | - | - | - | x[] | byref | 2046 // 2047 // | ptr | n.a. | | | - | | bycopy| 2048 // | ptr | n.a. | - | x | - | - | bycopy| 2049 // | ptr | n.a. | x | - | - | - | null | 2050 // | ptr | n.a. | - | - | - | x | byref | 2051 // | ptr | n.a. | - | - | - | x[] | bycopy| 2052 // | ptr | n.a. | - | - | x | | bycopy| 2053 // | ptr | n.a. | - | - | x | x | bycopy| 2054 // | ptr | n.a. | - | - | x | x[] | bycopy| 2055 // ========================================================================= 2056 // Legend: 2057 // scl - scalar 2058 // ptr - pointer 2059 // agg - aggregate 2060 // x - applies 2061 // - - invalid in this combination 2062 // [] - mapped with an array section 2063 // byref - should be mapped by reference 2064 // byval - should be mapped by value 2065 // null - initialize a local variable to null on the device 2066 // 2067 // Observations: 2068 // - All scalar declarations that show up in a map clause have to be passed 2069 // by reference, because they may have been mapped in the enclosing data 2070 // environment. 2071 // - If the scalar value does not fit the size of uintptr, it has to be 2072 // passed by reference, regardless the result in the table above. 2073 // - For pointers mapped by value that have either an implicit map or an 2074 // array section, the runtime library may pass the NULL value to the 2075 // device instead of the value passed to it by the compiler. 2076 2077 if (Ty->isReferenceType()) 2078 Ty = Ty->castAs<ReferenceType>()->getPointeeType(); 2079 2080 // Locate map clauses and see if the variable being captured is referred to 2081 // in any of those clauses. Here we only care about variables, not fields, 2082 // because fields are part of aggregates. 2083 bool IsVariableAssociatedWithSection = false; 2084 2085 DSAStack->checkMappableExprComponentListsForDeclAtLevel( 2086 D, Level, 2087 [&IsVariableUsedInMapClause, &IsVariableAssociatedWithSection, 2088 D](OMPClauseMappableExprCommon::MappableExprComponentListRef 2089 MapExprComponents, 2090 OpenMPClauseKind WhereFoundClauseKind) { 2091 // Only the map clause information influences how a variable is 2092 // captured. E.g. is_device_ptr does not require changing the default 2093 // behavior. 2094 if (WhereFoundClauseKind != OMPC_map) 2095 return false; 2096 2097 auto EI = MapExprComponents.rbegin(); 2098 auto EE = MapExprComponents.rend(); 2099 2100 assert(EI != EE && "Invalid map expression!"); 2101 2102 if (isa<DeclRefExpr>(EI->getAssociatedExpression())) 2103 IsVariableUsedInMapClause |= EI->getAssociatedDeclaration() == D; 2104 2105 ++EI; 2106 if (EI == EE) 2107 return false; 2108 2109 if (isa<ArraySubscriptExpr>(EI->getAssociatedExpression()) || 2110 isa<OMPArraySectionExpr>(EI->getAssociatedExpression()) || 2111 isa<MemberExpr>(EI->getAssociatedExpression()) || 2112 isa<OMPArrayShapingExpr>(EI->getAssociatedExpression())) { 2113 IsVariableAssociatedWithSection = true; 2114 // There is nothing more we need to know about this variable. 2115 return true; 2116 } 2117 2118 // Keep looking for more map info. 2119 return false; 2120 }); 2121 2122 if (IsVariableUsedInMapClause) { 2123 // If variable is identified in a map clause it is always captured by 2124 // reference except if it is a pointer that is dereferenced somehow. 2125 IsByRef = !(Ty->isPointerType() && IsVariableAssociatedWithSection); 2126 } else { 2127 // By default, all the data that has a scalar type is mapped by copy 2128 // (except for reduction variables). 2129 // Defaultmap scalar is mutual exclusive to defaultmap pointer 2130 IsByRef = (DSAStack->isForceCaptureByReferenceInTargetExecutable() && 2131 !Ty->isAnyPointerType()) || 2132 !Ty->isScalarType() || 2133 DSAStack->isDefaultmapCapturedByRef( 2134 Level, getVariableCategoryFromDecl(LangOpts, D)) || 2135 DSAStack->hasExplicitDSA( 2136 D, 2137 [](OpenMPClauseKind K, bool AppliedToPointee) { 2138 return K == OMPC_reduction && !AppliedToPointee; 2139 }, 2140 Level); 2141 } 2142 } 2143 2144 if (IsByRef && Ty.getNonReferenceType()->isScalarType()) { 2145 IsByRef = 2146 ((IsVariableUsedInMapClause && 2147 DSAStack->getCaptureRegion(Level, OpenMPCaptureLevel) == 2148 OMPD_target) || 2149 !(DSAStack->hasExplicitDSA( 2150 D, 2151 [](OpenMPClauseKind K, bool AppliedToPointee) -> bool { 2152 return K == OMPC_firstprivate || 2153 (K == OMPC_reduction && AppliedToPointee); 2154 }, 2155 Level, /*NotLastprivate=*/true) || 2156 DSAStack->isUsesAllocatorsDecl(Level, D))) && 2157 // If the variable is artificial and must be captured by value - try to 2158 // capture by value. 2159 !(isa<OMPCapturedExprDecl>(D) && !D->hasAttr<OMPCaptureNoInitAttr>() && 2160 !cast<OMPCapturedExprDecl>(D)->getInit()->isGLValue()) && 2161 // If the variable is implicitly firstprivate and scalar - capture by 2162 // copy 2163 !((DSAStack->getDefaultDSA() == DSA_firstprivate || 2164 DSAStack->getDefaultDSA() == DSA_private) && 2165 !DSAStack->hasExplicitDSA( 2166 D, [](OpenMPClauseKind K, bool) { return K != OMPC_unknown; }, 2167 Level) && 2168 !DSAStack->isLoopControlVariable(D, Level).first); 2169 } 2170 2171 // When passing data by copy, we need to make sure it fits the uintptr size 2172 // and alignment, because the runtime library only deals with uintptr types. 2173 // If it does not fit the uintptr size, we need to pass the data by reference 2174 // instead. 2175 if (!IsByRef && 2176 (Ctx.getTypeSizeInChars(Ty) > 2177 Ctx.getTypeSizeInChars(Ctx.getUIntPtrType()) || 2178 Ctx.getDeclAlign(D) > Ctx.getTypeAlignInChars(Ctx.getUIntPtrType()))) { 2179 IsByRef = true; 2180 } 2181 2182 return IsByRef; 2183 } 2184 2185 unsigned Sema::getOpenMPNestingLevel() const { 2186 assert(getLangOpts().OpenMP); 2187 return DSAStack->getNestingLevel(); 2188 } 2189 2190 bool Sema::isInOpenMPTaskUntiedContext() const { 2191 return isOpenMPTaskingDirective(DSAStack->getCurrentDirective()) && 2192 DSAStack->isUntiedRegion(); 2193 } 2194 2195 bool Sema::isInOpenMPTargetExecutionDirective() const { 2196 return (isOpenMPTargetExecutionDirective(DSAStack->getCurrentDirective()) && 2197 !DSAStack->isClauseParsingMode()) || 2198 DSAStack->hasDirective( 2199 [](OpenMPDirectiveKind K, const DeclarationNameInfo &, 2200 SourceLocation) -> bool { 2201 return isOpenMPTargetExecutionDirective(K); 2202 }, 2203 false); 2204 } 2205 2206 VarDecl *Sema::isOpenMPCapturedDecl(ValueDecl *D, bool CheckScopeInfo, 2207 unsigned StopAt) { 2208 assert(LangOpts.OpenMP && "OpenMP is not allowed"); 2209 D = getCanonicalDecl(D); 2210 2211 auto *VD = dyn_cast<VarDecl>(D); 2212 // Do not capture constexpr variables. 2213 if (VD && VD->isConstexpr()) 2214 return nullptr; 2215 2216 // If we want to determine whether the variable should be captured from the 2217 // perspective of the current capturing scope, and we've already left all the 2218 // capturing scopes of the top directive on the stack, check from the 2219 // perspective of its parent directive (if any) instead. 2220 DSAStackTy::ParentDirectiveScope InParentDirectiveRAII( 2221 *DSAStack, CheckScopeInfo && DSAStack->isBodyComplete()); 2222 2223 // If we are attempting to capture a global variable in a directive with 2224 // 'target' we return true so that this global is also mapped to the device. 2225 // 2226 if (VD && !VD->hasLocalStorage() && 2227 (getCurCapturedRegion() || getCurBlock() || getCurLambda())) { 2228 if (isInOpenMPTargetExecutionDirective()) { 2229 DSAStackTy::DSAVarData DVarTop = 2230 DSAStack->getTopDSA(D, DSAStack->isClauseParsingMode()); 2231 if (DVarTop.CKind != OMPC_unknown && DVarTop.RefExpr) 2232 return VD; 2233 // If the declaration is enclosed in a 'declare target' directive, 2234 // then it should not be captured. 2235 // 2236 if (OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD)) 2237 return nullptr; 2238 CapturedRegionScopeInfo *CSI = nullptr; 2239 for (FunctionScopeInfo *FSI : llvm::drop_begin( 2240 llvm::reverse(FunctionScopes), 2241 CheckScopeInfo ? (FunctionScopes.size() - (StopAt + 1)) : 0)) { 2242 if (!isa<CapturingScopeInfo>(FSI)) 2243 return nullptr; 2244 if (auto *RSI = dyn_cast<CapturedRegionScopeInfo>(FSI)) 2245 if (RSI->CapRegionKind == CR_OpenMP) { 2246 CSI = RSI; 2247 break; 2248 } 2249 } 2250 assert(CSI && "Failed to find CapturedRegionScopeInfo"); 2251 SmallVector<OpenMPDirectiveKind, 4> Regions; 2252 getOpenMPCaptureRegions(Regions, 2253 DSAStack->getDirective(CSI->OpenMPLevel)); 2254 if (Regions[CSI->OpenMPCaptureLevel] != OMPD_task) 2255 return VD; 2256 } 2257 if (isInOpenMPDeclareTargetContext()) { 2258 // Try to mark variable as declare target if it is used in capturing 2259 // regions. 2260 if (LangOpts.OpenMP <= 45 && 2261 !OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD)) 2262 checkDeclIsAllowedInOpenMPTarget(nullptr, VD); 2263 return nullptr; 2264 } 2265 } 2266 2267 if (CheckScopeInfo) { 2268 bool OpenMPFound = false; 2269 for (unsigned I = StopAt + 1; I > 0; --I) { 2270 FunctionScopeInfo *FSI = FunctionScopes[I - 1]; 2271 if (!isa<CapturingScopeInfo>(FSI)) 2272 return nullptr; 2273 if (auto *RSI = dyn_cast<CapturedRegionScopeInfo>(FSI)) 2274 if (RSI->CapRegionKind == CR_OpenMP) { 2275 OpenMPFound = true; 2276 break; 2277 } 2278 } 2279 if (!OpenMPFound) 2280 return nullptr; 2281 } 2282 2283 if (DSAStack->getCurrentDirective() != OMPD_unknown && 2284 (!DSAStack->isClauseParsingMode() || 2285 DSAStack->getParentDirective() != OMPD_unknown)) { 2286 auto &&Info = DSAStack->isLoopControlVariable(D); 2287 if (Info.first || 2288 (VD && VD->hasLocalStorage() && 2289 isImplicitOrExplicitTaskingRegion(DSAStack->getCurrentDirective())) || 2290 (VD && DSAStack->isForceVarCapturing())) 2291 return VD ? VD : Info.second; 2292 DSAStackTy::DSAVarData DVarTop = 2293 DSAStack->getTopDSA(D, DSAStack->isClauseParsingMode()); 2294 if (DVarTop.CKind != OMPC_unknown && isOpenMPPrivate(DVarTop.CKind) && 2295 (!VD || VD->hasLocalStorage() || !DVarTop.AppliedToPointee)) 2296 return VD ? VD : cast<VarDecl>(DVarTop.PrivateCopy->getDecl()); 2297 // Threadprivate variables must not be captured. 2298 if (isOpenMPThreadPrivate(DVarTop.CKind)) 2299 return nullptr; 2300 // The variable is not private or it is the variable in the directive with 2301 // default(none) clause and not used in any clause. 2302 DSAStackTy::DSAVarData DVarPrivate = DSAStack->hasDSA( 2303 D, 2304 [](OpenMPClauseKind C, bool AppliedToPointee) { 2305 return isOpenMPPrivate(C) && !AppliedToPointee; 2306 }, 2307 [](OpenMPDirectiveKind) { return true; }, 2308 DSAStack->isClauseParsingMode()); 2309 // Global shared must not be captured. 2310 if (VD && !VD->hasLocalStorage() && DVarPrivate.CKind == OMPC_unknown && 2311 ((DSAStack->getDefaultDSA() != DSA_none && 2312 DSAStack->getDefaultDSA() != DSA_private && 2313 DSAStack->getDefaultDSA() != DSA_firstprivate) || 2314 DVarTop.CKind == OMPC_shared)) 2315 return nullptr; 2316 if (DVarPrivate.CKind != OMPC_unknown || 2317 (VD && (DSAStack->getDefaultDSA() == DSA_none || 2318 DSAStack->getDefaultDSA() == DSA_private || 2319 DSAStack->getDefaultDSA() == DSA_firstprivate))) 2320 return VD ? VD : cast<VarDecl>(DVarPrivate.PrivateCopy->getDecl()); 2321 } 2322 return nullptr; 2323 } 2324 2325 void Sema::adjustOpenMPTargetScopeIndex(unsigned &FunctionScopesIndex, 2326 unsigned Level) const { 2327 FunctionScopesIndex -= getOpenMPCaptureLevels(DSAStack->getDirective(Level)); 2328 } 2329 2330 void Sema::startOpenMPLoop() { 2331 assert(LangOpts.OpenMP && "OpenMP must be enabled."); 2332 if (isOpenMPLoopDirective(DSAStack->getCurrentDirective())) 2333 DSAStack->loopInit(); 2334 } 2335 2336 void Sema::startOpenMPCXXRangeFor() { 2337 assert(LangOpts.OpenMP && "OpenMP must be enabled."); 2338 if (isOpenMPLoopDirective(DSAStack->getCurrentDirective())) { 2339 DSAStack->resetPossibleLoopCounter(); 2340 DSAStack->loopStart(); 2341 } 2342 } 2343 2344 OpenMPClauseKind Sema::isOpenMPPrivateDecl(ValueDecl *D, unsigned Level, 2345 unsigned CapLevel) const { 2346 assert(LangOpts.OpenMP && "OpenMP is not allowed"); 2347 if (DSAStack->hasExplicitDirective(isOpenMPTaskingDirective, Level)) { 2348 bool IsTriviallyCopyable = 2349 D->getType().getNonReferenceType().isTriviallyCopyableType(Context) && 2350 !D->getType() 2351 .getNonReferenceType() 2352 .getCanonicalType() 2353 ->getAsCXXRecordDecl(); 2354 OpenMPDirectiveKind DKind = DSAStack->getDirective(Level); 2355 SmallVector<OpenMPDirectiveKind, 4> CaptureRegions; 2356 getOpenMPCaptureRegions(CaptureRegions, DKind); 2357 if (isOpenMPTaskingDirective(CaptureRegions[CapLevel]) && 2358 (IsTriviallyCopyable || 2359 !isOpenMPTaskLoopDirective(CaptureRegions[CapLevel]))) { 2360 if (DSAStack->hasExplicitDSA( 2361 D, 2362 [](OpenMPClauseKind K, bool) { return K == OMPC_firstprivate; }, 2363 Level, /*NotLastprivate=*/true)) 2364 return OMPC_firstprivate; 2365 DSAStackTy::DSAVarData DVar = DSAStack->getImplicitDSA(D, Level); 2366 if (DVar.CKind != OMPC_shared && 2367 !DSAStack->isLoopControlVariable(D, Level).first && !DVar.RefExpr) { 2368 DSAStack->addImplicitTaskFirstprivate(Level, D); 2369 return OMPC_firstprivate; 2370 } 2371 } 2372 } 2373 if (isOpenMPLoopDirective(DSAStack->getCurrentDirective())) { 2374 if (DSAStack->getAssociatedLoops() > 0 && !DSAStack->isLoopStarted()) { 2375 DSAStack->resetPossibleLoopCounter(D); 2376 DSAStack->loopStart(); 2377 return OMPC_private; 2378 } 2379 if ((DSAStack->getPossiblyLoopCunter() == D->getCanonicalDecl() || 2380 DSAStack->isLoopControlVariable(D).first) && 2381 !DSAStack->hasExplicitDSA( 2382 D, [](OpenMPClauseKind K, bool) { return K != OMPC_private; }, 2383 Level) && 2384 !isOpenMPSimdDirective(DSAStack->getCurrentDirective())) 2385 return OMPC_private; 2386 } 2387 if (const auto *VD = dyn_cast<VarDecl>(D)) { 2388 if (DSAStack->isThreadPrivate(const_cast<VarDecl *>(VD)) && 2389 DSAStack->isForceVarCapturing() && 2390 !DSAStack->hasExplicitDSA( 2391 D, [](OpenMPClauseKind K, bool) { return K == OMPC_copyin; }, 2392 Level)) 2393 return OMPC_private; 2394 } 2395 // User-defined allocators are private since they must be defined in the 2396 // context of target region. 2397 if (DSAStack->hasExplicitDirective(isOpenMPTargetExecutionDirective, Level) && 2398 DSAStack->isUsesAllocatorsDecl(Level, D).value_or( 2399 DSAStackTy::UsesAllocatorsDeclKind::AllocatorTrait) == 2400 DSAStackTy::UsesAllocatorsDeclKind::UserDefinedAllocator) 2401 return OMPC_private; 2402 return (DSAStack->hasExplicitDSA( 2403 D, [](OpenMPClauseKind K, bool) { return K == OMPC_private; }, 2404 Level) || 2405 (DSAStack->isClauseParsingMode() && 2406 DSAStack->getClauseParsingMode() == OMPC_private) || 2407 // Consider taskgroup reduction descriptor variable a private 2408 // to avoid possible capture in the region. 2409 (DSAStack->hasExplicitDirective( 2410 [](OpenMPDirectiveKind K) { 2411 return K == OMPD_taskgroup || 2412 ((isOpenMPParallelDirective(K) || 2413 isOpenMPWorksharingDirective(K)) && 2414 !isOpenMPSimdDirective(K)); 2415 }, 2416 Level) && 2417 DSAStack->isTaskgroupReductionRef(D, Level))) 2418 ? OMPC_private 2419 : OMPC_unknown; 2420 } 2421 2422 void Sema::setOpenMPCaptureKind(FieldDecl *FD, const ValueDecl *D, 2423 unsigned Level) { 2424 assert(LangOpts.OpenMP && "OpenMP is not allowed"); 2425 D = getCanonicalDecl(D); 2426 OpenMPClauseKind OMPC = OMPC_unknown; 2427 for (unsigned I = DSAStack->getNestingLevel() + 1; I > Level; --I) { 2428 const unsigned NewLevel = I - 1; 2429 if (DSAStack->hasExplicitDSA( 2430 D, 2431 [&OMPC](const OpenMPClauseKind K, bool AppliedToPointee) { 2432 if (isOpenMPPrivate(K) && !AppliedToPointee) { 2433 OMPC = K; 2434 return true; 2435 } 2436 return false; 2437 }, 2438 NewLevel)) 2439 break; 2440 if (DSAStack->checkMappableExprComponentListsForDeclAtLevel( 2441 D, NewLevel, 2442 [](OMPClauseMappableExprCommon::MappableExprComponentListRef, 2443 OpenMPClauseKind) { return true; })) { 2444 OMPC = OMPC_map; 2445 break; 2446 } 2447 if (DSAStack->hasExplicitDirective(isOpenMPTargetExecutionDirective, 2448 NewLevel)) { 2449 OMPC = OMPC_map; 2450 if (DSAStack->mustBeFirstprivateAtLevel( 2451 NewLevel, getVariableCategoryFromDecl(LangOpts, D))) 2452 OMPC = OMPC_firstprivate; 2453 break; 2454 } 2455 } 2456 if (OMPC != OMPC_unknown) 2457 FD->addAttr(OMPCaptureKindAttr::CreateImplicit(Context, unsigned(OMPC))); 2458 } 2459 2460 bool Sema::isOpenMPTargetCapturedDecl(const ValueDecl *D, unsigned Level, 2461 unsigned CaptureLevel) const { 2462 assert(LangOpts.OpenMP && "OpenMP is not allowed"); 2463 // Return true if the current level is no longer enclosed in a target region. 2464 2465 SmallVector<OpenMPDirectiveKind, 4> Regions; 2466 getOpenMPCaptureRegions(Regions, DSAStack->getDirective(Level)); 2467 const auto *VD = dyn_cast<VarDecl>(D); 2468 return VD && !VD->hasLocalStorage() && 2469 DSAStack->hasExplicitDirective(isOpenMPTargetExecutionDirective, 2470 Level) && 2471 Regions[CaptureLevel] != OMPD_task; 2472 } 2473 2474 bool Sema::isOpenMPGlobalCapturedDecl(ValueDecl *D, unsigned Level, 2475 unsigned CaptureLevel) const { 2476 assert(LangOpts.OpenMP && "OpenMP is not allowed"); 2477 // Return true if the current level is no longer enclosed in a target region. 2478 2479 if (const auto *VD = dyn_cast<VarDecl>(D)) { 2480 if (!VD->hasLocalStorage()) { 2481 if (isInOpenMPTargetExecutionDirective()) 2482 return true; 2483 DSAStackTy::DSAVarData TopDVar = 2484 DSAStack->getTopDSA(D, /*FromParent=*/false); 2485 unsigned NumLevels = 2486 getOpenMPCaptureLevels(DSAStack->getDirective(Level)); 2487 if (Level == 0) 2488 // non-file scope static variale with default(firstprivate) 2489 // should be gloabal captured. 2490 return (NumLevels == CaptureLevel + 1 && 2491 (TopDVar.CKind != OMPC_shared || 2492 DSAStack->getDefaultDSA() == DSA_firstprivate)); 2493 do { 2494 --Level; 2495 DSAStackTy::DSAVarData DVar = DSAStack->getImplicitDSA(D, Level); 2496 if (DVar.CKind != OMPC_shared) 2497 return true; 2498 } while (Level > 0); 2499 } 2500 } 2501 return true; 2502 } 2503 2504 void Sema::DestroyDataSharingAttributesStack() { delete DSAStack; } 2505 2506 void Sema::ActOnOpenMPBeginDeclareVariant(SourceLocation Loc, 2507 OMPTraitInfo &TI) { 2508 OMPDeclareVariantScopes.push_back(OMPDeclareVariantScope(TI)); 2509 } 2510 2511 void Sema::ActOnOpenMPEndDeclareVariant() { 2512 assert(isInOpenMPDeclareVariantScope() && 2513 "Not in OpenMP declare variant scope!"); 2514 2515 OMPDeclareVariantScopes.pop_back(); 2516 } 2517 2518 void Sema::finalizeOpenMPDelayedAnalysis(const FunctionDecl *Caller, 2519 const FunctionDecl *Callee, 2520 SourceLocation Loc) { 2521 assert(LangOpts.OpenMP && "Expected OpenMP compilation mode."); 2522 Optional<OMPDeclareTargetDeclAttr::DevTypeTy> DevTy = 2523 OMPDeclareTargetDeclAttr::getDeviceType(Caller->getMostRecentDecl()); 2524 // Ignore host functions during device analyzis. 2525 if (LangOpts.OpenMPIsDevice && 2526 (!DevTy || *DevTy == OMPDeclareTargetDeclAttr::DT_Host)) 2527 return; 2528 // Ignore nohost functions during host analyzis. 2529 if (!LangOpts.OpenMPIsDevice && DevTy && 2530 *DevTy == OMPDeclareTargetDeclAttr::DT_NoHost) 2531 return; 2532 const FunctionDecl *FD = Callee->getMostRecentDecl(); 2533 DevTy = OMPDeclareTargetDeclAttr::getDeviceType(FD); 2534 if (LangOpts.OpenMPIsDevice && DevTy && 2535 *DevTy == OMPDeclareTargetDeclAttr::DT_Host) { 2536 // Diagnose host function called during device codegen. 2537 StringRef HostDevTy = 2538 getOpenMPSimpleClauseTypeName(OMPC_device_type, OMPC_DEVICE_TYPE_host); 2539 Diag(Loc, diag::err_omp_wrong_device_function_call) << HostDevTy << 0; 2540 Diag(*OMPDeclareTargetDeclAttr::getLocation(FD), 2541 diag::note_omp_marked_device_type_here) 2542 << HostDevTy; 2543 return; 2544 } 2545 if (!LangOpts.OpenMPIsDevice && !LangOpts.OpenMPOffloadMandatory && DevTy && 2546 *DevTy == OMPDeclareTargetDeclAttr::DT_NoHost) { 2547 // Diagnose nohost function called during host codegen. 2548 StringRef NoHostDevTy = getOpenMPSimpleClauseTypeName( 2549 OMPC_device_type, OMPC_DEVICE_TYPE_nohost); 2550 Diag(Loc, diag::err_omp_wrong_device_function_call) << NoHostDevTy << 1; 2551 Diag(*OMPDeclareTargetDeclAttr::getLocation(FD), 2552 diag::note_omp_marked_device_type_here) 2553 << NoHostDevTy; 2554 } 2555 } 2556 2557 void Sema::StartOpenMPDSABlock(OpenMPDirectiveKind DKind, 2558 const DeclarationNameInfo &DirName, 2559 Scope *CurScope, SourceLocation Loc) { 2560 DSAStack->push(DKind, DirName, CurScope, Loc); 2561 PushExpressionEvaluationContext( 2562 ExpressionEvaluationContext::PotentiallyEvaluated); 2563 } 2564 2565 void Sema::StartOpenMPClause(OpenMPClauseKind K) { 2566 DSAStack->setClauseParsingMode(K); 2567 } 2568 2569 void Sema::EndOpenMPClause() { 2570 DSAStack->setClauseParsingMode(/*K=*/OMPC_unknown); 2571 CleanupVarDeclMarking(); 2572 } 2573 2574 static std::pair<ValueDecl *, bool> 2575 getPrivateItem(Sema &S, Expr *&RefExpr, SourceLocation &ELoc, 2576 SourceRange &ERange, bool AllowArraySection = false); 2577 2578 /// Check consistency of the reduction clauses. 2579 static void checkReductionClauses(Sema &S, DSAStackTy *Stack, 2580 ArrayRef<OMPClause *> Clauses) { 2581 bool InscanFound = false; 2582 SourceLocation InscanLoc; 2583 // OpenMP 5.0, 2.19.5.4 reduction Clause, Restrictions. 2584 // A reduction clause without the inscan reduction-modifier may not appear on 2585 // a construct on which a reduction clause with the inscan reduction-modifier 2586 // appears. 2587 for (OMPClause *C : Clauses) { 2588 if (C->getClauseKind() != OMPC_reduction) 2589 continue; 2590 auto *RC = cast<OMPReductionClause>(C); 2591 if (RC->getModifier() == OMPC_REDUCTION_inscan) { 2592 InscanFound = true; 2593 InscanLoc = RC->getModifierLoc(); 2594 continue; 2595 } 2596 if (RC->getModifier() == OMPC_REDUCTION_task) { 2597 // OpenMP 5.0, 2.19.5.4 reduction Clause. 2598 // A reduction clause with the task reduction-modifier may only appear on 2599 // a parallel construct, a worksharing construct or a combined or 2600 // composite construct for which any of the aforementioned constructs is a 2601 // constituent construct and simd or loop are not constituent constructs. 2602 OpenMPDirectiveKind CurDir = Stack->getCurrentDirective(); 2603 if (!(isOpenMPParallelDirective(CurDir) || 2604 isOpenMPWorksharingDirective(CurDir)) || 2605 isOpenMPSimdDirective(CurDir)) 2606 S.Diag(RC->getModifierLoc(), 2607 diag::err_omp_reduction_task_not_parallel_or_worksharing); 2608 continue; 2609 } 2610 } 2611 if (InscanFound) { 2612 for (OMPClause *C : Clauses) { 2613 if (C->getClauseKind() != OMPC_reduction) 2614 continue; 2615 auto *RC = cast<OMPReductionClause>(C); 2616 if (RC->getModifier() != OMPC_REDUCTION_inscan) { 2617 S.Diag(RC->getModifier() == OMPC_REDUCTION_unknown 2618 ? RC->getBeginLoc() 2619 : RC->getModifierLoc(), 2620 diag::err_omp_inscan_reduction_expected); 2621 S.Diag(InscanLoc, diag::note_omp_previous_inscan_reduction); 2622 continue; 2623 } 2624 for (Expr *Ref : RC->varlists()) { 2625 assert(Ref && "NULL expr in OpenMP nontemporal clause."); 2626 SourceLocation ELoc; 2627 SourceRange ERange; 2628 Expr *SimpleRefExpr = Ref; 2629 auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange, 2630 /*AllowArraySection=*/true); 2631 ValueDecl *D = Res.first; 2632 if (!D) 2633 continue; 2634 if (!Stack->isUsedInScanDirective(getCanonicalDecl(D))) { 2635 S.Diag(Ref->getExprLoc(), 2636 diag::err_omp_reduction_not_inclusive_exclusive) 2637 << Ref->getSourceRange(); 2638 } 2639 } 2640 } 2641 } 2642 } 2643 2644 static void checkAllocateClauses(Sema &S, DSAStackTy *Stack, 2645 ArrayRef<OMPClause *> Clauses); 2646 static DeclRefExpr *buildCapture(Sema &S, ValueDecl *D, Expr *CaptureExpr, 2647 bool WithInit); 2648 2649 static void reportOriginalDsa(Sema &SemaRef, const DSAStackTy *Stack, 2650 const ValueDecl *D, 2651 const DSAStackTy::DSAVarData &DVar, 2652 bool IsLoopIterVar = false); 2653 2654 void Sema::EndOpenMPDSABlock(Stmt *CurDirective) { 2655 // OpenMP [2.14.3.5, Restrictions, C/C++, p.1] 2656 // A variable of class type (or array thereof) that appears in a lastprivate 2657 // clause requires an accessible, unambiguous default constructor for the 2658 // class type, unless the list item is also specified in a firstprivate 2659 // clause. 2660 if (const auto *D = dyn_cast_or_null<OMPExecutableDirective>(CurDirective)) { 2661 for (OMPClause *C : D->clauses()) { 2662 if (auto *Clause = dyn_cast<OMPLastprivateClause>(C)) { 2663 SmallVector<Expr *, 8> PrivateCopies; 2664 for (Expr *DE : Clause->varlists()) { 2665 if (DE->isValueDependent() || DE->isTypeDependent()) { 2666 PrivateCopies.push_back(nullptr); 2667 continue; 2668 } 2669 auto *DRE = cast<DeclRefExpr>(DE->IgnoreParens()); 2670 auto *VD = cast<VarDecl>(DRE->getDecl()); 2671 QualType Type = VD->getType().getNonReferenceType(); 2672 const DSAStackTy::DSAVarData DVar = 2673 DSAStack->getTopDSA(VD, /*FromParent=*/false); 2674 if (DVar.CKind == OMPC_lastprivate) { 2675 // Generate helper private variable and initialize it with the 2676 // default value. The address of the original variable is replaced 2677 // by the address of the new private variable in CodeGen. This new 2678 // variable is not added to IdResolver, so the code in the OpenMP 2679 // region uses original variable for proper diagnostics. 2680 VarDecl *VDPrivate = buildVarDecl( 2681 *this, DE->getExprLoc(), Type.getUnqualifiedType(), 2682 VD->getName(), VD->hasAttrs() ? &VD->getAttrs() : nullptr, DRE); 2683 ActOnUninitializedDecl(VDPrivate); 2684 if (VDPrivate->isInvalidDecl()) { 2685 PrivateCopies.push_back(nullptr); 2686 continue; 2687 } 2688 PrivateCopies.push_back(buildDeclRefExpr( 2689 *this, VDPrivate, DE->getType(), DE->getExprLoc())); 2690 } else { 2691 // The variable is also a firstprivate, so initialization sequence 2692 // for private copy is generated already. 2693 PrivateCopies.push_back(nullptr); 2694 } 2695 } 2696 Clause->setPrivateCopies(PrivateCopies); 2697 continue; 2698 } 2699 // Finalize nontemporal clause by handling private copies, if any. 2700 if (auto *Clause = dyn_cast<OMPNontemporalClause>(C)) { 2701 SmallVector<Expr *, 8> PrivateRefs; 2702 for (Expr *RefExpr : Clause->varlists()) { 2703 assert(RefExpr && "NULL expr in OpenMP nontemporal clause."); 2704 SourceLocation ELoc; 2705 SourceRange ERange; 2706 Expr *SimpleRefExpr = RefExpr; 2707 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 2708 if (Res.second) 2709 // It will be analyzed later. 2710 PrivateRefs.push_back(RefExpr); 2711 ValueDecl *D = Res.first; 2712 if (!D) 2713 continue; 2714 2715 const DSAStackTy::DSAVarData DVar = 2716 DSAStack->getTopDSA(D, /*FromParent=*/false); 2717 PrivateRefs.push_back(DVar.PrivateCopy ? DVar.PrivateCopy 2718 : SimpleRefExpr); 2719 } 2720 Clause->setPrivateRefs(PrivateRefs); 2721 continue; 2722 } 2723 if (auto *Clause = dyn_cast<OMPUsesAllocatorsClause>(C)) { 2724 for (unsigned I = 0, E = Clause->getNumberOfAllocators(); I < E; ++I) { 2725 OMPUsesAllocatorsClause::Data D = Clause->getAllocatorData(I); 2726 auto *DRE = dyn_cast<DeclRefExpr>(D.Allocator->IgnoreParenImpCasts()); 2727 if (!DRE) 2728 continue; 2729 ValueDecl *VD = DRE->getDecl(); 2730 if (!VD || !isa<VarDecl>(VD)) 2731 continue; 2732 DSAStackTy::DSAVarData DVar = 2733 DSAStack->getTopDSA(VD, /*FromParent=*/false); 2734 // OpenMP [2.12.5, target Construct] 2735 // Memory allocators that appear in a uses_allocators clause cannot 2736 // appear in other data-sharing attribute clauses or data-mapping 2737 // attribute clauses in the same construct. 2738 Expr *MapExpr = nullptr; 2739 if (DVar.RefExpr || 2740 DSAStack->checkMappableExprComponentListsForDecl( 2741 VD, /*CurrentRegionOnly=*/true, 2742 [VD, &MapExpr]( 2743 OMPClauseMappableExprCommon::MappableExprComponentListRef 2744 MapExprComponents, 2745 OpenMPClauseKind C) { 2746 auto MI = MapExprComponents.rbegin(); 2747 auto ME = MapExprComponents.rend(); 2748 if (MI != ME && 2749 MI->getAssociatedDeclaration()->getCanonicalDecl() == 2750 VD->getCanonicalDecl()) { 2751 MapExpr = MI->getAssociatedExpression(); 2752 return true; 2753 } 2754 return false; 2755 })) { 2756 Diag(D.Allocator->getExprLoc(), 2757 diag::err_omp_allocator_used_in_clauses) 2758 << D.Allocator->getSourceRange(); 2759 if (DVar.RefExpr) 2760 reportOriginalDsa(*this, DSAStack, VD, DVar); 2761 else 2762 Diag(MapExpr->getExprLoc(), diag::note_used_here) 2763 << MapExpr->getSourceRange(); 2764 } 2765 } 2766 continue; 2767 } 2768 } 2769 // Check allocate clauses. 2770 if (!CurContext->isDependentContext()) 2771 checkAllocateClauses(*this, DSAStack, D->clauses()); 2772 checkReductionClauses(*this, DSAStack, D->clauses()); 2773 } 2774 2775 DSAStack->pop(); 2776 DiscardCleanupsInEvaluationContext(); 2777 PopExpressionEvaluationContext(); 2778 } 2779 2780 static bool FinishOpenMPLinearClause(OMPLinearClause &Clause, DeclRefExpr *IV, 2781 Expr *NumIterations, Sema &SemaRef, 2782 Scope *S, DSAStackTy *Stack); 2783 2784 namespace { 2785 2786 class VarDeclFilterCCC final : public CorrectionCandidateCallback { 2787 private: 2788 Sema &SemaRef; 2789 2790 public: 2791 explicit VarDeclFilterCCC(Sema &S) : SemaRef(S) {} 2792 bool ValidateCandidate(const TypoCorrection &Candidate) override { 2793 NamedDecl *ND = Candidate.getCorrectionDecl(); 2794 if (const auto *VD = dyn_cast_or_null<VarDecl>(ND)) { 2795 return VD->hasGlobalStorage() && 2796 SemaRef.isDeclInScope(ND, SemaRef.getCurLexicalContext(), 2797 SemaRef.getCurScope()); 2798 } 2799 return false; 2800 } 2801 2802 std::unique_ptr<CorrectionCandidateCallback> clone() override { 2803 return std::make_unique<VarDeclFilterCCC>(*this); 2804 } 2805 }; 2806 2807 class VarOrFuncDeclFilterCCC final : public CorrectionCandidateCallback { 2808 private: 2809 Sema &SemaRef; 2810 2811 public: 2812 explicit VarOrFuncDeclFilterCCC(Sema &S) : SemaRef(S) {} 2813 bool ValidateCandidate(const TypoCorrection &Candidate) override { 2814 NamedDecl *ND = Candidate.getCorrectionDecl(); 2815 if (ND && ((isa<VarDecl>(ND) && ND->getKind() == Decl::Var) || 2816 isa<FunctionDecl>(ND))) { 2817 return SemaRef.isDeclInScope(ND, SemaRef.getCurLexicalContext(), 2818 SemaRef.getCurScope()); 2819 } 2820 return false; 2821 } 2822 2823 std::unique_ptr<CorrectionCandidateCallback> clone() override { 2824 return std::make_unique<VarOrFuncDeclFilterCCC>(*this); 2825 } 2826 }; 2827 2828 } // namespace 2829 2830 ExprResult Sema::ActOnOpenMPIdExpression(Scope *CurScope, 2831 CXXScopeSpec &ScopeSpec, 2832 const DeclarationNameInfo &Id, 2833 OpenMPDirectiveKind Kind) { 2834 LookupResult Lookup(*this, Id, LookupOrdinaryName); 2835 LookupParsedName(Lookup, CurScope, &ScopeSpec, true); 2836 2837 if (Lookup.isAmbiguous()) 2838 return ExprError(); 2839 2840 VarDecl *VD; 2841 if (!Lookup.isSingleResult()) { 2842 VarDeclFilterCCC CCC(*this); 2843 if (TypoCorrection Corrected = 2844 CorrectTypo(Id, LookupOrdinaryName, CurScope, nullptr, CCC, 2845 CTK_ErrorRecovery)) { 2846 diagnoseTypo(Corrected, 2847 PDiag(Lookup.empty() 2848 ? diag::err_undeclared_var_use_suggest 2849 : diag::err_omp_expected_var_arg_suggest) 2850 << Id.getName()); 2851 VD = Corrected.getCorrectionDeclAs<VarDecl>(); 2852 } else { 2853 Diag(Id.getLoc(), Lookup.empty() ? diag::err_undeclared_var_use 2854 : diag::err_omp_expected_var_arg) 2855 << Id.getName(); 2856 return ExprError(); 2857 } 2858 } else if (!(VD = Lookup.getAsSingle<VarDecl>())) { 2859 Diag(Id.getLoc(), diag::err_omp_expected_var_arg) << Id.getName(); 2860 Diag(Lookup.getFoundDecl()->getLocation(), diag::note_declared_at); 2861 return ExprError(); 2862 } 2863 Lookup.suppressDiagnostics(); 2864 2865 // OpenMP [2.9.2, Syntax, C/C++] 2866 // Variables must be file-scope, namespace-scope, or static block-scope. 2867 if (Kind == OMPD_threadprivate && !VD->hasGlobalStorage()) { 2868 Diag(Id.getLoc(), diag::err_omp_global_var_arg) 2869 << getOpenMPDirectiveName(Kind) << !VD->isStaticLocal(); 2870 bool IsDecl = 2871 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 2872 Diag(VD->getLocation(), 2873 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 2874 << VD; 2875 return ExprError(); 2876 } 2877 2878 VarDecl *CanonicalVD = VD->getCanonicalDecl(); 2879 NamedDecl *ND = CanonicalVD; 2880 // OpenMP [2.9.2, Restrictions, C/C++, p.2] 2881 // A threadprivate directive for file-scope variables must appear outside 2882 // any definition or declaration. 2883 if (CanonicalVD->getDeclContext()->isTranslationUnit() && 2884 !getCurLexicalContext()->isTranslationUnit()) { 2885 Diag(Id.getLoc(), diag::err_omp_var_scope) 2886 << getOpenMPDirectiveName(Kind) << VD; 2887 bool IsDecl = 2888 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 2889 Diag(VD->getLocation(), 2890 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 2891 << VD; 2892 return ExprError(); 2893 } 2894 // OpenMP [2.9.2, Restrictions, C/C++, p.3] 2895 // A threadprivate directive for static class member variables must appear 2896 // in the class definition, in the same scope in which the member 2897 // variables are declared. 2898 if (CanonicalVD->isStaticDataMember() && 2899 !CanonicalVD->getDeclContext()->Equals(getCurLexicalContext())) { 2900 Diag(Id.getLoc(), diag::err_omp_var_scope) 2901 << getOpenMPDirectiveName(Kind) << VD; 2902 bool IsDecl = 2903 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 2904 Diag(VD->getLocation(), 2905 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 2906 << VD; 2907 return ExprError(); 2908 } 2909 // OpenMP [2.9.2, Restrictions, C/C++, p.4] 2910 // A threadprivate directive for namespace-scope variables must appear 2911 // outside any definition or declaration other than the namespace 2912 // definition itself. 2913 if (CanonicalVD->getDeclContext()->isNamespace() && 2914 (!getCurLexicalContext()->isFileContext() || 2915 !getCurLexicalContext()->Encloses(CanonicalVD->getDeclContext()))) { 2916 Diag(Id.getLoc(), diag::err_omp_var_scope) 2917 << getOpenMPDirectiveName(Kind) << VD; 2918 bool IsDecl = 2919 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 2920 Diag(VD->getLocation(), 2921 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 2922 << VD; 2923 return ExprError(); 2924 } 2925 // OpenMP [2.9.2, Restrictions, C/C++, p.6] 2926 // A threadprivate directive for static block-scope variables must appear 2927 // in the scope of the variable and not in a nested scope. 2928 if (CanonicalVD->isLocalVarDecl() && CurScope && 2929 !isDeclInScope(ND, getCurLexicalContext(), CurScope)) { 2930 Diag(Id.getLoc(), diag::err_omp_var_scope) 2931 << getOpenMPDirectiveName(Kind) << VD; 2932 bool IsDecl = 2933 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 2934 Diag(VD->getLocation(), 2935 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 2936 << VD; 2937 return ExprError(); 2938 } 2939 2940 // OpenMP [2.9.2, Restrictions, C/C++, p.2-6] 2941 // A threadprivate directive must lexically precede all references to any 2942 // of the variables in its list. 2943 if (Kind == OMPD_threadprivate && VD->isUsed() && 2944 !DSAStack->isThreadPrivate(VD)) { 2945 Diag(Id.getLoc(), diag::err_omp_var_used) 2946 << getOpenMPDirectiveName(Kind) << VD; 2947 return ExprError(); 2948 } 2949 2950 QualType ExprType = VD->getType().getNonReferenceType(); 2951 return DeclRefExpr::Create(Context, NestedNameSpecifierLoc(), 2952 SourceLocation(), VD, 2953 /*RefersToEnclosingVariableOrCapture=*/false, 2954 Id.getLoc(), ExprType, VK_LValue); 2955 } 2956 2957 Sema::DeclGroupPtrTy 2958 Sema::ActOnOpenMPThreadprivateDirective(SourceLocation Loc, 2959 ArrayRef<Expr *> VarList) { 2960 if (OMPThreadPrivateDecl *D = CheckOMPThreadPrivateDecl(Loc, VarList)) { 2961 CurContext->addDecl(D); 2962 return DeclGroupPtrTy::make(DeclGroupRef(D)); 2963 } 2964 return nullptr; 2965 } 2966 2967 namespace { 2968 class LocalVarRefChecker final 2969 : public ConstStmtVisitor<LocalVarRefChecker, bool> { 2970 Sema &SemaRef; 2971 2972 public: 2973 bool VisitDeclRefExpr(const DeclRefExpr *E) { 2974 if (const auto *VD = dyn_cast<VarDecl>(E->getDecl())) { 2975 if (VD->hasLocalStorage()) { 2976 SemaRef.Diag(E->getBeginLoc(), 2977 diag::err_omp_local_var_in_threadprivate_init) 2978 << E->getSourceRange(); 2979 SemaRef.Diag(VD->getLocation(), diag::note_defined_here) 2980 << VD << VD->getSourceRange(); 2981 return true; 2982 } 2983 } 2984 return false; 2985 } 2986 bool VisitStmt(const Stmt *S) { 2987 for (const Stmt *Child : S->children()) { 2988 if (Child && Visit(Child)) 2989 return true; 2990 } 2991 return false; 2992 } 2993 explicit LocalVarRefChecker(Sema &SemaRef) : SemaRef(SemaRef) {} 2994 }; 2995 } // namespace 2996 2997 OMPThreadPrivateDecl * 2998 Sema::CheckOMPThreadPrivateDecl(SourceLocation Loc, ArrayRef<Expr *> VarList) { 2999 SmallVector<Expr *, 8> Vars; 3000 for (Expr *RefExpr : VarList) { 3001 auto *DE = cast<DeclRefExpr>(RefExpr); 3002 auto *VD = cast<VarDecl>(DE->getDecl()); 3003 SourceLocation ILoc = DE->getExprLoc(); 3004 3005 // Mark variable as used. 3006 VD->setReferenced(); 3007 VD->markUsed(Context); 3008 3009 QualType QType = VD->getType(); 3010 if (QType->isDependentType() || QType->isInstantiationDependentType()) { 3011 // It will be analyzed later. 3012 Vars.push_back(DE); 3013 continue; 3014 } 3015 3016 // OpenMP [2.9.2, Restrictions, C/C++, p.10] 3017 // A threadprivate variable must not have an incomplete type. 3018 if (RequireCompleteType(ILoc, VD->getType(), 3019 diag::err_omp_threadprivate_incomplete_type)) { 3020 continue; 3021 } 3022 3023 // OpenMP [2.9.2, Restrictions, C/C++, p.10] 3024 // A threadprivate variable must not have a reference type. 3025 if (VD->getType()->isReferenceType()) { 3026 Diag(ILoc, diag::err_omp_ref_type_arg) 3027 << getOpenMPDirectiveName(OMPD_threadprivate) << VD->getType(); 3028 bool IsDecl = 3029 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 3030 Diag(VD->getLocation(), 3031 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 3032 << VD; 3033 continue; 3034 } 3035 3036 // Check if this is a TLS variable. If TLS is not being supported, produce 3037 // the corresponding diagnostic. 3038 if ((VD->getTLSKind() != VarDecl::TLS_None && 3039 !(VD->hasAttr<OMPThreadPrivateDeclAttr>() && 3040 getLangOpts().OpenMPUseTLS && 3041 getASTContext().getTargetInfo().isTLSSupported())) || 3042 (VD->getStorageClass() == SC_Register && VD->hasAttr<AsmLabelAttr>() && 3043 !VD->isLocalVarDecl())) { 3044 Diag(ILoc, diag::err_omp_var_thread_local) 3045 << VD << ((VD->getTLSKind() != VarDecl::TLS_None) ? 0 : 1); 3046 bool IsDecl = 3047 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 3048 Diag(VD->getLocation(), 3049 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 3050 << VD; 3051 continue; 3052 } 3053 3054 // Check if initial value of threadprivate variable reference variable with 3055 // local storage (it is not supported by runtime). 3056 if (const Expr *Init = VD->getAnyInitializer()) { 3057 LocalVarRefChecker Checker(*this); 3058 if (Checker.Visit(Init)) 3059 continue; 3060 } 3061 3062 Vars.push_back(RefExpr); 3063 DSAStack->addDSA(VD, DE, OMPC_threadprivate); 3064 VD->addAttr(OMPThreadPrivateDeclAttr::CreateImplicit( 3065 Context, SourceRange(Loc, Loc))); 3066 if (ASTMutationListener *ML = Context.getASTMutationListener()) 3067 ML->DeclarationMarkedOpenMPThreadPrivate(VD); 3068 } 3069 OMPThreadPrivateDecl *D = nullptr; 3070 if (!Vars.empty()) { 3071 D = OMPThreadPrivateDecl::Create(Context, getCurLexicalContext(), Loc, 3072 Vars); 3073 D->setAccess(AS_public); 3074 } 3075 return D; 3076 } 3077 3078 static OMPAllocateDeclAttr::AllocatorTypeTy 3079 getAllocatorKind(Sema &S, DSAStackTy *Stack, Expr *Allocator) { 3080 if (!Allocator) 3081 return OMPAllocateDeclAttr::OMPNullMemAlloc; 3082 if (Allocator->isTypeDependent() || Allocator->isValueDependent() || 3083 Allocator->isInstantiationDependent() || 3084 Allocator->containsUnexpandedParameterPack()) 3085 return OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; 3086 auto AllocatorKindRes = OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; 3087 const Expr *AE = Allocator->IgnoreParenImpCasts(); 3088 for (int I = 0; I < OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; ++I) { 3089 auto AllocatorKind = static_cast<OMPAllocateDeclAttr::AllocatorTypeTy>(I); 3090 const Expr *DefAllocator = Stack->getAllocator(AllocatorKind); 3091 llvm::FoldingSetNodeID AEId, DAEId; 3092 AE->Profile(AEId, S.getASTContext(), /*Canonical=*/true); 3093 DefAllocator->Profile(DAEId, S.getASTContext(), /*Canonical=*/true); 3094 if (AEId == DAEId) { 3095 AllocatorKindRes = AllocatorKind; 3096 break; 3097 } 3098 } 3099 return AllocatorKindRes; 3100 } 3101 3102 static bool checkPreviousOMPAllocateAttribute( 3103 Sema &S, DSAStackTy *Stack, Expr *RefExpr, VarDecl *VD, 3104 OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind, Expr *Allocator) { 3105 if (!VD->hasAttr<OMPAllocateDeclAttr>()) 3106 return false; 3107 const auto *A = VD->getAttr<OMPAllocateDeclAttr>(); 3108 Expr *PrevAllocator = A->getAllocator(); 3109 OMPAllocateDeclAttr::AllocatorTypeTy PrevAllocatorKind = 3110 getAllocatorKind(S, Stack, PrevAllocator); 3111 bool AllocatorsMatch = AllocatorKind == PrevAllocatorKind; 3112 if (AllocatorsMatch && 3113 AllocatorKind == OMPAllocateDeclAttr::OMPUserDefinedMemAlloc && 3114 Allocator && PrevAllocator) { 3115 const Expr *AE = Allocator->IgnoreParenImpCasts(); 3116 const Expr *PAE = PrevAllocator->IgnoreParenImpCasts(); 3117 llvm::FoldingSetNodeID AEId, PAEId; 3118 AE->Profile(AEId, S.Context, /*Canonical=*/true); 3119 PAE->Profile(PAEId, S.Context, /*Canonical=*/true); 3120 AllocatorsMatch = AEId == PAEId; 3121 } 3122 if (!AllocatorsMatch) { 3123 SmallString<256> AllocatorBuffer; 3124 llvm::raw_svector_ostream AllocatorStream(AllocatorBuffer); 3125 if (Allocator) 3126 Allocator->printPretty(AllocatorStream, nullptr, S.getPrintingPolicy()); 3127 SmallString<256> PrevAllocatorBuffer; 3128 llvm::raw_svector_ostream PrevAllocatorStream(PrevAllocatorBuffer); 3129 if (PrevAllocator) 3130 PrevAllocator->printPretty(PrevAllocatorStream, nullptr, 3131 S.getPrintingPolicy()); 3132 3133 SourceLocation AllocatorLoc = 3134 Allocator ? Allocator->getExprLoc() : RefExpr->getExprLoc(); 3135 SourceRange AllocatorRange = 3136 Allocator ? Allocator->getSourceRange() : RefExpr->getSourceRange(); 3137 SourceLocation PrevAllocatorLoc = 3138 PrevAllocator ? PrevAllocator->getExprLoc() : A->getLocation(); 3139 SourceRange PrevAllocatorRange = 3140 PrevAllocator ? PrevAllocator->getSourceRange() : A->getRange(); 3141 S.Diag(AllocatorLoc, diag::warn_omp_used_different_allocator) 3142 << (Allocator ? 1 : 0) << AllocatorStream.str() 3143 << (PrevAllocator ? 1 : 0) << PrevAllocatorStream.str() 3144 << AllocatorRange; 3145 S.Diag(PrevAllocatorLoc, diag::note_omp_previous_allocator) 3146 << PrevAllocatorRange; 3147 return true; 3148 } 3149 return false; 3150 } 3151 3152 static void 3153 applyOMPAllocateAttribute(Sema &S, VarDecl *VD, 3154 OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind, 3155 Expr *Allocator, Expr *Alignment, SourceRange SR) { 3156 if (VD->hasAttr<OMPAllocateDeclAttr>()) 3157 return; 3158 if (Alignment && 3159 (Alignment->isTypeDependent() || Alignment->isValueDependent() || 3160 Alignment->isInstantiationDependent() || 3161 Alignment->containsUnexpandedParameterPack())) 3162 // Apply later when we have a usable value. 3163 return; 3164 if (Allocator && 3165 (Allocator->isTypeDependent() || Allocator->isValueDependent() || 3166 Allocator->isInstantiationDependent() || 3167 Allocator->containsUnexpandedParameterPack())) 3168 return; 3169 auto *A = OMPAllocateDeclAttr::CreateImplicit(S.Context, AllocatorKind, 3170 Allocator, Alignment, SR); 3171 VD->addAttr(A); 3172 if (ASTMutationListener *ML = S.Context.getASTMutationListener()) 3173 ML->DeclarationMarkedOpenMPAllocate(VD, A); 3174 } 3175 3176 Sema::DeclGroupPtrTy 3177 Sema::ActOnOpenMPAllocateDirective(SourceLocation Loc, ArrayRef<Expr *> VarList, 3178 ArrayRef<OMPClause *> Clauses, 3179 DeclContext *Owner) { 3180 assert(Clauses.size() <= 2 && "Expected at most two clauses."); 3181 Expr *Alignment = nullptr; 3182 Expr *Allocator = nullptr; 3183 if (Clauses.empty()) { 3184 // OpenMP 5.0, 2.11.3 allocate Directive, Restrictions. 3185 // allocate directives that appear in a target region must specify an 3186 // allocator clause unless a requires directive with the dynamic_allocators 3187 // clause is present in the same compilation unit. 3188 if (LangOpts.OpenMPIsDevice && 3189 !DSAStack->hasRequiresDeclWithClause<OMPDynamicAllocatorsClause>()) 3190 targetDiag(Loc, diag::err_expected_allocator_clause); 3191 } else { 3192 for (const OMPClause *C : Clauses) 3193 if (const auto *AC = dyn_cast<OMPAllocatorClause>(C)) 3194 Allocator = AC->getAllocator(); 3195 else if (const auto *AC = dyn_cast<OMPAlignClause>(C)) 3196 Alignment = AC->getAlignment(); 3197 else 3198 llvm_unreachable("Unexpected clause on allocate directive"); 3199 } 3200 OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind = 3201 getAllocatorKind(*this, DSAStack, Allocator); 3202 SmallVector<Expr *, 8> Vars; 3203 for (Expr *RefExpr : VarList) { 3204 auto *DE = cast<DeclRefExpr>(RefExpr); 3205 auto *VD = cast<VarDecl>(DE->getDecl()); 3206 3207 // Check if this is a TLS variable or global register. 3208 if (VD->getTLSKind() != VarDecl::TLS_None || 3209 VD->hasAttr<OMPThreadPrivateDeclAttr>() || 3210 (VD->getStorageClass() == SC_Register && VD->hasAttr<AsmLabelAttr>() && 3211 !VD->isLocalVarDecl())) 3212 continue; 3213 3214 // If the used several times in the allocate directive, the same allocator 3215 // must be used. 3216 if (checkPreviousOMPAllocateAttribute(*this, DSAStack, RefExpr, VD, 3217 AllocatorKind, Allocator)) 3218 continue; 3219 3220 // OpenMP, 2.11.3 allocate Directive, Restrictions, C / C++ 3221 // If a list item has a static storage type, the allocator expression in the 3222 // allocator clause must be a constant expression that evaluates to one of 3223 // the predefined memory allocator values. 3224 if (Allocator && VD->hasGlobalStorage()) { 3225 if (AllocatorKind == OMPAllocateDeclAttr::OMPUserDefinedMemAlloc) { 3226 Diag(Allocator->getExprLoc(), 3227 diag::err_omp_expected_predefined_allocator) 3228 << Allocator->getSourceRange(); 3229 bool IsDecl = VD->isThisDeclarationADefinition(Context) == 3230 VarDecl::DeclarationOnly; 3231 Diag(VD->getLocation(), 3232 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 3233 << VD; 3234 continue; 3235 } 3236 } 3237 3238 Vars.push_back(RefExpr); 3239 applyOMPAllocateAttribute(*this, VD, AllocatorKind, Allocator, Alignment, 3240 DE->getSourceRange()); 3241 } 3242 if (Vars.empty()) 3243 return nullptr; 3244 if (!Owner) 3245 Owner = getCurLexicalContext(); 3246 auto *D = OMPAllocateDecl::Create(Context, Owner, Loc, Vars, Clauses); 3247 D->setAccess(AS_public); 3248 Owner->addDecl(D); 3249 return DeclGroupPtrTy::make(DeclGroupRef(D)); 3250 } 3251 3252 Sema::DeclGroupPtrTy 3253 Sema::ActOnOpenMPRequiresDirective(SourceLocation Loc, 3254 ArrayRef<OMPClause *> ClauseList) { 3255 OMPRequiresDecl *D = nullptr; 3256 if (!CurContext->isFileContext()) { 3257 Diag(Loc, diag::err_omp_invalid_scope) << "requires"; 3258 } else { 3259 D = CheckOMPRequiresDecl(Loc, ClauseList); 3260 if (D) { 3261 CurContext->addDecl(D); 3262 DSAStack->addRequiresDecl(D); 3263 } 3264 } 3265 return DeclGroupPtrTy::make(DeclGroupRef(D)); 3266 } 3267 3268 void Sema::ActOnOpenMPAssumesDirective(SourceLocation Loc, 3269 OpenMPDirectiveKind DKind, 3270 ArrayRef<std::string> Assumptions, 3271 bool SkippedClauses) { 3272 if (!SkippedClauses && Assumptions.empty()) 3273 Diag(Loc, diag::err_omp_no_clause_for_directive) 3274 << llvm::omp::getAllAssumeClauseOptions() 3275 << llvm::omp::getOpenMPDirectiveName(DKind); 3276 3277 auto *AA = AssumptionAttr::Create(Context, llvm::join(Assumptions, ","), Loc); 3278 if (DKind == llvm::omp::Directive::OMPD_begin_assumes) { 3279 OMPAssumeScoped.push_back(AA); 3280 return; 3281 } 3282 3283 // Global assumes without assumption clauses are ignored. 3284 if (Assumptions.empty()) 3285 return; 3286 3287 assert(DKind == llvm::omp::Directive::OMPD_assumes && 3288 "Unexpected omp assumption directive!"); 3289 OMPAssumeGlobal.push_back(AA); 3290 3291 // The OMPAssumeGlobal scope above will take care of new declarations but 3292 // we also want to apply the assumption to existing ones, e.g., to 3293 // declarations in included headers. To this end, we traverse all existing 3294 // declaration contexts and annotate function declarations here. 3295 SmallVector<DeclContext *, 8> DeclContexts; 3296 auto *Ctx = CurContext; 3297 while (Ctx->getLexicalParent()) 3298 Ctx = Ctx->getLexicalParent(); 3299 DeclContexts.push_back(Ctx); 3300 while (!DeclContexts.empty()) { 3301 DeclContext *DC = DeclContexts.pop_back_val(); 3302 for (auto *SubDC : DC->decls()) { 3303 if (SubDC->isInvalidDecl()) 3304 continue; 3305 if (auto *CTD = dyn_cast<ClassTemplateDecl>(SubDC)) { 3306 DeclContexts.push_back(CTD->getTemplatedDecl()); 3307 llvm::append_range(DeclContexts, CTD->specializations()); 3308 continue; 3309 } 3310 if (auto *DC = dyn_cast<DeclContext>(SubDC)) 3311 DeclContexts.push_back(DC); 3312 if (auto *F = dyn_cast<FunctionDecl>(SubDC)) { 3313 F->addAttr(AA); 3314 continue; 3315 } 3316 } 3317 } 3318 } 3319 3320 void Sema::ActOnOpenMPEndAssumesDirective() { 3321 assert(isInOpenMPAssumeScope() && "Not in OpenMP assumes scope!"); 3322 OMPAssumeScoped.pop_back(); 3323 } 3324 3325 OMPRequiresDecl *Sema::CheckOMPRequiresDecl(SourceLocation Loc, 3326 ArrayRef<OMPClause *> ClauseList) { 3327 /// For target specific clauses, the requires directive cannot be 3328 /// specified after the handling of any of the target regions in the 3329 /// current compilation unit. 3330 ArrayRef<SourceLocation> TargetLocations = 3331 DSAStack->getEncounteredTargetLocs(); 3332 SourceLocation AtomicLoc = DSAStack->getAtomicDirectiveLoc(); 3333 if (!TargetLocations.empty() || !AtomicLoc.isInvalid()) { 3334 for (const OMPClause *CNew : ClauseList) { 3335 // Check if any of the requires clauses affect target regions. 3336 if (isa<OMPUnifiedSharedMemoryClause>(CNew) || 3337 isa<OMPUnifiedAddressClause>(CNew) || 3338 isa<OMPReverseOffloadClause>(CNew) || 3339 isa<OMPDynamicAllocatorsClause>(CNew)) { 3340 Diag(Loc, diag::err_omp_directive_before_requires) 3341 << "target" << getOpenMPClauseName(CNew->getClauseKind()); 3342 for (SourceLocation TargetLoc : TargetLocations) { 3343 Diag(TargetLoc, diag::note_omp_requires_encountered_directive) 3344 << "target"; 3345 } 3346 } else if (!AtomicLoc.isInvalid() && 3347 isa<OMPAtomicDefaultMemOrderClause>(CNew)) { 3348 Diag(Loc, diag::err_omp_directive_before_requires) 3349 << "atomic" << getOpenMPClauseName(CNew->getClauseKind()); 3350 Diag(AtomicLoc, diag::note_omp_requires_encountered_directive) 3351 << "atomic"; 3352 } 3353 } 3354 } 3355 3356 if (!DSAStack->hasDuplicateRequiresClause(ClauseList)) 3357 return OMPRequiresDecl::Create(Context, getCurLexicalContext(), Loc, 3358 ClauseList); 3359 return nullptr; 3360 } 3361 3362 static void reportOriginalDsa(Sema &SemaRef, const DSAStackTy *Stack, 3363 const ValueDecl *D, 3364 const DSAStackTy::DSAVarData &DVar, 3365 bool IsLoopIterVar) { 3366 if (DVar.RefExpr) { 3367 SemaRef.Diag(DVar.RefExpr->getExprLoc(), diag::note_omp_explicit_dsa) 3368 << getOpenMPClauseName(DVar.CKind); 3369 return; 3370 } 3371 enum { 3372 PDSA_StaticMemberShared, 3373 PDSA_StaticLocalVarShared, 3374 PDSA_LoopIterVarPrivate, 3375 PDSA_LoopIterVarLinear, 3376 PDSA_LoopIterVarLastprivate, 3377 PDSA_ConstVarShared, 3378 PDSA_GlobalVarShared, 3379 PDSA_TaskVarFirstprivate, 3380 PDSA_LocalVarPrivate, 3381 PDSA_Implicit 3382 } Reason = PDSA_Implicit; 3383 bool ReportHint = false; 3384 auto ReportLoc = D->getLocation(); 3385 auto *VD = dyn_cast<VarDecl>(D); 3386 if (IsLoopIterVar) { 3387 if (DVar.CKind == OMPC_private) 3388 Reason = PDSA_LoopIterVarPrivate; 3389 else if (DVar.CKind == OMPC_lastprivate) 3390 Reason = PDSA_LoopIterVarLastprivate; 3391 else 3392 Reason = PDSA_LoopIterVarLinear; 3393 } else if (isOpenMPTaskingDirective(DVar.DKind) && 3394 DVar.CKind == OMPC_firstprivate) { 3395 Reason = PDSA_TaskVarFirstprivate; 3396 ReportLoc = DVar.ImplicitDSALoc; 3397 } else if (VD && VD->isStaticLocal()) 3398 Reason = PDSA_StaticLocalVarShared; 3399 else if (VD && VD->isStaticDataMember()) 3400 Reason = PDSA_StaticMemberShared; 3401 else if (VD && VD->isFileVarDecl()) 3402 Reason = PDSA_GlobalVarShared; 3403 else if (D->getType().isConstant(SemaRef.getASTContext())) 3404 Reason = PDSA_ConstVarShared; 3405 else if (VD && VD->isLocalVarDecl() && DVar.CKind == OMPC_private) { 3406 ReportHint = true; 3407 Reason = PDSA_LocalVarPrivate; 3408 } 3409 if (Reason != PDSA_Implicit) { 3410 SemaRef.Diag(ReportLoc, diag::note_omp_predetermined_dsa) 3411 << Reason << ReportHint 3412 << getOpenMPDirectiveName(Stack->getCurrentDirective()); 3413 } else if (DVar.ImplicitDSALoc.isValid()) { 3414 SemaRef.Diag(DVar.ImplicitDSALoc, diag::note_omp_implicit_dsa) 3415 << getOpenMPClauseName(DVar.CKind); 3416 } 3417 } 3418 3419 static OpenMPMapClauseKind 3420 getMapClauseKindFromModifier(OpenMPDefaultmapClauseModifier M, 3421 bool IsAggregateOrDeclareTarget) { 3422 OpenMPMapClauseKind Kind = OMPC_MAP_unknown; 3423 switch (M) { 3424 case OMPC_DEFAULTMAP_MODIFIER_alloc: 3425 Kind = OMPC_MAP_alloc; 3426 break; 3427 case OMPC_DEFAULTMAP_MODIFIER_to: 3428 Kind = OMPC_MAP_to; 3429 break; 3430 case OMPC_DEFAULTMAP_MODIFIER_from: 3431 Kind = OMPC_MAP_from; 3432 break; 3433 case OMPC_DEFAULTMAP_MODIFIER_tofrom: 3434 Kind = OMPC_MAP_tofrom; 3435 break; 3436 case OMPC_DEFAULTMAP_MODIFIER_present: 3437 // OpenMP 5.1 [2.21.7.3] defaultmap clause, Description] 3438 // If implicit-behavior is present, each variable referenced in the 3439 // construct in the category specified by variable-category is treated as if 3440 // it had been listed in a map clause with the map-type of alloc and 3441 // map-type-modifier of present. 3442 Kind = OMPC_MAP_alloc; 3443 break; 3444 case OMPC_DEFAULTMAP_MODIFIER_firstprivate: 3445 case OMPC_DEFAULTMAP_MODIFIER_last: 3446 llvm_unreachable("Unexpected defaultmap implicit behavior"); 3447 case OMPC_DEFAULTMAP_MODIFIER_none: 3448 case OMPC_DEFAULTMAP_MODIFIER_default: 3449 case OMPC_DEFAULTMAP_MODIFIER_unknown: 3450 // IsAggregateOrDeclareTarget could be true if: 3451 // 1. the implicit behavior for aggregate is tofrom 3452 // 2. it's a declare target link 3453 if (IsAggregateOrDeclareTarget) { 3454 Kind = OMPC_MAP_tofrom; 3455 break; 3456 } 3457 llvm_unreachable("Unexpected defaultmap implicit behavior"); 3458 } 3459 assert(Kind != OMPC_MAP_unknown && "Expect map kind to be known"); 3460 return Kind; 3461 } 3462 3463 namespace { 3464 class DSAAttrChecker final : public StmtVisitor<DSAAttrChecker, void> { 3465 DSAStackTy *Stack; 3466 Sema &SemaRef; 3467 bool ErrorFound = false; 3468 bool TryCaptureCXXThisMembers = false; 3469 CapturedStmt *CS = nullptr; 3470 const static unsigned DefaultmapKindNum = OMPC_DEFAULTMAP_pointer + 1; 3471 llvm::SmallVector<Expr *, 4> ImplicitFirstprivate; 3472 llvm::SmallVector<Expr *, 4> ImplicitPrivate; 3473 llvm::SmallVector<Expr *, 4> ImplicitMap[DefaultmapKindNum][OMPC_MAP_delete]; 3474 llvm::SmallVector<OpenMPMapModifierKind, NumberOfOMPMapClauseModifiers> 3475 ImplicitMapModifier[DefaultmapKindNum]; 3476 Sema::VarsWithInheritedDSAType VarsWithInheritedDSA; 3477 llvm::SmallDenseSet<const ValueDecl *, 4> ImplicitDeclarations; 3478 3479 void VisitSubCaptures(OMPExecutableDirective *S) { 3480 // Check implicitly captured variables. 3481 if (!S->hasAssociatedStmt() || !S->getAssociatedStmt()) 3482 return; 3483 if (S->getDirectiveKind() == OMPD_atomic || 3484 S->getDirectiveKind() == OMPD_critical || 3485 S->getDirectiveKind() == OMPD_section || 3486 S->getDirectiveKind() == OMPD_master || 3487 S->getDirectiveKind() == OMPD_masked || 3488 isOpenMPLoopTransformationDirective(S->getDirectiveKind())) { 3489 Visit(S->getAssociatedStmt()); 3490 return; 3491 } 3492 visitSubCaptures(S->getInnermostCapturedStmt()); 3493 // Try to capture inner this->member references to generate correct mappings 3494 // and diagnostics. 3495 if (TryCaptureCXXThisMembers || 3496 (isOpenMPTargetExecutionDirective(Stack->getCurrentDirective()) && 3497 llvm::any_of(S->getInnermostCapturedStmt()->captures(), 3498 [](const CapturedStmt::Capture &C) { 3499 return C.capturesThis(); 3500 }))) { 3501 bool SavedTryCaptureCXXThisMembers = TryCaptureCXXThisMembers; 3502 TryCaptureCXXThisMembers = true; 3503 Visit(S->getInnermostCapturedStmt()->getCapturedStmt()); 3504 TryCaptureCXXThisMembers = SavedTryCaptureCXXThisMembers; 3505 } 3506 // In tasks firstprivates are not captured anymore, need to analyze them 3507 // explicitly. 3508 if (isOpenMPTaskingDirective(S->getDirectiveKind()) && 3509 !isOpenMPTaskLoopDirective(S->getDirectiveKind())) { 3510 for (OMPClause *C : S->clauses()) 3511 if (auto *FC = dyn_cast<OMPFirstprivateClause>(C)) { 3512 for (Expr *Ref : FC->varlists()) 3513 Visit(Ref); 3514 } 3515 } 3516 } 3517 3518 public: 3519 void VisitDeclRefExpr(DeclRefExpr *E) { 3520 if (TryCaptureCXXThisMembers || E->isTypeDependent() || 3521 E->isValueDependent() || E->containsUnexpandedParameterPack() || 3522 E->isInstantiationDependent()) 3523 return; 3524 if (auto *VD = dyn_cast<VarDecl>(E->getDecl())) { 3525 // Check the datasharing rules for the expressions in the clauses. 3526 if (!CS || (isa<OMPCapturedExprDecl>(VD) && !CS->capturesVariable(VD) && 3527 !Stack->getTopDSA(VD, /*FromParent=*/false).RefExpr)) { 3528 if (auto *CED = dyn_cast<OMPCapturedExprDecl>(VD)) 3529 if (!CED->hasAttr<OMPCaptureNoInitAttr>()) { 3530 Visit(CED->getInit()); 3531 return; 3532 } 3533 } else if (VD->isImplicit() || isa<OMPCapturedExprDecl>(VD)) 3534 // Do not analyze internal variables and do not enclose them into 3535 // implicit clauses. 3536 return; 3537 VD = VD->getCanonicalDecl(); 3538 // Skip internally declared variables. 3539 if (VD->hasLocalStorage() && CS && !CS->capturesVariable(VD) && 3540 !Stack->isImplicitTaskFirstprivate(VD)) 3541 return; 3542 // Skip allocators in uses_allocators clauses. 3543 if (Stack->isUsesAllocatorsDecl(VD)) 3544 return; 3545 3546 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(VD, /*FromParent=*/false); 3547 // Check if the variable has explicit DSA set and stop analysis if it so. 3548 if (DVar.RefExpr || !ImplicitDeclarations.insert(VD).second) 3549 return; 3550 3551 // Skip internally declared static variables. 3552 llvm::Optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res = 3553 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD); 3554 if (VD->hasGlobalStorage() && CS && !CS->capturesVariable(VD) && 3555 (Stack->hasRequiresDeclWithClause<OMPUnifiedSharedMemoryClause>() || 3556 !Res || *Res != OMPDeclareTargetDeclAttr::MT_Link) && 3557 !Stack->isImplicitTaskFirstprivate(VD)) 3558 return; 3559 3560 SourceLocation ELoc = E->getExprLoc(); 3561 OpenMPDirectiveKind DKind = Stack->getCurrentDirective(); 3562 // The default(none) clause requires that each variable that is referenced 3563 // in the construct, and does not have a predetermined data-sharing 3564 // attribute, must have its data-sharing attribute explicitly determined 3565 // by being listed in a data-sharing attribute clause. 3566 if (DVar.CKind == OMPC_unknown && 3567 (Stack->getDefaultDSA() == DSA_none || 3568 Stack->getDefaultDSA() == DSA_private || 3569 Stack->getDefaultDSA() == DSA_firstprivate) && 3570 isImplicitOrExplicitTaskingRegion(DKind) && 3571 VarsWithInheritedDSA.count(VD) == 0) { 3572 bool InheritedDSA = Stack->getDefaultDSA() == DSA_none; 3573 if (!InheritedDSA && (Stack->getDefaultDSA() == DSA_firstprivate || 3574 Stack->getDefaultDSA() == DSA_private)) { 3575 DSAStackTy::DSAVarData DVar = 3576 Stack->getImplicitDSA(VD, /*FromParent=*/false); 3577 InheritedDSA = DVar.CKind == OMPC_unknown; 3578 } 3579 if (InheritedDSA) 3580 VarsWithInheritedDSA[VD] = E; 3581 if (Stack->getDefaultDSA() == DSA_none) 3582 return; 3583 } 3584 3585 // OpenMP 5.0 [2.19.7.2, defaultmap clause, Description] 3586 // If implicit-behavior is none, each variable referenced in the 3587 // construct that does not have a predetermined data-sharing attribute 3588 // and does not appear in a to or link clause on a declare target 3589 // directive must be listed in a data-mapping attribute clause, a 3590 // data-sharing attribute clause (including a data-sharing attribute 3591 // clause on a combined construct where target. is one of the 3592 // constituent constructs), or an is_device_ptr clause. 3593 OpenMPDefaultmapClauseKind ClauseKind = 3594 getVariableCategoryFromDecl(SemaRef.getLangOpts(), VD); 3595 if (SemaRef.getLangOpts().OpenMP >= 50) { 3596 bool IsModifierNone = Stack->getDefaultmapModifier(ClauseKind) == 3597 OMPC_DEFAULTMAP_MODIFIER_none; 3598 if (DVar.CKind == OMPC_unknown && IsModifierNone && 3599 VarsWithInheritedDSA.count(VD) == 0 && !Res) { 3600 // Only check for data-mapping attribute and is_device_ptr here 3601 // since we have already make sure that the declaration does not 3602 // have a data-sharing attribute above 3603 if (!Stack->checkMappableExprComponentListsForDecl( 3604 VD, /*CurrentRegionOnly=*/true, 3605 [VD](OMPClauseMappableExprCommon::MappableExprComponentListRef 3606 MapExprComponents, 3607 OpenMPClauseKind) { 3608 auto MI = MapExprComponents.rbegin(); 3609 auto ME = MapExprComponents.rend(); 3610 return MI != ME && MI->getAssociatedDeclaration() == VD; 3611 })) { 3612 VarsWithInheritedDSA[VD] = E; 3613 return; 3614 } 3615 } 3616 } 3617 if (SemaRef.getLangOpts().OpenMP > 50) { 3618 bool IsModifierPresent = Stack->getDefaultmapModifier(ClauseKind) == 3619 OMPC_DEFAULTMAP_MODIFIER_present; 3620 if (IsModifierPresent) { 3621 if (llvm::find(ImplicitMapModifier[ClauseKind], 3622 OMPC_MAP_MODIFIER_present) == 3623 std::end(ImplicitMapModifier[ClauseKind])) { 3624 ImplicitMapModifier[ClauseKind].push_back( 3625 OMPC_MAP_MODIFIER_present); 3626 } 3627 } 3628 } 3629 3630 if (isOpenMPTargetExecutionDirective(DKind) && 3631 !Stack->isLoopControlVariable(VD).first) { 3632 if (!Stack->checkMappableExprComponentListsForDecl( 3633 VD, /*CurrentRegionOnly=*/true, 3634 [this](OMPClauseMappableExprCommon::MappableExprComponentListRef 3635 StackComponents, 3636 OpenMPClauseKind) { 3637 if (SemaRef.LangOpts.OpenMP >= 50) 3638 return !StackComponents.empty(); 3639 // Variable is used if it has been marked as an array, array 3640 // section, array shaping or the variable iself. 3641 return StackComponents.size() == 1 || 3642 std::all_of( 3643 std::next(StackComponents.rbegin()), 3644 StackComponents.rend(), 3645 [](const OMPClauseMappableExprCommon:: 3646 MappableComponent &MC) { 3647 return MC.getAssociatedDeclaration() == 3648 nullptr && 3649 (isa<OMPArraySectionExpr>( 3650 MC.getAssociatedExpression()) || 3651 isa<OMPArrayShapingExpr>( 3652 MC.getAssociatedExpression()) || 3653 isa<ArraySubscriptExpr>( 3654 MC.getAssociatedExpression())); 3655 }); 3656 })) { 3657 bool IsFirstprivate = false; 3658 // By default lambdas are captured as firstprivates. 3659 if (const auto *RD = 3660 VD->getType().getNonReferenceType()->getAsCXXRecordDecl()) 3661 IsFirstprivate = RD->isLambda(); 3662 IsFirstprivate = 3663 IsFirstprivate || (Stack->mustBeFirstprivate(ClauseKind) && !Res); 3664 if (IsFirstprivate) { 3665 ImplicitFirstprivate.emplace_back(E); 3666 } else { 3667 OpenMPDefaultmapClauseModifier M = 3668 Stack->getDefaultmapModifier(ClauseKind); 3669 OpenMPMapClauseKind Kind = getMapClauseKindFromModifier( 3670 M, ClauseKind == OMPC_DEFAULTMAP_aggregate || Res); 3671 ImplicitMap[ClauseKind][Kind].emplace_back(E); 3672 } 3673 return; 3674 } 3675 } 3676 3677 // OpenMP [2.9.3.6, Restrictions, p.2] 3678 // A list item that appears in a reduction clause of the innermost 3679 // enclosing worksharing or parallel construct may not be accessed in an 3680 // explicit task. 3681 DVar = Stack->hasInnermostDSA( 3682 VD, 3683 [](OpenMPClauseKind C, bool AppliedToPointee) { 3684 return C == OMPC_reduction && !AppliedToPointee; 3685 }, 3686 [](OpenMPDirectiveKind K) { 3687 return isOpenMPParallelDirective(K) || 3688 isOpenMPWorksharingDirective(K) || isOpenMPTeamsDirective(K); 3689 }, 3690 /*FromParent=*/true); 3691 if (isOpenMPTaskingDirective(DKind) && DVar.CKind == OMPC_reduction) { 3692 ErrorFound = true; 3693 SemaRef.Diag(ELoc, diag::err_omp_reduction_in_task); 3694 reportOriginalDsa(SemaRef, Stack, VD, DVar); 3695 return; 3696 } 3697 3698 // Define implicit data-sharing attributes for task. 3699 DVar = Stack->getImplicitDSA(VD, /*FromParent=*/false); 3700 if (((isOpenMPTaskingDirective(DKind) && DVar.CKind != OMPC_shared) || 3701 (((Stack->getDefaultDSA() == DSA_firstprivate && 3702 DVar.CKind == OMPC_firstprivate) || 3703 (Stack->getDefaultDSA() == DSA_private && 3704 DVar.CKind == OMPC_private)) && 3705 !DVar.RefExpr)) && 3706 !Stack->isLoopControlVariable(VD).first) { 3707 if (Stack->getDefaultDSA() == DSA_private) 3708 ImplicitPrivate.push_back(E); 3709 else 3710 ImplicitFirstprivate.push_back(E); 3711 return; 3712 } 3713 3714 // Store implicitly used globals with declare target link for parent 3715 // target. 3716 if (!isOpenMPTargetExecutionDirective(DKind) && Res && 3717 *Res == OMPDeclareTargetDeclAttr::MT_Link) { 3718 Stack->addToParentTargetRegionLinkGlobals(E); 3719 return; 3720 } 3721 } 3722 } 3723 void VisitMemberExpr(MemberExpr *E) { 3724 if (E->isTypeDependent() || E->isValueDependent() || 3725 E->containsUnexpandedParameterPack() || E->isInstantiationDependent()) 3726 return; 3727 auto *FD = dyn_cast<FieldDecl>(E->getMemberDecl()); 3728 OpenMPDirectiveKind DKind = Stack->getCurrentDirective(); 3729 if (auto *TE = dyn_cast<CXXThisExpr>(E->getBase()->IgnoreParenCasts())) { 3730 if (!FD) 3731 return; 3732 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(FD, /*FromParent=*/false); 3733 // Check if the variable has explicit DSA set and stop analysis if it 3734 // so. 3735 if (DVar.RefExpr || !ImplicitDeclarations.insert(FD).second) 3736 return; 3737 3738 if (isOpenMPTargetExecutionDirective(DKind) && 3739 !Stack->isLoopControlVariable(FD).first && 3740 !Stack->checkMappableExprComponentListsForDecl( 3741 FD, /*CurrentRegionOnly=*/true, 3742 [](OMPClauseMappableExprCommon::MappableExprComponentListRef 3743 StackComponents, 3744 OpenMPClauseKind) { 3745 return isa<CXXThisExpr>( 3746 cast<MemberExpr>( 3747 StackComponents.back().getAssociatedExpression()) 3748 ->getBase() 3749 ->IgnoreParens()); 3750 })) { 3751 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.3] 3752 // A bit-field cannot appear in a map clause. 3753 // 3754 if (FD->isBitField()) 3755 return; 3756 3757 // Check to see if the member expression is referencing a class that 3758 // has already been explicitly mapped 3759 if (Stack->isClassPreviouslyMapped(TE->getType())) 3760 return; 3761 3762 OpenMPDefaultmapClauseModifier Modifier = 3763 Stack->getDefaultmapModifier(OMPC_DEFAULTMAP_aggregate); 3764 OpenMPDefaultmapClauseKind ClauseKind = 3765 getVariableCategoryFromDecl(SemaRef.getLangOpts(), FD); 3766 OpenMPMapClauseKind Kind = getMapClauseKindFromModifier( 3767 Modifier, /*IsAggregateOrDeclareTarget*/ true); 3768 ImplicitMap[ClauseKind][Kind].emplace_back(E); 3769 return; 3770 } 3771 3772 SourceLocation ELoc = E->getExprLoc(); 3773 // OpenMP [2.9.3.6, Restrictions, p.2] 3774 // A list item that appears in a reduction clause of the innermost 3775 // enclosing worksharing or parallel construct may not be accessed in 3776 // an explicit task. 3777 DVar = Stack->hasInnermostDSA( 3778 FD, 3779 [](OpenMPClauseKind C, bool AppliedToPointee) { 3780 return C == OMPC_reduction && !AppliedToPointee; 3781 }, 3782 [](OpenMPDirectiveKind K) { 3783 return isOpenMPParallelDirective(K) || 3784 isOpenMPWorksharingDirective(K) || isOpenMPTeamsDirective(K); 3785 }, 3786 /*FromParent=*/true); 3787 if (isOpenMPTaskingDirective(DKind) && DVar.CKind == OMPC_reduction) { 3788 ErrorFound = true; 3789 SemaRef.Diag(ELoc, diag::err_omp_reduction_in_task); 3790 reportOriginalDsa(SemaRef, Stack, FD, DVar); 3791 return; 3792 } 3793 3794 // Define implicit data-sharing attributes for task. 3795 DVar = Stack->getImplicitDSA(FD, /*FromParent=*/false); 3796 if (isOpenMPTaskingDirective(DKind) && DVar.CKind != OMPC_shared && 3797 !Stack->isLoopControlVariable(FD).first) { 3798 // Check if there is a captured expression for the current field in the 3799 // region. Do not mark it as firstprivate unless there is no captured 3800 // expression. 3801 // TODO: try to make it firstprivate. 3802 if (DVar.CKind != OMPC_unknown) 3803 ImplicitFirstprivate.push_back(E); 3804 } 3805 return; 3806 } 3807 if (isOpenMPTargetExecutionDirective(DKind)) { 3808 OMPClauseMappableExprCommon::MappableExprComponentList CurComponents; 3809 if (!checkMapClauseExpressionBase(SemaRef, E, CurComponents, OMPC_map, 3810 Stack->getCurrentDirective(), 3811 /*NoDiagnose=*/true)) 3812 return; 3813 const auto *VD = cast<ValueDecl>( 3814 CurComponents.back().getAssociatedDeclaration()->getCanonicalDecl()); 3815 if (!Stack->checkMappableExprComponentListsForDecl( 3816 VD, /*CurrentRegionOnly=*/true, 3817 [&CurComponents]( 3818 OMPClauseMappableExprCommon::MappableExprComponentListRef 3819 StackComponents, 3820 OpenMPClauseKind) { 3821 auto CCI = CurComponents.rbegin(); 3822 auto CCE = CurComponents.rend(); 3823 for (const auto &SC : llvm::reverse(StackComponents)) { 3824 // Do both expressions have the same kind? 3825 if (CCI->getAssociatedExpression()->getStmtClass() != 3826 SC.getAssociatedExpression()->getStmtClass()) 3827 if (!((isa<OMPArraySectionExpr>( 3828 SC.getAssociatedExpression()) || 3829 isa<OMPArrayShapingExpr>( 3830 SC.getAssociatedExpression())) && 3831 isa<ArraySubscriptExpr>( 3832 CCI->getAssociatedExpression()))) 3833 return false; 3834 3835 const Decl *CCD = CCI->getAssociatedDeclaration(); 3836 const Decl *SCD = SC.getAssociatedDeclaration(); 3837 CCD = CCD ? CCD->getCanonicalDecl() : nullptr; 3838 SCD = SCD ? SCD->getCanonicalDecl() : nullptr; 3839 if (SCD != CCD) 3840 return false; 3841 std::advance(CCI, 1); 3842 if (CCI == CCE) 3843 break; 3844 } 3845 return true; 3846 })) { 3847 Visit(E->getBase()); 3848 } 3849 } else if (!TryCaptureCXXThisMembers) { 3850 Visit(E->getBase()); 3851 } 3852 } 3853 void VisitOMPExecutableDirective(OMPExecutableDirective *S) { 3854 for (OMPClause *C : S->clauses()) { 3855 // Skip analysis of arguments of private clauses for task|target 3856 // directives. 3857 if (isa_and_nonnull<OMPPrivateClause>(C)) 3858 continue; 3859 // Skip analysis of arguments of implicitly defined firstprivate clause 3860 // for task|target directives. 3861 // Skip analysis of arguments of implicitly defined map clause for target 3862 // directives. 3863 if (C && !((isa<OMPFirstprivateClause>(C) || isa<OMPMapClause>(C)) && 3864 C->isImplicit() && 3865 !isOpenMPTaskingDirective(Stack->getCurrentDirective()))) { 3866 for (Stmt *CC : C->children()) { 3867 if (CC) 3868 Visit(CC); 3869 } 3870 } 3871 } 3872 // Check implicitly captured variables. 3873 VisitSubCaptures(S); 3874 } 3875 3876 void VisitOMPLoopTransformationDirective(OMPLoopTransformationDirective *S) { 3877 // Loop transformation directives do not introduce data sharing 3878 VisitStmt(S); 3879 } 3880 3881 void VisitCallExpr(CallExpr *S) { 3882 for (Stmt *C : S->arguments()) { 3883 if (C) { 3884 // Check implicitly captured variables in the task-based directives to 3885 // check if they must be firstprivatized. 3886 Visit(C); 3887 } 3888 } 3889 if (Expr *Callee = S->getCallee()) 3890 if (auto *CE = dyn_cast<MemberExpr>(Callee->IgnoreParenImpCasts())) 3891 Visit(CE->getBase()); 3892 } 3893 void VisitStmt(Stmt *S) { 3894 for (Stmt *C : S->children()) { 3895 if (C) { 3896 // Check implicitly captured variables in the task-based directives to 3897 // check if they must be firstprivatized. 3898 Visit(C); 3899 } 3900 } 3901 } 3902 3903 void visitSubCaptures(CapturedStmt *S) { 3904 for (const CapturedStmt::Capture &Cap : S->captures()) { 3905 if (!Cap.capturesVariable() && !Cap.capturesVariableByCopy()) 3906 continue; 3907 VarDecl *VD = Cap.getCapturedVar(); 3908 // Do not try to map the variable if it or its sub-component was mapped 3909 // already. 3910 if (isOpenMPTargetExecutionDirective(Stack->getCurrentDirective()) && 3911 Stack->checkMappableExprComponentListsForDecl( 3912 VD, /*CurrentRegionOnly=*/true, 3913 [](OMPClauseMappableExprCommon::MappableExprComponentListRef, 3914 OpenMPClauseKind) { return true; })) 3915 continue; 3916 DeclRefExpr *DRE = buildDeclRefExpr( 3917 SemaRef, VD, VD->getType().getNonLValueExprType(SemaRef.Context), 3918 Cap.getLocation(), /*RefersToCapture=*/true); 3919 Visit(DRE); 3920 } 3921 } 3922 bool isErrorFound() const { return ErrorFound; } 3923 ArrayRef<Expr *> getImplicitFirstprivate() const { 3924 return ImplicitFirstprivate; 3925 } 3926 ArrayRef<Expr *> getImplicitPrivate() const { return ImplicitPrivate; } 3927 ArrayRef<Expr *> getImplicitMap(OpenMPDefaultmapClauseKind DK, 3928 OpenMPMapClauseKind MK) const { 3929 return ImplicitMap[DK][MK]; 3930 } 3931 ArrayRef<OpenMPMapModifierKind> 3932 getImplicitMapModifier(OpenMPDefaultmapClauseKind Kind) const { 3933 return ImplicitMapModifier[Kind]; 3934 } 3935 const Sema::VarsWithInheritedDSAType &getVarsWithInheritedDSA() const { 3936 return VarsWithInheritedDSA; 3937 } 3938 3939 DSAAttrChecker(DSAStackTy *S, Sema &SemaRef, CapturedStmt *CS) 3940 : Stack(S), SemaRef(SemaRef), ErrorFound(false), CS(CS) { 3941 // Process declare target link variables for the target directives. 3942 if (isOpenMPTargetExecutionDirective(S->getCurrentDirective())) { 3943 for (DeclRefExpr *E : Stack->getLinkGlobals()) 3944 Visit(E); 3945 } 3946 } 3947 }; 3948 } // namespace 3949 3950 static void handleDeclareVariantConstructTrait(DSAStackTy *Stack, 3951 OpenMPDirectiveKind DKind, 3952 bool ScopeEntry) { 3953 SmallVector<llvm::omp::TraitProperty, 8> Traits; 3954 if (isOpenMPTargetExecutionDirective(DKind)) 3955 Traits.emplace_back(llvm::omp::TraitProperty::construct_target_target); 3956 if (isOpenMPTeamsDirective(DKind)) 3957 Traits.emplace_back(llvm::omp::TraitProperty::construct_teams_teams); 3958 if (isOpenMPParallelDirective(DKind)) 3959 Traits.emplace_back(llvm::omp::TraitProperty::construct_parallel_parallel); 3960 if (isOpenMPWorksharingDirective(DKind)) 3961 Traits.emplace_back(llvm::omp::TraitProperty::construct_for_for); 3962 if (isOpenMPSimdDirective(DKind)) 3963 Traits.emplace_back(llvm::omp::TraitProperty::construct_simd_simd); 3964 Stack->handleConstructTrait(Traits, ScopeEntry); 3965 } 3966 3967 void Sema::ActOnOpenMPRegionStart(OpenMPDirectiveKind DKind, Scope *CurScope) { 3968 switch (DKind) { 3969 case OMPD_parallel: 3970 case OMPD_parallel_for: 3971 case OMPD_parallel_for_simd: 3972 case OMPD_parallel_sections: 3973 case OMPD_parallel_master: 3974 case OMPD_parallel_masked: 3975 case OMPD_parallel_loop: 3976 case OMPD_teams: 3977 case OMPD_teams_distribute: 3978 case OMPD_teams_distribute_simd: { 3979 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 3980 QualType KmpInt32PtrTy = 3981 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3982 Sema::CapturedParamNameType Params[] = { 3983 std::make_pair(".global_tid.", KmpInt32PtrTy), 3984 std::make_pair(".bound_tid.", KmpInt32PtrTy), 3985 std::make_pair(StringRef(), QualType()) // __context with shared vars 3986 }; 3987 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3988 Params); 3989 break; 3990 } 3991 case OMPD_target_teams: 3992 case OMPD_target_parallel: 3993 case OMPD_target_parallel_for: 3994 case OMPD_target_parallel_for_simd: 3995 case OMPD_target_teams_loop: 3996 case OMPD_target_parallel_loop: 3997 case OMPD_target_teams_distribute: 3998 case OMPD_target_teams_distribute_simd: { 3999 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 4000 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 4001 QualType KmpInt32PtrTy = 4002 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 4003 QualType Args[] = {VoidPtrTy}; 4004 FunctionProtoType::ExtProtoInfo EPI; 4005 EPI.Variadic = true; 4006 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 4007 Sema::CapturedParamNameType Params[] = { 4008 std::make_pair(".global_tid.", KmpInt32Ty), 4009 std::make_pair(".part_id.", KmpInt32PtrTy), 4010 std::make_pair(".privates.", VoidPtrTy), 4011 std::make_pair( 4012 ".copy_fn.", 4013 Context.getPointerType(CopyFnType).withConst().withRestrict()), 4014 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 4015 std::make_pair(StringRef(), QualType()) // __context with shared vars 4016 }; 4017 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 4018 Params, /*OpenMPCaptureLevel=*/0); 4019 // Mark this captured region as inlined, because we don't use outlined 4020 // function directly. 4021 getCurCapturedRegion()->TheCapturedDecl->addAttr( 4022 AlwaysInlineAttr::CreateImplicit( 4023 Context, {}, AttributeCommonInfo::AS_Keyword, 4024 AlwaysInlineAttr::Keyword_forceinline)); 4025 Sema::CapturedParamNameType ParamsTarget[] = { 4026 std::make_pair(StringRef(), QualType()) // __context with shared vars 4027 }; 4028 // Start a captured region for 'target' with no implicit parameters. 4029 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 4030 ParamsTarget, /*OpenMPCaptureLevel=*/1); 4031 Sema::CapturedParamNameType ParamsTeamsOrParallel[] = { 4032 std::make_pair(".global_tid.", KmpInt32PtrTy), 4033 std::make_pair(".bound_tid.", KmpInt32PtrTy), 4034 std::make_pair(StringRef(), QualType()) // __context with shared vars 4035 }; 4036 // Start a captured region for 'teams' or 'parallel'. Both regions have 4037 // the same implicit parameters. 4038 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 4039 ParamsTeamsOrParallel, /*OpenMPCaptureLevel=*/2); 4040 break; 4041 } 4042 case OMPD_target: 4043 case OMPD_target_simd: { 4044 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 4045 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 4046 QualType KmpInt32PtrTy = 4047 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 4048 QualType Args[] = {VoidPtrTy}; 4049 FunctionProtoType::ExtProtoInfo EPI; 4050 EPI.Variadic = true; 4051 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 4052 Sema::CapturedParamNameType Params[] = { 4053 std::make_pair(".global_tid.", KmpInt32Ty), 4054 std::make_pair(".part_id.", KmpInt32PtrTy), 4055 std::make_pair(".privates.", VoidPtrTy), 4056 std::make_pair( 4057 ".copy_fn.", 4058 Context.getPointerType(CopyFnType).withConst().withRestrict()), 4059 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 4060 std::make_pair(StringRef(), QualType()) // __context with shared vars 4061 }; 4062 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 4063 Params, /*OpenMPCaptureLevel=*/0); 4064 // Mark this captured region as inlined, because we don't use outlined 4065 // function directly. 4066 getCurCapturedRegion()->TheCapturedDecl->addAttr( 4067 AlwaysInlineAttr::CreateImplicit( 4068 Context, {}, AttributeCommonInfo::AS_Keyword, 4069 AlwaysInlineAttr::Keyword_forceinline)); 4070 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 4071 std::make_pair(StringRef(), QualType()), 4072 /*OpenMPCaptureLevel=*/1); 4073 break; 4074 } 4075 case OMPD_atomic: 4076 case OMPD_critical: 4077 case OMPD_section: 4078 case OMPD_master: 4079 case OMPD_masked: 4080 case OMPD_tile: 4081 case OMPD_unroll: 4082 break; 4083 case OMPD_loop: 4084 // TODO: 'loop' may require additional parameters depending on the binding. 4085 // Treat similar to OMPD_simd/OMPD_for for now. 4086 case OMPD_simd: 4087 case OMPD_for: 4088 case OMPD_for_simd: 4089 case OMPD_sections: 4090 case OMPD_single: 4091 case OMPD_taskgroup: 4092 case OMPD_distribute: 4093 case OMPD_distribute_simd: 4094 case OMPD_ordered: 4095 case OMPD_target_data: 4096 case OMPD_dispatch: { 4097 Sema::CapturedParamNameType Params[] = { 4098 std::make_pair(StringRef(), QualType()) // __context with shared vars 4099 }; 4100 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 4101 Params); 4102 break; 4103 } 4104 case OMPD_task: { 4105 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 4106 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 4107 QualType KmpInt32PtrTy = 4108 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 4109 QualType Args[] = {VoidPtrTy}; 4110 FunctionProtoType::ExtProtoInfo EPI; 4111 EPI.Variadic = true; 4112 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 4113 Sema::CapturedParamNameType Params[] = { 4114 std::make_pair(".global_tid.", KmpInt32Ty), 4115 std::make_pair(".part_id.", KmpInt32PtrTy), 4116 std::make_pair(".privates.", VoidPtrTy), 4117 std::make_pair( 4118 ".copy_fn.", 4119 Context.getPointerType(CopyFnType).withConst().withRestrict()), 4120 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 4121 std::make_pair(StringRef(), QualType()) // __context with shared vars 4122 }; 4123 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 4124 Params); 4125 // Mark this captured region as inlined, because we don't use outlined 4126 // function directly. 4127 getCurCapturedRegion()->TheCapturedDecl->addAttr( 4128 AlwaysInlineAttr::CreateImplicit( 4129 Context, {}, AttributeCommonInfo::AS_Keyword, 4130 AlwaysInlineAttr::Keyword_forceinline)); 4131 break; 4132 } 4133 case OMPD_taskloop: 4134 case OMPD_taskloop_simd: 4135 case OMPD_master_taskloop: 4136 case OMPD_masked_taskloop: 4137 case OMPD_masked_taskloop_simd: 4138 case OMPD_master_taskloop_simd: { 4139 QualType KmpInt32Ty = 4140 Context.getIntTypeForBitwidth(/*DestWidth=*/32, /*Signed=*/1) 4141 .withConst(); 4142 QualType KmpUInt64Ty = 4143 Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/0) 4144 .withConst(); 4145 QualType KmpInt64Ty = 4146 Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/1) 4147 .withConst(); 4148 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 4149 QualType KmpInt32PtrTy = 4150 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 4151 QualType Args[] = {VoidPtrTy}; 4152 FunctionProtoType::ExtProtoInfo EPI; 4153 EPI.Variadic = true; 4154 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 4155 Sema::CapturedParamNameType Params[] = { 4156 std::make_pair(".global_tid.", KmpInt32Ty), 4157 std::make_pair(".part_id.", KmpInt32PtrTy), 4158 std::make_pair(".privates.", VoidPtrTy), 4159 std::make_pair( 4160 ".copy_fn.", 4161 Context.getPointerType(CopyFnType).withConst().withRestrict()), 4162 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 4163 std::make_pair(".lb.", KmpUInt64Ty), 4164 std::make_pair(".ub.", KmpUInt64Ty), 4165 std::make_pair(".st.", KmpInt64Ty), 4166 std::make_pair(".liter.", KmpInt32Ty), 4167 std::make_pair(".reductions.", VoidPtrTy), 4168 std::make_pair(StringRef(), QualType()) // __context with shared vars 4169 }; 4170 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 4171 Params); 4172 // Mark this captured region as inlined, because we don't use outlined 4173 // function directly. 4174 getCurCapturedRegion()->TheCapturedDecl->addAttr( 4175 AlwaysInlineAttr::CreateImplicit( 4176 Context, {}, AttributeCommonInfo::AS_Keyword, 4177 AlwaysInlineAttr::Keyword_forceinline)); 4178 break; 4179 } 4180 case OMPD_parallel_master_taskloop: 4181 case OMPD_parallel_master_taskloop_simd: { 4182 QualType KmpInt32Ty = 4183 Context.getIntTypeForBitwidth(/*DestWidth=*/32, /*Signed=*/1) 4184 .withConst(); 4185 QualType KmpUInt64Ty = 4186 Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/0) 4187 .withConst(); 4188 QualType KmpInt64Ty = 4189 Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/1) 4190 .withConst(); 4191 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 4192 QualType KmpInt32PtrTy = 4193 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 4194 Sema::CapturedParamNameType ParamsParallel[] = { 4195 std::make_pair(".global_tid.", KmpInt32PtrTy), 4196 std::make_pair(".bound_tid.", KmpInt32PtrTy), 4197 std::make_pair(StringRef(), QualType()) // __context with shared vars 4198 }; 4199 // Start a captured region for 'parallel'. 4200 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 4201 ParamsParallel, /*OpenMPCaptureLevel=*/0); 4202 QualType Args[] = {VoidPtrTy}; 4203 FunctionProtoType::ExtProtoInfo EPI; 4204 EPI.Variadic = true; 4205 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 4206 Sema::CapturedParamNameType Params[] = { 4207 std::make_pair(".global_tid.", KmpInt32Ty), 4208 std::make_pair(".part_id.", KmpInt32PtrTy), 4209 std::make_pair(".privates.", VoidPtrTy), 4210 std::make_pair( 4211 ".copy_fn.", 4212 Context.getPointerType(CopyFnType).withConst().withRestrict()), 4213 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 4214 std::make_pair(".lb.", KmpUInt64Ty), 4215 std::make_pair(".ub.", KmpUInt64Ty), 4216 std::make_pair(".st.", KmpInt64Ty), 4217 std::make_pair(".liter.", KmpInt32Ty), 4218 std::make_pair(".reductions.", VoidPtrTy), 4219 std::make_pair(StringRef(), QualType()) // __context with shared vars 4220 }; 4221 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 4222 Params, /*OpenMPCaptureLevel=*/1); 4223 // Mark this captured region as inlined, because we don't use outlined 4224 // function directly. 4225 getCurCapturedRegion()->TheCapturedDecl->addAttr( 4226 AlwaysInlineAttr::CreateImplicit( 4227 Context, {}, AttributeCommonInfo::AS_Keyword, 4228 AlwaysInlineAttr::Keyword_forceinline)); 4229 break; 4230 } 4231 case OMPD_distribute_parallel_for_simd: 4232 case OMPD_distribute_parallel_for: { 4233 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 4234 QualType KmpInt32PtrTy = 4235 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 4236 Sema::CapturedParamNameType Params[] = { 4237 std::make_pair(".global_tid.", KmpInt32PtrTy), 4238 std::make_pair(".bound_tid.", KmpInt32PtrTy), 4239 std::make_pair(".previous.lb.", Context.getSizeType().withConst()), 4240 std::make_pair(".previous.ub.", Context.getSizeType().withConst()), 4241 std::make_pair(StringRef(), QualType()) // __context with shared vars 4242 }; 4243 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 4244 Params); 4245 break; 4246 } 4247 case OMPD_target_teams_distribute_parallel_for: 4248 case OMPD_target_teams_distribute_parallel_for_simd: { 4249 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 4250 QualType KmpInt32PtrTy = 4251 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 4252 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 4253 4254 QualType Args[] = {VoidPtrTy}; 4255 FunctionProtoType::ExtProtoInfo EPI; 4256 EPI.Variadic = true; 4257 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 4258 Sema::CapturedParamNameType Params[] = { 4259 std::make_pair(".global_tid.", KmpInt32Ty), 4260 std::make_pair(".part_id.", KmpInt32PtrTy), 4261 std::make_pair(".privates.", VoidPtrTy), 4262 std::make_pair( 4263 ".copy_fn.", 4264 Context.getPointerType(CopyFnType).withConst().withRestrict()), 4265 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 4266 std::make_pair(StringRef(), QualType()) // __context with shared vars 4267 }; 4268 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 4269 Params, /*OpenMPCaptureLevel=*/0); 4270 // Mark this captured region as inlined, because we don't use outlined 4271 // function directly. 4272 getCurCapturedRegion()->TheCapturedDecl->addAttr( 4273 AlwaysInlineAttr::CreateImplicit( 4274 Context, {}, AttributeCommonInfo::AS_Keyword, 4275 AlwaysInlineAttr::Keyword_forceinline)); 4276 Sema::CapturedParamNameType ParamsTarget[] = { 4277 std::make_pair(StringRef(), QualType()) // __context with shared vars 4278 }; 4279 // Start a captured region for 'target' with no implicit parameters. 4280 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 4281 ParamsTarget, /*OpenMPCaptureLevel=*/1); 4282 4283 Sema::CapturedParamNameType ParamsTeams[] = { 4284 std::make_pair(".global_tid.", KmpInt32PtrTy), 4285 std::make_pair(".bound_tid.", KmpInt32PtrTy), 4286 std::make_pair(StringRef(), QualType()) // __context with shared vars 4287 }; 4288 // Start a captured region for 'target' with no implicit parameters. 4289 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 4290 ParamsTeams, /*OpenMPCaptureLevel=*/2); 4291 4292 Sema::CapturedParamNameType ParamsParallel[] = { 4293 std::make_pair(".global_tid.", KmpInt32PtrTy), 4294 std::make_pair(".bound_tid.", KmpInt32PtrTy), 4295 std::make_pair(".previous.lb.", Context.getSizeType().withConst()), 4296 std::make_pair(".previous.ub.", Context.getSizeType().withConst()), 4297 std::make_pair(StringRef(), QualType()) // __context with shared vars 4298 }; 4299 // Start a captured region for 'teams' or 'parallel'. Both regions have 4300 // the same implicit parameters. 4301 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 4302 ParamsParallel, /*OpenMPCaptureLevel=*/3); 4303 break; 4304 } 4305 4306 case OMPD_teams_loop: { 4307 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 4308 QualType KmpInt32PtrTy = 4309 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 4310 4311 Sema::CapturedParamNameType ParamsTeams[] = { 4312 std::make_pair(".global_tid.", KmpInt32PtrTy), 4313 std::make_pair(".bound_tid.", KmpInt32PtrTy), 4314 std::make_pair(StringRef(), QualType()) // __context with shared vars 4315 }; 4316 // Start a captured region for 'teams'. 4317 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 4318 ParamsTeams, /*OpenMPCaptureLevel=*/0); 4319 break; 4320 } 4321 4322 case OMPD_teams_distribute_parallel_for: 4323 case OMPD_teams_distribute_parallel_for_simd: { 4324 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 4325 QualType KmpInt32PtrTy = 4326 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 4327 4328 Sema::CapturedParamNameType ParamsTeams[] = { 4329 std::make_pair(".global_tid.", KmpInt32PtrTy), 4330 std::make_pair(".bound_tid.", KmpInt32PtrTy), 4331 std::make_pair(StringRef(), QualType()) // __context with shared vars 4332 }; 4333 // Start a captured region for 'target' with no implicit parameters. 4334 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 4335 ParamsTeams, /*OpenMPCaptureLevel=*/0); 4336 4337 Sema::CapturedParamNameType ParamsParallel[] = { 4338 std::make_pair(".global_tid.", KmpInt32PtrTy), 4339 std::make_pair(".bound_tid.", KmpInt32PtrTy), 4340 std::make_pair(".previous.lb.", Context.getSizeType().withConst()), 4341 std::make_pair(".previous.ub.", Context.getSizeType().withConst()), 4342 std::make_pair(StringRef(), QualType()) // __context with shared vars 4343 }; 4344 // Start a captured region for 'teams' or 'parallel'. Both regions have 4345 // the same implicit parameters. 4346 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 4347 ParamsParallel, /*OpenMPCaptureLevel=*/1); 4348 break; 4349 } 4350 case OMPD_target_update: 4351 case OMPD_target_enter_data: 4352 case OMPD_target_exit_data: { 4353 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 4354 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 4355 QualType KmpInt32PtrTy = 4356 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 4357 QualType Args[] = {VoidPtrTy}; 4358 FunctionProtoType::ExtProtoInfo EPI; 4359 EPI.Variadic = true; 4360 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 4361 Sema::CapturedParamNameType Params[] = { 4362 std::make_pair(".global_tid.", KmpInt32Ty), 4363 std::make_pair(".part_id.", KmpInt32PtrTy), 4364 std::make_pair(".privates.", VoidPtrTy), 4365 std::make_pair( 4366 ".copy_fn.", 4367 Context.getPointerType(CopyFnType).withConst().withRestrict()), 4368 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 4369 std::make_pair(StringRef(), QualType()) // __context with shared vars 4370 }; 4371 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 4372 Params); 4373 // Mark this captured region as inlined, because we don't use outlined 4374 // function directly. 4375 getCurCapturedRegion()->TheCapturedDecl->addAttr( 4376 AlwaysInlineAttr::CreateImplicit( 4377 Context, {}, AttributeCommonInfo::AS_Keyword, 4378 AlwaysInlineAttr::Keyword_forceinline)); 4379 break; 4380 } 4381 case OMPD_threadprivate: 4382 case OMPD_allocate: 4383 case OMPD_taskyield: 4384 case OMPD_barrier: 4385 case OMPD_taskwait: 4386 case OMPD_cancellation_point: 4387 case OMPD_cancel: 4388 case OMPD_flush: 4389 case OMPD_depobj: 4390 case OMPD_scan: 4391 case OMPD_declare_reduction: 4392 case OMPD_declare_mapper: 4393 case OMPD_declare_simd: 4394 case OMPD_declare_target: 4395 case OMPD_end_declare_target: 4396 case OMPD_requires: 4397 case OMPD_declare_variant: 4398 case OMPD_begin_declare_variant: 4399 case OMPD_end_declare_variant: 4400 case OMPD_metadirective: 4401 llvm_unreachable("OpenMP Directive is not allowed"); 4402 case OMPD_unknown: 4403 default: 4404 llvm_unreachable("Unknown OpenMP directive"); 4405 } 4406 DSAStack->setContext(CurContext); 4407 handleDeclareVariantConstructTrait(DSAStack, DKind, /* ScopeEntry */ true); 4408 } 4409 4410 int Sema::getNumberOfConstructScopes(unsigned Level) const { 4411 return getOpenMPCaptureLevels(DSAStack->getDirective(Level)); 4412 } 4413 4414 int Sema::getOpenMPCaptureLevels(OpenMPDirectiveKind DKind) { 4415 SmallVector<OpenMPDirectiveKind, 4> CaptureRegions; 4416 getOpenMPCaptureRegions(CaptureRegions, DKind); 4417 return CaptureRegions.size(); 4418 } 4419 4420 static OMPCapturedExprDecl *buildCaptureDecl(Sema &S, IdentifierInfo *Id, 4421 Expr *CaptureExpr, bool WithInit, 4422 bool AsExpression) { 4423 assert(CaptureExpr); 4424 ASTContext &C = S.getASTContext(); 4425 Expr *Init = AsExpression ? CaptureExpr : CaptureExpr->IgnoreImpCasts(); 4426 QualType Ty = Init->getType(); 4427 if (CaptureExpr->getObjectKind() == OK_Ordinary && CaptureExpr->isGLValue()) { 4428 if (S.getLangOpts().CPlusPlus) { 4429 Ty = C.getLValueReferenceType(Ty); 4430 } else { 4431 Ty = C.getPointerType(Ty); 4432 ExprResult Res = 4433 S.CreateBuiltinUnaryOp(CaptureExpr->getExprLoc(), UO_AddrOf, Init); 4434 if (!Res.isUsable()) 4435 return nullptr; 4436 Init = Res.get(); 4437 } 4438 WithInit = true; 4439 } 4440 auto *CED = OMPCapturedExprDecl::Create(C, S.CurContext, Id, Ty, 4441 CaptureExpr->getBeginLoc()); 4442 if (!WithInit) 4443 CED->addAttr(OMPCaptureNoInitAttr::CreateImplicit(C)); 4444 S.CurContext->addHiddenDecl(CED); 4445 Sema::TentativeAnalysisScope Trap(S); 4446 S.AddInitializerToDecl(CED, Init, /*DirectInit=*/false); 4447 return CED; 4448 } 4449 4450 static DeclRefExpr *buildCapture(Sema &S, ValueDecl *D, Expr *CaptureExpr, 4451 bool WithInit) { 4452 OMPCapturedExprDecl *CD; 4453 if (VarDecl *VD = S.isOpenMPCapturedDecl(D)) 4454 CD = cast<OMPCapturedExprDecl>(VD); 4455 else 4456 CD = buildCaptureDecl(S, D->getIdentifier(), CaptureExpr, WithInit, 4457 /*AsExpression=*/false); 4458 return buildDeclRefExpr(S, CD, CD->getType().getNonReferenceType(), 4459 CaptureExpr->getExprLoc()); 4460 } 4461 4462 static ExprResult buildCapture(Sema &S, Expr *CaptureExpr, DeclRefExpr *&Ref) { 4463 CaptureExpr = S.DefaultLvalueConversion(CaptureExpr).get(); 4464 if (!Ref) { 4465 OMPCapturedExprDecl *CD = buildCaptureDecl( 4466 S, &S.getASTContext().Idents.get(".capture_expr."), CaptureExpr, 4467 /*WithInit=*/true, /*AsExpression=*/true); 4468 Ref = buildDeclRefExpr(S, CD, CD->getType().getNonReferenceType(), 4469 CaptureExpr->getExprLoc()); 4470 } 4471 ExprResult Res = Ref; 4472 if (!S.getLangOpts().CPlusPlus && 4473 CaptureExpr->getObjectKind() == OK_Ordinary && CaptureExpr->isGLValue() && 4474 Ref->getType()->isPointerType()) { 4475 Res = S.CreateBuiltinUnaryOp(CaptureExpr->getExprLoc(), UO_Deref, Ref); 4476 if (!Res.isUsable()) 4477 return ExprError(); 4478 } 4479 return S.DefaultLvalueConversion(Res.get()); 4480 } 4481 4482 namespace { 4483 // OpenMP directives parsed in this section are represented as a 4484 // CapturedStatement with an associated statement. If a syntax error 4485 // is detected during the parsing of the associated statement, the 4486 // compiler must abort processing and close the CapturedStatement. 4487 // 4488 // Combined directives such as 'target parallel' have more than one 4489 // nested CapturedStatements. This RAII ensures that we unwind out 4490 // of all the nested CapturedStatements when an error is found. 4491 class CaptureRegionUnwinderRAII { 4492 private: 4493 Sema &S; 4494 bool &ErrorFound; 4495 OpenMPDirectiveKind DKind = OMPD_unknown; 4496 4497 public: 4498 CaptureRegionUnwinderRAII(Sema &S, bool &ErrorFound, 4499 OpenMPDirectiveKind DKind) 4500 : S(S), ErrorFound(ErrorFound), DKind(DKind) {} 4501 ~CaptureRegionUnwinderRAII() { 4502 if (ErrorFound) { 4503 int ThisCaptureLevel = S.getOpenMPCaptureLevels(DKind); 4504 while (--ThisCaptureLevel >= 0) 4505 S.ActOnCapturedRegionError(); 4506 } 4507 } 4508 }; 4509 } // namespace 4510 4511 void Sema::tryCaptureOpenMPLambdas(ValueDecl *V) { 4512 // Capture variables captured by reference in lambdas for target-based 4513 // directives. 4514 if (!CurContext->isDependentContext() && 4515 (isOpenMPTargetExecutionDirective(DSAStack->getCurrentDirective()) || 4516 isOpenMPTargetDataManagementDirective( 4517 DSAStack->getCurrentDirective()))) { 4518 QualType Type = V->getType(); 4519 if (const auto *RD = Type.getCanonicalType() 4520 .getNonReferenceType() 4521 ->getAsCXXRecordDecl()) { 4522 bool SavedForceCaptureByReferenceInTargetExecutable = 4523 DSAStack->isForceCaptureByReferenceInTargetExecutable(); 4524 DSAStack->setForceCaptureByReferenceInTargetExecutable( 4525 /*V=*/true); 4526 if (RD->isLambda()) { 4527 llvm::DenseMap<const VarDecl *, FieldDecl *> Captures; 4528 FieldDecl *ThisCapture; 4529 RD->getCaptureFields(Captures, ThisCapture); 4530 for (const LambdaCapture &LC : RD->captures()) { 4531 if (LC.getCaptureKind() == LCK_ByRef) { 4532 VarDecl *VD = LC.getCapturedVar(); 4533 DeclContext *VDC = VD->getDeclContext(); 4534 if (!VDC->Encloses(CurContext)) 4535 continue; 4536 MarkVariableReferenced(LC.getLocation(), VD); 4537 } else if (LC.getCaptureKind() == LCK_This) { 4538 QualType ThisTy = getCurrentThisType(); 4539 if (!ThisTy.isNull() && 4540 Context.typesAreCompatible(ThisTy, ThisCapture->getType())) 4541 CheckCXXThisCapture(LC.getLocation()); 4542 } 4543 } 4544 } 4545 DSAStack->setForceCaptureByReferenceInTargetExecutable( 4546 SavedForceCaptureByReferenceInTargetExecutable); 4547 } 4548 } 4549 } 4550 4551 static bool checkOrderedOrderSpecified(Sema &S, 4552 const ArrayRef<OMPClause *> Clauses) { 4553 const OMPOrderedClause *Ordered = nullptr; 4554 const OMPOrderClause *Order = nullptr; 4555 4556 for (const OMPClause *Clause : Clauses) { 4557 if (Clause->getClauseKind() == OMPC_ordered) 4558 Ordered = cast<OMPOrderedClause>(Clause); 4559 else if (Clause->getClauseKind() == OMPC_order) { 4560 Order = cast<OMPOrderClause>(Clause); 4561 if (Order->getKind() != OMPC_ORDER_concurrent) 4562 Order = nullptr; 4563 } 4564 if (Ordered && Order) 4565 break; 4566 } 4567 4568 if (Ordered && Order) { 4569 S.Diag(Order->getKindKwLoc(), 4570 diag::err_omp_simple_clause_incompatible_with_ordered) 4571 << getOpenMPClauseName(OMPC_order) 4572 << getOpenMPSimpleClauseTypeName(OMPC_order, OMPC_ORDER_concurrent) 4573 << SourceRange(Order->getBeginLoc(), Order->getEndLoc()); 4574 S.Diag(Ordered->getBeginLoc(), diag::note_omp_ordered_param) 4575 << 0 << SourceRange(Ordered->getBeginLoc(), Ordered->getEndLoc()); 4576 return true; 4577 } 4578 return false; 4579 } 4580 4581 StmtResult Sema::ActOnOpenMPRegionEnd(StmtResult S, 4582 ArrayRef<OMPClause *> Clauses) { 4583 handleDeclareVariantConstructTrait(DSAStack, DSAStack->getCurrentDirective(), 4584 /* ScopeEntry */ false); 4585 if (DSAStack->getCurrentDirective() == OMPD_atomic || 4586 DSAStack->getCurrentDirective() == OMPD_critical || 4587 DSAStack->getCurrentDirective() == OMPD_section || 4588 DSAStack->getCurrentDirective() == OMPD_master || 4589 DSAStack->getCurrentDirective() == OMPD_masked) 4590 return S; 4591 4592 bool ErrorFound = false; 4593 CaptureRegionUnwinderRAII CaptureRegionUnwinder( 4594 *this, ErrorFound, DSAStack->getCurrentDirective()); 4595 if (!S.isUsable()) { 4596 ErrorFound = true; 4597 return StmtError(); 4598 } 4599 4600 SmallVector<OpenMPDirectiveKind, 4> CaptureRegions; 4601 getOpenMPCaptureRegions(CaptureRegions, DSAStack->getCurrentDirective()); 4602 OMPOrderedClause *OC = nullptr; 4603 OMPScheduleClause *SC = nullptr; 4604 SmallVector<const OMPLinearClause *, 4> LCs; 4605 SmallVector<const OMPClauseWithPreInit *, 4> PICs; 4606 // This is required for proper codegen. 4607 for (OMPClause *Clause : Clauses) { 4608 if (!LangOpts.OpenMPSimd && 4609 (isOpenMPTaskingDirective(DSAStack->getCurrentDirective()) || 4610 DSAStack->getCurrentDirective() == OMPD_target) && 4611 Clause->getClauseKind() == OMPC_in_reduction) { 4612 // Capture taskgroup task_reduction descriptors inside the tasking regions 4613 // with the corresponding in_reduction items. 4614 auto *IRC = cast<OMPInReductionClause>(Clause); 4615 for (Expr *E : IRC->taskgroup_descriptors()) 4616 if (E) 4617 MarkDeclarationsReferencedInExpr(E); 4618 } 4619 if (isOpenMPPrivate(Clause->getClauseKind()) || 4620 Clause->getClauseKind() == OMPC_copyprivate || 4621 (getLangOpts().OpenMPUseTLS && 4622 getASTContext().getTargetInfo().isTLSSupported() && 4623 Clause->getClauseKind() == OMPC_copyin)) { 4624 DSAStack->setForceVarCapturing(Clause->getClauseKind() == OMPC_copyin); 4625 // Mark all variables in private list clauses as used in inner region. 4626 for (Stmt *VarRef : Clause->children()) { 4627 if (auto *E = cast_or_null<Expr>(VarRef)) { 4628 MarkDeclarationsReferencedInExpr(E); 4629 } 4630 } 4631 DSAStack->setForceVarCapturing(/*V=*/false); 4632 } else if (isOpenMPLoopTransformationDirective( 4633 DSAStack->getCurrentDirective())) { 4634 assert(CaptureRegions.empty() && 4635 "No captured regions in loop transformation directives."); 4636 } else if (CaptureRegions.size() > 1 || 4637 CaptureRegions.back() != OMPD_unknown) { 4638 if (auto *C = OMPClauseWithPreInit::get(Clause)) 4639 PICs.push_back(C); 4640 if (auto *C = OMPClauseWithPostUpdate::get(Clause)) { 4641 if (Expr *E = C->getPostUpdateExpr()) 4642 MarkDeclarationsReferencedInExpr(E); 4643 } 4644 } 4645 if (Clause->getClauseKind() == OMPC_schedule) 4646 SC = cast<OMPScheduleClause>(Clause); 4647 else if (Clause->getClauseKind() == OMPC_ordered) 4648 OC = cast<OMPOrderedClause>(Clause); 4649 else if (Clause->getClauseKind() == OMPC_linear) 4650 LCs.push_back(cast<OMPLinearClause>(Clause)); 4651 } 4652 // Capture allocator expressions if used. 4653 for (Expr *E : DSAStack->getInnerAllocators()) 4654 MarkDeclarationsReferencedInExpr(E); 4655 // OpenMP, 2.7.1 Loop Construct, Restrictions 4656 // The nonmonotonic modifier cannot be specified if an ordered clause is 4657 // specified. 4658 if (SC && 4659 (SC->getFirstScheduleModifier() == OMPC_SCHEDULE_MODIFIER_nonmonotonic || 4660 SC->getSecondScheduleModifier() == 4661 OMPC_SCHEDULE_MODIFIER_nonmonotonic) && 4662 OC) { 4663 Diag(SC->getFirstScheduleModifier() == OMPC_SCHEDULE_MODIFIER_nonmonotonic 4664 ? SC->getFirstScheduleModifierLoc() 4665 : SC->getSecondScheduleModifierLoc(), 4666 diag::err_omp_simple_clause_incompatible_with_ordered) 4667 << getOpenMPClauseName(OMPC_schedule) 4668 << getOpenMPSimpleClauseTypeName(OMPC_schedule, 4669 OMPC_SCHEDULE_MODIFIER_nonmonotonic) 4670 << SourceRange(OC->getBeginLoc(), OC->getEndLoc()); 4671 ErrorFound = true; 4672 } 4673 // OpenMP 5.0, 2.9.2 Worksharing-Loop Construct, Restrictions. 4674 // If an order(concurrent) clause is present, an ordered clause may not appear 4675 // on the same directive. 4676 if (checkOrderedOrderSpecified(*this, Clauses)) 4677 ErrorFound = true; 4678 if (!LCs.empty() && OC && OC->getNumForLoops()) { 4679 for (const OMPLinearClause *C : LCs) { 4680 Diag(C->getBeginLoc(), diag::err_omp_linear_ordered) 4681 << SourceRange(OC->getBeginLoc(), OC->getEndLoc()); 4682 } 4683 ErrorFound = true; 4684 } 4685 if (isOpenMPWorksharingDirective(DSAStack->getCurrentDirective()) && 4686 isOpenMPSimdDirective(DSAStack->getCurrentDirective()) && OC && 4687 OC->getNumForLoops()) { 4688 Diag(OC->getBeginLoc(), diag::err_omp_ordered_simd) 4689 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 4690 ErrorFound = true; 4691 } 4692 if (ErrorFound) { 4693 return StmtError(); 4694 } 4695 StmtResult SR = S; 4696 unsigned CompletedRegions = 0; 4697 for (OpenMPDirectiveKind ThisCaptureRegion : llvm::reverse(CaptureRegions)) { 4698 // Mark all variables in private list clauses as used in inner region. 4699 // Required for proper codegen of combined directives. 4700 // TODO: add processing for other clauses. 4701 if (ThisCaptureRegion != OMPD_unknown) { 4702 for (const clang::OMPClauseWithPreInit *C : PICs) { 4703 OpenMPDirectiveKind CaptureRegion = C->getCaptureRegion(); 4704 // Find the particular capture region for the clause if the 4705 // directive is a combined one with multiple capture regions. 4706 // If the directive is not a combined one, the capture region 4707 // associated with the clause is OMPD_unknown and is generated 4708 // only once. 4709 if (CaptureRegion == ThisCaptureRegion || 4710 CaptureRegion == OMPD_unknown) { 4711 if (auto *DS = cast_or_null<DeclStmt>(C->getPreInitStmt())) { 4712 for (Decl *D : DS->decls()) 4713 MarkVariableReferenced(D->getLocation(), cast<VarDecl>(D)); 4714 } 4715 } 4716 } 4717 } 4718 if (ThisCaptureRegion == OMPD_target) { 4719 // Capture allocator traits in the target region. They are used implicitly 4720 // and, thus, are not captured by default. 4721 for (OMPClause *C : Clauses) { 4722 if (const auto *UAC = dyn_cast<OMPUsesAllocatorsClause>(C)) { 4723 for (unsigned I = 0, End = UAC->getNumberOfAllocators(); I < End; 4724 ++I) { 4725 OMPUsesAllocatorsClause::Data D = UAC->getAllocatorData(I); 4726 if (Expr *E = D.AllocatorTraits) 4727 MarkDeclarationsReferencedInExpr(E); 4728 } 4729 continue; 4730 } 4731 } 4732 } 4733 if (ThisCaptureRegion == OMPD_parallel) { 4734 // Capture temp arrays for inscan reductions and locals in aligned 4735 // clauses. 4736 for (OMPClause *C : Clauses) { 4737 if (auto *RC = dyn_cast<OMPReductionClause>(C)) { 4738 if (RC->getModifier() != OMPC_REDUCTION_inscan) 4739 continue; 4740 for (Expr *E : RC->copy_array_temps()) 4741 MarkDeclarationsReferencedInExpr(E); 4742 } 4743 if (auto *AC = dyn_cast<OMPAlignedClause>(C)) { 4744 for (Expr *E : AC->varlists()) 4745 MarkDeclarationsReferencedInExpr(E); 4746 } 4747 } 4748 } 4749 if (++CompletedRegions == CaptureRegions.size()) 4750 DSAStack->setBodyComplete(); 4751 SR = ActOnCapturedRegionEnd(SR.get()); 4752 } 4753 return SR; 4754 } 4755 4756 static bool checkCancelRegion(Sema &SemaRef, OpenMPDirectiveKind CurrentRegion, 4757 OpenMPDirectiveKind CancelRegion, 4758 SourceLocation StartLoc) { 4759 // CancelRegion is only needed for cancel and cancellation_point. 4760 if (CurrentRegion != OMPD_cancel && CurrentRegion != OMPD_cancellation_point) 4761 return false; 4762 4763 if (CancelRegion == OMPD_parallel || CancelRegion == OMPD_for || 4764 CancelRegion == OMPD_sections || CancelRegion == OMPD_taskgroup) 4765 return false; 4766 4767 SemaRef.Diag(StartLoc, diag::err_omp_wrong_cancel_region) 4768 << getOpenMPDirectiveName(CancelRegion); 4769 return true; 4770 } 4771 4772 static bool checkNestingOfRegions(Sema &SemaRef, const DSAStackTy *Stack, 4773 OpenMPDirectiveKind CurrentRegion, 4774 const DeclarationNameInfo &CurrentName, 4775 OpenMPDirectiveKind CancelRegion, 4776 OpenMPBindClauseKind BindKind, 4777 SourceLocation StartLoc) { 4778 if (Stack->getCurScope()) { 4779 OpenMPDirectiveKind ParentRegion = Stack->getParentDirective(); 4780 OpenMPDirectiveKind OffendingRegion = ParentRegion; 4781 bool NestingProhibited = false; 4782 bool CloseNesting = true; 4783 bool OrphanSeen = false; 4784 enum { 4785 NoRecommend, 4786 ShouldBeInParallelRegion, 4787 ShouldBeInOrderedRegion, 4788 ShouldBeInTargetRegion, 4789 ShouldBeInTeamsRegion, 4790 ShouldBeInLoopSimdRegion, 4791 } Recommend = NoRecommend; 4792 if (isOpenMPSimdDirective(ParentRegion) && 4793 ((SemaRef.LangOpts.OpenMP <= 45 && CurrentRegion != OMPD_ordered) || 4794 (SemaRef.LangOpts.OpenMP >= 50 && CurrentRegion != OMPD_ordered && 4795 CurrentRegion != OMPD_simd && CurrentRegion != OMPD_atomic && 4796 CurrentRegion != OMPD_scan))) { 4797 // OpenMP [2.16, Nesting of Regions] 4798 // OpenMP constructs may not be nested inside a simd region. 4799 // OpenMP [2.8.1,simd Construct, Restrictions] 4800 // An ordered construct with the simd clause is the only OpenMP 4801 // construct that can appear in the simd region. 4802 // Allowing a SIMD construct nested in another SIMD construct is an 4803 // extension. The OpenMP 4.5 spec does not allow it. Issue a warning 4804 // message. 4805 // OpenMP 5.0 [2.9.3.1, simd Construct, Restrictions] 4806 // The only OpenMP constructs that can be encountered during execution of 4807 // a simd region are the atomic construct, the loop construct, the simd 4808 // construct and the ordered construct with the simd clause. 4809 SemaRef.Diag(StartLoc, (CurrentRegion != OMPD_simd) 4810 ? diag::err_omp_prohibited_region_simd 4811 : diag::warn_omp_nesting_simd) 4812 << (SemaRef.LangOpts.OpenMP >= 50 ? 1 : 0); 4813 return CurrentRegion != OMPD_simd; 4814 } 4815 if (ParentRegion == OMPD_atomic) { 4816 // OpenMP [2.16, Nesting of Regions] 4817 // OpenMP constructs may not be nested inside an atomic region. 4818 SemaRef.Diag(StartLoc, diag::err_omp_prohibited_region_atomic); 4819 return true; 4820 } 4821 if (CurrentRegion == OMPD_section) { 4822 // OpenMP [2.7.2, sections Construct, Restrictions] 4823 // Orphaned section directives are prohibited. That is, the section 4824 // directives must appear within the sections construct and must not be 4825 // encountered elsewhere in the sections region. 4826 if (ParentRegion != OMPD_sections && 4827 ParentRegion != OMPD_parallel_sections) { 4828 SemaRef.Diag(StartLoc, diag::err_omp_orphaned_section_directive) 4829 << (ParentRegion != OMPD_unknown) 4830 << getOpenMPDirectiveName(ParentRegion); 4831 return true; 4832 } 4833 return false; 4834 } 4835 // Allow some constructs (except teams and cancellation constructs) to be 4836 // orphaned (they could be used in functions, called from OpenMP regions 4837 // with the required preconditions). 4838 if (ParentRegion == OMPD_unknown && 4839 !isOpenMPNestingTeamsDirective(CurrentRegion) && 4840 CurrentRegion != OMPD_cancellation_point && 4841 CurrentRegion != OMPD_cancel && CurrentRegion != OMPD_scan) 4842 return false; 4843 if (CurrentRegion == OMPD_cancellation_point || 4844 CurrentRegion == OMPD_cancel) { 4845 // OpenMP [2.16, Nesting of Regions] 4846 // A cancellation point construct for which construct-type-clause is 4847 // taskgroup must be nested inside a task construct. A cancellation 4848 // point construct for which construct-type-clause is not taskgroup must 4849 // be closely nested inside an OpenMP construct that matches the type 4850 // specified in construct-type-clause. 4851 // A cancel construct for which construct-type-clause is taskgroup must be 4852 // nested inside a task construct. A cancel construct for which 4853 // construct-type-clause is not taskgroup must be closely nested inside an 4854 // OpenMP construct that matches the type specified in 4855 // construct-type-clause. 4856 NestingProhibited = 4857 !((CancelRegion == OMPD_parallel && 4858 (ParentRegion == OMPD_parallel || 4859 ParentRegion == OMPD_target_parallel)) || 4860 (CancelRegion == OMPD_for && 4861 (ParentRegion == OMPD_for || ParentRegion == OMPD_parallel_for || 4862 ParentRegion == OMPD_target_parallel_for || 4863 ParentRegion == OMPD_distribute_parallel_for || 4864 ParentRegion == OMPD_teams_distribute_parallel_for || 4865 ParentRegion == OMPD_target_teams_distribute_parallel_for)) || 4866 (CancelRegion == OMPD_taskgroup && 4867 (ParentRegion == OMPD_task || 4868 (SemaRef.getLangOpts().OpenMP >= 50 && 4869 (ParentRegion == OMPD_taskloop || 4870 ParentRegion == OMPD_master_taskloop || 4871 ParentRegion == OMPD_masked_taskloop || 4872 ParentRegion == OMPD_parallel_master_taskloop)))) || 4873 (CancelRegion == OMPD_sections && 4874 (ParentRegion == OMPD_section || ParentRegion == OMPD_sections || 4875 ParentRegion == OMPD_parallel_sections))); 4876 OrphanSeen = ParentRegion == OMPD_unknown; 4877 } else if (CurrentRegion == OMPD_master || CurrentRegion == OMPD_masked) { 4878 // OpenMP 5.1 [2.22, Nesting of Regions] 4879 // A masked region may not be closely nested inside a worksharing, loop, 4880 // atomic, task, or taskloop region. 4881 NestingProhibited = isOpenMPWorksharingDirective(ParentRegion) || 4882 isOpenMPGenericLoopDirective(ParentRegion) || 4883 isOpenMPTaskingDirective(ParentRegion); 4884 } else if (CurrentRegion == OMPD_critical && CurrentName.getName()) { 4885 // OpenMP [2.16, Nesting of Regions] 4886 // A critical region may not be nested (closely or otherwise) inside a 4887 // critical region with the same name. Note that this restriction is not 4888 // sufficient to prevent deadlock. 4889 SourceLocation PreviousCriticalLoc; 4890 bool DeadLock = Stack->hasDirective( 4891 [CurrentName, &PreviousCriticalLoc](OpenMPDirectiveKind K, 4892 const DeclarationNameInfo &DNI, 4893 SourceLocation Loc) { 4894 if (K == OMPD_critical && DNI.getName() == CurrentName.getName()) { 4895 PreviousCriticalLoc = Loc; 4896 return true; 4897 } 4898 return false; 4899 }, 4900 false /* skip top directive */); 4901 if (DeadLock) { 4902 SemaRef.Diag(StartLoc, 4903 diag::err_omp_prohibited_region_critical_same_name) 4904 << CurrentName.getName(); 4905 if (PreviousCriticalLoc.isValid()) 4906 SemaRef.Diag(PreviousCriticalLoc, 4907 diag::note_omp_previous_critical_region); 4908 return true; 4909 } 4910 } else if (CurrentRegion == OMPD_barrier) { 4911 // OpenMP 5.1 [2.22, Nesting of Regions] 4912 // A barrier region may not be closely nested inside a worksharing, loop, 4913 // task, taskloop, critical, ordered, atomic, or masked region. 4914 NestingProhibited = 4915 isOpenMPWorksharingDirective(ParentRegion) || 4916 isOpenMPGenericLoopDirective(ParentRegion) || 4917 isOpenMPTaskingDirective(ParentRegion) || 4918 ParentRegion == OMPD_master || ParentRegion == OMPD_masked || 4919 ParentRegion == OMPD_parallel_master || 4920 ParentRegion == OMPD_parallel_masked || 4921 ParentRegion == OMPD_critical || ParentRegion == OMPD_ordered; 4922 } else if (isOpenMPWorksharingDirective(CurrentRegion) && 4923 !isOpenMPParallelDirective(CurrentRegion) && 4924 !isOpenMPTeamsDirective(CurrentRegion)) { 4925 // OpenMP 5.1 [2.22, Nesting of Regions] 4926 // A loop region that binds to a parallel region or a worksharing region 4927 // may not be closely nested inside a worksharing, loop, task, taskloop, 4928 // critical, ordered, atomic, or masked region. 4929 NestingProhibited = 4930 isOpenMPWorksharingDirective(ParentRegion) || 4931 isOpenMPGenericLoopDirective(ParentRegion) || 4932 isOpenMPTaskingDirective(ParentRegion) || 4933 ParentRegion == OMPD_master || ParentRegion == OMPD_masked || 4934 ParentRegion == OMPD_parallel_master || 4935 ParentRegion == OMPD_parallel_masked || 4936 ParentRegion == OMPD_critical || ParentRegion == OMPD_ordered; 4937 Recommend = ShouldBeInParallelRegion; 4938 } else if (CurrentRegion == OMPD_ordered) { 4939 // OpenMP [2.16, Nesting of Regions] 4940 // An ordered region may not be closely nested inside a critical, 4941 // atomic, or explicit task region. 4942 // An ordered region must be closely nested inside a loop region (or 4943 // parallel loop region) with an ordered clause. 4944 // OpenMP [2.8.1,simd Construct, Restrictions] 4945 // An ordered construct with the simd clause is the only OpenMP construct 4946 // that can appear in the simd region. 4947 NestingProhibited = ParentRegion == OMPD_critical || 4948 isOpenMPTaskingDirective(ParentRegion) || 4949 !(isOpenMPSimdDirective(ParentRegion) || 4950 Stack->isParentOrderedRegion()); 4951 Recommend = ShouldBeInOrderedRegion; 4952 } else if (isOpenMPNestingTeamsDirective(CurrentRegion)) { 4953 // OpenMP [2.16, Nesting of Regions] 4954 // If specified, a teams construct must be contained within a target 4955 // construct. 4956 NestingProhibited = 4957 (SemaRef.LangOpts.OpenMP <= 45 && ParentRegion != OMPD_target) || 4958 (SemaRef.LangOpts.OpenMP >= 50 && ParentRegion != OMPD_unknown && 4959 ParentRegion != OMPD_target); 4960 OrphanSeen = ParentRegion == OMPD_unknown; 4961 Recommend = ShouldBeInTargetRegion; 4962 } else if (CurrentRegion == OMPD_scan) { 4963 // OpenMP [2.16, Nesting of Regions] 4964 // If specified, a teams construct must be contained within a target 4965 // construct. 4966 NestingProhibited = 4967 SemaRef.LangOpts.OpenMP < 50 || 4968 (ParentRegion != OMPD_simd && ParentRegion != OMPD_for && 4969 ParentRegion != OMPD_for_simd && ParentRegion != OMPD_parallel_for && 4970 ParentRegion != OMPD_parallel_for_simd); 4971 OrphanSeen = ParentRegion == OMPD_unknown; 4972 Recommend = ShouldBeInLoopSimdRegion; 4973 } 4974 if (!NestingProhibited && 4975 !isOpenMPTargetExecutionDirective(CurrentRegion) && 4976 !isOpenMPTargetDataManagementDirective(CurrentRegion) && 4977 (ParentRegion == OMPD_teams || ParentRegion == OMPD_target_teams)) { 4978 // OpenMP [5.1, 2.22, Nesting of Regions] 4979 // distribute, distribute simd, distribute parallel worksharing-loop, 4980 // distribute parallel worksharing-loop SIMD, loop, parallel regions, 4981 // including any parallel regions arising from combined constructs, 4982 // omp_get_num_teams() regions, and omp_get_team_num() regions are the 4983 // only OpenMP regions that may be strictly nested inside the teams 4984 // region. 4985 // 4986 // As an extension, we permit atomic within teams as well. 4987 NestingProhibited = !isOpenMPParallelDirective(CurrentRegion) && 4988 !isOpenMPDistributeDirective(CurrentRegion) && 4989 CurrentRegion != OMPD_loop && 4990 !(SemaRef.getLangOpts().OpenMPExtensions && 4991 CurrentRegion == OMPD_atomic); 4992 Recommend = ShouldBeInParallelRegion; 4993 } 4994 if (!NestingProhibited && CurrentRegion == OMPD_loop) { 4995 // OpenMP [5.1, 2.11.7, loop Construct, Restrictions] 4996 // If the bind clause is present on the loop construct and binding is 4997 // teams then the corresponding loop region must be strictly nested inside 4998 // a teams region. 4999 NestingProhibited = BindKind == OMPC_BIND_teams && 5000 ParentRegion != OMPD_teams && 5001 ParentRegion != OMPD_target_teams; 5002 Recommend = ShouldBeInTeamsRegion; 5003 } 5004 if (!NestingProhibited && 5005 isOpenMPNestingDistributeDirective(CurrentRegion)) { 5006 // OpenMP 4.5 [2.17 Nesting of Regions] 5007 // The region associated with the distribute construct must be strictly 5008 // nested inside a teams region 5009 NestingProhibited = 5010 (ParentRegion != OMPD_teams && ParentRegion != OMPD_target_teams); 5011 Recommend = ShouldBeInTeamsRegion; 5012 } 5013 if (!NestingProhibited && 5014 (isOpenMPTargetExecutionDirective(CurrentRegion) || 5015 isOpenMPTargetDataManagementDirective(CurrentRegion))) { 5016 // OpenMP 4.5 [2.17 Nesting of Regions] 5017 // If a target, target update, target data, target enter data, or 5018 // target exit data construct is encountered during execution of a 5019 // target region, the behavior is unspecified. 5020 NestingProhibited = Stack->hasDirective( 5021 [&OffendingRegion](OpenMPDirectiveKind K, const DeclarationNameInfo &, 5022 SourceLocation) { 5023 if (isOpenMPTargetExecutionDirective(K)) { 5024 OffendingRegion = K; 5025 return true; 5026 } 5027 return false; 5028 }, 5029 false /* don't skip top directive */); 5030 CloseNesting = false; 5031 } 5032 if (NestingProhibited) { 5033 if (OrphanSeen) { 5034 SemaRef.Diag(StartLoc, diag::err_omp_orphaned_device_directive) 5035 << getOpenMPDirectiveName(CurrentRegion) << Recommend; 5036 } else { 5037 SemaRef.Diag(StartLoc, diag::err_omp_prohibited_region) 5038 << CloseNesting << getOpenMPDirectiveName(OffendingRegion) 5039 << Recommend << getOpenMPDirectiveName(CurrentRegion); 5040 } 5041 return true; 5042 } 5043 } 5044 return false; 5045 } 5046 5047 struct Kind2Unsigned { 5048 using argument_type = OpenMPDirectiveKind; 5049 unsigned operator()(argument_type DK) { return unsigned(DK); } 5050 }; 5051 static bool checkIfClauses(Sema &S, OpenMPDirectiveKind Kind, 5052 ArrayRef<OMPClause *> Clauses, 5053 ArrayRef<OpenMPDirectiveKind> AllowedNameModifiers) { 5054 bool ErrorFound = false; 5055 unsigned NamedModifiersNumber = 0; 5056 llvm::IndexedMap<const OMPIfClause *, Kind2Unsigned> FoundNameModifiers; 5057 FoundNameModifiers.resize(llvm::omp::Directive_enumSize + 1); 5058 SmallVector<SourceLocation, 4> NameModifierLoc; 5059 for (const OMPClause *C : Clauses) { 5060 if (const auto *IC = dyn_cast_or_null<OMPIfClause>(C)) { 5061 // At most one if clause without a directive-name-modifier can appear on 5062 // the directive. 5063 OpenMPDirectiveKind CurNM = IC->getNameModifier(); 5064 if (FoundNameModifiers[CurNM]) { 5065 S.Diag(C->getBeginLoc(), diag::err_omp_more_one_clause) 5066 << getOpenMPDirectiveName(Kind) << getOpenMPClauseName(OMPC_if) 5067 << (CurNM != OMPD_unknown) << getOpenMPDirectiveName(CurNM); 5068 ErrorFound = true; 5069 } else if (CurNM != OMPD_unknown) { 5070 NameModifierLoc.push_back(IC->getNameModifierLoc()); 5071 ++NamedModifiersNumber; 5072 } 5073 FoundNameModifiers[CurNM] = IC; 5074 if (CurNM == OMPD_unknown) 5075 continue; 5076 // Check if the specified name modifier is allowed for the current 5077 // directive. 5078 // At most one if clause with the particular directive-name-modifier can 5079 // appear on the directive. 5080 if (!llvm::is_contained(AllowedNameModifiers, CurNM)) { 5081 S.Diag(IC->getNameModifierLoc(), 5082 diag::err_omp_wrong_if_directive_name_modifier) 5083 << getOpenMPDirectiveName(CurNM) << getOpenMPDirectiveName(Kind); 5084 ErrorFound = true; 5085 } 5086 } 5087 } 5088 // If any if clause on the directive includes a directive-name-modifier then 5089 // all if clauses on the directive must include a directive-name-modifier. 5090 if (FoundNameModifiers[OMPD_unknown] && NamedModifiersNumber > 0) { 5091 if (NamedModifiersNumber == AllowedNameModifiers.size()) { 5092 S.Diag(FoundNameModifiers[OMPD_unknown]->getBeginLoc(), 5093 diag::err_omp_no_more_if_clause); 5094 } else { 5095 std::string Values; 5096 std::string Sep(", "); 5097 unsigned AllowedCnt = 0; 5098 unsigned TotalAllowedNum = 5099 AllowedNameModifiers.size() - NamedModifiersNumber; 5100 for (unsigned Cnt = 0, End = AllowedNameModifiers.size(); Cnt < End; 5101 ++Cnt) { 5102 OpenMPDirectiveKind NM = AllowedNameModifiers[Cnt]; 5103 if (!FoundNameModifiers[NM]) { 5104 Values += "'"; 5105 Values += getOpenMPDirectiveName(NM); 5106 Values += "'"; 5107 if (AllowedCnt + 2 == TotalAllowedNum) 5108 Values += " or "; 5109 else if (AllowedCnt + 1 != TotalAllowedNum) 5110 Values += Sep; 5111 ++AllowedCnt; 5112 } 5113 } 5114 S.Diag(FoundNameModifiers[OMPD_unknown]->getCondition()->getBeginLoc(), 5115 diag::err_omp_unnamed_if_clause) 5116 << (TotalAllowedNum > 1) << Values; 5117 } 5118 for (SourceLocation Loc : NameModifierLoc) { 5119 S.Diag(Loc, diag::note_omp_previous_named_if_clause); 5120 } 5121 ErrorFound = true; 5122 } 5123 return ErrorFound; 5124 } 5125 5126 static std::pair<ValueDecl *, bool> getPrivateItem(Sema &S, Expr *&RefExpr, 5127 SourceLocation &ELoc, 5128 SourceRange &ERange, 5129 bool AllowArraySection) { 5130 if (RefExpr->isTypeDependent() || RefExpr->isValueDependent() || 5131 RefExpr->containsUnexpandedParameterPack()) 5132 return std::make_pair(nullptr, true); 5133 5134 // OpenMP [3.1, C/C++] 5135 // A list item is a variable name. 5136 // OpenMP [2.9.3.3, Restrictions, p.1] 5137 // A variable that is part of another variable (as an array or 5138 // structure element) cannot appear in a private clause. 5139 RefExpr = RefExpr->IgnoreParens(); 5140 enum { 5141 NoArrayExpr = -1, 5142 ArraySubscript = 0, 5143 OMPArraySection = 1 5144 } IsArrayExpr = NoArrayExpr; 5145 if (AllowArraySection) { 5146 if (auto *ASE = dyn_cast_or_null<ArraySubscriptExpr>(RefExpr)) { 5147 Expr *Base = ASE->getBase()->IgnoreParenImpCasts(); 5148 while (auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base)) 5149 Base = TempASE->getBase()->IgnoreParenImpCasts(); 5150 RefExpr = Base; 5151 IsArrayExpr = ArraySubscript; 5152 } else if (auto *OASE = dyn_cast_or_null<OMPArraySectionExpr>(RefExpr)) { 5153 Expr *Base = OASE->getBase()->IgnoreParenImpCasts(); 5154 while (auto *TempOASE = dyn_cast<OMPArraySectionExpr>(Base)) 5155 Base = TempOASE->getBase()->IgnoreParenImpCasts(); 5156 while (auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base)) 5157 Base = TempASE->getBase()->IgnoreParenImpCasts(); 5158 RefExpr = Base; 5159 IsArrayExpr = OMPArraySection; 5160 } 5161 } 5162 ELoc = RefExpr->getExprLoc(); 5163 ERange = RefExpr->getSourceRange(); 5164 RefExpr = RefExpr->IgnoreParenImpCasts(); 5165 auto *DE = dyn_cast_or_null<DeclRefExpr>(RefExpr); 5166 auto *ME = dyn_cast_or_null<MemberExpr>(RefExpr); 5167 if ((!DE || !isa<VarDecl>(DE->getDecl())) && 5168 (S.getCurrentThisType().isNull() || !ME || 5169 !isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts()) || 5170 !isa<FieldDecl>(ME->getMemberDecl()))) { 5171 if (IsArrayExpr != NoArrayExpr) { 5172 S.Diag(ELoc, diag::err_omp_expected_base_var_name) 5173 << IsArrayExpr << ERange; 5174 } else { 5175 S.Diag(ELoc, 5176 AllowArraySection 5177 ? diag::err_omp_expected_var_name_member_expr_or_array_item 5178 : diag::err_omp_expected_var_name_member_expr) 5179 << (S.getCurrentThisType().isNull() ? 0 : 1) << ERange; 5180 } 5181 return std::make_pair(nullptr, false); 5182 } 5183 return std::make_pair( 5184 getCanonicalDecl(DE ? DE->getDecl() : ME->getMemberDecl()), false); 5185 } 5186 5187 namespace { 5188 /// Checks if the allocator is used in uses_allocators clause to be allowed in 5189 /// target regions. 5190 class AllocatorChecker final : public ConstStmtVisitor<AllocatorChecker, bool> { 5191 DSAStackTy *S = nullptr; 5192 5193 public: 5194 bool VisitDeclRefExpr(const DeclRefExpr *E) { 5195 return S->isUsesAllocatorsDecl(E->getDecl()) 5196 .value_or(DSAStackTy::UsesAllocatorsDeclKind::AllocatorTrait) == 5197 DSAStackTy::UsesAllocatorsDeclKind::AllocatorTrait; 5198 } 5199 bool VisitStmt(const Stmt *S) { 5200 for (const Stmt *Child : S->children()) { 5201 if (Child && Visit(Child)) 5202 return true; 5203 } 5204 return false; 5205 } 5206 explicit AllocatorChecker(DSAStackTy *S) : S(S) {} 5207 }; 5208 } // namespace 5209 5210 static void checkAllocateClauses(Sema &S, DSAStackTy *Stack, 5211 ArrayRef<OMPClause *> Clauses) { 5212 assert(!S.CurContext->isDependentContext() && 5213 "Expected non-dependent context."); 5214 auto AllocateRange = 5215 llvm::make_filter_range(Clauses, OMPAllocateClause::classof); 5216 llvm::DenseMap<CanonicalDeclPtr<Decl>, CanonicalDeclPtr<VarDecl>> DeclToCopy; 5217 auto PrivateRange = llvm::make_filter_range(Clauses, [](const OMPClause *C) { 5218 return isOpenMPPrivate(C->getClauseKind()); 5219 }); 5220 for (OMPClause *Cl : PrivateRange) { 5221 MutableArrayRef<Expr *>::iterator I, It, Et; 5222 if (Cl->getClauseKind() == OMPC_private) { 5223 auto *PC = cast<OMPPrivateClause>(Cl); 5224 I = PC->private_copies().begin(); 5225 It = PC->varlist_begin(); 5226 Et = PC->varlist_end(); 5227 } else if (Cl->getClauseKind() == OMPC_firstprivate) { 5228 auto *PC = cast<OMPFirstprivateClause>(Cl); 5229 I = PC->private_copies().begin(); 5230 It = PC->varlist_begin(); 5231 Et = PC->varlist_end(); 5232 } else if (Cl->getClauseKind() == OMPC_lastprivate) { 5233 auto *PC = cast<OMPLastprivateClause>(Cl); 5234 I = PC->private_copies().begin(); 5235 It = PC->varlist_begin(); 5236 Et = PC->varlist_end(); 5237 } else if (Cl->getClauseKind() == OMPC_linear) { 5238 auto *PC = cast<OMPLinearClause>(Cl); 5239 I = PC->privates().begin(); 5240 It = PC->varlist_begin(); 5241 Et = PC->varlist_end(); 5242 } else if (Cl->getClauseKind() == OMPC_reduction) { 5243 auto *PC = cast<OMPReductionClause>(Cl); 5244 I = PC->privates().begin(); 5245 It = PC->varlist_begin(); 5246 Et = PC->varlist_end(); 5247 } else if (Cl->getClauseKind() == OMPC_task_reduction) { 5248 auto *PC = cast<OMPTaskReductionClause>(Cl); 5249 I = PC->privates().begin(); 5250 It = PC->varlist_begin(); 5251 Et = PC->varlist_end(); 5252 } else if (Cl->getClauseKind() == OMPC_in_reduction) { 5253 auto *PC = cast<OMPInReductionClause>(Cl); 5254 I = PC->privates().begin(); 5255 It = PC->varlist_begin(); 5256 Et = PC->varlist_end(); 5257 } else { 5258 llvm_unreachable("Expected private clause."); 5259 } 5260 for (Expr *E : llvm::make_range(It, Et)) { 5261 if (!*I) { 5262 ++I; 5263 continue; 5264 } 5265 SourceLocation ELoc; 5266 SourceRange ERange; 5267 Expr *SimpleRefExpr = E; 5268 auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange, 5269 /*AllowArraySection=*/true); 5270 DeclToCopy.try_emplace(Res.first, 5271 cast<VarDecl>(cast<DeclRefExpr>(*I)->getDecl())); 5272 ++I; 5273 } 5274 } 5275 for (OMPClause *C : AllocateRange) { 5276 auto *AC = cast<OMPAllocateClause>(C); 5277 if (S.getLangOpts().OpenMP >= 50 && 5278 !Stack->hasRequiresDeclWithClause<OMPDynamicAllocatorsClause>() && 5279 isOpenMPTargetExecutionDirective(Stack->getCurrentDirective()) && 5280 AC->getAllocator()) { 5281 Expr *Allocator = AC->getAllocator(); 5282 // OpenMP, 2.12.5 target Construct 5283 // Memory allocators that do not appear in a uses_allocators clause cannot 5284 // appear as an allocator in an allocate clause or be used in the target 5285 // region unless a requires directive with the dynamic_allocators clause 5286 // is present in the same compilation unit. 5287 AllocatorChecker Checker(Stack); 5288 if (Checker.Visit(Allocator)) 5289 S.Diag(Allocator->getExprLoc(), 5290 diag::err_omp_allocator_not_in_uses_allocators) 5291 << Allocator->getSourceRange(); 5292 } 5293 OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind = 5294 getAllocatorKind(S, Stack, AC->getAllocator()); 5295 // OpenMP, 2.11.4 allocate Clause, Restrictions. 5296 // For task, taskloop or target directives, allocation requests to memory 5297 // allocators with the trait access set to thread result in unspecified 5298 // behavior. 5299 if (AllocatorKind == OMPAllocateDeclAttr::OMPThreadMemAlloc && 5300 (isOpenMPTaskingDirective(Stack->getCurrentDirective()) || 5301 isOpenMPTargetExecutionDirective(Stack->getCurrentDirective()))) { 5302 S.Diag(AC->getAllocator()->getExprLoc(), 5303 diag::warn_omp_allocate_thread_on_task_target_directive) 5304 << getOpenMPDirectiveName(Stack->getCurrentDirective()); 5305 } 5306 for (Expr *E : AC->varlists()) { 5307 SourceLocation ELoc; 5308 SourceRange ERange; 5309 Expr *SimpleRefExpr = E; 5310 auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange); 5311 ValueDecl *VD = Res.first; 5312 DSAStackTy::DSAVarData Data = Stack->getTopDSA(VD, /*FromParent=*/false); 5313 if (!isOpenMPPrivate(Data.CKind)) { 5314 S.Diag(E->getExprLoc(), 5315 diag::err_omp_expected_private_copy_for_allocate); 5316 continue; 5317 } 5318 VarDecl *PrivateVD = DeclToCopy[VD]; 5319 if (checkPreviousOMPAllocateAttribute(S, Stack, E, PrivateVD, 5320 AllocatorKind, AC->getAllocator())) 5321 continue; 5322 // Placeholder until allocate clause supports align modifier. 5323 Expr *Alignment = nullptr; 5324 applyOMPAllocateAttribute(S, PrivateVD, AllocatorKind, AC->getAllocator(), 5325 Alignment, E->getSourceRange()); 5326 } 5327 } 5328 } 5329 5330 namespace { 5331 /// Rewrite statements and expressions for Sema \p Actions CurContext. 5332 /// 5333 /// Used to wrap already parsed statements/expressions into a new CapturedStmt 5334 /// context. DeclRefExpr used inside the new context are changed to refer to the 5335 /// captured variable instead. 5336 class CaptureVars : public TreeTransform<CaptureVars> { 5337 using BaseTransform = TreeTransform<CaptureVars>; 5338 5339 public: 5340 CaptureVars(Sema &Actions) : BaseTransform(Actions) {} 5341 5342 bool AlwaysRebuild() { return true; } 5343 }; 5344 } // namespace 5345 5346 static VarDecl *precomputeExpr(Sema &Actions, 5347 SmallVectorImpl<Stmt *> &BodyStmts, Expr *E, 5348 StringRef Name) { 5349 Expr *NewE = AssertSuccess(CaptureVars(Actions).TransformExpr(E)); 5350 VarDecl *NewVar = buildVarDecl(Actions, {}, NewE->getType(), Name, nullptr, 5351 dyn_cast<DeclRefExpr>(E->IgnoreImplicit())); 5352 auto *NewDeclStmt = cast<DeclStmt>(AssertSuccess( 5353 Actions.ActOnDeclStmt(Actions.ConvertDeclToDeclGroup(NewVar), {}, {}))); 5354 Actions.AddInitializerToDecl(NewDeclStmt->getSingleDecl(), NewE, false); 5355 BodyStmts.push_back(NewDeclStmt); 5356 return NewVar; 5357 } 5358 5359 /// Create a closure that computes the number of iterations of a loop. 5360 /// 5361 /// \param Actions The Sema object. 5362 /// \param LogicalTy Type for the logical iteration number. 5363 /// \param Rel Comparison operator of the loop condition. 5364 /// \param StartExpr Value of the loop counter at the first iteration. 5365 /// \param StopExpr Expression the loop counter is compared against in the loop 5366 /// condition. \param StepExpr Amount of increment after each iteration. 5367 /// 5368 /// \return Closure (CapturedStmt) of the distance calculation. 5369 static CapturedStmt *buildDistanceFunc(Sema &Actions, QualType LogicalTy, 5370 BinaryOperator::Opcode Rel, 5371 Expr *StartExpr, Expr *StopExpr, 5372 Expr *StepExpr) { 5373 ASTContext &Ctx = Actions.getASTContext(); 5374 TypeSourceInfo *LogicalTSI = Ctx.getTrivialTypeSourceInfo(LogicalTy); 5375 5376 // Captured regions currently don't support return values, we use an 5377 // out-parameter instead. All inputs are implicit captures. 5378 // TODO: Instead of capturing each DeclRefExpr occurring in 5379 // StartExpr/StopExpr/Step, these could also be passed as a value capture. 5380 QualType ResultTy = Ctx.getLValueReferenceType(LogicalTy); 5381 Sema::CapturedParamNameType Params[] = {{"Distance", ResultTy}, 5382 {StringRef(), QualType()}}; 5383 Actions.ActOnCapturedRegionStart({}, nullptr, CR_Default, Params); 5384 5385 Stmt *Body; 5386 { 5387 Sema::CompoundScopeRAII CompoundScope(Actions); 5388 CapturedDecl *CS = cast<CapturedDecl>(Actions.CurContext); 5389 5390 // Get the LValue expression for the result. 5391 ImplicitParamDecl *DistParam = CS->getParam(0); 5392 DeclRefExpr *DistRef = Actions.BuildDeclRefExpr( 5393 DistParam, LogicalTy, VK_LValue, {}, nullptr, nullptr, {}, nullptr); 5394 5395 SmallVector<Stmt *, 4> BodyStmts; 5396 5397 // Capture all referenced variable references. 5398 // TODO: Instead of computing NewStart/NewStop/NewStep inside the 5399 // CapturedStmt, we could compute them before and capture the result, to be 5400 // used jointly with the LoopVar function. 5401 VarDecl *NewStart = precomputeExpr(Actions, BodyStmts, StartExpr, ".start"); 5402 VarDecl *NewStop = precomputeExpr(Actions, BodyStmts, StopExpr, ".stop"); 5403 VarDecl *NewStep = precomputeExpr(Actions, BodyStmts, StepExpr, ".step"); 5404 auto BuildVarRef = [&](VarDecl *VD) { 5405 return buildDeclRefExpr(Actions, VD, VD->getType(), {}); 5406 }; 5407 5408 IntegerLiteral *Zero = IntegerLiteral::Create( 5409 Ctx, llvm::APInt(Ctx.getIntWidth(LogicalTy), 0), LogicalTy, {}); 5410 IntegerLiteral *One = IntegerLiteral::Create( 5411 Ctx, llvm::APInt(Ctx.getIntWidth(LogicalTy), 1), LogicalTy, {}); 5412 Expr *Dist; 5413 if (Rel == BO_NE) { 5414 // When using a != comparison, the increment can be +1 or -1. This can be 5415 // dynamic at runtime, so we need to check for the direction. 5416 Expr *IsNegStep = AssertSuccess( 5417 Actions.BuildBinOp(nullptr, {}, BO_LT, BuildVarRef(NewStep), Zero)); 5418 5419 // Positive increment. 5420 Expr *ForwardRange = AssertSuccess(Actions.BuildBinOp( 5421 nullptr, {}, BO_Sub, BuildVarRef(NewStop), BuildVarRef(NewStart))); 5422 ForwardRange = AssertSuccess( 5423 Actions.BuildCStyleCastExpr({}, LogicalTSI, {}, ForwardRange)); 5424 Expr *ForwardDist = AssertSuccess(Actions.BuildBinOp( 5425 nullptr, {}, BO_Div, ForwardRange, BuildVarRef(NewStep))); 5426 5427 // Negative increment. 5428 Expr *BackwardRange = AssertSuccess(Actions.BuildBinOp( 5429 nullptr, {}, BO_Sub, BuildVarRef(NewStart), BuildVarRef(NewStop))); 5430 BackwardRange = AssertSuccess( 5431 Actions.BuildCStyleCastExpr({}, LogicalTSI, {}, BackwardRange)); 5432 Expr *NegIncAmount = AssertSuccess( 5433 Actions.BuildUnaryOp(nullptr, {}, UO_Minus, BuildVarRef(NewStep))); 5434 Expr *BackwardDist = AssertSuccess( 5435 Actions.BuildBinOp(nullptr, {}, BO_Div, BackwardRange, NegIncAmount)); 5436 5437 // Use the appropriate case. 5438 Dist = AssertSuccess(Actions.ActOnConditionalOp( 5439 {}, {}, IsNegStep, BackwardDist, ForwardDist)); 5440 } else { 5441 assert((Rel == BO_LT || Rel == BO_LE || Rel == BO_GE || Rel == BO_GT) && 5442 "Expected one of these relational operators"); 5443 5444 // We can derive the direction from any other comparison operator. It is 5445 // non well-formed OpenMP if Step increments/decrements in the other 5446 // directions. Whether at least the first iteration passes the loop 5447 // condition. 5448 Expr *HasAnyIteration = AssertSuccess(Actions.BuildBinOp( 5449 nullptr, {}, Rel, BuildVarRef(NewStart), BuildVarRef(NewStop))); 5450 5451 // Compute the range between first and last counter value. 5452 Expr *Range; 5453 if (Rel == BO_GE || Rel == BO_GT) 5454 Range = AssertSuccess(Actions.BuildBinOp( 5455 nullptr, {}, BO_Sub, BuildVarRef(NewStart), BuildVarRef(NewStop))); 5456 else 5457 Range = AssertSuccess(Actions.BuildBinOp( 5458 nullptr, {}, BO_Sub, BuildVarRef(NewStop), BuildVarRef(NewStart))); 5459 5460 // Ensure unsigned range space. 5461 Range = 5462 AssertSuccess(Actions.BuildCStyleCastExpr({}, LogicalTSI, {}, Range)); 5463 5464 if (Rel == BO_LE || Rel == BO_GE) { 5465 // Add one to the range if the relational operator is inclusive. 5466 Range = 5467 AssertSuccess(Actions.BuildBinOp(nullptr, {}, BO_Add, Range, One)); 5468 } 5469 5470 // Divide by the absolute step amount. If the range is not a multiple of 5471 // the step size, rounding-up the effective upper bound ensures that the 5472 // last iteration is included. 5473 // Note that the rounding-up may cause an overflow in a temporry that 5474 // could be avoided, but would have occurred in a C-style for-loop as well. 5475 Expr *Divisor = BuildVarRef(NewStep); 5476 if (Rel == BO_GE || Rel == BO_GT) 5477 Divisor = 5478 AssertSuccess(Actions.BuildUnaryOp(nullptr, {}, UO_Minus, Divisor)); 5479 Expr *DivisorMinusOne = 5480 AssertSuccess(Actions.BuildBinOp(nullptr, {}, BO_Sub, Divisor, One)); 5481 Expr *RangeRoundUp = AssertSuccess( 5482 Actions.BuildBinOp(nullptr, {}, BO_Add, Range, DivisorMinusOne)); 5483 Dist = AssertSuccess( 5484 Actions.BuildBinOp(nullptr, {}, BO_Div, RangeRoundUp, Divisor)); 5485 5486 // If there is not at least one iteration, the range contains garbage. Fix 5487 // to zero in this case. 5488 Dist = AssertSuccess( 5489 Actions.ActOnConditionalOp({}, {}, HasAnyIteration, Dist, Zero)); 5490 } 5491 5492 // Assign the result to the out-parameter. 5493 Stmt *ResultAssign = AssertSuccess(Actions.BuildBinOp( 5494 Actions.getCurScope(), {}, BO_Assign, DistRef, Dist)); 5495 BodyStmts.push_back(ResultAssign); 5496 5497 Body = AssertSuccess(Actions.ActOnCompoundStmt({}, {}, BodyStmts, false)); 5498 } 5499 5500 return cast<CapturedStmt>( 5501 AssertSuccess(Actions.ActOnCapturedRegionEnd(Body))); 5502 } 5503 5504 /// Create a closure that computes the loop variable from the logical iteration 5505 /// number. 5506 /// 5507 /// \param Actions The Sema object. 5508 /// \param LoopVarTy Type for the loop variable used for result value. 5509 /// \param LogicalTy Type for the logical iteration number. 5510 /// \param StartExpr Value of the loop counter at the first iteration. 5511 /// \param Step Amount of increment after each iteration. 5512 /// \param Deref Whether the loop variable is a dereference of the loop 5513 /// counter variable. 5514 /// 5515 /// \return Closure (CapturedStmt) of the loop value calculation. 5516 static CapturedStmt *buildLoopVarFunc(Sema &Actions, QualType LoopVarTy, 5517 QualType LogicalTy, 5518 DeclRefExpr *StartExpr, Expr *Step, 5519 bool Deref) { 5520 ASTContext &Ctx = Actions.getASTContext(); 5521 5522 // Pass the result as an out-parameter. Passing as return value would require 5523 // the OpenMPIRBuilder to know additional C/C++ semantics, such as how to 5524 // invoke a copy constructor. 5525 QualType TargetParamTy = Ctx.getLValueReferenceType(LoopVarTy); 5526 Sema::CapturedParamNameType Params[] = {{"LoopVar", TargetParamTy}, 5527 {"Logical", LogicalTy}, 5528 {StringRef(), QualType()}}; 5529 Actions.ActOnCapturedRegionStart({}, nullptr, CR_Default, Params); 5530 5531 // Capture the initial iterator which represents the LoopVar value at the 5532 // zero's logical iteration. Since the original ForStmt/CXXForRangeStmt update 5533 // it in every iteration, capture it by value before it is modified. 5534 VarDecl *StartVar = cast<VarDecl>(StartExpr->getDecl()); 5535 bool Invalid = Actions.tryCaptureVariable(StartVar, {}, 5536 Sema::TryCapture_ExplicitByVal, {}); 5537 (void)Invalid; 5538 assert(!Invalid && "Expecting capture-by-value to work."); 5539 5540 Expr *Body; 5541 { 5542 Sema::CompoundScopeRAII CompoundScope(Actions); 5543 auto *CS = cast<CapturedDecl>(Actions.CurContext); 5544 5545 ImplicitParamDecl *TargetParam = CS->getParam(0); 5546 DeclRefExpr *TargetRef = Actions.BuildDeclRefExpr( 5547 TargetParam, LoopVarTy, VK_LValue, {}, nullptr, nullptr, {}, nullptr); 5548 ImplicitParamDecl *IndvarParam = CS->getParam(1); 5549 DeclRefExpr *LogicalRef = Actions.BuildDeclRefExpr( 5550 IndvarParam, LogicalTy, VK_LValue, {}, nullptr, nullptr, {}, nullptr); 5551 5552 // Capture the Start expression. 5553 CaptureVars Recap(Actions); 5554 Expr *NewStart = AssertSuccess(Recap.TransformExpr(StartExpr)); 5555 Expr *NewStep = AssertSuccess(Recap.TransformExpr(Step)); 5556 5557 Expr *Skip = AssertSuccess( 5558 Actions.BuildBinOp(nullptr, {}, BO_Mul, NewStep, LogicalRef)); 5559 // TODO: Explicitly cast to the iterator's difference_type instead of 5560 // relying on implicit conversion. 5561 Expr *Advanced = 5562 AssertSuccess(Actions.BuildBinOp(nullptr, {}, BO_Add, NewStart, Skip)); 5563 5564 if (Deref) { 5565 // For range-based for-loops convert the loop counter value to a concrete 5566 // loop variable value by dereferencing the iterator. 5567 Advanced = 5568 AssertSuccess(Actions.BuildUnaryOp(nullptr, {}, UO_Deref, Advanced)); 5569 } 5570 5571 // Assign the result to the output parameter. 5572 Body = AssertSuccess(Actions.BuildBinOp(Actions.getCurScope(), {}, 5573 BO_Assign, TargetRef, Advanced)); 5574 } 5575 return cast<CapturedStmt>( 5576 AssertSuccess(Actions.ActOnCapturedRegionEnd(Body))); 5577 } 5578 5579 StmtResult Sema::ActOnOpenMPCanonicalLoop(Stmt *AStmt) { 5580 ASTContext &Ctx = getASTContext(); 5581 5582 // Extract the common elements of ForStmt and CXXForRangeStmt: 5583 // Loop variable, repeat condition, increment 5584 Expr *Cond, *Inc; 5585 VarDecl *LIVDecl, *LUVDecl; 5586 if (auto *For = dyn_cast<ForStmt>(AStmt)) { 5587 Stmt *Init = For->getInit(); 5588 if (auto *LCVarDeclStmt = dyn_cast<DeclStmt>(Init)) { 5589 // For statement declares loop variable. 5590 LIVDecl = cast<VarDecl>(LCVarDeclStmt->getSingleDecl()); 5591 } else if (auto *LCAssign = dyn_cast<BinaryOperator>(Init)) { 5592 // For statement reuses variable. 5593 assert(LCAssign->getOpcode() == BO_Assign && 5594 "init part must be a loop variable assignment"); 5595 auto *CounterRef = cast<DeclRefExpr>(LCAssign->getLHS()); 5596 LIVDecl = cast<VarDecl>(CounterRef->getDecl()); 5597 } else 5598 llvm_unreachable("Cannot determine loop variable"); 5599 LUVDecl = LIVDecl; 5600 5601 Cond = For->getCond(); 5602 Inc = For->getInc(); 5603 } else if (auto *RangeFor = dyn_cast<CXXForRangeStmt>(AStmt)) { 5604 DeclStmt *BeginStmt = RangeFor->getBeginStmt(); 5605 LIVDecl = cast<VarDecl>(BeginStmt->getSingleDecl()); 5606 LUVDecl = RangeFor->getLoopVariable(); 5607 5608 Cond = RangeFor->getCond(); 5609 Inc = RangeFor->getInc(); 5610 } else 5611 llvm_unreachable("unhandled kind of loop"); 5612 5613 QualType CounterTy = LIVDecl->getType(); 5614 QualType LVTy = LUVDecl->getType(); 5615 5616 // Analyze the loop condition. 5617 Expr *LHS, *RHS; 5618 BinaryOperator::Opcode CondRel; 5619 Cond = Cond->IgnoreImplicit(); 5620 if (auto *CondBinExpr = dyn_cast<BinaryOperator>(Cond)) { 5621 LHS = CondBinExpr->getLHS(); 5622 RHS = CondBinExpr->getRHS(); 5623 CondRel = CondBinExpr->getOpcode(); 5624 } else if (auto *CondCXXOp = dyn_cast<CXXOperatorCallExpr>(Cond)) { 5625 assert(CondCXXOp->getNumArgs() == 2 && "Comparison should have 2 operands"); 5626 LHS = CondCXXOp->getArg(0); 5627 RHS = CondCXXOp->getArg(1); 5628 switch (CondCXXOp->getOperator()) { 5629 case OO_ExclaimEqual: 5630 CondRel = BO_NE; 5631 break; 5632 case OO_Less: 5633 CondRel = BO_LT; 5634 break; 5635 case OO_LessEqual: 5636 CondRel = BO_LE; 5637 break; 5638 case OO_Greater: 5639 CondRel = BO_GT; 5640 break; 5641 case OO_GreaterEqual: 5642 CondRel = BO_GE; 5643 break; 5644 default: 5645 llvm_unreachable("unexpected iterator operator"); 5646 } 5647 } else 5648 llvm_unreachable("unexpected loop condition"); 5649 5650 // Normalize such that the loop counter is on the LHS. 5651 if (!isa<DeclRefExpr>(LHS->IgnoreImplicit()) || 5652 cast<DeclRefExpr>(LHS->IgnoreImplicit())->getDecl() != LIVDecl) { 5653 std::swap(LHS, RHS); 5654 CondRel = BinaryOperator::reverseComparisonOp(CondRel); 5655 } 5656 auto *CounterRef = cast<DeclRefExpr>(LHS->IgnoreImplicit()); 5657 5658 // Decide the bit width for the logical iteration counter. By default use the 5659 // unsigned ptrdiff_t integer size (for iterators and pointers). 5660 // TODO: For iterators, use iterator::difference_type, 5661 // std::iterator_traits<>::difference_type or decltype(it - end). 5662 QualType LogicalTy = Ctx.getUnsignedPointerDiffType(); 5663 if (CounterTy->isIntegerType()) { 5664 unsigned BitWidth = Ctx.getIntWidth(CounterTy); 5665 LogicalTy = Ctx.getIntTypeForBitwidth(BitWidth, false); 5666 } 5667 5668 // Analyze the loop increment. 5669 Expr *Step; 5670 if (auto *IncUn = dyn_cast<UnaryOperator>(Inc)) { 5671 int Direction; 5672 switch (IncUn->getOpcode()) { 5673 case UO_PreInc: 5674 case UO_PostInc: 5675 Direction = 1; 5676 break; 5677 case UO_PreDec: 5678 case UO_PostDec: 5679 Direction = -1; 5680 break; 5681 default: 5682 llvm_unreachable("unhandled unary increment operator"); 5683 } 5684 Step = IntegerLiteral::Create( 5685 Ctx, llvm::APInt(Ctx.getIntWidth(LogicalTy), Direction), LogicalTy, {}); 5686 } else if (auto *IncBin = dyn_cast<BinaryOperator>(Inc)) { 5687 if (IncBin->getOpcode() == BO_AddAssign) { 5688 Step = IncBin->getRHS(); 5689 } else if (IncBin->getOpcode() == BO_SubAssign) { 5690 Step = 5691 AssertSuccess(BuildUnaryOp(nullptr, {}, UO_Minus, IncBin->getRHS())); 5692 } else 5693 llvm_unreachable("unhandled binary increment operator"); 5694 } else if (auto *CondCXXOp = dyn_cast<CXXOperatorCallExpr>(Inc)) { 5695 switch (CondCXXOp->getOperator()) { 5696 case OO_PlusPlus: 5697 Step = IntegerLiteral::Create( 5698 Ctx, llvm::APInt(Ctx.getIntWidth(LogicalTy), 1), LogicalTy, {}); 5699 break; 5700 case OO_MinusMinus: 5701 Step = IntegerLiteral::Create( 5702 Ctx, llvm::APInt(Ctx.getIntWidth(LogicalTy), -1), LogicalTy, {}); 5703 break; 5704 case OO_PlusEqual: 5705 Step = CondCXXOp->getArg(1); 5706 break; 5707 case OO_MinusEqual: 5708 Step = AssertSuccess( 5709 BuildUnaryOp(nullptr, {}, UO_Minus, CondCXXOp->getArg(1))); 5710 break; 5711 default: 5712 llvm_unreachable("unhandled overloaded increment operator"); 5713 } 5714 } else 5715 llvm_unreachable("unknown increment expression"); 5716 5717 CapturedStmt *DistanceFunc = 5718 buildDistanceFunc(*this, LogicalTy, CondRel, LHS, RHS, Step); 5719 CapturedStmt *LoopVarFunc = buildLoopVarFunc( 5720 *this, LVTy, LogicalTy, CounterRef, Step, isa<CXXForRangeStmt>(AStmt)); 5721 DeclRefExpr *LVRef = BuildDeclRefExpr(LUVDecl, LUVDecl->getType(), VK_LValue, 5722 {}, nullptr, nullptr, {}, nullptr); 5723 return OMPCanonicalLoop::create(getASTContext(), AStmt, DistanceFunc, 5724 LoopVarFunc, LVRef); 5725 } 5726 5727 StmtResult Sema::ActOnOpenMPLoopnest(Stmt *AStmt) { 5728 // Handle a literal loop. 5729 if (isa<ForStmt>(AStmt) || isa<CXXForRangeStmt>(AStmt)) 5730 return ActOnOpenMPCanonicalLoop(AStmt); 5731 5732 // If not a literal loop, it must be the result of a loop transformation. 5733 OMPExecutableDirective *LoopTransform = cast<OMPExecutableDirective>(AStmt); 5734 assert( 5735 isOpenMPLoopTransformationDirective(LoopTransform->getDirectiveKind()) && 5736 "Loop transformation directive expected"); 5737 return LoopTransform; 5738 } 5739 5740 static ExprResult buildUserDefinedMapperRef(Sema &SemaRef, Scope *S, 5741 CXXScopeSpec &MapperIdScopeSpec, 5742 const DeclarationNameInfo &MapperId, 5743 QualType Type, 5744 Expr *UnresolvedMapper); 5745 5746 /// Perform DFS through the structure/class data members trying to find 5747 /// member(s) with user-defined 'default' mapper and generate implicit map 5748 /// clauses for such members with the found 'default' mapper. 5749 static void 5750 processImplicitMapsWithDefaultMappers(Sema &S, DSAStackTy *Stack, 5751 SmallVectorImpl<OMPClause *> &Clauses) { 5752 // Check for the deault mapper for data members. 5753 if (S.getLangOpts().OpenMP < 50) 5754 return; 5755 SmallVector<OMPClause *, 4> ImplicitMaps; 5756 for (int Cnt = 0, EndCnt = Clauses.size(); Cnt < EndCnt; ++Cnt) { 5757 auto *C = dyn_cast<OMPMapClause>(Clauses[Cnt]); 5758 if (!C) 5759 continue; 5760 SmallVector<Expr *, 4> SubExprs; 5761 auto *MI = C->mapperlist_begin(); 5762 for (auto I = C->varlist_begin(), End = C->varlist_end(); I != End; 5763 ++I, ++MI) { 5764 // Expression is mapped using mapper - skip it. 5765 if (*MI) 5766 continue; 5767 Expr *E = *I; 5768 // Expression is dependent - skip it, build the mapper when it gets 5769 // instantiated. 5770 if (E->isTypeDependent() || E->isValueDependent() || 5771 E->containsUnexpandedParameterPack()) 5772 continue; 5773 // Array section - need to check for the mapping of the array section 5774 // element. 5775 QualType CanonType = E->getType().getCanonicalType(); 5776 if (CanonType->isSpecificBuiltinType(BuiltinType::OMPArraySection)) { 5777 const auto *OASE = cast<OMPArraySectionExpr>(E->IgnoreParenImpCasts()); 5778 QualType BaseType = 5779 OMPArraySectionExpr::getBaseOriginalType(OASE->getBase()); 5780 QualType ElemType; 5781 if (const auto *ATy = BaseType->getAsArrayTypeUnsafe()) 5782 ElemType = ATy->getElementType(); 5783 else 5784 ElemType = BaseType->getPointeeType(); 5785 CanonType = ElemType; 5786 } 5787 5788 // DFS over data members in structures/classes. 5789 SmallVector<std::pair<QualType, FieldDecl *>, 4> Types( 5790 1, {CanonType, nullptr}); 5791 llvm::DenseMap<const Type *, Expr *> Visited; 5792 SmallVector<std::pair<FieldDecl *, unsigned>, 4> ParentChain( 5793 1, {nullptr, 1}); 5794 while (!Types.empty()) { 5795 QualType BaseType; 5796 FieldDecl *CurFD; 5797 std::tie(BaseType, CurFD) = Types.pop_back_val(); 5798 while (ParentChain.back().second == 0) 5799 ParentChain.pop_back(); 5800 --ParentChain.back().second; 5801 if (BaseType.isNull()) 5802 continue; 5803 // Only structs/classes are allowed to have mappers. 5804 const RecordDecl *RD = BaseType.getCanonicalType()->getAsRecordDecl(); 5805 if (!RD) 5806 continue; 5807 auto It = Visited.find(BaseType.getTypePtr()); 5808 if (It == Visited.end()) { 5809 // Try to find the associated user-defined mapper. 5810 CXXScopeSpec MapperIdScopeSpec; 5811 DeclarationNameInfo DefaultMapperId; 5812 DefaultMapperId.setName(S.Context.DeclarationNames.getIdentifier( 5813 &S.Context.Idents.get("default"))); 5814 DefaultMapperId.setLoc(E->getExprLoc()); 5815 ExprResult ER = buildUserDefinedMapperRef( 5816 S, Stack->getCurScope(), MapperIdScopeSpec, DefaultMapperId, 5817 BaseType, /*UnresolvedMapper=*/nullptr); 5818 if (ER.isInvalid()) 5819 continue; 5820 It = Visited.try_emplace(BaseType.getTypePtr(), ER.get()).first; 5821 } 5822 // Found default mapper. 5823 if (It->second) { 5824 auto *OE = new (S.Context) OpaqueValueExpr(E->getExprLoc(), CanonType, 5825 VK_LValue, OK_Ordinary, E); 5826 OE->setIsUnique(/*V=*/true); 5827 Expr *BaseExpr = OE; 5828 for (const auto &P : ParentChain) { 5829 if (P.first) { 5830 BaseExpr = S.BuildMemberExpr( 5831 BaseExpr, /*IsArrow=*/false, E->getExprLoc(), 5832 NestedNameSpecifierLoc(), SourceLocation(), P.first, 5833 DeclAccessPair::make(P.first, P.first->getAccess()), 5834 /*HadMultipleCandidates=*/false, DeclarationNameInfo(), 5835 P.first->getType(), VK_LValue, OK_Ordinary); 5836 BaseExpr = S.DefaultLvalueConversion(BaseExpr).get(); 5837 } 5838 } 5839 if (CurFD) 5840 BaseExpr = S.BuildMemberExpr( 5841 BaseExpr, /*IsArrow=*/false, E->getExprLoc(), 5842 NestedNameSpecifierLoc(), SourceLocation(), CurFD, 5843 DeclAccessPair::make(CurFD, CurFD->getAccess()), 5844 /*HadMultipleCandidates=*/false, DeclarationNameInfo(), 5845 CurFD->getType(), VK_LValue, OK_Ordinary); 5846 SubExprs.push_back(BaseExpr); 5847 continue; 5848 } 5849 // Check for the "default" mapper for data members. 5850 bool FirstIter = true; 5851 for (FieldDecl *FD : RD->fields()) { 5852 if (!FD) 5853 continue; 5854 QualType FieldTy = FD->getType(); 5855 if (FieldTy.isNull() || 5856 !(FieldTy->isStructureOrClassType() || FieldTy->isUnionType())) 5857 continue; 5858 if (FirstIter) { 5859 FirstIter = false; 5860 ParentChain.emplace_back(CurFD, 1); 5861 } else { 5862 ++ParentChain.back().second; 5863 } 5864 Types.emplace_back(FieldTy, FD); 5865 } 5866 } 5867 } 5868 if (SubExprs.empty()) 5869 continue; 5870 CXXScopeSpec MapperIdScopeSpec; 5871 DeclarationNameInfo MapperId; 5872 if (OMPClause *NewClause = S.ActOnOpenMPMapClause( 5873 C->getMapTypeModifiers(), C->getMapTypeModifiersLoc(), 5874 MapperIdScopeSpec, MapperId, C->getMapType(), 5875 /*IsMapTypeImplicit=*/true, SourceLocation(), SourceLocation(), 5876 SubExprs, OMPVarListLocTy())) 5877 Clauses.push_back(NewClause); 5878 } 5879 } 5880 5881 StmtResult Sema::ActOnOpenMPExecutableDirective( 5882 OpenMPDirectiveKind Kind, const DeclarationNameInfo &DirName, 5883 OpenMPDirectiveKind CancelRegion, ArrayRef<OMPClause *> Clauses, 5884 Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc) { 5885 StmtResult Res = StmtError(); 5886 OpenMPBindClauseKind BindKind = OMPC_BIND_unknown; 5887 if (const OMPBindClause *BC = 5888 OMPExecutableDirective::getSingleClause<OMPBindClause>(Clauses)) 5889 BindKind = BC->getBindKind(); 5890 // First check CancelRegion which is then used in checkNestingOfRegions. 5891 if (checkCancelRegion(*this, Kind, CancelRegion, StartLoc) || 5892 checkNestingOfRegions(*this, DSAStack, Kind, DirName, CancelRegion, 5893 BindKind, StartLoc)) 5894 return StmtError(); 5895 5896 llvm::SmallVector<OMPClause *, 8> ClausesWithImplicit; 5897 VarsWithInheritedDSAType VarsWithInheritedDSA; 5898 bool ErrorFound = false; 5899 ClausesWithImplicit.append(Clauses.begin(), Clauses.end()); 5900 if (AStmt && !CurContext->isDependentContext() && Kind != OMPD_atomic && 5901 Kind != OMPD_critical && Kind != OMPD_section && Kind != OMPD_master && 5902 Kind != OMPD_masked && !isOpenMPLoopTransformationDirective(Kind)) { 5903 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 5904 5905 // Check default data sharing attributes for referenced variables. 5906 DSAAttrChecker DSAChecker(DSAStack, *this, cast<CapturedStmt>(AStmt)); 5907 int ThisCaptureLevel = getOpenMPCaptureLevels(Kind); 5908 Stmt *S = AStmt; 5909 while (--ThisCaptureLevel >= 0) 5910 S = cast<CapturedStmt>(S)->getCapturedStmt(); 5911 DSAChecker.Visit(S); 5912 if (!isOpenMPTargetDataManagementDirective(Kind) && 5913 !isOpenMPTaskingDirective(Kind)) { 5914 // Visit subcaptures to generate implicit clauses for captured vars. 5915 auto *CS = cast<CapturedStmt>(AStmt); 5916 SmallVector<OpenMPDirectiveKind, 4> CaptureRegions; 5917 getOpenMPCaptureRegions(CaptureRegions, Kind); 5918 // Ignore outer tasking regions for target directives. 5919 if (CaptureRegions.size() > 1 && CaptureRegions.front() == OMPD_task) 5920 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 5921 DSAChecker.visitSubCaptures(CS); 5922 } 5923 if (DSAChecker.isErrorFound()) 5924 return StmtError(); 5925 // Generate list of implicitly defined firstprivate variables. 5926 VarsWithInheritedDSA = DSAChecker.getVarsWithInheritedDSA(); 5927 5928 SmallVector<Expr *, 4> ImplicitFirstprivates( 5929 DSAChecker.getImplicitFirstprivate().begin(), 5930 DSAChecker.getImplicitFirstprivate().end()); 5931 SmallVector<Expr *, 4> ImplicitPrivates( 5932 DSAChecker.getImplicitPrivate().begin(), 5933 DSAChecker.getImplicitPrivate().end()); 5934 const unsigned DefaultmapKindNum = OMPC_DEFAULTMAP_pointer + 1; 5935 SmallVector<Expr *, 4> ImplicitMaps[DefaultmapKindNum][OMPC_MAP_delete]; 5936 SmallVector<OpenMPMapModifierKind, NumberOfOMPMapClauseModifiers> 5937 ImplicitMapModifiers[DefaultmapKindNum]; 5938 SmallVector<SourceLocation, NumberOfOMPMapClauseModifiers> 5939 ImplicitMapModifiersLoc[DefaultmapKindNum]; 5940 // Get the original location of present modifier from Defaultmap clause. 5941 SourceLocation PresentModifierLocs[DefaultmapKindNum]; 5942 for (OMPClause *C : Clauses) { 5943 if (auto *DMC = dyn_cast<OMPDefaultmapClause>(C)) 5944 if (DMC->getDefaultmapModifier() == OMPC_DEFAULTMAP_MODIFIER_present) 5945 PresentModifierLocs[DMC->getDefaultmapKind()] = 5946 DMC->getDefaultmapModifierLoc(); 5947 } 5948 for (unsigned VC = 0; VC < DefaultmapKindNum; ++VC) { 5949 auto Kind = static_cast<OpenMPDefaultmapClauseKind>(VC); 5950 for (unsigned I = 0; I < OMPC_MAP_delete; ++I) { 5951 ArrayRef<Expr *> ImplicitMap = DSAChecker.getImplicitMap( 5952 Kind, static_cast<OpenMPMapClauseKind>(I)); 5953 ImplicitMaps[VC][I].append(ImplicitMap.begin(), ImplicitMap.end()); 5954 } 5955 ArrayRef<OpenMPMapModifierKind> ImplicitModifier = 5956 DSAChecker.getImplicitMapModifier(Kind); 5957 ImplicitMapModifiers[VC].append(ImplicitModifier.begin(), 5958 ImplicitModifier.end()); 5959 std::fill_n(std::back_inserter(ImplicitMapModifiersLoc[VC]), 5960 ImplicitModifier.size(), PresentModifierLocs[VC]); 5961 } 5962 // Mark taskgroup task_reduction descriptors as implicitly firstprivate. 5963 for (OMPClause *C : Clauses) { 5964 if (auto *IRC = dyn_cast<OMPInReductionClause>(C)) { 5965 for (Expr *E : IRC->taskgroup_descriptors()) 5966 if (E) 5967 ImplicitFirstprivates.emplace_back(E); 5968 } 5969 // OpenMP 5.0, 2.10.1 task Construct 5970 // [detach clause]... The event-handle will be considered as if it was 5971 // specified on a firstprivate clause. 5972 if (auto *DC = dyn_cast<OMPDetachClause>(C)) 5973 ImplicitFirstprivates.push_back(DC->getEventHandler()); 5974 } 5975 if (!ImplicitFirstprivates.empty()) { 5976 if (OMPClause *Implicit = ActOnOpenMPFirstprivateClause( 5977 ImplicitFirstprivates, SourceLocation(), SourceLocation(), 5978 SourceLocation())) { 5979 ClausesWithImplicit.push_back(Implicit); 5980 ErrorFound = cast<OMPFirstprivateClause>(Implicit)->varlist_size() != 5981 ImplicitFirstprivates.size(); 5982 } else { 5983 ErrorFound = true; 5984 } 5985 } 5986 if (!ImplicitPrivates.empty()) { 5987 if (OMPClause *Implicit = 5988 ActOnOpenMPPrivateClause(ImplicitPrivates, SourceLocation(), 5989 SourceLocation(), SourceLocation())) { 5990 ClausesWithImplicit.push_back(Implicit); 5991 ErrorFound = cast<OMPPrivateClause>(Implicit)->varlist_size() != 5992 ImplicitPrivates.size(); 5993 } else { 5994 ErrorFound = true; 5995 } 5996 } 5997 // OpenMP 5.0 [2.19.7] 5998 // If a list item appears in a reduction, lastprivate or linear 5999 // clause on a combined target construct then it is treated as 6000 // if it also appears in a map clause with a map-type of tofrom 6001 if (getLangOpts().OpenMP >= 50 && Kind != OMPD_target && 6002 isOpenMPTargetExecutionDirective(Kind)) { 6003 SmallVector<Expr *, 4> ImplicitExprs; 6004 for (OMPClause *C : Clauses) { 6005 if (auto *RC = dyn_cast<OMPReductionClause>(C)) 6006 for (Expr *E : RC->varlists()) 6007 if (!isa<DeclRefExpr>(E->IgnoreParenImpCasts())) 6008 ImplicitExprs.emplace_back(E); 6009 } 6010 if (!ImplicitExprs.empty()) { 6011 ArrayRef<Expr *> Exprs = ImplicitExprs; 6012 CXXScopeSpec MapperIdScopeSpec; 6013 DeclarationNameInfo MapperId; 6014 if (OMPClause *Implicit = ActOnOpenMPMapClause( 6015 OMPC_MAP_MODIFIER_unknown, SourceLocation(), MapperIdScopeSpec, 6016 MapperId, OMPC_MAP_tofrom, 6017 /*IsMapTypeImplicit=*/true, SourceLocation(), SourceLocation(), 6018 Exprs, OMPVarListLocTy(), /*NoDiagnose=*/true)) 6019 ClausesWithImplicit.emplace_back(Implicit); 6020 } 6021 } 6022 for (unsigned I = 0, E = DefaultmapKindNum; I < E; ++I) { 6023 int ClauseKindCnt = -1; 6024 for (ArrayRef<Expr *> ImplicitMap : ImplicitMaps[I]) { 6025 ++ClauseKindCnt; 6026 if (ImplicitMap.empty()) 6027 continue; 6028 CXXScopeSpec MapperIdScopeSpec; 6029 DeclarationNameInfo MapperId; 6030 auto Kind = static_cast<OpenMPMapClauseKind>(ClauseKindCnt); 6031 if (OMPClause *Implicit = ActOnOpenMPMapClause( 6032 ImplicitMapModifiers[I], ImplicitMapModifiersLoc[I], 6033 MapperIdScopeSpec, MapperId, Kind, /*IsMapTypeImplicit=*/true, 6034 SourceLocation(), SourceLocation(), ImplicitMap, 6035 OMPVarListLocTy())) { 6036 ClausesWithImplicit.emplace_back(Implicit); 6037 ErrorFound |= cast<OMPMapClause>(Implicit)->varlist_size() != 6038 ImplicitMap.size(); 6039 } else { 6040 ErrorFound = true; 6041 } 6042 } 6043 } 6044 // Build expressions for implicit maps of data members with 'default' 6045 // mappers. 6046 if (LangOpts.OpenMP >= 50) 6047 processImplicitMapsWithDefaultMappers(*this, DSAStack, 6048 ClausesWithImplicit); 6049 } 6050 6051 llvm::SmallVector<OpenMPDirectiveKind, 4> AllowedNameModifiers; 6052 switch (Kind) { 6053 case OMPD_parallel: 6054 Res = ActOnOpenMPParallelDirective(ClausesWithImplicit, AStmt, StartLoc, 6055 EndLoc); 6056 AllowedNameModifiers.push_back(OMPD_parallel); 6057 break; 6058 case OMPD_simd: 6059 Res = ActOnOpenMPSimdDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc, 6060 VarsWithInheritedDSA); 6061 if (LangOpts.OpenMP >= 50) 6062 AllowedNameModifiers.push_back(OMPD_simd); 6063 break; 6064 case OMPD_tile: 6065 Res = 6066 ActOnOpenMPTileDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc); 6067 break; 6068 case OMPD_unroll: 6069 Res = ActOnOpenMPUnrollDirective(ClausesWithImplicit, AStmt, StartLoc, 6070 EndLoc); 6071 break; 6072 case OMPD_for: 6073 Res = ActOnOpenMPForDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc, 6074 VarsWithInheritedDSA); 6075 break; 6076 case OMPD_for_simd: 6077 Res = ActOnOpenMPForSimdDirective(ClausesWithImplicit, AStmt, StartLoc, 6078 EndLoc, VarsWithInheritedDSA); 6079 if (LangOpts.OpenMP >= 50) 6080 AllowedNameModifiers.push_back(OMPD_simd); 6081 break; 6082 case OMPD_sections: 6083 Res = ActOnOpenMPSectionsDirective(ClausesWithImplicit, AStmt, StartLoc, 6084 EndLoc); 6085 break; 6086 case OMPD_section: 6087 assert(ClausesWithImplicit.empty() && 6088 "No clauses are allowed for 'omp section' directive"); 6089 Res = ActOnOpenMPSectionDirective(AStmt, StartLoc, EndLoc); 6090 break; 6091 case OMPD_single: 6092 Res = ActOnOpenMPSingleDirective(ClausesWithImplicit, AStmt, StartLoc, 6093 EndLoc); 6094 break; 6095 case OMPD_master: 6096 assert(ClausesWithImplicit.empty() && 6097 "No clauses are allowed for 'omp master' directive"); 6098 Res = ActOnOpenMPMasterDirective(AStmt, StartLoc, EndLoc); 6099 break; 6100 case OMPD_masked: 6101 Res = ActOnOpenMPMaskedDirective(ClausesWithImplicit, AStmt, StartLoc, 6102 EndLoc); 6103 break; 6104 case OMPD_critical: 6105 Res = ActOnOpenMPCriticalDirective(DirName, ClausesWithImplicit, AStmt, 6106 StartLoc, EndLoc); 6107 break; 6108 case OMPD_parallel_for: 6109 Res = ActOnOpenMPParallelForDirective(ClausesWithImplicit, AStmt, StartLoc, 6110 EndLoc, VarsWithInheritedDSA); 6111 AllowedNameModifiers.push_back(OMPD_parallel); 6112 break; 6113 case OMPD_parallel_for_simd: 6114 Res = ActOnOpenMPParallelForSimdDirective( 6115 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 6116 AllowedNameModifiers.push_back(OMPD_parallel); 6117 if (LangOpts.OpenMP >= 50) 6118 AllowedNameModifiers.push_back(OMPD_simd); 6119 break; 6120 case OMPD_parallel_master: 6121 Res = ActOnOpenMPParallelMasterDirective(ClausesWithImplicit, AStmt, 6122 StartLoc, EndLoc); 6123 AllowedNameModifiers.push_back(OMPD_parallel); 6124 break; 6125 case OMPD_parallel_masked: 6126 Res = ActOnOpenMPParallelMaskedDirective(ClausesWithImplicit, AStmt, 6127 StartLoc, EndLoc); 6128 AllowedNameModifiers.push_back(OMPD_parallel); 6129 break; 6130 case OMPD_parallel_sections: 6131 Res = ActOnOpenMPParallelSectionsDirective(ClausesWithImplicit, AStmt, 6132 StartLoc, EndLoc); 6133 AllowedNameModifiers.push_back(OMPD_parallel); 6134 break; 6135 case OMPD_task: 6136 Res = 6137 ActOnOpenMPTaskDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc); 6138 AllowedNameModifiers.push_back(OMPD_task); 6139 break; 6140 case OMPD_taskyield: 6141 assert(ClausesWithImplicit.empty() && 6142 "No clauses are allowed for 'omp taskyield' directive"); 6143 assert(AStmt == nullptr && 6144 "No associated statement allowed for 'omp taskyield' directive"); 6145 Res = ActOnOpenMPTaskyieldDirective(StartLoc, EndLoc); 6146 break; 6147 case OMPD_barrier: 6148 assert(ClausesWithImplicit.empty() && 6149 "No clauses are allowed for 'omp barrier' directive"); 6150 assert(AStmt == nullptr && 6151 "No associated statement allowed for 'omp barrier' directive"); 6152 Res = ActOnOpenMPBarrierDirective(StartLoc, EndLoc); 6153 break; 6154 case OMPD_taskwait: 6155 assert(AStmt == nullptr && 6156 "No associated statement allowed for 'omp taskwait' directive"); 6157 Res = ActOnOpenMPTaskwaitDirective(ClausesWithImplicit, StartLoc, EndLoc); 6158 break; 6159 case OMPD_taskgroup: 6160 Res = ActOnOpenMPTaskgroupDirective(ClausesWithImplicit, AStmt, StartLoc, 6161 EndLoc); 6162 break; 6163 case OMPD_flush: 6164 assert(AStmt == nullptr && 6165 "No associated statement allowed for 'omp flush' directive"); 6166 Res = ActOnOpenMPFlushDirective(ClausesWithImplicit, StartLoc, EndLoc); 6167 break; 6168 case OMPD_depobj: 6169 assert(AStmt == nullptr && 6170 "No associated statement allowed for 'omp depobj' directive"); 6171 Res = ActOnOpenMPDepobjDirective(ClausesWithImplicit, StartLoc, EndLoc); 6172 break; 6173 case OMPD_scan: 6174 assert(AStmt == nullptr && 6175 "No associated statement allowed for 'omp scan' directive"); 6176 Res = ActOnOpenMPScanDirective(ClausesWithImplicit, StartLoc, EndLoc); 6177 break; 6178 case OMPD_ordered: 6179 Res = ActOnOpenMPOrderedDirective(ClausesWithImplicit, AStmt, StartLoc, 6180 EndLoc); 6181 break; 6182 case OMPD_atomic: 6183 Res = ActOnOpenMPAtomicDirective(ClausesWithImplicit, AStmt, StartLoc, 6184 EndLoc); 6185 break; 6186 case OMPD_teams: 6187 Res = 6188 ActOnOpenMPTeamsDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc); 6189 break; 6190 case OMPD_target: 6191 Res = ActOnOpenMPTargetDirective(ClausesWithImplicit, AStmt, StartLoc, 6192 EndLoc); 6193 AllowedNameModifiers.push_back(OMPD_target); 6194 break; 6195 case OMPD_target_parallel: 6196 Res = ActOnOpenMPTargetParallelDirective(ClausesWithImplicit, AStmt, 6197 StartLoc, EndLoc); 6198 AllowedNameModifiers.push_back(OMPD_target); 6199 AllowedNameModifiers.push_back(OMPD_parallel); 6200 break; 6201 case OMPD_target_parallel_for: 6202 Res = ActOnOpenMPTargetParallelForDirective( 6203 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 6204 AllowedNameModifiers.push_back(OMPD_target); 6205 AllowedNameModifiers.push_back(OMPD_parallel); 6206 break; 6207 case OMPD_cancellation_point: 6208 assert(ClausesWithImplicit.empty() && 6209 "No clauses are allowed for 'omp cancellation point' directive"); 6210 assert(AStmt == nullptr && "No associated statement allowed for 'omp " 6211 "cancellation point' directive"); 6212 Res = ActOnOpenMPCancellationPointDirective(StartLoc, EndLoc, CancelRegion); 6213 break; 6214 case OMPD_cancel: 6215 assert(AStmt == nullptr && 6216 "No associated statement allowed for 'omp cancel' directive"); 6217 Res = ActOnOpenMPCancelDirective(ClausesWithImplicit, StartLoc, EndLoc, 6218 CancelRegion); 6219 AllowedNameModifiers.push_back(OMPD_cancel); 6220 break; 6221 case OMPD_target_data: 6222 Res = ActOnOpenMPTargetDataDirective(ClausesWithImplicit, AStmt, StartLoc, 6223 EndLoc); 6224 AllowedNameModifiers.push_back(OMPD_target_data); 6225 break; 6226 case OMPD_target_enter_data: 6227 Res = ActOnOpenMPTargetEnterDataDirective(ClausesWithImplicit, StartLoc, 6228 EndLoc, AStmt); 6229 AllowedNameModifiers.push_back(OMPD_target_enter_data); 6230 break; 6231 case OMPD_target_exit_data: 6232 Res = ActOnOpenMPTargetExitDataDirective(ClausesWithImplicit, StartLoc, 6233 EndLoc, AStmt); 6234 AllowedNameModifiers.push_back(OMPD_target_exit_data); 6235 break; 6236 case OMPD_taskloop: 6237 Res = ActOnOpenMPTaskLoopDirective(ClausesWithImplicit, AStmt, StartLoc, 6238 EndLoc, VarsWithInheritedDSA); 6239 AllowedNameModifiers.push_back(OMPD_taskloop); 6240 break; 6241 case OMPD_taskloop_simd: 6242 Res = ActOnOpenMPTaskLoopSimdDirective(ClausesWithImplicit, AStmt, StartLoc, 6243 EndLoc, VarsWithInheritedDSA); 6244 AllowedNameModifiers.push_back(OMPD_taskloop); 6245 if (LangOpts.OpenMP >= 50) 6246 AllowedNameModifiers.push_back(OMPD_simd); 6247 break; 6248 case OMPD_master_taskloop: 6249 Res = ActOnOpenMPMasterTaskLoopDirective( 6250 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 6251 AllowedNameModifiers.push_back(OMPD_taskloop); 6252 break; 6253 case OMPD_masked_taskloop: 6254 Res = ActOnOpenMPMaskedTaskLoopDirective( 6255 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 6256 AllowedNameModifiers.push_back(OMPD_taskloop); 6257 break; 6258 case OMPD_master_taskloop_simd: 6259 Res = ActOnOpenMPMasterTaskLoopSimdDirective( 6260 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 6261 AllowedNameModifiers.push_back(OMPD_taskloop); 6262 if (LangOpts.OpenMP >= 50) 6263 AllowedNameModifiers.push_back(OMPD_simd); 6264 break; 6265 case OMPD_masked_taskloop_simd: 6266 Res = ActOnOpenMPMaskedTaskLoopSimdDirective( 6267 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 6268 if (LangOpts.OpenMP >= 51) { 6269 AllowedNameModifiers.push_back(OMPD_taskloop); 6270 AllowedNameModifiers.push_back(OMPD_simd); 6271 } 6272 break; 6273 case OMPD_parallel_master_taskloop: 6274 Res = ActOnOpenMPParallelMasterTaskLoopDirective( 6275 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 6276 AllowedNameModifiers.push_back(OMPD_taskloop); 6277 AllowedNameModifiers.push_back(OMPD_parallel); 6278 break; 6279 case OMPD_parallel_master_taskloop_simd: 6280 Res = ActOnOpenMPParallelMasterTaskLoopSimdDirective( 6281 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 6282 AllowedNameModifiers.push_back(OMPD_taskloop); 6283 AllowedNameModifiers.push_back(OMPD_parallel); 6284 if (LangOpts.OpenMP >= 50) 6285 AllowedNameModifiers.push_back(OMPD_simd); 6286 break; 6287 case OMPD_distribute: 6288 Res = ActOnOpenMPDistributeDirective(ClausesWithImplicit, AStmt, StartLoc, 6289 EndLoc, VarsWithInheritedDSA); 6290 break; 6291 case OMPD_target_update: 6292 Res = ActOnOpenMPTargetUpdateDirective(ClausesWithImplicit, StartLoc, 6293 EndLoc, AStmt); 6294 AllowedNameModifiers.push_back(OMPD_target_update); 6295 break; 6296 case OMPD_distribute_parallel_for: 6297 Res = ActOnOpenMPDistributeParallelForDirective( 6298 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 6299 AllowedNameModifiers.push_back(OMPD_parallel); 6300 break; 6301 case OMPD_distribute_parallel_for_simd: 6302 Res = ActOnOpenMPDistributeParallelForSimdDirective( 6303 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 6304 AllowedNameModifiers.push_back(OMPD_parallel); 6305 if (LangOpts.OpenMP >= 50) 6306 AllowedNameModifiers.push_back(OMPD_simd); 6307 break; 6308 case OMPD_distribute_simd: 6309 Res = ActOnOpenMPDistributeSimdDirective( 6310 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 6311 if (LangOpts.OpenMP >= 50) 6312 AllowedNameModifiers.push_back(OMPD_simd); 6313 break; 6314 case OMPD_target_parallel_for_simd: 6315 Res = ActOnOpenMPTargetParallelForSimdDirective( 6316 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 6317 AllowedNameModifiers.push_back(OMPD_target); 6318 AllowedNameModifiers.push_back(OMPD_parallel); 6319 if (LangOpts.OpenMP >= 50) 6320 AllowedNameModifiers.push_back(OMPD_simd); 6321 break; 6322 case OMPD_target_simd: 6323 Res = ActOnOpenMPTargetSimdDirective(ClausesWithImplicit, AStmt, StartLoc, 6324 EndLoc, VarsWithInheritedDSA); 6325 AllowedNameModifiers.push_back(OMPD_target); 6326 if (LangOpts.OpenMP >= 50) 6327 AllowedNameModifiers.push_back(OMPD_simd); 6328 break; 6329 case OMPD_teams_distribute: 6330 Res = ActOnOpenMPTeamsDistributeDirective( 6331 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 6332 break; 6333 case OMPD_teams_distribute_simd: 6334 Res = ActOnOpenMPTeamsDistributeSimdDirective( 6335 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 6336 if (LangOpts.OpenMP >= 50) 6337 AllowedNameModifiers.push_back(OMPD_simd); 6338 break; 6339 case OMPD_teams_distribute_parallel_for_simd: 6340 Res = ActOnOpenMPTeamsDistributeParallelForSimdDirective( 6341 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 6342 AllowedNameModifiers.push_back(OMPD_parallel); 6343 if (LangOpts.OpenMP >= 50) 6344 AllowedNameModifiers.push_back(OMPD_simd); 6345 break; 6346 case OMPD_teams_distribute_parallel_for: 6347 Res = ActOnOpenMPTeamsDistributeParallelForDirective( 6348 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 6349 AllowedNameModifiers.push_back(OMPD_parallel); 6350 break; 6351 case OMPD_target_teams: 6352 Res = ActOnOpenMPTargetTeamsDirective(ClausesWithImplicit, AStmt, StartLoc, 6353 EndLoc); 6354 AllowedNameModifiers.push_back(OMPD_target); 6355 break; 6356 case OMPD_target_teams_distribute: 6357 Res = ActOnOpenMPTargetTeamsDistributeDirective( 6358 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 6359 AllowedNameModifiers.push_back(OMPD_target); 6360 break; 6361 case OMPD_target_teams_distribute_parallel_for: 6362 Res = ActOnOpenMPTargetTeamsDistributeParallelForDirective( 6363 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 6364 AllowedNameModifiers.push_back(OMPD_target); 6365 AllowedNameModifiers.push_back(OMPD_parallel); 6366 break; 6367 case OMPD_target_teams_distribute_parallel_for_simd: 6368 Res = ActOnOpenMPTargetTeamsDistributeParallelForSimdDirective( 6369 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 6370 AllowedNameModifiers.push_back(OMPD_target); 6371 AllowedNameModifiers.push_back(OMPD_parallel); 6372 if (LangOpts.OpenMP >= 50) 6373 AllowedNameModifiers.push_back(OMPD_simd); 6374 break; 6375 case OMPD_target_teams_distribute_simd: 6376 Res = ActOnOpenMPTargetTeamsDistributeSimdDirective( 6377 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 6378 AllowedNameModifiers.push_back(OMPD_target); 6379 if (LangOpts.OpenMP >= 50) 6380 AllowedNameModifiers.push_back(OMPD_simd); 6381 break; 6382 case OMPD_interop: 6383 assert(AStmt == nullptr && 6384 "No associated statement allowed for 'omp interop' directive"); 6385 Res = ActOnOpenMPInteropDirective(ClausesWithImplicit, StartLoc, EndLoc); 6386 break; 6387 case OMPD_dispatch: 6388 Res = ActOnOpenMPDispatchDirective(ClausesWithImplicit, AStmt, StartLoc, 6389 EndLoc); 6390 break; 6391 case OMPD_loop: 6392 Res = ActOnOpenMPGenericLoopDirective(ClausesWithImplicit, AStmt, StartLoc, 6393 EndLoc, VarsWithInheritedDSA); 6394 break; 6395 case OMPD_teams_loop: 6396 Res = ActOnOpenMPTeamsGenericLoopDirective( 6397 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 6398 break; 6399 case OMPD_target_teams_loop: 6400 Res = ActOnOpenMPTargetTeamsGenericLoopDirective( 6401 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 6402 break; 6403 case OMPD_parallel_loop: 6404 Res = ActOnOpenMPParallelGenericLoopDirective( 6405 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 6406 break; 6407 case OMPD_target_parallel_loop: 6408 Res = ActOnOpenMPTargetParallelGenericLoopDirective( 6409 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 6410 break; 6411 case OMPD_declare_target: 6412 case OMPD_end_declare_target: 6413 case OMPD_threadprivate: 6414 case OMPD_allocate: 6415 case OMPD_declare_reduction: 6416 case OMPD_declare_mapper: 6417 case OMPD_declare_simd: 6418 case OMPD_requires: 6419 case OMPD_declare_variant: 6420 case OMPD_begin_declare_variant: 6421 case OMPD_end_declare_variant: 6422 llvm_unreachable("OpenMP Directive is not allowed"); 6423 case OMPD_unknown: 6424 default: 6425 llvm_unreachable("Unknown OpenMP directive"); 6426 } 6427 6428 ErrorFound = Res.isInvalid() || ErrorFound; 6429 6430 // Check variables in the clauses if default(none) or 6431 // default(firstprivate) was specified. 6432 if (DSAStack->getDefaultDSA() == DSA_none || 6433 DSAStack->getDefaultDSA() == DSA_private || 6434 DSAStack->getDefaultDSA() == DSA_firstprivate) { 6435 DSAAttrChecker DSAChecker(DSAStack, *this, nullptr); 6436 for (OMPClause *C : Clauses) { 6437 switch (C->getClauseKind()) { 6438 case OMPC_num_threads: 6439 case OMPC_dist_schedule: 6440 // Do not analyse if no parent teams directive. 6441 if (isOpenMPTeamsDirective(Kind)) 6442 break; 6443 continue; 6444 case OMPC_if: 6445 if (isOpenMPTeamsDirective(Kind) && 6446 cast<OMPIfClause>(C)->getNameModifier() != OMPD_target) 6447 break; 6448 if (isOpenMPParallelDirective(Kind) && 6449 isOpenMPTaskLoopDirective(Kind) && 6450 cast<OMPIfClause>(C)->getNameModifier() != OMPD_parallel) 6451 break; 6452 continue; 6453 case OMPC_schedule: 6454 case OMPC_detach: 6455 break; 6456 case OMPC_grainsize: 6457 case OMPC_num_tasks: 6458 case OMPC_final: 6459 case OMPC_priority: 6460 case OMPC_novariants: 6461 case OMPC_nocontext: 6462 // Do not analyze if no parent parallel directive. 6463 if (isOpenMPParallelDirective(Kind)) 6464 break; 6465 continue; 6466 case OMPC_ordered: 6467 case OMPC_device: 6468 case OMPC_num_teams: 6469 case OMPC_thread_limit: 6470 case OMPC_hint: 6471 case OMPC_collapse: 6472 case OMPC_safelen: 6473 case OMPC_simdlen: 6474 case OMPC_sizes: 6475 case OMPC_default: 6476 case OMPC_proc_bind: 6477 case OMPC_private: 6478 case OMPC_firstprivate: 6479 case OMPC_lastprivate: 6480 case OMPC_shared: 6481 case OMPC_reduction: 6482 case OMPC_task_reduction: 6483 case OMPC_in_reduction: 6484 case OMPC_linear: 6485 case OMPC_aligned: 6486 case OMPC_copyin: 6487 case OMPC_copyprivate: 6488 case OMPC_nowait: 6489 case OMPC_untied: 6490 case OMPC_mergeable: 6491 case OMPC_allocate: 6492 case OMPC_read: 6493 case OMPC_write: 6494 case OMPC_update: 6495 case OMPC_capture: 6496 case OMPC_compare: 6497 case OMPC_seq_cst: 6498 case OMPC_acq_rel: 6499 case OMPC_acquire: 6500 case OMPC_release: 6501 case OMPC_relaxed: 6502 case OMPC_depend: 6503 case OMPC_threads: 6504 case OMPC_simd: 6505 case OMPC_map: 6506 case OMPC_nogroup: 6507 case OMPC_defaultmap: 6508 case OMPC_to: 6509 case OMPC_from: 6510 case OMPC_use_device_ptr: 6511 case OMPC_use_device_addr: 6512 case OMPC_is_device_ptr: 6513 case OMPC_has_device_addr: 6514 case OMPC_nontemporal: 6515 case OMPC_order: 6516 case OMPC_destroy: 6517 case OMPC_inclusive: 6518 case OMPC_exclusive: 6519 case OMPC_uses_allocators: 6520 case OMPC_affinity: 6521 case OMPC_bind: 6522 case OMPC_filter: 6523 continue; 6524 case OMPC_allocator: 6525 case OMPC_flush: 6526 case OMPC_depobj: 6527 case OMPC_threadprivate: 6528 case OMPC_uniform: 6529 case OMPC_unknown: 6530 case OMPC_unified_address: 6531 case OMPC_unified_shared_memory: 6532 case OMPC_reverse_offload: 6533 case OMPC_dynamic_allocators: 6534 case OMPC_atomic_default_mem_order: 6535 case OMPC_device_type: 6536 case OMPC_match: 6537 case OMPC_when: 6538 default: 6539 llvm_unreachable("Unexpected clause"); 6540 } 6541 for (Stmt *CC : C->children()) { 6542 if (CC) 6543 DSAChecker.Visit(CC); 6544 } 6545 } 6546 for (const auto &P : DSAChecker.getVarsWithInheritedDSA()) 6547 VarsWithInheritedDSA[P.getFirst()] = P.getSecond(); 6548 } 6549 for (const auto &P : VarsWithInheritedDSA) { 6550 if (P.getFirst()->isImplicit() || isa<OMPCapturedExprDecl>(P.getFirst())) 6551 continue; 6552 ErrorFound = true; 6553 if (DSAStack->getDefaultDSA() == DSA_none || 6554 DSAStack->getDefaultDSA() == DSA_private || 6555 DSAStack->getDefaultDSA() == DSA_firstprivate) { 6556 Diag(P.second->getExprLoc(), diag::err_omp_no_dsa_for_variable) 6557 << P.first << P.second->getSourceRange(); 6558 Diag(DSAStack->getDefaultDSALocation(), diag::note_omp_default_dsa_none); 6559 } else if (getLangOpts().OpenMP >= 50) { 6560 Diag(P.second->getExprLoc(), 6561 diag::err_omp_defaultmap_no_attr_for_variable) 6562 << P.first << P.second->getSourceRange(); 6563 Diag(DSAStack->getDefaultDSALocation(), 6564 diag::note_omp_defaultmap_attr_none); 6565 } 6566 } 6567 6568 if (!AllowedNameModifiers.empty()) 6569 ErrorFound = checkIfClauses(*this, Kind, Clauses, AllowedNameModifiers) || 6570 ErrorFound; 6571 6572 if (ErrorFound) 6573 return StmtError(); 6574 6575 if (!CurContext->isDependentContext() && 6576 isOpenMPTargetExecutionDirective(Kind) && 6577 !(DSAStack->hasRequiresDeclWithClause<OMPUnifiedSharedMemoryClause>() || 6578 DSAStack->hasRequiresDeclWithClause<OMPUnifiedAddressClause>() || 6579 DSAStack->hasRequiresDeclWithClause<OMPReverseOffloadClause>() || 6580 DSAStack->hasRequiresDeclWithClause<OMPDynamicAllocatorsClause>())) { 6581 // Register target to DSA Stack. 6582 DSAStack->addTargetDirLocation(StartLoc); 6583 } 6584 6585 return Res; 6586 } 6587 6588 Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareSimdDirective( 6589 DeclGroupPtrTy DG, OMPDeclareSimdDeclAttr::BranchStateTy BS, Expr *Simdlen, 6590 ArrayRef<Expr *> Uniforms, ArrayRef<Expr *> Aligneds, 6591 ArrayRef<Expr *> Alignments, ArrayRef<Expr *> Linears, 6592 ArrayRef<unsigned> LinModifiers, ArrayRef<Expr *> Steps, SourceRange SR) { 6593 assert(Aligneds.size() == Alignments.size()); 6594 assert(Linears.size() == LinModifiers.size()); 6595 assert(Linears.size() == Steps.size()); 6596 if (!DG || DG.get().isNull()) 6597 return DeclGroupPtrTy(); 6598 6599 const int SimdId = 0; 6600 if (!DG.get().isSingleDecl()) { 6601 Diag(SR.getBegin(), diag::err_omp_single_decl_in_declare_simd_variant) 6602 << SimdId; 6603 return DG; 6604 } 6605 Decl *ADecl = DG.get().getSingleDecl(); 6606 if (auto *FTD = dyn_cast<FunctionTemplateDecl>(ADecl)) 6607 ADecl = FTD->getTemplatedDecl(); 6608 6609 auto *FD = dyn_cast<FunctionDecl>(ADecl); 6610 if (!FD) { 6611 Diag(ADecl->getLocation(), diag::err_omp_function_expected) << SimdId; 6612 return DeclGroupPtrTy(); 6613 } 6614 6615 // OpenMP [2.8.2, declare simd construct, Description] 6616 // The parameter of the simdlen clause must be a constant positive integer 6617 // expression. 6618 ExprResult SL; 6619 if (Simdlen) 6620 SL = VerifyPositiveIntegerConstantInClause(Simdlen, OMPC_simdlen); 6621 // OpenMP [2.8.2, declare simd construct, Description] 6622 // The special this pointer can be used as if was one of the arguments to the 6623 // function in any of the linear, aligned, or uniform clauses. 6624 // The uniform clause declares one or more arguments to have an invariant 6625 // value for all concurrent invocations of the function in the execution of a 6626 // single SIMD loop. 6627 llvm::DenseMap<const Decl *, const Expr *> UniformedArgs; 6628 const Expr *UniformedLinearThis = nullptr; 6629 for (const Expr *E : Uniforms) { 6630 E = E->IgnoreParenImpCasts(); 6631 if (const auto *DRE = dyn_cast<DeclRefExpr>(E)) 6632 if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) 6633 if (FD->getNumParams() > PVD->getFunctionScopeIndex() && 6634 FD->getParamDecl(PVD->getFunctionScopeIndex()) 6635 ->getCanonicalDecl() == PVD->getCanonicalDecl()) { 6636 UniformedArgs.try_emplace(PVD->getCanonicalDecl(), E); 6637 continue; 6638 } 6639 if (isa<CXXThisExpr>(E)) { 6640 UniformedLinearThis = E; 6641 continue; 6642 } 6643 Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause) 6644 << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0); 6645 } 6646 // OpenMP [2.8.2, declare simd construct, Description] 6647 // The aligned clause declares that the object to which each list item points 6648 // is aligned to the number of bytes expressed in the optional parameter of 6649 // the aligned clause. 6650 // The special this pointer can be used as if was one of the arguments to the 6651 // function in any of the linear, aligned, or uniform clauses. 6652 // The type of list items appearing in the aligned clause must be array, 6653 // pointer, reference to array, or reference to pointer. 6654 llvm::DenseMap<const Decl *, const Expr *> AlignedArgs; 6655 const Expr *AlignedThis = nullptr; 6656 for (const Expr *E : Aligneds) { 6657 E = E->IgnoreParenImpCasts(); 6658 if (const auto *DRE = dyn_cast<DeclRefExpr>(E)) 6659 if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) { 6660 const VarDecl *CanonPVD = PVD->getCanonicalDecl(); 6661 if (FD->getNumParams() > PVD->getFunctionScopeIndex() && 6662 FD->getParamDecl(PVD->getFunctionScopeIndex()) 6663 ->getCanonicalDecl() == CanonPVD) { 6664 // OpenMP [2.8.1, simd construct, Restrictions] 6665 // A list-item cannot appear in more than one aligned clause. 6666 if (AlignedArgs.count(CanonPVD) > 0) { 6667 Diag(E->getExprLoc(), diag::err_omp_used_in_clause_twice) 6668 << 1 << getOpenMPClauseName(OMPC_aligned) 6669 << E->getSourceRange(); 6670 Diag(AlignedArgs[CanonPVD]->getExprLoc(), 6671 diag::note_omp_explicit_dsa) 6672 << getOpenMPClauseName(OMPC_aligned); 6673 continue; 6674 } 6675 AlignedArgs[CanonPVD] = E; 6676 QualType QTy = PVD->getType() 6677 .getNonReferenceType() 6678 .getUnqualifiedType() 6679 .getCanonicalType(); 6680 const Type *Ty = QTy.getTypePtrOrNull(); 6681 if (!Ty || (!Ty->isArrayType() && !Ty->isPointerType())) { 6682 Diag(E->getExprLoc(), diag::err_omp_aligned_expected_array_or_ptr) 6683 << QTy << getLangOpts().CPlusPlus << E->getSourceRange(); 6684 Diag(PVD->getLocation(), diag::note_previous_decl) << PVD; 6685 } 6686 continue; 6687 } 6688 } 6689 if (isa<CXXThisExpr>(E)) { 6690 if (AlignedThis) { 6691 Diag(E->getExprLoc(), diag::err_omp_used_in_clause_twice) 6692 << 2 << getOpenMPClauseName(OMPC_aligned) << E->getSourceRange(); 6693 Diag(AlignedThis->getExprLoc(), diag::note_omp_explicit_dsa) 6694 << getOpenMPClauseName(OMPC_aligned); 6695 } 6696 AlignedThis = E; 6697 continue; 6698 } 6699 Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause) 6700 << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0); 6701 } 6702 // The optional parameter of the aligned clause, alignment, must be a constant 6703 // positive integer expression. If no optional parameter is specified, 6704 // implementation-defined default alignments for SIMD instructions on the 6705 // target platforms are assumed. 6706 SmallVector<const Expr *, 4> NewAligns; 6707 for (Expr *E : Alignments) { 6708 ExprResult Align; 6709 if (E) 6710 Align = VerifyPositiveIntegerConstantInClause(E, OMPC_aligned); 6711 NewAligns.push_back(Align.get()); 6712 } 6713 // OpenMP [2.8.2, declare simd construct, Description] 6714 // The linear clause declares one or more list items to be private to a SIMD 6715 // lane and to have a linear relationship with respect to the iteration space 6716 // of a loop. 6717 // The special this pointer can be used as if was one of the arguments to the 6718 // function in any of the linear, aligned, or uniform clauses. 6719 // When a linear-step expression is specified in a linear clause it must be 6720 // either a constant integer expression or an integer-typed parameter that is 6721 // specified in a uniform clause on the directive. 6722 llvm::DenseMap<const Decl *, const Expr *> LinearArgs; 6723 const bool IsUniformedThis = UniformedLinearThis != nullptr; 6724 auto MI = LinModifiers.begin(); 6725 for (const Expr *E : Linears) { 6726 auto LinKind = static_cast<OpenMPLinearClauseKind>(*MI); 6727 ++MI; 6728 E = E->IgnoreParenImpCasts(); 6729 if (const auto *DRE = dyn_cast<DeclRefExpr>(E)) 6730 if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) { 6731 const VarDecl *CanonPVD = PVD->getCanonicalDecl(); 6732 if (FD->getNumParams() > PVD->getFunctionScopeIndex() && 6733 FD->getParamDecl(PVD->getFunctionScopeIndex()) 6734 ->getCanonicalDecl() == CanonPVD) { 6735 // OpenMP [2.15.3.7, linear Clause, Restrictions] 6736 // A list-item cannot appear in more than one linear clause. 6737 if (LinearArgs.count(CanonPVD) > 0) { 6738 Diag(E->getExprLoc(), diag::err_omp_wrong_dsa) 6739 << getOpenMPClauseName(OMPC_linear) 6740 << getOpenMPClauseName(OMPC_linear) << E->getSourceRange(); 6741 Diag(LinearArgs[CanonPVD]->getExprLoc(), 6742 diag::note_omp_explicit_dsa) 6743 << getOpenMPClauseName(OMPC_linear); 6744 continue; 6745 } 6746 // Each argument can appear in at most one uniform or linear clause. 6747 if (UniformedArgs.count(CanonPVD) > 0) { 6748 Diag(E->getExprLoc(), diag::err_omp_wrong_dsa) 6749 << getOpenMPClauseName(OMPC_linear) 6750 << getOpenMPClauseName(OMPC_uniform) << E->getSourceRange(); 6751 Diag(UniformedArgs[CanonPVD]->getExprLoc(), 6752 diag::note_omp_explicit_dsa) 6753 << getOpenMPClauseName(OMPC_uniform); 6754 continue; 6755 } 6756 LinearArgs[CanonPVD] = E; 6757 if (E->isValueDependent() || E->isTypeDependent() || 6758 E->isInstantiationDependent() || 6759 E->containsUnexpandedParameterPack()) 6760 continue; 6761 (void)CheckOpenMPLinearDecl(CanonPVD, E->getExprLoc(), LinKind, 6762 PVD->getOriginalType(), 6763 /*IsDeclareSimd=*/true); 6764 continue; 6765 } 6766 } 6767 if (isa<CXXThisExpr>(E)) { 6768 if (UniformedLinearThis) { 6769 Diag(E->getExprLoc(), diag::err_omp_wrong_dsa) 6770 << getOpenMPClauseName(OMPC_linear) 6771 << getOpenMPClauseName(IsUniformedThis ? OMPC_uniform : OMPC_linear) 6772 << E->getSourceRange(); 6773 Diag(UniformedLinearThis->getExprLoc(), diag::note_omp_explicit_dsa) 6774 << getOpenMPClauseName(IsUniformedThis ? OMPC_uniform 6775 : OMPC_linear); 6776 continue; 6777 } 6778 UniformedLinearThis = E; 6779 if (E->isValueDependent() || E->isTypeDependent() || 6780 E->isInstantiationDependent() || E->containsUnexpandedParameterPack()) 6781 continue; 6782 (void)CheckOpenMPLinearDecl(/*D=*/nullptr, E->getExprLoc(), LinKind, 6783 E->getType(), /*IsDeclareSimd=*/true); 6784 continue; 6785 } 6786 Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause) 6787 << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0); 6788 } 6789 Expr *Step = nullptr; 6790 Expr *NewStep = nullptr; 6791 SmallVector<Expr *, 4> NewSteps; 6792 for (Expr *E : Steps) { 6793 // Skip the same step expression, it was checked already. 6794 if (Step == E || !E) { 6795 NewSteps.push_back(E ? NewStep : nullptr); 6796 continue; 6797 } 6798 Step = E; 6799 if (const auto *DRE = dyn_cast<DeclRefExpr>(Step)) 6800 if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) { 6801 const VarDecl *CanonPVD = PVD->getCanonicalDecl(); 6802 if (UniformedArgs.count(CanonPVD) == 0) { 6803 Diag(Step->getExprLoc(), diag::err_omp_expected_uniform_param) 6804 << Step->getSourceRange(); 6805 } else if (E->isValueDependent() || E->isTypeDependent() || 6806 E->isInstantiationDependent() || 6807 E->containsUnexpandedParameterPack() || 6808 CanonPVD->getType()->hasIntegerRepresentation()) { 6809 NewSteps.push_back(Step); 6810 } else { 6811 Diag(Step->getExprLoc(), diag::err_omp_expected_int_param) 6812 << Step->getSourceRange(); 6813 } 6814 continue; 6815 } 6816 NewStep = Step; 6817 if (Step && !Step->isValueDependent() && !Step->isTypeDependent() && 6818 !Step->isInstantiationDependent() && 6819 !Step->containsUnexpandedParameterPack()) { 6820 NewStep = PerformOpenMPImplicitIntegerConversion(Step->getExprLoc(), Step) 6821 .get(); 6822 if (NewStep) 6823 NewStep = 6824 VerifyIntegerConstantExpression(NewStep, /*FIXME*/ AllowFold).get(); 6825 } 6826 NewSteps.push_back(NewStep); 6827 } 6828 auto *NewAttr = OMPDeclareSimdDeclAttr::CreateImplicit( 6829 Context, BS, SL.get(), const_cast<Expr **>(Uniforms.data()), 6830 Uniforms.size(), const_cast<Expr **>(Aligneds.data()), Aligneds.size(), 6831 const_cast<Expr **>(NewAligns.data()), NewAligns.size(), 6832 const_cast<Expr **>(Linears.data()), Linears.size(), 6833 const_cast<unsigned *>(LinModifiers.data()), LinModifiers.size(), 6834 NewSteps.data(), NewSteps.size(), SR); 6835 ADecl->addAttr(NewAttr); 6836 return DG; 6837 } 6838 6839 static void setPrototype(Sema &S, FunctionDecl *FD, FunctionDecl *FDWithProto, 6840 QualType NewType) { 6841 assert(NewType->isFunctionProtoType() && 6842 "Expected function type with prototype."); 6843 assert(FD->getType()->isFunctionNoProtoType() && 6844 "Expected function with type with no prototype."); 6845 assert(FDWithProto->getType()->isFunctionProtoType() && 6846 "Expected function with prototype."); 6847 // Synthesize parameters with the same types. 6848 FD->setType(NewType); 6849 SmallVector<ParmVarDecl *, 16> Params; 6850 for (const ParmVarDecl *P : FDWithProto->parameters()) { 6851 auto *Param = ParmVarDecl::Create(S.getASTContext(), FD, SourceLocation(), 6852 SourceLocation(), nullptr, P->getType(), 6853 /*TInfo=*/nullptr, SC_None, nullptr); 6854 Param->setScopeInfo(0, Params.size()); 6855 Param->setImplicit(); 6856 Params.push_back(Param); 6857 } 6858 6859 FD->setParams(Params); 6860 } 6861 6862 void Sema::ActOnFinishedFunctionDefinitionInOpenMPAssumeScope(Decl *D) { 6863 if (D->isInvalidDecl()) 6864 return; 6865 FunctionDecl *FD = nullptr; 6866 if (auto *UTemplDecl = dyn_cast<FunctionTemplateDecl>(D)) 6867 FD = UTemplDecl->getTemplatedDecl(); 6868 else 6869 FD = cast<FunctionDecl>(D); 6870 assert(FD && "Expected a function declaration!"); 6871 6872 // If we are instantiating templates we do *not* apply scoped assumptions but 6873 // only global ones. We apply scoped assumption to the template definition 6874 // though. 6875 if (!inTemplateInstantiation()) { 6876 for (AssumptionAttr *AA : OMPAssumeScoped) 6877 FD->addAttr(AA); 6878 } 6879 for (AssumptionAttr *AA : OMPAssumeGlobal) 6880 FD->addAttr(AA); 6881 } 6882 6883 Sema::OMPDeclareVariantScope::OMPDeclareVariantScope(OMPTraitInfo &TI) 6884 : TI(&TI), NameSuffix(TI.getMangledName()) {} 6885 6886 void Sema::ActOnStartOfFunctionDefinitionInOpenMPDeclareVariantScope( 6887 Scope *S, Declarator &D, MultiTemplateParamsArg TemplateParamLists, 6888 SmallVectorImpl<FunctionDecl *> &Bases) { 6889 if (!D.getIdentifier()) 6890 return; 6891 6892 OMPDeclareVariantScope &DVScope = OMPDeclareVariantScopes.back(); 6893 6894 // Template specialization is an extension, check if we do it. 6895 bool IsTemplated = !TemplateParamLists.empty(); 6896 if (IsTemplated & 6897 !DVScope.TI->isExtensionActive( 6898 llvm::omp::TraitProperty::implementation_extension_allow_templates)) 6899 return; 6900 6901 IdentifierInfo *BaseII = D.getIdentifier(); 6902 LookupResult Lookup(*this, DeclarationName(BaseII), D.getIdentifierLoc(), 6903 LookupOrdinaryName); 6904 LookupParsedName(Lookup, S, &D.getCXXScopeSpec()); 6905 6906 TypeSourceInfo *TInfo = GetTypeForDeclarator(D, S); 6907 QualType FType = TInfo->getType(); 6908 6909 bool IsConstexpr = 6910 D.getDeclSpec().getConstexprSpecifier() == ConstexprSpecKind::Constexpr; 6911 bool IsConsteval = 6912 D.getDeclSpec().getConstexprSpecifier() == ConstexprSpecKind::Consteval; 6913 6914 for (auto *Candidate : Lookup) { 6915 auto *CandidateDecl = Candidate->getUnderlyingDecl(); 6916 FunctionDecl *UDecl = nullptr; 6917 if (IsTemplated && isa<FunctionTemplateDecl>(CandidateDecl)) { 6918 auto *FTD = cast<FunctionTemplateDecl>(CandidateDecl); 6919 if (FTD->getTemplateParameters()->size() == TemplateParamLists.size()) 6920 UDecl = FTD->getTemplatedDecl(); 6921 } else if (!IsTemplated) 6922 UDecl = dyn_cast<FunctionDecl>(CandidateDecl); 6923 if (!UDecl) 6924 continue; 6925 6926 // Don't specialize constexpr/consteval functions with 6927 // non-constexpr/consteval functions. 6928 if (UDecl->isConstexpr() && !IsConstexpr) 6929 continue; 6930 if (UDecl->isConsteval() && !IsConsteval) 6931 continue; 6932 6933 QualType UDeclTy = UDecl->getType(); 6934 if (!UDeclTy->isDependentType()) { 6935 QualType NewType = Context.mergeFunctionTypes( 6936 FType, UDeclTy, /* OfBlockPointer */ false, 6937 /* Unqualified */ false, /* AllowCXX */ true); 6938 if (NewType.isNull()) 6939 continue; 6940 } 6941 6942 // Found a base! 6943 Bases.push_back(UDecl); 6944 } 6945 6946 bool UseImplicitBase = !DVScope.TI->isExtensionActive( 6947 llvm::omp::TraitProperty::implementation_extension_disable_implicit_base); 6948 // If no base was found we create a declaration that we use as base. 6949 if (Bases.empty() && UseImplicitBase) { 6950 D.setFunctionDefinitionKind(FunctionDefinitionKind::Declaration); 6951 Decl *BaseD = HandleDeclarator(S, D, TemplateParamLists); 6952 BaseD->setImplicit(true); 6953 if (auto *BaseTemplD = dyn_cast<FunctionTemplateDecl>(BaseD)) 6954 Bases.push_back(BaseTemplD->getTemplatedDecl()); 6955 else 6956 Bases.push_back(cast<FunctionDecl>(BaseD)); 6957 } 6958 6959 std::string MangledName; 6960 MangledName += D.getIdentifier()->getName(); 6961 MangledName += getOpenMPVariantManglingSeparatorStr(); 6962 MangledName += DVScope.NameSuffix; 6963 IdentifierInfo &VariantII = Context.Idents.get(MangledName); 6964 6965 VariantII.setMangledOpenMPVariantName(true); 6966 D.SetIdentifier(&VariantII, D.getBeginLoc()); 6967 } 6968 6969 void Sema::ActOnFinishedFunctionDefinitionInOpenMPDeclareVariantScope( 6970 Decl *D, SmallVectorImpl<FunctionDecl *> &Bases) { 6971 // Do not mark function as is used to prevent its emission if this is the 6972 // only place where it is used. 6973 EnterExpressionEvaluationContext Unevaluated( 6974 *this, Sema::ExpressionEvaluationContext::Unevaluated); 6975 6976 FunctionDecl *FD = nullptr; 6977 if (auto *UTemplDecl = dyn_cast<FunctionTemplateDecl>(D)) 6978 FD = UTemplDecl->getTemplatedDecl(); 6979 else 6980 FD = cast<FunctionDecl>(D); 6981 auto *VariantFuncRef = DeclRefExpr::Create( 6982 Context, NestedNameSpecifierLoc(), SourceLocation(), FD, 6983 /* RefersToEnclosingVariableOrCapture */ false, 6984 /* NameLoc */ FD->getLocation(), FD->getType(), 6985 ExprValueKind::VK_PRValue); 6986 6987 OMPDeclareVariantScope &DVScope = OMPDeclareVariantScopes.back(); 6988 auto *OMPDeclareVariantA = OMPDeclareVariantAttr::CreateImplicit( 6989 Context, VariantFuncRef, DVScope.TI, 6990 /*NothingArgs=*/nullptr, /*NothingArgsSize=*/0, 6991 /*NeedDevicePtrArgs=*/nullptr, /*NeedDevicePtrArgsSize=*/0, 6992 /*AppendArgs=*/nullptr, /*AppendArgsSize=*/0); 6993 for (FunctionDecl *BaseFD : Bases) 6994 BaseFD->addAttr(OMPDeclareVariantA); 6995 } 6996 6997 ExprResult Sema::ActOnOpenMPCall(ExprResult Call, Scope *Scope, 6998 SourceLocation LParenLoc, 6999 MultiExprArg ArgExprs, 7000 SourceLocation RParenLoc, Expr *ExecConfig) { 7001 // The common case is a regular call we do not want to specialize at all. Try 7002 // to make that case fast by bailing early. 7003 CallExpr *CE = dyn_cast<CallExpr>(Call.get()); 7004 if (!CE) 7005 return Call; 7006 7007 FunctionDecl *CalleeFnDecl = CE->getDirectCallee(); 7008 if (!CalleeFnDecl) 7009 return Call; 7010 7011 if (!CalleeFnDecl->hasAttr<OMPDeclareVariantAttr>()) 7012 return Call; 7013 7014 ASTContext &Context = getASTContext(); 7015 std::function<void(StringRef)> DiagUnknownTrait = [this, 7016 CE](StringRef ISATrait) { 7017 // TODO Track the selector locations in a way that is accessible here to 7018 // improve the diagnostic location. 7019 Diag(CE->getBeginLoc(), diag::warn_unknown_declare_variant_isa_trait) 7020 << ISATrait; 7021 }; 7022 TargetOMPContext OMPCtx(Context, std::move(DiagUnknownTrait), 7023 getCurFunctionDecl(), DSAStack->getConstructTraits()); 7024 7025 QualType CalleeFnType = CalleeFnDecl->getType(); 7026 7027 SmallVector<Expr *, 4> Exprs; 7028 SmallVector<VariantMatchInfo, 4> VMIs; 7029 while (CalleeFnDecl) { 7030 for (OMPDeclareVariantAttr *A : 7031 CalleeFnDecl->specific_attrs<OMPDeclareVariantAttr>()) { 7032 Expr *VariantRef = A->getVariantFuncRef(); 7033 7034 VariantMatchInfo VMI; 7035 OMPTraitInfo &TI = A->getTraitInfo(); 7036 TI.getAsVariantMatchInfo(Context, VMI); 7037 if (!isVariantApplicableInContext(VMI, OMPCtx, 7038 /* DeviceSetOnly */ false)) 7039 continue; 7040 7041 VMIs.push_back(VMI); 7042 Exprs.push_back(VariantRef); 7043 } 7044 7045 CalleeFnDecl = CalleeFnDecl->getPreviousDecl(); 7046 } 7047 7048 ExprResult NewCall; 7049 do { 7050 int BestIdx = getBestVariantMatchForContext(VMIs, OMPCtx); 7051 if (BestIdx < 0) 7052 return Call; 7053 Expr *BestExpr = cast<DeclRefExpr>(Exprs[BestIdx]); 7054 Decl *BestDecl = cast<DeclRefExpr>(BestExpr)->getDecl(); 7055 7056 { 7057 // Try to build a (member) call expression for the current best applicable 7058 // variant expression. We allow this to fail in which case we continue 7059 // with the next best variant expression. The fail case is part of the 7060 // implementation defined behavior in the OpenMP standard when it talks 7061 // about what differences in the function prototypes: "Any differences 7062 // that the specific OpenMP context requires in the prototype of the 7063 // variant from the base function prototype are implementation defined." 7064 // This wording is there to allow the specialized variant to have a 7065 // different type than the base function. This is intended and OK but if 7066 // we cannot create a call the difference is not in the "implementation 7067 // defined range" we allow. 7068 Sema::TentativeAnalysisScope Trap(*this); 7069 7070 if (auto *SpecializedMethod = dyn_cast<CXXMethodDecl>(BestDecl)) { 7071 auto *MemberCall = dyn_cast<CXXMemberCallExpr>(CE); 7072 BestExpr = MemberExpr::CreateImplicit( 7073 Context, MemberCall->getImplicitObjectArgument(), 7074 /* IsArrow */ false, SpecializedMethod, Context.BoundMemberTy, 7075 MemberCall->getValueKind(), MemberCall->getObjectKind()); 7076 } 7077 NewCall = BuildCallExpr(Scope, BestExpr, LParenLoc, ArgExprs, RParenLoc, 7078 ExecConfig); 7079 if (NewCall.isUsable()) { 7080 if (CallExpr *NCE = dyn_cast<CallExpr>(NewCall.get())) { 7081 FunctionDecl *NewCalleeFnDecl = NCE->getDirectCallee(); 7082 QualType NewType = Context.mergeFunctionTypes( 7083 CalleeFnType, NewCalleeFnDecl->getType(), 7084 /* OfBlockPointer */ false, 7085 /* Unqualified */ false, /* AllowCXX */ true); 7086 if (!NewType.isNull()) 7087 break; 7088 // Don't use the call if the function type was not compatible. 7089 NewCall = nullptr; 7090 } 7091 } 7092 } 7093 7094 VMIs.erase(VMIs.begin() + BestIdx); 7095 Exprs.erase(Exprs.begin() + BestIdx); 7096 } while (!VMIs.empty()); 7097 7098 if (!NewCall.isUsable()) 7099 return Call; 7100 return PseudoObjectExpr::Create(Context, CE, {NewCall.get()}, 0); 7101 } 7102 7103 Optional<std::pair<FunctionDecl *, Expr *>> 7104 Sema::checkOpenMPDeclareVariantFunction(Sema::DeclGroupPtrTy DG, 7105 Expr *VariantRef, OMPTraitInfo &TI, 7106 unsigned NumAppendArgs, 7107 SourceRange SR) { 7108 if (!DG || DG.get().isNull()) 7109 return None; 7110 7111 const int VariantId = 1; 7112 // Must be applied only to single decl. 7113 if (!DG.get().isSingleDecl()) { 7114 Diag(SR.getBegin(), diag::err_omp_single_decl_in_declare_simd_variant) 7115 << VariantId << SR; 7116 return None; 7117 } 7118 Decl *ADecl = DG.get().getSingleDecl(); 7119 if (auto *FTD = dyn_cast<FunctionTemplateDecl>(ADecl)) 7120 ADecl = FTD->getTemplatedDecl(); 7121 7122 // Decl must be a function. 7123 auto *FD = dyn_cast<FunctionDecl>(ADecl); 7124 if (!FD) { 7125 Diag(ADecl->getLocation(), diag::err_omp_function_expected) 7126 << VariantId << SR; 7127 return None; 7128 } 7129 7130 auto &&HasMultiVersionAttributes = [](const FunctionDecl *FD) { 7131 // The 'target' attribute needs to be separately checked because it does 7132 // not always signify a multiversion function declaration. 7133 return FD->isMultiVersion() || FD->hasAttr<TargetAttr>(); 7134 }; 7135 // OpenMP is not compatible with multiversion function attributes. 7136 if (HasMultiVersionAttributes(FD)) { 7137 Diag(FD->getLocation(), diag::err_omp_declare_variant_incompat_attributes) 7138 << SR; 7139 return None; 7140 } 7141 7142 // Allow #pragma omp declare variant only if the function is not used. 7143 if (FD->isUsed(false)) 7144 Diag(SR.getBegin(), diag::warn_omp_declare_variant_after_used) 7145 << FD->getLocation(); 7146 7147 // Check if the function was emitted already. 7148 const FunctionDecl *Definition; 7149 if (!FD->isThisDeclarationADefinition() && FD->isDefined(Definition) && 7150 (LangOpts.EmitAllDecls || Context.DeclMustBeEmitted(Definition))) 7151 Diag(SR.getBegin(), diag::warn_omp_declare_variant_after_emitted) 7152 << FD->getLocation(); 7153 7154 // The VariantRef must point to function. 7155 if (!VariantRef) { 7156 Diag(SR.getBegin(), diag::err_omp_function_expected) << VariantId; 7157 return None; 7158 } 7159 7160 auto ShouldDelayChecks = [](Expr *&E, bool) { 7161 return E && (E->isTypeDependent() || E->isValueDependent() || 7162 E->containsUnexpandedParameterPack() || 7163 E->isInstantiationDependent()); 7164 }; 7165 // Do not check templates, wait until instantiation. 7166 if (FD->isDependentContext() || ShouldDelayChecks(VariantRef, false) || 7167 TI.anyScoreOrCondition(ShouldDelayChecks)) 7168 return std::make_pair(FD, VariantRef); 7169 7170 // Deal with non-constant score and user condition expressions. 7171 auto HandleNonConstantScoresAndConditions = [this](Expr *&E, 7172 bool IsScore) -> bool { 7173 if (!E || E->isIntegerConstantExpr(Context)) 7174 return false; 7175 7176 if (IsScore) { 7177 // We warn on non-constant scores and pretend they were not present. 7178 Diag(E->getExprLoc(), diag::warn_omp_declare_variant_score_not_constant) 7179 << E; 7180 E = nullptr; 7181 } else { 7182 // We could replace a non-constant user condition with "false" but we 7183 // will soon need to handle these anyway for the dynamic version of 7184 // OpenMP context selectors. 7185 Diag(E->getExprLoc(), 7186 diag::err_omp_declare_variant_user_condition_not_constant) 7187 << E; 7188 } 7189 return true; 7190 }; 7191 if (TI.anyScoreOrCondition(HandleNonConstantScoresAndConditions)) 7192 return None; 7193 7194 QualType AdjustedFnType = FD->getType(); 7195 if (NumAppendArgs) { 7196 const auto *PTy = AdjustedFnType->getAsAdjusted<FunctionProtoType>(); 7197 if (!PTy) { 7198 Diag(FD->getLocation(), diag::err_omp_declare_variant_prototype_required) 7199 << SR; 7200 return None; 7201 } 7202 // Adjust the function type to account for an extra omp_interop_t for each 7203 // specified in the append_args clause. 7204 const TypeDecl *TD = nullptr; 7205 LookupResult Result(*this, &Context.Idents.get("omp_interop_t"), 7206 SR.getBegin(), Sema::LookupOrdinaryName); 7207 if (LookupName(Result, getCurScope())) { 7208 NamedDecl *ND = Result.getFoundDecl(); 7209 TD = dyn_cast_or_null<TypeDecl>(ND); 7210 } 7211 if (!TD) { 7212 Diag(SR.getBegin(), diag::err_omp_interop_type_not_found) << SR; 7213 return None; 7214 } 7215 QualType InteropType = Context.getTypeDeclType(TD); 7216 if (PTy->isVariadic()) { 7217 Diag(FD->getLocation(), diag::err_omp_append_args_with_varargs) << SR; 7218 return None; 7219 } 7220 llvm::SmallVector<QualType, 8> Params; 7221 Params.append(PTy->param_type_begin(), PTy->param_type_end()); 7222 Params.insert(Params.end(), NumAppendArgs, InteropType); 7223 AdjustedFnType = Context.getFunctionType(PTy->getReturnType(), Params, 7224 PTy->getExtProtoInfo()); 7225 } 7226 7227 // Convert VariantRef expression to the type of the original function to 7228 // resolve possible conflicts. 7229 ExprResult VariantRefCast = VariantRef; 7230 if (LangOpts.CPlusPlus) { 7231 QualType FnPtrType; 7232 auto *Method = dyn_cast<CXXMethodDecl>(FD); 7233 if (Method && !Method->isStatic()) { 7234 const Type *ClassType = 7235 Context.getTypeDeclType(Method->getParent()).getTypePtr(); 7236 FnPtrType = Context.getMemberPointerType(AdjustedFnType, ClassType); 7237 ExprResult ER; 7238 { 7239 // Build adrr_of unary op to correctly handle type checks for member 7240 // functions. 7241 Sema::TentativeAnalysisScope Trap(*this); 7242 ER = CreateBuiltinUnaryOp(VariantRef->getBeginLoc(), UO_AddrOf, 7243 VariantRef); 7244 } 7245 if (!ER.isUsable()) { 7246 Diag(VariantRef->getExprLoc(), diag::err_omp_function_expected) 7247 << VariantId << VariantRef->getSourceRange(); 7248 return None; 7249 } 7250 VariantRef = ER.get(); 7251 } else { 7252 FnPtrType = Context.getPointerType(AdjustedFnType); 7253 } 7254 QualType VarianPtrType = Context.getPointerType(VariantRef->getType()); 7255 if (VarianPtrType.getUnqualifiedType() != FnPtrType.getUnqualifiedType()) { 7256 ImplicitConversionSequence ICS = TryImplicitConversion( 7257 VariantRef, FnPtrType.getUnqualifiedType(), 7258 /*SuppressUserConversions=*/false, AllowedExplicit::None, 7259 /*InOverloadResolution=*/false, 7260 /*CStyle=*/false, 7261 /*AllowObjCWritebackConversion=*/false); 7262 if (ICS.isFailure()) { 7263 Diag(VariantRef->getExprLoc(), 7264 diag::err_omp_declare_variant_incompat_types) 7265 << VariantRef->getType() 7266 << ((Method && !Method->isStatic()) ? FnPtrType : FD->getType()) 7267 << (NumAppendArgs ? 1 : 0) << VariantRef->getSourceRange(); 7268 return None; 7269 } 7270 VariantRefCast = PerformImplicitConversion( 7271 VariantRef, FnPtrType.getUnqualifiedType(), AA_Converting); 7272 if (!VariantRefCast.isUsable()) 7273 return None; 7274 } 7275 // Drop previously built artificial addr_of unary op for member functions. 7276 if (Method && !Method->isStatic()) { 7277 Expr *PossibleAddrOfVariantRef = VariantRefCast.get(); 7278 if (auto *UO = dyn_cast<UnaryOperator>( 7279 PossibleAddrOfVariantRef->IgnoreImplicit())) 7280 VariantRefCast = UO->getSubExpr(); 7281 } 7282 } 7283 7284 ExprResult ER = CheckPlaceholderExpr(VariantRefCast.get()); 7285 if (!ER.isUsable() || 7286 !ER.get()->IgnoreParenImpCasts()->getType()->isFunctionType()) { 7287 Diag(VariantRef->getExprLoc(), diag::err_omp_function_expected) 7288 << VariantId << VariantRef->getSourceRange(); 7289 return None; 7290 } 7291 7292 // The VariantRef must point to function. 7293 auto *DRE = dyn_cast<DeclRefExpr>(ER.get()->IgnoreParenImpCasts()); 7294 if (!DRE) { 7295 Diag(VariantRef->getExprLoc(), diag::err_omp_function_expected) 7296 << VariantId << VariantRef->getSourceRange(); 7297 return None; 7298 } 7299 auto *NewFD = dyn_cast_or_null<FunctionDecl>(DRE->getDecl()); 7300 if (!NewFD) { 7301 Diag(VariantRef->getExprLoc(), diag::err_omp_function_expected) 7302 << VariantId << VariantRef->getSourceRange(); 7303 return None; 7304 } 7305 7306 if (FD->getCanonicalDecl() == NewFD->getCanonicalDecl()) { 7307 Diag(VariantRef->getExprLoc(), 7308 diag::err_omp_declare_variant_same_base_function) 7309 << VariantRef->getSourceRange(); 7310 return None; 7311 } 7312 7313 // Check if function types are compatible in C. 7314 if (!LangOpts.CPlusPlus) { 7315 QualType NewType = 7316 Context.mergeFunctionTypes(AdjustedFnType, NewFD->getType()); 7317 if (NewType.isNull()) { 7318 Diag(VariantRef->getExprLoc(), 7319 diag::err_omp_declare_variant_incompat_types) 7320 << NewFD->getType() << FD->getType() << (NumAppendArgs ? 1 : 0) 7321 << VariantRef->getSourceRange(); 7322 return None; 7323 } 7324 if (NewType->isFunctionProtoType()) { 7325 if (FD->getType()->isFunctionNoProtoType()) 7326 setPrototype(*this, FD, NewFD, NewType); 7327 else if (NewFD->getType()->isFunctionNoProtoType()) 7328 setPrototype(*this, NewFD, FD, NewType); 7329 } 7330 } 7331 7332 // Check if variant function is not marked with declare variant directive. 7333 if (NewFD->hasAttrs() && NewFD->hasAttr<OMPDeclareVariantAttr>()) { 7334 Diag(VariantRef->getExprLoc(), 7335 diag::warn_omp_declare_variant_marked_as_declare_variant) 7336 << VariantRef->getSourceRange(); 7337 SourceRange SR = 7338 NewFD->specific_attr_begin<OMPDeclareVariantAttr>()->getRange(); 7339 Diag(SR.getBegin(), diag::note_omp_marked_declare_variant_here) << SR; 7340 return None; 7341 } 7342 7343 enum DoesntSupport { 7344 VirtFuncs = 1, 7345 Constructors = 3, 7346 Destructors = 4, 7347 DeletedFuncs = 5, 7348 DefaultedFuncs = 6, 7349 ConstexprFuncs = 7, 7350 ConstevalFuncs = 8, 7351 }; 7352 if (const auto *CXXFD = dyn_cast<CXXMethodDecl>(FD)) { 7353 if (CXXFD->isVirtual()) { 7354 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support) 7355 << VirtFuncs; 7356 return None; 7357 } 7358 7359 if (isa<CXXConstructorDecl>(FD)) { 7360 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support) 7361 << Constructors; 7362 return None; 7363 } 7364 7365 if (isa<CXXDestructorDecl>(FD)) { 7366 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support) 7367 << Destructors; 7368 return None; 7369 } 7370 } 7371 7372 if (FD->isDeleted()) { 7373 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support) 7374 << DeletedFuncs; 7375 return None; 7376 } 7377 7378 if (FD->isDefaulted()) { 7379 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support) 7380 << DefaultedFuncs; 7381 return None; 7382 } 7383 7384 if (FD->isConstexpr()) { 7385 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support) 7386 << (NewFD->isConsteval() ? ConstevalFuncs : ConstexprFuncs); 7387 return None; 7388 } 7389 7390 // Check general compatibility. 7391 if (areMultiversionVariantFunctionsCompatible( 7392 FD, NewFD, PartialDiagnostic::NullDiagnostic(), 7393 PartialDiagnosticAt(SourceLocation(), 7394 PartialDiagnostic::NullDiagnostic()), 7395 PartialDiagnosticAt( 7396 VariantRef->getExprLoc(), 7397 PDiag(diag::err_omp_declare_variant_doesnt_support)), 7398 PartialDiagnosticAt(VariantRef->getExprLoc(), 7399 PDiag(diag::err_omp_declare_variant_diff) 7400 << FD->getLocation()), 7401 /*TemplatesSupported=*/true, /*ConstexprSupported=*/false, 7402 /*CLinkageMayDiffer=*/true)) 7403 return None; 7404 return std::make_pair(FD, cast<Expr>(DRE)); 7405 } 7406 7407 void Sema::ActOnOpenMPDeclareVariantDirective( 7408 FunctionDecl *FD, Expr *VariantRef, OMPTraitInfo &TI, 7409 ArrayRef<Expr *> AdjustArgsNothing, 7410 ArrayRef<Expr *> AdjustArgsNeedDevicePtr, 7411 ArrayRef<OMPDeclareVariantAttr::InteropType> AppendArgs, 7412 SourceLocation AdjustArgsLoc, SourceLocation AppendArgsLoc, 7413 SourceRange SR) { 7414 7415 // OpenMP 5.1 [2.3.5, declare variant directive, Restrictions] 7416 // An adjust_args clause or append_args clause can only be specified if the 7417 // dispatch selector of the construct selector set appears in the match 7418 // clause. 7419 7420 SmallVector<Expr *, 8> AllAdjustArgs; 7421 llvm::append_range(AllAdjustArgs, AdjustArgsNothing); 7422 llvm::append_range(AllAdjustArgs, AdjustArgsNeedDevicePtr); 7423 7424 if (!AllAdjustArgs.empty() || !AppendArgs.empty()) { 7425 VariantMatchInfo VMI; 7426 TI.getAsVariantMatchInfo(Context, VMI); 7427 if (!llvm::is_contained( 7428 VMI.ConstructTraits, 7429 llvm::omp::TraitProperty::construct_dispatch_dispatch)) { 7430 if (!AllAdjustArgs.empty()) 7431 Diag(AdjustArgsLoc, diag::err_omp_clause_requires_dispatch_construct) 7432 << getOpenMPClauseName(OMPC_adjust_args); 7433 if (!AppendArgs.empty()) 7434 Diag(AppendArgsLoc, diag::err_omp_clause_requires_dispatch_construct) 7435 << getOpenMPClauseName(OMPC_append_args); 7436 return; 7437 } 7438 } 7439 7440 // OpenMP 5.1 [2.3.5, declare variant directive, Restrictions] 7441 // Each argument can only appear in a single adjust_args clause for each 7442 // declare variant directive. 7443 llvm::SmallPtrSet<const VarDecl *, 4> AdjustVars; 7444 7445 for (Expr *E : AllAdjustArgs) { 7446 E = E->IgnoreParenImpCasts(); 7447 if (const auto *DRE = dyn_cast<DeclRefExpr>(E)) { 7448 if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) { 7449 const VarDecl *CanonPVD = PVD->getCanonicalDecl(); 7450 if (FD->getNumParams() > PVD->getFunctionScopeIndex() && 7451 FD->getParamDecl(PVD->getFunctionScopeIndex()) 7452 ->getCanonicalDecl() == CanonPVD) { 7453 // It's a parameter of the function, check duplicates. 7454 if (!AdjustVars.insert(CanonPVD).second) { 7455 Diag(DRE->getLocation(), diag::err_omp_adjust_arg_multiple_clauses) 7456 << PVD; 7457 return; 7458 } 7459 continue; 7460 } 7461 } 7462 } 7463 // Anything that is not a function parameter is an error. 7464 Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause) << FD << 0; 7465 return; 7466 } 7467 7468 auto *NewAttr = OMPDeclareVariantAttr::CreateImplicit( 7469 Context, VariantRef, &TI, const_cast<Expr **>(AdjustArgsNothing.data()), 7470 AdjustArgsNothing.size(), 7471 const_cast<Expr **>(AdjustArgsNeedDevicePtr.data()), 7472 AdjustArgsNeedDevicePtr.size(), 7473 const_cast<OMPDeclareVariantAttr::InteropType *>(AppendArgs.data()), 7474 AppendArgs.size(), SR); 7475 FD->addAttr(NewAttr); 7476 } 7477 7478 StmtResult Sema::ActOnOpenMPParallelDirective(ArrayRef<OMPClause *> Clauses, 7479 Stmt *AStmt, 7480 SourceLocation StartLoc, 7481 SourceLocation EndLoc) { 7482 if (!AStmt) 7483 return StmtError(); 7484 7485 auto *CS = cast<CapturedStmt>(AStmt); 7486 // 1.2.2 OpenMP Language Terminology 7487 // Structured block - An executable statement with a single entry at the 7488 // top and a single exit at the bottom. 7489 // The point of exit cannot be a branch out of the structured block. 7490 // longjmp() and throw() must not violate the entry/exit criteria. 7491 CS->getCapturedDecl()->setNothrow(); 7492 7493 setFunctionHasBranchProtectedScope(); 7494 7495 return OMPParallelDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt, 7496 DSAStack->getTaskgroupReductionRef(), 7497 DSAStack->isCancelRegion()); 7498 } 7499 7500 namespace { 7501 /// Iteration space of a single for loop. 7502 struct LoopIterationSpace final { 7503 /// True if the condition operator is the strict compare operator (<, > or 7504 /// !=). 7505 bool IsStrictCompare = false; 7506 /// Condition of the loop. 7507 Expr *PreCond = nullptr; 7508 /// This expression calculates the number of iterations in the loop. 7509 /// It is always possible to calculate it before starting the loop. 7510 Expr *NumIterations = nullptr; 7511 /// The loop counter variable. 7512 Expr *CounterVar = nullptr; 7513 /// Private loop counter variable. 7514 Expr *PrivateCounterVar = nullptr; 7515 /// This is initializer for the initial value of #CounterVar. 7516 Expr *CounterInit = nullptr; 7517 /// This is step for the #CounterVar used to generate its update: 7518 /// #CounterVar = #CounterInit + #CounterStep * CurrentIteration. 7519 Expr *CounterStep = nullptr; 7520 /// Should step be subtracted? 7521 bool Subtract = false; 7522 /// Source range of the loop init. 7523 SourceRange InitSrcRange; 7524 /// Source range of the loop condition. 7525 SourceRange CondSrcRange; 7526 /// Source range of the loop increment. 7527 SourceRange IncSrcRange; 7528 /// Minimum value that can have the loop control variable. Used to support 7529 /// non-rectangular loops. Applied only for LCV with the non-iterator types, 7530 /// since only such variables can be used in non-loop invariant expressions. 7531 Expr *MinValue = nullptr; 7532 /// Maximum value that can have the loop control variable. Used to support 7533 /// non-rectangular loops. Applied only for LCV with the non-iterator type, 7534 /// since only such variables can be used in non-loop invariant expressions. 7535 Expr *MaxValue = nullptr; 7536 /// true, if the lower bound depends on the outer loop control var. 7537 bool IsNonRectangularLB = false; 7538 /// true, if the upper bound depends on the outer loop control var. 7539 bool IsNonRectangularUB = false; 7540 /// Index of the loop this loop depends on and forms non-rectangular loop 7541 /// nest. 7542 unsigned LoopDependentIdx = 0; 7543 /// Final condition for the non-rectangular loop nest support. It is used to 7544 /// check that the number of iterations for this particular counter must be 7545 /// finished. 7546 Expr *FinalCondition = nullptr; 7547 }; 7548 7549 /// Helper class for checking canonical form of the OpenMP loops and 7550 /// extracting iteration space of each loop in the loop nest, that will be used 7551 /// for IR generation. 7552 class OpenMPIterationSpaceChecker { 7553 /// Reference to Sema. 7554 Sema &SemaRef; 7555 /// Does the loop associated directive support non-rectangular loops? 7556 bool SupportsNonRectangular; 7557 /// Data-sharing stack. 7558 DSAStackTy &Stack; 7559 /// A location for diagnostics (when there is no some better location). 7560 SourceLocation DefaultLoc; 7561 /// A location for diagnostics (when increment is not compatible). 7562 SourceLocation ConditionLoc; 7563 /// A source location for referring to loop init later. 7564 SourceRange InitSrcRange; 7565 /// A source location for referring to condition later. 7566 SourceRange ConditionSrcRange; 7567 /// A source location for referring to increment later. 7568 SourceRange IncrementSrcRange; 7569 /// Loop variable. 7570 ValueDecl *LCDecl = nullptr; 7571 /// Reference to loop variable. 7572 Expr *LCRef = nullptr; 7573 /// Lower bound (initializer for the var). 7574 Expr *LB = nullptr; 7575 /// Upper bound. 7576 Expr *UB = nullptr; 7577 /// Loop step (increment). 7578 Expr *Step = nullptr; 7579 /// This flag is true when condition is one of: 7580 /// Var < UB 7581 /// Var <= UB 7582 /// UB > Var 7583 /// UB >= Var 7584 /// This will have no value when the condition is != 7585 llvm::Optional<bool> TestIsLessOp; 7586 /// This flag is true when condition is strict ( < or > ). 7587 bool TestIsStrictOp = false; 7588 /// This flag is true when step is subtracted on each iteration. 7589 bool SubtractStep = false; 7590 /// The outer loop counter this loop depends on (if any). 7591 const ValueDecl *DepDecl = nullptr; 7592 /// Contains number of loop (starts from 1) on which loop counter init 7593 /// expression of this loop depends on. 7594 Optional<unsigned> InitDependOnLC; 7595 /// Contains number of loop (starts from 1) on which loop counter condition 7596 /// expression of this loop depends on. 7597 Optional<unsigned> CondDependOnLC; 7598 /// Checks if the provide statement depends on the loop counter. 7599 Optional<unsigned> doesDependOnLoopCounter(const Stmt *S, bool IsInitializer); 7600 /// Original condition required for checking of the exit condition for 7601 /// non-rectangular loop. 7602 Expr *Condition = nullptr; 7603 7604 public: 7605 OpenMPIterationSpaceChecker(Sema &SemaRef, bool SupportsNonRectangular, 7606 DSAStackTy &Stack, SourceLocation DefaultLoc) 7607 : SemaRef(SemaRef), SupportsNonRectangular(SupportsNonRectangular), 7608 Stack(Stack), DefaultLoc(DefaultLoc), ConditionLoc(DefaultLoc) {} 7609 /// Check init-expr for canonical loop form and save loop counter 7610 /// variable - #Var and its initialization value - #LB. 7611 bool checkAndSetInit(Stmt *S, bool EmitDiags = true); 7612 /// Check test-expr for canonical form, save upper-bound (#UB), flags 7613 /// for less/greater and for strict/non-strict comparison. 7614 bool checkAndSetCond(Expr *S); 7615 /// Check incr-expr for canonical loop form and return true if it 7616 /// does not conform, otherwise save loop step (#Step). 7617 bool checkAndSetInc(Expr *S); 7618 /// Return the loop counter variable. 7619 ValueDecl *getLoopDecl() const { return LCDecl; } 7620 /// Return the reference expression to loop counter variable. 7621 Expr *getLoopDeclRefExpr() const { return LCRef; } 7622 /// Source range of the loop init. 7623 SourceRange getInitSrcRange() const { return InitSrcRange; } 7624 /// Source range of the loop condition. 7625 SourceRange getConditionSrcRange() const { return ConditionSrcRange; } 7626 /// Source range of the loop increment. 7627 SourceRange getIncrementSrcRange() const { return IncrementSrcRange; } 7628 /// True if the step should be subtracted. 7629 bool shouldSubtractStep() const { return SubtractStep; } 7630 /// True, if the compare operator is strict (<, > or !=). 7631 bool isStrictTestOp() const { return TestIsStrictOp; } 7632 /// Build the expression to calculate the number of iterations. 7633 Expr *buildNumIterations( 7634 Scope *S, ArrayRef<LoopIterationSpace> ResultIterSpaces, bool LimitedType, 7635 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const; 7636 /// Build the precondition expression for the loops. 7637 Expr * 7638 buildPreCond(Scope *S, Expr *Cond, 7639 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const; 7640 /// Build reference expression to the counter be used for codegen. 7641 DeclRefExpr * 7642 buildCounterVar(llvm::MapVector<const Expr *, DeclRefExpr *> &Captures, 7643 DSAStackTy &DSA) const; 7644 /// Build reference expression to the private counter be used for 7645 /// codegen. 7646 Expr *buildPrivateCounterVar() const; 7647 /// Build initialization of the counter be used for codegen. 7648 Expr *buildCounterInit() const; 7649 /// Build step of the counter be used for codegen. 7650 Expr *buildCounterStep() const; 7651 /// Build loop data with counter value for depend clauses in ordered 7652 /// directives. 7653 Expr * 7654 buildOrderedLoopData(Scope *S, Expr *Counter, 7655 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures, 7656 SourceLocation Loc, Expr *Inc = nullptr, 7657 OverloadedOperatorKind OOK = OO_Amp); 7658 /// Builds the minimum value for the loop counter. 7659 std::pair<Expr *, Expr *> buildMinMaxValues( 7660 Scope *S, llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const; 7661 /// Builds final condition for the non-rectangular loops. 7662 Expr *buildFinalCondition(Scope *S) const; 7663 /// Return true if any expression is dependent. 7664 bool dependent() const; 7665 /// Returns true if the initializer forms non-rectangular loop. 7666 bool doesInitDependOnLC() const { return InitDependOnLC.hasValue(); } 7667 /// Returns true if the condition forms non-rectangular loop. 7668 bool doesCondDependOnLC() const { return CondDependOnLC.hasValue(); } 7669 /// Returns index of the loop we depend on (starting from 1), or 0 otherwise. 7670 unsigned getLoopDependentIdx() const { 7671 return InitDependOnLC.value_or(CondDependOnLC.value_or(0)); 7672 } 7673 7674 private: 7675 /// Check the right-hand side of an assignment in the increment 7676 /// expression. 7677 bool checkAndSetIncRHS(Expr *RHS); 7678 /// Helper to set loop counter variable and its initializer. 7679 bool setLCDeclAndLB(ValueDecl *NewLCDecl, Expr *NewDeclRefExpr, Expr *NewLB, 7680 bool EmitDiags); 7681 /// Helper to set upper bound. 7682 bool setUB(Expr *NewUB, llvm::Optional<bool> LessOp, bool StrictOp, 7683 SourceRange SR, SourceLocation SL); 7684 /// Helper to set loop increment. 7685 bool setStep(Expr *NewStep, bool Subtract); 7686 }; 7687 7688 bool OpenMPIterationSpaceChecker::dependent() const { 7689 if (!LCDecl) { 7690 assert(!LB && !UB && !Step); 7691 return false; 7692 } 7693 return LCDecl->getType()->isDependentType() || 7694 (LB && LB->isValueDependent()) || (UB && UB->isValueDependent()) || 7695 (Step && Step->isValueDependent()); 7696 } 7697 7698 bool OpenMPIterationSpaceChecker::setLCDeclAndLB(ValueDecl *NewLCDecl, 7699 Expr *NewLCRefExpr, 7700 Expr *NewLB, bool EmitDiags) { 7701 // State consistency checking to ensure correct usage. 7702 assert(LCDecl == nullptr && LB == nullptr && LCRef == nullptr && 7703 UB == nullptr && Step == nullptr && !TestIsLessOp && !TestIsStrictOp); 7704 if (!NewLCDecl || !NewLB || NewLB->containsErrors()) 7705 return true; 7706 LCDecl = getCanonicalDecl(NewLCDecl); 7707 LCRef = NewLCRefExpr; 7708 if (auto *CE = dyn_cast_or_null<CXXConstructExpr>(NewLB)) 7709 if (const CXXConstructorDecl *Ctor = CE->getConstructor()) 7710 if ((Ctor->isCopyOrMoveConstructor() || 7711 Ctor->isConvertingConstructor(/*AllowExplicit=*/false)) && 7712 CE->getNumArgs() > 0 && CE->getArg(0) != nullptr) 7713 NewLB = CE->getArg(0)->IgnoreParenImpCasts(); 7714 LB = NewLB; 7715 if (EmitDiags) 7716 InitDependOnLC = doesDependOnLoopCounter(LB, /*IsInitializer=*/true); 7717 return false; 7718 } 7719 7720 bool OpenMPIterationSpaceChecker::setUB(Expr *NewUB, 7721 llvm::Optional<bool> LessOp, 7722 bool StrictOp, SourceRange SR, 7723 SourceLocation SL) { 7724 // State consistency checking to ensure correct usage. 7725 assert(LCDecl != nullptr && LB != nullptr && UB == nullptr && 7726 Step == nullptr && !TestIsLessOp && !TestIsStrictOp); 7727 if (!NewUB || NewUB->containsErrors()) 7728 return true; 7729 UB = NewUB; 7730 if (LessOp) 7731 TestIsLessOp = LessOp; 7732 TestIsStrictOp = StrictOp; 7733 ConditionSrcRange = SR; 7734 ConditionLoc = SL; 7735 CondDependOnLC = doesDependOnLoopCounter(UB, /*IsInitializer=*/false); 7736 return false; 7737 } 7738 7739 bool OpenMPIterationSpaceChecker::setStep(Expr *NewStep, bool Subtract) { 7740 // State consistency checking to ensure correct usage. 7741 assert(LCDecl != nullptr && LB != nullptr && Step == nullptr); 7742 if (!NewStep || NewStep->containsErrors()) 7743 return true; 7744 if (!NewStep->isValueDependent()) { 7745 // Check that the step is integer expression. 7746 SourceLocation StepLoc = NewStep->getBeginLoc(); 7747 ExprResult Val = SemaRef.PerformOpenMPImplicitIntegerConversion( 7748 StepLoc, getExprAsWritten(NewStep)); 7749 if (Val.isInvalid()) 7750 return true; 7751 NewStep = Val.get(); 7752 7753 // OpenMP [2.6, Canonical Loop Form, Restrictions] 7754 // If test-expr is of form var relational-op b and relational-op is < or 7755 // <= then incr-expr must cause var to increase on each iteration of the 7756 // loop. If test-expr is of form var relational-op b and relational-op is 7757 // > or >= then incr-expr must cause var to decrease on each iteration of 7758 // the loop. 7759 // If test-expr is of form b relational-op var and relational-op is < or 7760 // <= then incr-expr must cause var to decrease on each iteration of the 7761 // loop. If test-expr is of form b relational-op var and relational-op is 7762 // > or >= then incr-expr must cause var to increase on each iteration of 7763 // the loop. 7764 Optional<llvm::APSInt> Result = 7765 NewStep->getIntegerConstantExpr(SemaRef.Context); 7766 bool IsUnsigned = !NewStep->getType()->hasSignedIntegerRepresentation(); 7767 bool IsConstNeg = 7768 Result && Result->isSigned() && (Subtract != Result->isNegative()); 7769 bool IsConstPos = 7770 Result && Result->isSigned() && (Subtract == Result->isNegative()); 7771 bool IsConstZero = Result && !Result->getBoolValue(); 7772 7773 // != with increment is treated as <; != with decrement is treated as > 7774 if (!TestIsLessOp) 7775 TestIsLessOp = IsConstPos || (IsUnsigned && !Subtract); 7776 if (UB && 7777 (IsConstZero || (TestIsLessOp.getValue() 7778 ? (IsConstNeg || (IsUnsigned && Subtract)) 7779 : (IsConstPos || (IsUnsigned && !Subtract))))) { 7780 SemaRef.Diag(NewStep->getExprLoc(), 7781 diag::err_omp_loop_incr_not_compatible) 7782 << LCDecl << TestIsLessOp.getValue() << NewStep->getSourceRange(); 7783 SemaRef.Diag(ConditionLoc, 7784 diag::note_omp_loop_cond_requres_compatible_incr) 7785 << TestIsLessOp.getValue() << ConditionSrcRange; 7786 return true; 7787 } 7788 if (TestIsLessOp.getValue() == Subtract) { 7789 NewStep = 7790 SemaRef.CreateBuiltinUnaryOp(NewStep->getExprLoc(), UO_Minus, NewStep) 7791 .get(); 7792 Subtract = !Subtract; 7793 } 7794 } 7795 7796 Step = NewStep; 7797 SubtractStep = Subtract; 7798 return false; 7799 } 7800 7801 namespace { 7802 /// Checker for the non-rectangular loops. Checks if the initializer or 7803 /// condition expression references loop counter variable. 7804 class LoopCounterRefChecker final 7805 : public ConstStmtVisitor<LoopCounterRefChecker, bool> { 7806 Sema &SemaRef; 7807 DSAStackTy &Stack; 7808 const ValueDecl *CurLCDecl = nullptr; 7809 const ValueDecl *DepDecl = nullptr; 7810 const ValueDecl *PrevDepDecl = nullptr; 7811 bool IsInitializer = true; 7812 bool SupportsNonRectangular; 7813 unsigned BaseLoopId = 0; 7814 bool checkDecl(const Expr *E, const ValueDecl *VD) { 7815 if (getCanonicalDecl(VD) == getCanonicalDecl(CurLCDecl)) { 7816 SemaRef.Diag(E->getExprLoc(), diag::err_omp_stmt_depends_on_loop_counter) 7817 << (IsInitializer ? 0 : 1); 7818 return false; 7819 } 7820 const auto &&Data = Stack.isLoopControlVariable(VD); 7821 // OpenMP, 2.9.1 Canonical Loop Form, Restrictions. 7822 // The type of the loop iterator on which we depend may not have a random 7823 // access iterator type. 7824 if (Data.first && VD->getType()->isRecordType()) { 7825 SmallString<128> Name; 7826 llvm::raw_svector_ostream OS(Name); 7827 VD->getNameForDiagnostic(OS, SemaRef.getPrintingPolicy(), 7828 /*Qualified=*/true); 7829 SemaRef.Diag(E->getExprLoc(), 7830 diag::err_omp_wrong_dependency_iterator_type) 7831 << OS.str(); 7832 SemaRef.Diag(VD->getLocation(), diag::note_previous_decl) << VD; 7833 return false; 7834 } 7835 if (Data.first && !SupportsNonRectangular) { 7836 SemaRef.Diag(E->getExprLoc(), diag::err_omp_invariant_dependency); 7837 return false; 7838 } 7839 if (Data.first && 7840 (DepDecl || (PrevDepDecl && 7841 getCanonicalDecl(VD) != getCanonicalDecl(PrevDepDecl)))) { 7842 if (!DepDecl && PrevDepDecl) 7843 DepDecl = PrevDepDecl; 7844 SmallString<128> Name; 7845 llvm::raw_svector_ostream OS(Name); 7846 DepDecl->getNameForDiagnostic(OS, SemaRef.getPrintingPolicy(), 7847 /*Qualified=*/true); 7848 SemaRef.Diag(E->getExprLoc(), 7849 diag::err_omp_invariant_or_linear_dependency) 7850 << OS.str(); 7851 return false; 7852 } 7853 if (Data.first) { 7854 DepDecl = VD; 7855 BaseLoopId = Data.first; 7856 } 7857 return Data.first; 7858 } 7859 7860 public: 7861 bool VisitDeclRefExpr(const DeclRefExpr *E) { 7862 const ValueDecl *VD = E->getDecl(); 7863 if (isa<VarDecl>(VD)) 7864 return checkDecl(E, VD); 7865 return false; 7866 } 7867 bool VisitMemberExpr(const MemberExpr *E) { 7868 if (isa<CXXThisExpr>(E->getBase()->IgnoreParens())) { 7869 const ValueDecl *VD = E->getMemberDecl(); 7870 if (isa<VarDecl>(VD) || isa<FieldDecl>(VD)) 7871 return checkDecl(E, VD); 7872 } 7873 return false; 7874 } 7875 bool VisitStmt(const Stmt *S) { 7876 bool Res = false; 7877 for (const Stmt *Child : S->children()) 7878 Res = (Child && Visit(Child)) || Res; 7879 return Res; 7880 } 7881 explicit LoopCounterRefChecker(Sema &SemaRef, DSAStackTy &Stack, 7882 const ValueDecl *CurLCDecl, bool IsInitializer, 7883 const ValueDecl *PrevDepDecl = nullptr, 7884 bool SupportsNonRectangular = true) 7885 : SemaRef(SemaRef), Stack(Stack), CurLCDecl(CurLCDecl), 7886 PrevDepDecl(PrevDepDecl), IsInitializer(IsInitializer), 7887 SupportsNonRectangular(SupportsNonRectangular) {} 7888 unsigned getBaseLoopId() const { 7889 assert(CurLCDecl && "Expected loop dependency."); 7890 return BaseLoopId; 7891 } 7892 const ValueDecl *getDepDecl() const { 7893 assert(CurLCDecl && "Expected loop dependency."); 7894 return DepDecl; 7895 } 7896 }; 7897 } // namespace 7898 7899 Optional<unsigned> 7900 OpenMPIterationSpaceChecker::doesDependOnLoopCounter(const Stmt *S, 7901 bool IsInitializer) { 7902 // Check for the non-rectangular loops. 7903 LoopCounterRefChecker LoopStmtChecker(SemaRef, Stack, LCDecl, IsInitializer, 7904 DepDecl, SupportsNonRectangular); 7905 if (LoopStmtChecker.Visit(S)) { 7906 DepDecl = LoopStmtChecker.getDepDecl(); 7907 return LoopStmtChecker.getBaseLoopId(); 7908 } 7909 return llvm::None; 7910 } 7911 7912 bool OpenMPIterationSpaceChecker::checkAndSetInit(Stmt *S, bool EmitDiags) { 7913 // Check init-expr for canonical loop form and save loop counter 7914 // variable - #Var and its initialization value - #LB. 7915 // OpenMP [2.6] Canonical loop form. init-expr may be one of the following: 7916 // var = lb 7917 // integer-type var = lb 7918 // random-access-iterator-type var = lb 7919 // pointer-type var = lb 7920 // 7921 if (!S) { 7922 if (EmitDiags) { 7923 SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_init); 7924 } 7925 return true; 7926 } 7927 if (auto *ExprTemp = dyn_cast<ExprWithCleanups>(S)) 7928 if (!ExprTemp->cleanupsHaveSideEffects()) 7929 S = ExprTemp->getSubExpr(); 7930 7931 InitSrcRange = S->getSourceRange(); 7932 if (Expr *E = dyn_cast<Expr>(S)) 7933 S = E->IgnoreParens(); 7934 if (auto *BO = dyn_cast<BinaryOperator>(S)) { 7935 if (BO->getOpcode() == BO_Assign) { 7936 Expr *LHS = BO->getLHS()->IgnoreParens(); 7937 if (auto *DRE = dyn_cast<DeclRefExpr>(LHS)) { 7938 if (auto *CED = dyn_cast<OMPCapturedExprDecl>(DRE->getDecl())) 7939 if (auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit()))) 7940 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(), 7941 EmitDiags); 7942 return setLCDeclAndLB(DRE->getDecl(), DRE, BO->getRHS(), EmitDiags); 7943 } 7944 if (auto *ME = dyn_cast<MemberExpr>(LHS)) { 7945 if (ME->isArrow() && 7946 isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts())) 7947 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(), 7948 EmitDiags); 7949 } 7950 } 7951 } else if (auto *DS = dyn_cast<DeclStmt>(S)) { 7952 if (DS->isSingleDecl()) { 7953 if (auto *Var = dyn_cast_or_null<VarDecl>(DS->getSingleDecl())) { 7954 if (Var->hasInit() && !Var->getType()->isReferenceType()) { 7955 // Accept non-canonical init form here but emit ext. warning. 7956 if (Var->getInitStyle() != VarDecl::CInit && EmitDiags) 7957 SemaRef.Diag(S->getBeginLoc(), 7958 diag::ext_omp_loop_not_canonical_init) 7959 << S->getSourceRange(); 7960 return setLCDeclAndLB( 7961 Var, 7962 buildDeclRefExpr(SemaRef, Var, 7963 Var->getType().getNonReferenceType(), 7964 DS->getBeginLoc()), 7965 Var->getInit(), EmitDiags); 7966 } 7967 } 7968 } 7969 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) { 7970 if (CE->getOperator() == OO_Equal) { 7971 Expr *LHS = CE->getArg(0); 7972 if (auto *DRE = dyn_cast<DeclRefExpr>(LHS)) { 7973 if (auto *CED = dyn_cast<OMPCapturedExprDecl>(DRE->getDecl())) 7974 if (auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit()))) 7975 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(), 7976 EmitDiags); 7977 return setLCDeclAndLB(DRE->getDecl(), DRE, CE->getArg(1), EmitDiags); 7978 } 7979 if (auto *ME = dyn_cast<MemberExpr>(LHS)) { 7980 if (ME->isArrow() && 7981 isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts())) 7982 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(), 7983 EmitDiags); 7984 } 7985 } 7986 } 7987 7988 if (dependent() || SemaRef.CurContext->isDependentContext()) 7989 return false; 7990 if (EmitDiags) { 7991 SemaRef.Diag(S->getBeginLoc(), diag::err_omp_loop_not_canonical_init) 7992 << S->getSourceRange(); 7993 } 7994 return true; 7995 } 7996 7997 /// Ignore parenthesizes, implicit casts, copy constructor and return the 7998 /// variable (which may be the loop variable) if possible. 7999 static const ValueDecl *getInitLCDecl(const Expr *E) { 8000 if (!E) 8001 return nullptr; 8002 E = getExprAsWritten(E); 8003 if (const auto *CE = dyn_cast_or_null<CXXConstructExpr>(E)) 8004 if (const CXXConstructorDecl *Ctor = CE->getConstructor()) 8005 if ((Ctor->isCopyOrMoveConstructor() || 8006 Ctor->isConvertingConstructor(/*AllowExplicit=*/false)) && 8007 CE->getNumArgs() > 0 && CE->getArg(0) != nullptr) 8008 E = CE->getArg(0)->IgnoreParenImpCasts(); 8009 if (const auto *DRE = dyn_cast_or_null<DeclRefExpr>(E)) { 8010 if (const auto *VD = dyn_cast<VarDecl>(DRE->getDecl())) 8011 return getCanonicalDecl(VD); 8012 } 8013 if (const auto *ME = dyn_cast_or_null<MemberExpr>(E)) 8014 if (ME->isArrow() && isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts())) 8015 return getCanonicalDecl(ME->getMemberDecl()); 8016 return nullptr; 8017 } 8018 8019 bool OpenMPIterationSpaceChecker::checkAndSetCond(Expr *S) { 8020 // Check test-expr for canonical form, save upper-bound UB, flags for 8021 // less/greater and for strict/non-strict comparison. 8022 // OpenMP [2.9] Canonical loop form. Test-expr may be one of the following: 8023 // var relational-op b 8024 // b relational-op var 8025 // 8026 bool IneqCondIsCanonical = SemaRef.getLangOpts().OpenMP >= 50; 8027 if (!S) { 8028 SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_cond) 8029 << (IneqCondIsCanonical ? 1 : 0) << LCDecl; 8030 return true; 8031 } 8032 Condition = S; 8033 S = getExprAsWritten(S); 8034 SourceLocation CondLoc = S->getBeginLoc(); 8035 auto &&CheckAndSetCond = [this, IneqCondIsCanonical]( 8036 BinaryOperatorKind Opcode, const Expr *LHS, 8037 const Expr *RHS, SourceRange SR, 8038 SourceLocation OpLoc) -> llvm::Optional<bool> { 8039 if (BinaryOperator::isRelationalOp(Opcode)) { 8040 if (getInitLCDecl(LHS) == LCDecl) 8041 return setUB(const_cast<Expr *>(RHS), 8042 (Opcode == BO_LT || Opcode == BO_LE), 8043 (Opcode == BO_LT || Opcode == BO_GT), SR, OpLoc); 8044 if (getInitLCDecl(RHS) == LCDecl) 8045 return setUB(const_cast<Expr *>(LHS), 8046 (Opcode == BO_GT || Opcode == BO_GE), 8047 (Opcode == BO_LT || Opcode == BO_GT), SR, OpLoc); 8048 } else if (IneqCondIsCanonical && Opcode == BO_NE) { 8049 return setUB(const_cast<Expr *>(getInitLCDecl(LHS) == LCDecl ? RHS : LHS), 8050 /*LessOp=*/llvm::None, 8051 /*StrictOp=*/true, SR, OpLoc); 8052 } 8053 return llvm::None; 8054 }; 8055 llvm::Optional<bool> Res; 8056 if (auto *RBO = dyn_cast<CXXRewrittenBinaryOperator>(S)) { 8057 CXXRewrittenBinaryOperator::DecomposedForm DF = RBO->getDecomposedForm(); 8058 Res = CheckAndSetCond(DF.Opcode, DF.LHS, DF.RHS, RBO->getSourceRange(), 8059 RBO->getOperatorLoc()); 8060 } else if (auto *BO = dyn_cast<BinaryOperator>(S)) { 8061 Res = CheckAndSetCond(BO->getOpcode(), BO->getLHS(), BO->getRHS(), 8062 BO->getSourceRange(), BO->getOperatorLoc()); 8063 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) { 8064 if (CE->getNumArgs() == 2) { 8065 Res = CheckAndSetCond( 8066 BinaryOperator::getOverloadedOpcode(CE->getOperator()), CE->getArg(0), 8067 CE->getArg(1), CE->getSourceRange(), CE->getOperatorLoc()); 8068 } 8069 } 8070 if (Res) 8071 return *Res; 8072 if (dependent() || SemaRef.CurContext->isDependentContext()) 8073 return false; 8074 SemaRef.Diag(CondLoc, diag::err_omp_loop_not_canonical_cond) 8075 << (IneqCondIsCanonical ? 1 : 0) << S->getSourceRange() << LCDecl; 8076 return true; 8077 } 8078 8079 bool OpenMPIterationSpaceChecker::checkAndSetIncRHS(Expr *RHS) { 8080 // RHS of canonical loop form increment can be: 8081 // var + incr 8082 // incr + var 8083 // var - incr 8084 // 8085 RHS = RHS->IgnoreParenImpCasts(); 8086 if (auto *BO = dyn_cast<BinaryOperator>(RHS)) { 8087 if (BO->isAdditiveOp()) { 8088 bool IsAdd = BO->getOpcode() == BO_Add; 8089 if (getInitLCDecl(BO->getLHS()) == LCDecl) 8090 return setStep(BO->getRHS(), !IsAdd); 8091 if (IsAdd && getInitLCDecl(BO->getRHS()) == LCDecl) 8092 return setStep(BO->getLHS(), /*Subtract=*/false); 8093 } 8094 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(RHS)) { 8095 bool IsAdd = CE->getOperator() == OO_Plus; 8096 if ((IsAdd || CE->getOperator() == OO_Minus) && CE->getNumArgs() == 2) { 8097 if (getInitLCDecl(CE->getArg(0)) == LCDecl) 8098 return setStep(CE->getArg(1), !IsAdd); 8099 if (IsAdd && getInitLCDecl(CE->getArg(1)) == LCDecl) 8100 return setStep(CE->getArg(0), /*Subtract=*/false); 8101 } 8102 } 8103 if (dependent() || SemaRef.CurContext->isDependentContext()) 8104 return false; 8105 SemaRef.Diag(RHS->getBeginLoc(), diag::err_omp_loop_not_canonical_incr) 8106 << RHS->getSourceRange() << LCDecl; 8107 return true; 8108 } 8109 8110 bool OpenMPIterationSpaceChecker::checkAndSetInc(Expr *S) { 8111 // Check incr-expr for canonical loop form and return true if it 8112 // does not conform. 8113 // OpenMP [2.6] Canonical loop form. Test-expr may be one of the following: 8114 // ++var 8115 // var++ 8116 // --var 8117 // var-- 8118 // var += incr 8119 // var -= incr 8120 // var = var + incr 8121 // var = incr + var 8122 // var = var - incr 8123 // 8124 if (!S) { 8125 SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_incr) << LCDecl; 8126 return true; 8127 } 8128 if (auto *ExprTemp = dyn_cast<ExprWithCleanups>(S)) 8129 if (!ExprTemp->cleanupsHaveSideEffects()) 8130 S = ExprTemp->getSubExpr(); 8131 8132 IncrementSrcRange = S->getSourceRange(); 8133 S = S->IgnoreParens(); 8134 if (auto *UO = dyn_cast<UnaryOperator>(S)) { 8135 if (UO->isIncrementDecrementOp() && 8136 getInitLCDecl(UO->getSubExpr()) == LCDecl) 8137 return setStep(SemaRef 8138 .ActOnIntegerConstant(UO->getBeginLoc(), 8139 (UO->isDecrementOp() ? -1 : 1)) 8140 .get(), 8141 /*Subtract=*/false); 8142 } else if (auto *BO = dyn_cast<BinaryOperator>(S)) { 8143 switch (BO->getOpcode()) { 8144 case BO_AddAssign: 8145 case BO_SubAssign: 8146 if (getInitLCDecl(BO->getLHS()) == LCDecl) 8147 return setStep(BO->getRHS(), BO->getOpcode() == BO_SubAssign); 8148 break; 8149 case BO_Assign: 8150 if (getInitLCDecl(BO->getLHS()) == LCDecl) 8151 return checkAndSetIncRHS(BO->getRHS()); 8152 break; 8153 default: 8154 break; 8155 } 8156 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) { 8157 switch (CE->getOperator()) { 8158 case OO_PlusPlus: 8159 case OO_MinusMinus: 8160 if (getInitLCDecl(CE->getArg(0)) == LCDecl) 8161 return setStep(SemaRef 8162 .ActOnIntegerConstant( 8163 CE->getBeginLoc(), 8164 ((CE->getOperator() == OO_MinusMinus) ? -1 : 1)) 8165 .get(), 8166 /*Subtract=*/false); 8167 break; 8168 case OO_PlusEqual: 8169 case OO_MinusEqual: 8170 if (getInitLCDecl(CE->getArg(0)) == LCDecl) 8171 return setStep(CE->getArg(1), CE->getOperator() == OO_MinusEqual); 8172 break; 8173 case OO_Equal: 8174 if (getInitLCDecl(CE->getArg(0)) == LCDecl) 8175 return checkAndSetIncRHS(CE->getArg(1)); 8176 break; 8177 default: 8178 break; 8179 } 8180 } 8181 if (dependent() || SemaRef.CurContext->isDependentContext()) 8182 return false; 8183 SemaRef.Diag(S->getBeginLoc(), diag::err_omp_loop_not_canonical_incr) 8184 << S->getSourceRange() << LCDecl; 8185 return true; 8186 } 8187 8188 static ExprResult 8189 tryBuildCapture(Sema &SemaRef, Expr *Capture, 8190 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) { 8191 if (SemaRef.CurContext->isDependentContext() || Capture->containsErrors()) 8192 return Capture; 8193 if (Capture->isEvaluatable(SemaRef.Context, Expr::SE_AllowSideEffects)) 8194 return SemaRef.PerformImplicitConversion( 8195 Capture->IgnoreImpCasts(), Capture->getType(), Sema::AA_Converting, 8196 /*AllowExplicit=*/true); 8197 auto I = Captures.find(Capture); 8198 if (I != Captures.end()) 8199 return buildCapture(SemaRef, Capture, I->second); 8200 DeclRefExpr *Ref = nullptr; 8201 ExprResult Res = buildCapture(SemaRef, Capture, Ref); 8202 Captures[Capture] = Ref; 8203 return Res; 8204 } 8205 8206 /// Calculate number of iterations, transforming to unsigned, if number of 8207 /// iterations may be larger than the original type. 8208 static Expr * 8209 calculateNumIters(Sema &SemaRef, Scope *S, SourceLocation DefaultLoc, 8210 Expr *Lower, Expr *Upper, Expr *Step, QualType LCTy, 8211 bool TestIsStrictOp, bool RoundToStep, 8212 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) { 8213 ExprResult NewStep = tryBuildCapture(SemaRef, Step, Captures); 8214 if (!NewStep.isUsable()) 8215 return nullptr; 8216 llvm::APSInt LRes, SRes; 8217 bool IsLowerConst = false, IsStepConst = false; 8218 if (Optional<llvm::APSInt> Res = 8219 Lower->getIntegerConstantExpr(SemaRef.Context)) { 8220 LRes = *Res; 8221 IsLowerConst = true; 8222 } 8223 if (Optional<llvm::APSInt> Res = 8224 Step->getIntegerConstantExpr(SemaRef.Context)) { 8225 SRes = *Res; 8226 IsStepConst = true; 8227 } 8228 bool NoNeedToConvert = IsLowerConst && !RoundToStep && 8229 ((!TestIsStrictOp && LRes.isNonNegative()) || 8230 (TestIsStrictOp && LRes.isStrictlyPositive())); 8231 bool NeedToReorganize = false; 8232 // Check if any subexpressions in Lower -Step [+ 1] lead to overflow. 8233 if (!NoNeedToConvert && IsLowerConst && 8234 (TestIsStrictOp || (RoundToStep && IsStepConst))) { 8235 NoNeedToConvert = true; 8236 if (RoundToStep) { 8237 unsigned BW = LRes.getBitWidth() > SRes.getBitWidth() 8238 ? LRes.getBitWidth() 8239 : SRes.getBitWidth(); 8240 LRes = LRes.extend(BW + 1); 8241 LRes.setIsSigned(true); 8242 SRes = SRes.extend(BW + 1); 8243 SRes.setIsSigned(true); 8244 LRes -= SRes; 8245 NoNeedToConvert = LRes.trunc(BW).extend(BW + 1) == LRes; 8246 LRes = LRes.trunc(BW); 8247 } 8248 if (TestIsStrictOp) { 8249 unsigned BW = LRes.getBitWidth(); 8250 LRes = LRes.extend(BW + 1); 8251 LRes.setIsSigned(true); 8252 ++LRes; 8253 NoNeedToConvert = 8254 NoNeedToConvert && LRes.trunc(BW).extend(BW + 1) == LRes; 8255 // truncate to the original bitwidth. 8256 LRes = LRes.trunc(BW); 8257 } 8258 NeedToReorganize = NoNeedToConvert; 8259 } 8260 llvm::APSInt URes; 8261 bool IsUpperConst = false; 8262 if (Optional<llvm::APSInt> Res = 8263 Upper->getIntegerConstantExpr(SemaRef.Context)) { 8264 URes = *Res; 8265 IsUpperConst = true; 8266 } 8267 if (NoNeedToConvert && IsLowerConst && IsUpperConst && 8268 (!RoundToStep || IsStepConst)) { 8269 unsigned BW = LRes.getBitWidth() > URes.getBitWidth() ? LRes.getBitWidth() 8270 : URes.getBitWidth(); 8271 LRes = LRes.extend(BW + 1); 8272 LRes.setIsSigned(true); 8273 URes = URes.extend(BW + 1); 8274 URes.setIsSigned(true); 8275 URes -= LRes; 8276 NoNeedToConvert = URes.trunc(BW).extend(BW + 1) == URes; 8277 NeedToReorganize = NoNeedToConvert; 8278 } 8279 // If the boundaries are not constant or (Lower - Step [+ 1]) is not constant 8280 // or less than zero (Upper - (Lower - Step [+ 1]) may overflow) - promote to 8281 // unsigned. 8282 if ((!NoNeedToConvert || (LRes.isNegative() && !IsUpperConst)) && 8283 !LCTy->isDependentType() && LCTy->isIntegerType()) { 8284 QualType LowerTy = Lower->getType(); 8285 QualType UpperTy = Upper->getType(); 8286 uint64_t LowerSize = SemaRef.Context.getTypeSize(LowerTy); 8287 uint64_t UpperSize = SemaRef.Context.getTypeSize(UpperTy); 8288 if ((LowerSize <= UpperSize && UpperTy->hasSignedIntegerRepresentation()) || 8289 (LowerSize > UpperSize && LowerTy->hasSignedIntegerRepresentation())) { 8290 QualType CastType = SemaRef.Context.getIntTypeForBitwidth( 8291 LowerSize > UpperSize ? LowerSize : UpperSize, /*Signed=*/0); 8292 Upper = 8293 SemaRef 8294 .PerformImplicitConversion( 8295 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Upper).get(), 8296 CastType, Sema::AA_Converting) 8297 .get(); 8298 Lower = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Lower).get(); 8299 NewStep = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, NewStep.get()); 8300 } 8301 } 8302 if (!Lower || !Upper || NewStep.isInvalid()) 8303 return nullptr; 8304 8305 ExprResult Diff; 8306 // If need to reorganize, then calculate the form as Upper - (Lower - Step [+ 8307 // 1]). 8308 if (NeedToReorganize) { 8309 Diff = Lower; 8310 8311 if (RoundToStep) { 8312 // Lower - Step 8313 Diff = 8314 SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Diff.get(), NewStep.get()); 8315 if (!Diff.isUsable()) 8316 return nullptr; 8317 } 8318 8319 // Lower - Step [+ 1] 8320 if (TestIsStrictOp) 8321 Diff = SemaRef.BuildBinOp( 8322 S, DefaultLoc, BO_Add, Diff.get(), 8323 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()); 8324 if (!Diff.isUsable()) 8325 return nullptr; 8326 8327 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get()); 8328 if (!Diff.isUsable()) 8329 return nullptr; 8330 8331 // Upper - (Lower - Step [+ 1]). 8332 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Diff.get()); 8333 if (!Diff.isUsable()) 8334 return nullptr; 8335 } else { 8336 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Lower); 8337 8338 if (!Diff.isUsable() && LCTy->getAsCXXRecordDecl()) { 8339 // BuildBinOp already emitted error, this one is to point user to upper 8340 // and lower bound, and to tell what is passed to 'operator-'. 8341 SemaRef.Diag(Upper->getBeginLoc(), diag::err_omp_loop_diff_cxx) 8342 << Upper->getSourceRange() << Lower->getSourceRange(); 8343 return nullptr; 8344 } 8345 8346 if (!Diff.isUsable()) 8347 return nullptr; 8348 8349 // Upper - Lower [- 1] 8350 if (TestIsStrictOp) 8351 Diff = SemaRef.BuildBinOp( 8352 S, DefaultLoc, BO_Sub, Diff.get(), 8353 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()); 8354 if (!Diff.isUsable()) 8355 return nullptr; 8356 8357 if (RoundToStep) { 8358 // Upper - Lower [- 1] + Step 8359 Diff = 8360 SemaRef.BuildBinOp(S, DefaultLoc, BO_Add, Diff.get(), NewStep.get()); 8361 if (!Diff.isUsable()) 8362 return nullptr; 8363 } 8364 } 8365 8366 // Parentheses (for dumping/debugging purposes only). 8367 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get()); 8368 if (!Diff.isUsable()) 8369 return nullptr; 8370 8371 // (Upper - Lower [- 1] + Step) / Step or (Upper - Lower) / Step 8372 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Div, Diff.get(), NewStep.get()); 8373 if (!Diff.isUsable()) 8374 return nullptr; 8375 8376 return Diff.get(); 8377 } 8378 8379 /// Build the expression to calculate the number of iterations. 8380 Expr *OpenMPIterationSpaceChecker::buildNumIterations( 8381 Scope *S, ArrayRef<LoopIterationSpace> ResultIterSpaces, bool LimitedType, 8382 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const { 8383 QualType VarType = LCDecl->getType().getNonReferenceType(); 8384 if (!VarType->isIntegerType() && !VarType->isPointerType() && 8385 !SemaRef.getLangOpts().CPlusPlus) 8386 return nullptr; 8387 Expr *LBVal = LB; 8388 Expr *UBVal = UB; 8389 // LB = TestIsLessOp.getValue() ? min(LB(MinVal), LB(MaxVal)) : 8390 // max(LB(MinVal), LB(MaxVal)) 8391 if (InitDependOnLC) { 8392 const LoopIterationSpace &IS = ResultIterSpaces[*InitDependOnLC - 1]; 8393 if (!IS.MinValue || !IS.MaxValue) 8394 return nullptr; 8395 // OuterVar = Min 8396 ExprResult MinValue = 8397 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MinValue); 8398 if (!MinValue.isUsable()) 8399 return nullptr; 8400 8401 ExprResult LBMinVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign, 8402 IS.CounterVar, MinValue.get()); 8403 if (!LBMinVal.isUsable()) 8404 return nullptr; 8405 // OuterVar = Min, LBVal 8406 LBMinVal = 8407 SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, LBMinVal.get(), LBVal); 8408 if (!LBMinVal.isUsable()) 8409 return nullptr; 8410 // (OuterVar = Min, LBVal) 8411 LBMinVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, LBMinVal.get()); 8412 if (!LBMinVal.isUsable()) 8413 return nullptr; 8414 8415 // OuterVar = Max 8416 ExprResult MaxValue = 8417 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MaxValue); 8418 if (!MaxValue.isUsable()) 8419 return nullptr; 8420 8421 ExprResult LBMaxVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign, 8422 IS.CounterVar, MaxValue.get()); 8423 if (!LBMaxVal.isUsable()) 8424 return nullptr; 8425 // OuterVar = Max, LBVal 8426 LBMaxVal = 8427 SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, LBMaxVal.get(), LBVal); 8428 if (!LBMaxVal.isUsable()) 8429 return nullptr; 8430 // (OuterVar = Max, LBVal) 8431 LBMaxVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, LBMaxVal.get()); 8432 if (!LBMaxVal.isUsable()) 8433 return nullptr; 8434 8435 Expr *LBMin = tryBuildCapture(SemaRef, LBMinVal.get(), Captures).get(); 8436 Expr *LBMax = tryBuildCapture(SemaRef, LBMaxVal.get(), Captures).get(); 8437 if (!LBMin || !LBMax) 8438 return nullptr; 8439 // LB(MinVal) < LB(MaxVal) 8440 ExprResult MinLessMaxRes = 8441 SemaRef.BuildBinOp(S, DefaultLoc, BO_LT, LBMin, LBMax); 8442 if (!MinLessMaxRes.isUsable()) 8443 return nullptr; 8444 Expr *MinLessMax = 8445 tryBuildCapture(SemaRef, MinLessMaxRes.get(), Captures).get(); 8446 if (!MinLessMax) 8447 return nullptr; 8448 if (*TestIsLessOp) { 8449 // LB(MinVal) < LB(MaxVal) ? LB(MinVal) : LB(MaxVal) - min(LB(MinVal), 8450 // LB(MaxVal)) 8451 ExprResult MinLB = SemaRef.ActOnConditionalOp(DefaultLoc, DefaultLoc, 8452 MinLessMax, LBMin, LBMax); 8453 if (!MinLB.isUsable()) 8454 return nullptr; 8455 LBVal = MinLB.get(); 8456 } else { 8457 // LB(MinVal) < LB(MaxVal) ? LB(MaxVal) : LB(MinVal) - max(LB(MinVal), 8458 // LB(MaxVal)) 8459 ExprResult MaxLB = SemaRef.ActOnConditionalOp(DefaultLoc, DefaultLoc, 8460 MinLessMax, LBMax, LBMin); 8461 if (!MaxLB.isUsable()) 8462 return nullptr; 8463 LBVal = MaxLB.get(); 8464 } 8465 } 8466 // UB = TestIsLessOp.getValue() ? max(UB(MinVal), UB(MaxVal)) : 8467 // min(UB(MinVal), UB(MaxVal)) 8468 if (CondDependOnLC) { 8469 const LoopIterationSpace &IS = ResultIterSpaces[*CondDependOnLC - 1]; 8470 if (!IS.MinValue || !IS.MaxValue) 8471 return nullptr; 8472 // OuterVar = Min 8473 ExprResult MinValue = 8474 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MinValue); 8475 if (!MinValue.isUsable()) 8476 return nullptr; 8477 8478 ExprResult UBMinVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign, 8479 IS.CounterVar, MinValue.get()); 8480 if (!UBMinVal.isUsable()) 8481 return nullptr; 8482 // OuterVar = Min, UBVal 8483 UBMinVal = 8484 SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, UBMinVal.get(), UBVal); 8485 if (!UBMinVal.isUsable()) 8486 return nullptr; 8487 // (OuterVar = Min, UBVal) 8488 UBMinVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, UBMinVal.get()); 8489 if (!UBMinVal.isUsable()) 8490 return nullptr; 8491 8492 // OuterVar = Max 8493 ExprResult MaxValue = 8494 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MaxValue); 8495 if (!MaxValue.isUsable()) 8496 return nullptr; 8497 8498 ExprResult UBMaxVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign, 8499 IS.CounterVar, MaxValue.get()); 8500 if (!UBMaxVal.isUsable()) 8501 return nullptr; 8502 // OuterVar = Max, UBVal 8503 UBMaxVal = 8504 SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, UBMaxVal.get(), UBVal); 8505 if (!UBMaxVal.isUsable()) 8506 return nullptr; 8507 // (OuterVar = Max, UBVal) 8508 UBMaxVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, UBMaxVal.get()); 8509 if (!UBMaxVal.isUsable()) 8510 return nullptr; 8511 8512 Expr *UBMin = tryBuildCapture(SemaRef, UBMinVal.get(), Captures).get(); 8513 Expr *UBMax = tryBuildCapture(SemaRef, UBMaxVal.get(), Captures).get(); 8514 if (!UBMin || !UBMax) 8515 return nullptr; 8516 // UB(MinVal) > UB(MaxVal) 8517 ExprResult MinGreaterMaxRes = 8518 SemaRef.BuildBinOp(S, DefaultLoc, BO_GT, UBMin, UBMax); 8519 if (!MinGreaterMaxRes.isUsable()) 8520 return nullptr; 8521 Expr *MinGreaterMax = 8522 tryBuildCapture(SemaRef, MinGreaterMaxRes.get(), Captures).get(); 8523 if (!MinGreaterMax) 8524 return nullptr; 8525 if (*TestIsLessOp) { 8526 // UB(MinVal) > UB(MaxVal) ? UB(MinVal) : UB(MaxVal) - max(UB(MinVal), 8527 // UB(MaxVal)) 8528 ExprResult MaxUB = SemaRef.ActOnConditionalOp( 8529 DefaultLoc, DefaultLoc, MinGreaterMax, UBMin, UBMax); 8530 if (!MaxUB.isUsable()) 8531 return nullptr; 8532 UBVal = MaxUB.get(); 8533 } else { 8534 // UB(MinVal) > UB(MaxVal) ? UB(MaxVal) : UB(MinVal) - min(UB(MinVal), 8535 // UB(MaxVal)) 8536 ExprResult MinUB = SemaRef.ActOnConditionalOp( 8537 DefaultLoc, DefaultLoc, MinGreaterMax, UBMax, UBMin); 8538 if (!MinUB.isUsable()) 8539 return nullptr; 8540 UBVal = MinUB.get(); 8541 } 8542 } 8543 Expr *UBExpr = TestIsLessOp.getValue() ? UBVal : LBVal; 8544 Expr *LBExpr = TestIsLessOp.getValue() ? LBVal : UBVal; 8545 Expr *Upper = tryBuildCapture(SemaRef, UBExpr, Captures).get(); 8546 Expr *Lower = tryBuildCapture(SemaRef, LBExpr, Captures).get(); 8547 if (!Upper || !Lower) 8548 return nullptr; 8549 8550 ExprResult Diff = calculateNumIters(SemaRef, S, DefaultLoc, Lower, Upper, 8551 Step, VarType, TestIsStrictOp, 8552 /*RoundToStep=*/true, Captures); 8553 if (!Diff.isUsable()) 8554 return nullptr; 8555 8556 // OpenMP runtime requires 32-bit or 64-bit loop variables. 8557 QualType Type = Diff.get()->getType(); 8558 ASTContext &C = SemaRef.Context; 8559 bool UseVarType = VarType->hasIntegerRepresentation() && 8560 C.getTypeSize(Type) > C.getTypeSize(VarType); 8561 if (!Type->isIntegerType() || UseVarType) { 8562 unsigned NewSize = 8563 UseVarType ? C.getTypeSize(VarType) : C.getTypeSize(Type); 8564 bool IsSigned = UseVarType ? VarType->hasSignedIntegerRepresentation() 8565 : Type->hasSignedIntegerRepresentation(); 8566 Type = C.getIntTypeForBitwidth(NewSize, IsSigned); 8567 if (!SemaRef.Context.hasSameType(Diff.get()->getType(), Type)) { 8568 Diff = SemaRef.PerformImplicitConversion( 8569 Diff.get(), Type, Sema::AA_Converting, /*AllowExplicit=*/true); 8570 if (!Diff.isUsable()) 8571 return nullptr; 8572 } 8573 } 8574 if (LimitedType) { 8575 unsigned NewSize = (C.getTypeSize(Type) > 32) ? 64 : 32; 8576 if (NewSize != C.getTypeSize(Type)) { 8577 if (NewSize < C.getTypeSize(Type)) { 8578 assert(NewSize == 64 && "incorrect loop var size"); 8579 SemaRef.Diag(DefaultLoc, diag::warn_omp_loop_64_bit_var) 8580 << InitSrcRange << ConditionSrcRange; 8581 } 8582 QualType NewType = C.getIntTypeForBitwidth( 8583 NewSize, Type->hasSignedIntegerRepresentation() || 8584 C.getTypeSize(Type) < NewSize); 8585 if (!SemaRef.Context.hasSameType(Diff.get()->getType(), NewType)) { 8586 Diff = SemaRef.PerformImplicitConversion(Diff.get(), NewType, 8587 Sema::AA_Converting, true); 8588 if (!Diff.isUsable()) 8589 return nullptr; 8590 } 8591 } 8592 } 8593 8594 return Diff.get(); 8595 } 8596 8597 std::pair<Expr *, Expr *> OpenMPIterationSpaceChecker::buildMinMaxValues( 8598 Scope *S, llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const { 8599 // Do not build for iterators, they cannot be used in non-rectangular loop 8600 // nests. 8601 if (LCDecl->getType()->isRecordType()) 8602 return std::make_pair(nullptr, nullptr); 8603 // If we subtract, the min is in the condition, otherwise the min is in the 8604 // init value. 8605 Expr *MinExpr = nullptr; 8606 Expr *MaxExpr = nullptr; 8607 Expr *LBExpr = TestIsLessOp.getValue() ? LB : UB; 8608 Expr *UBExpr = TestIsLessOp.getValue() ? UB : LB; 8609 bool LBNonRect = TestIsLessOp.getValue() ? InitDependOnLC.hasValue() 8610 : CondDependOnLC.hasValue(); 8611 bool UBNonRect = TestIsLessOp.getValue() ? CondDependOnLC.hasValue() 8612 : InitDependOnLC.hasValue(); 8613 Expr *Lower = 8614 LBNonRect ? LBExpr : tryBuildCapture(SemaRef, LBExpr, Captures).get(); 8615 Expr *Upper = 8616 UBNonRect ? UBExpr : tryBuildCapture(SemaRef, UBExpr, Captures).get(); 8617 if (!Upper || !Lower) 8618 return std::make_pair(nullptr, nullptr); 8619 8620 if (*TestIsLessOp) 8621 MinExpr = Lower; 8622 else 8623 MaxExpr = Upper; 8624 8625 // Build minimum/maximum value based on number of iterations. 8626 QualType VarType = LCDecl->getType().getNonReferenceType(); 8627 8628 ExprResult Diff = calculateNumIters(SemaRef, S, DefaultLoc, Lower, Upper, 8629 Step, VarType, TestIsStrictOp, 8630 /*RoundToStep=*/false, Captures); 8631 if (!Diff.isUsable()) 8632 return std::make_pair(nullptr, nullptr); 8633 8634 // ((Upper - Lower [- 1]) / Step) * Step 8635 // Parentheses (for dumping/debugging purposes only). 8636 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get()); 8637 if (!Diff.isUsable()) 8638 return std::make_pair(nullptr, nullptr); 8639 8640 ExprResult NewStep = tryBuildCapture(SemaRef, Step, Captures); 8641 if (!NewStep.isUsable()) 8642 return std::make_pair(nullptr, nullptr); 8643 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Mul, Diff.get(), NewStep.get()); 8644 if (!Diff.isUsable()) 8645 return std::make_pair(nullptr, nullptr); 8646 8647 // Parentheses (for dumping/debugging purposes only). 8648 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get()); 8649 if (!Diff.isUsable()) 8650 return std::make_pair(nullptr, nullptr); 8651 8652 // Convert to the ptrdiff_t, if original type is pointer. 8653 if (VarType->isAnyPointerType() && 8654 !SemaRef.Context.hasSameType( 8655 Diff.get()->getType(), 8656 SemaRef.Context.getUnsignedPointerDiffType())) { 8657 Diff = SemaRef.PerformImplicitConversion( 8658 Diff.get(), SemaRef.Context.getUnsignedPointerDiffType(), 8659 Sema::AA_Converting, /*AllowExplicit=*/true); 8660 } 8661 if (!Diff.isUsable()) 8662 return std::make_pair(nullptr, nullptr); 8663 8664 if (*TestIsLessOp) { 8665 // MinExpr = Lower; 8666 // MaxExpr = Lower + (((Upper - Lower [- 1]) / Step) * Step) 8667 Diff = SemaRef.BuildBinOp( 8668 S, DefaultLoc, BO_Add, 8669 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Lower).get(), 8670 Diff.get()); 8671 if (!Diff.isUsable()) 8672 return std::make_pair(nullptr, nullptr); 8673 } else { 8674 // MaxExpr = Upper; 8675 // MinExpr = Upper - (((Upper - Lower [- 1]) / Step) * Step) 8676 Diff = SemaRef.BuildBinOp( 8677 S, DefaultLoc, BO_Sub, 8678 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Upper).get(), 8679 Diff.get()); 8680 if (!Diff.isUsable()) 8681 return std::make_pair(nullptr, nullptr); 8682 } 8683 8684 // Convert to the original type. 8685 if (SemaRef.Context.hasSameType(Diff.get()->getType(), VarType)) 8686 Diff = SemaRef.PerformImplicitConversion(Diff.get(), VarType, 8687 Sema::AA_Converting, 8688 /*AllowExplicit=*/true); 8689 if (!Diff.isUsable()) 8690 return std::make_pair(nullptr, nullptr); 8691 8692 Sema::TentativeAnalysisScope Trap(SemaRef); 8693 Diff = SemaRef.ActOnFinishFullExpr(Diff.get(), /*DiscardedValue=*/false); 8694 if (!Diff.isUsable()) 8695 return std::make_pair(nullptr, nullptr); 8696 8697 if (*TestIsLessOp) 8698 MaxExpr = Diff.get(); 8699 else 8700 MinExpr = Diff.get(); 8701 8702 return std::make_pair(MinExpr, MaxExpr); 8703 } 8704 8705 Expr *OpenMPIterationSpaceChecker::buildFinalCondition(Scope *S) const { 8706 if (InitDependOnLC || CondDependOnLC) 8707 return Condition; 8708 return nullptr; 8709 } 8710 8711 Expr *OpenMPIterationSpaceChecker::buildPreCond( 8712 Scope *S, Expr *Cond, 8713 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const { 8714 // Do not build a precondition when the condition/initialization is dependent 8715 // to prevent pessimistic early loop exit. 8716 // TODO: this can be improved by calculating min/max values but not sure that 8717 // it will be very effective. 8718 if (CondDependOnLC || InitDependOnLC) 8719 return SemaRef 8720 .PerformImplicitConversion( 8721 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get(), 8722 SemaRef.Context.BoolTy, /*Action=*/Sema::AA_Casting, 8723 /*AllowExplicit=*/true) 8724 .get(); 8725 8726 // Try to build LB <op> UB, where <op> is <, >, <=, or >=. 8727 Sema::TentativeAnalysisScope Trap(SemaRef); 8728 8729 ExprResult NewLB = tryBuildCapture(SemaRef, LB, Captures); 8730 ExprResult NewUB = tryBuildCapture(SemaRef, UB, Captures); 8731 if (!NewLB.isUsable() || !NewUB.isUsable()) 8732 return nullptr; 8733 8734 ExprResult CondExpr = SemaRef.BuildBinOp( 8735 S, DefaultLoc, 8736 TestIsLessOp.getValue() ? (TestIsStrictOp ? BO_LT : BO_LE) 8737 : (TestIsStrictOp ? BO_GT : BO_GE), 8738 NewLB.get(), NewUB.get()); 8739 if (CondExpr.isUsable()) { 8740 if (!SemaRef.Context.hasSameUnqualifiedType(CondExpr.get()->getType(), 8741 SemaRef.Context.BoolTy)) 8742 CondExpr = SemaRef.PerformImplicitConversion( 8743 CondExpr.get(), SemaRef.Context.BoolTy, /*Action=*/Sema::AA_Casting, 8744 /*AllowExplicit=*/true); 8745 } 8746 8747 // Otherwise use original loop condition and evaluate it in runtime. 8748 return CondExpr.isUsable() ? CondExpr.get() : Cond; 8749 } 8750 8751 /// Build reference expression to the counter be used for codegen. 8752 DeclRefExpr *OpenMPIterationSpaceChecker::buildCounterVar( 8753 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures, 8754 DSAStackTy &DSA) const { 8755 auto *VD = dyn_cast<VarDecl>(LCDecl); 8756 if (!VD) { 8757 VD = SemaRef.isOpenMPCapturedDecl(LCDecl); 8758 DeclRefExpr *Ref = buildDeclRefExpr( 8759 SemaRef, VD, VD->getType().getNonReferenceType(), DefaultLoc); 8760 const DSAStackTy::DSAVarData Data = 8761 DSA.getTopDSA(LCDecl, /*FromParent=*/false); 8762 // If the loop control decl is explicitly marked as private, do not mark it 8763 // as captured again. 8764 if (!isOpenMPPrivate(Data.CKind) || !Data.RefExpr) 8765 Captures.insert(std::make_pair(LCRef, Ref)); 8766 return Ref; 8767 } 8768 return cast<DeclRefExpr>(LCRef); 8769 } 8770 8771 Expr *OpenMPIterationSpaceChecker::buildPrivateCounterVar() const { 8772 if (LCDecl && !LCDecl->isInvalidDecl()) { 8773 QualType Type = LCDecl->getType().getNonReferenceType(); 8774 VarDecl *PrivateVar = buildVarDecl( 8775 SemaRef, DefaultLoc, Type, LCDecl->getName(), 8776 LCDecl->hasAttrs() ? &LCDecl->getAttrs() : nullptr, 8777 isa<VarDecl>(LCDecl) 8778 ? buildDeclRefExpr(SemaRef, cast<VarDecl>(LCDecl), Type, DefaultLoc) 8779 : nullptr); 8780 if (PrivateVar->isInvalidDecl()) 8781 return nullptr; 8782 return buildDeclRefExpr(SemaRef, PrivateVar, Type, DefaultLoc); 8783 } 8784 return nullptr; 8785 } 8786 8787 /// Build initialization of the counter to be used for codegen. 8788 Expr *OpenMPIterationSpaceChecker::buildCounterInit() const { return LB; } 8789 8790 /// Build step of the counter be used for codegen. 8791 Expr *OpenMPIterationSpaceChecker::buildCounterStep() const { return Step; } 8792 8793 Expr *OpenMPIterationSpaceChecker::buildOrderedLoopData( 8794 Scope *S, Expr *Counter, 8795 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures, SourceLocation Loc, 8796 Expr *Inc, OverloadedOperatorKind OOK) { 8797 Expr *Cnt = SemaRef.DefaultLvalueConversion(Counter).get(); 8798 if (!Cnt) 8799 return nullptr; 8800 if (Inc) { 8801 assert((OOK == OO_Plus || OOK == OO_Minus) && 8802 "Expected only + or - operations for depend clauses."); 8803 BinaryOperatorKind BOK = (OOK == OO_Plus) ? BO_Add : BO_Sub; 8804 Cnt = SemaRef.BuildBinOp(S, Loc, BOK, Cnt, Inc).get(); 8805 if (!Cnt) 8806 return nullptr; 8807 } 8808 QualType VarType = LCDecl->getType().getNonReferenceType(); 8809 if (!VarType->isIntegerType() && !VarType->isPointerType() && 8810 !SemaRef.getLangOpts().CPlusPlus) 8811 return nullptr; 8812 // Upper - Lower 8813 Expr *Upper = TestIsLessOp.getValue() 8814 ? Cnt 8815 : tryBuildCapture(SemaRef, LB, Captures).get(); 8816 Expr *Lower = TestIsLessOp.getValue() 8817 ? tryBuildCapture(SemaRef, LB, Captures).get() 8818 : Cnt; 8819 if (!Upper || !Lower) 8820 return nullptr; 8821 8822 ExprResult Diff = calculateNumIters( 8823 SemaRef, S, DefaultLoc, Lower, Upper, Step, VarType, 8824 /*TestIsStrictOp=*/false, /*RoundToStep=*/false, Captures); 8825 if (!Diff.isUsable()) 8826 return nullptr; 8827 8828 return Diff.get(); 8829 } 8830 } // namespace 8831 8832 void Sema::ActOnOpenMPLoopInitialization(SourceLocation ForLoc, Stmt *Init) { 8833 assert(getLangOpts().OpenMP && "OpenMP is not active."); 8834 assert(Init && "Expected loop in canonical form."); 8835 unsigned AssociatedLoops = DSAStack->getAssociatedLoops(); 8836 if (AssociatedLoops > 0 && 8837 isOpenMPLoopDirective(DSAStack->getCurrentDirective())) { 8838 DSAStack->loopStart(); 8839 OpenMPIterationSpaceChecker ISC(*this, /*SupportsNonRectangular=*/true, 8840 *DSAStack, ForLoc); 8841 if (!ISC.checkAndSetInit(Init, /*EmitDiags=*/false)) { 8842 if (ValueDecl *D = ISC.getLoopDecl()) { 8843 auto *VD = dyn_cast<VarDecl>(D); 8844 DeclRefExpr *PrivateRef = nullptr; 8845 if (!VD) { 8846 if (VarDecl *Private = isOpenMPCapturedDecl(D)) { 8847 VD = Private; 8848 } else { 8849 PrivateRef = buildCapture(*this, D, ISC.getLoopDeclRefExpr(), 8850 /*WithInit=*/false); 8851 VD = cast<VarDecl>(PrivateRef->getDecl()); 8852 } 8853 } 8854 DSAStack->addLoopControlVariable(D, VD); 8855 const Decl *LD = DSAStack->getPossiblyLoopCunter(); 8856 if (LD != D->getCanonicalDecl()) { 8857 DSAStack->resetPossibleLoopCounter(); 8858 if (auto *Var = dyn_cast_or_null<VarDecl>(LD)) 8859 MarkDeclarationsReferencedInExpr( 8860 buildDeclRefExpr(*this, const_cast<VarDecl *>(Var), 8861 Var->getType().getNonLValueExprType(Context), 8862 ForLoc, /*RefersToCapture=*/true)); 8863 } 8864 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 8865 // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables 8866 // Referenced in a Construct, C/C++]. The loop iteration variable in the 8867 // associated for-loop of a simd construct with just one associated 8868 // for-loop may be listed in a linear clause with a constant-linear-step 8869 // that is the increment of the associated for-loop. The loop iteration 8870 // variable(s) in the associated for-loop(s) of a for or parallel for 8871 // construct may be listed in a private or lastprivate clause. 8872 DSAStackTy::DSAVarData DVar = 8873 DSAStack->getTopDSA(D, /*FromParent=*/false); 8874 // If LoopVarRefExpr is nullptr it means the corresponding loop variable 8875 // is declared in the loop and it is predetermined as a private. 8876 Expr *LoopDeclRefExpr = ISC.getLoopDeclRefExpr(); 8877 OpenMPClauseKind PredeterminedCKind = 8878 isOpenMPSimdDirective(DKind) 8879 ? (DSAStack->hasMutipleLoops() ? OMPC_lastprivate : OMPC_linear) 8880 : OMPC_private; 8881 if (((isOpenMPSimdDirective(DKind) && DVar.CKind != OMPC_unknown && 8882 DVar.CKind != PredeterminedCKind && DVar.RefExpr && 8883 (LangOpts.OpenMP <= 45 || (DVar.CKind != OMPC_lastprivate && 8884 DVar.CKind != OMPC_private))) || 8885 ((isOpenMPWorksharingDirective(DKind) || DKind == OMPD_taskloop || 8886 DKind == OMPD_master_taskloop || 8887 DKind == OMPD_masked_taskloop || 8888 DKind == OMPD_parallel_master_taskloop || 8889 isOpenMPDistributeDirective(DKind)) && 8890 !isOpenMPSimdDirective(DKind) && DVar.CKind != OMPC_unknown && 8891 DVar.CKind != OMPC_private && DVar.CKind != OMPC_lastprivate)) && 8892 (DVar.CKind != OMPC_private || DVar.RefExpr)) { 8893 Diag(Init->getBeginLoc(), diag::err_omp_loop_var_dsa) 8894 << getOpenMPClauseName(DVar.CKind) 8895 << getOpenMPDirectiveName(DKind) 8896 << getOpenMPClauseName(PredeterminedCKind); 8897 if (DVar.RefExpr == nullptr) 8898 DVar.CKind = PredeterminedCKind; 8899 reportOriginalDsa(*this, DSAStack, D, DVar, 8900 /*IsLoopIterVar=*/true); 8901 } else if (LoopDeclRefExpr) { 8902 // Make the loop iteration variable private (for worksharing 8903 // constructs), linear (for simd directives with the only one 8904 // associated loop) or lastprivate (for simd directives with several 8905 // collapsed or ordered loops). 8906 if (DVar.CKind == OMPC_unknown) 8907 DSAStack->addDSA(D, LoopDeclRefExpr, PredeterminedCKind, 8908 PrivateRef); 8909 } 8910 } 8911 } 8912 DSAStack->setAssociatedLoops(AssociatedLoops - 1); 8913 } 8914 } 8915 8916 /// Called on a for stmt to check and extract its iteration space 8917 /// for further processing (such as collapsing). 8918 static bool checkOpenMPIterationSpace( 8919 OpenMPDirectiveKind DKind, Stmt *S, Sema &SemaRef, DSAStackTy &DSA, 8920 unsigned CurrentNestedLoopCount, unsigned NestedLoopCount, 8921 unsigned TotalNestedLoopCount, Expr *CollapseLoopCountExpr, 8922 Expr *OrderedLoopCountExpr, 8923 Sema::VarsWithInheritedDSAType &VarsWithImplicitDSA, 8924 llvm::MutableArrayRef<LoopIterationSpace> ResultIterSpaces, 8925 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) { 8926 bool SupportsNonRectangular = !isOpenMPLoopTransformationDirective(DKind); 8927 // OpenMP [2.9.1, Canonical Loop Form] 8928 // for (init-expr; test-expr; incr-expr) structured-block 8929 // for (range-decl: range-expr) structured-block 8930 if (auto *CanonLoop = dyn_cast_or_null<OMPCanonicalLoop>(S)) 8931 S = CanonLoop->getLoopStmt(); 8932 auto *For = dyn_cast_or_null<ForStmt>(S); 8933 auto *CXXFor = dyn_cast_or_null<CXXForRangeStmt>(S); 8934 // Ranged for is supported only in OpenMP 5.0. 8935 if (!For && (SemaRef.LangOpts.OpenMP <= 45 || !CXXFor)) { 8936 SemaRef.Diag(S->getBeginLoc(), diag::err_omp_not_for) 8937 << (CollapseLoopCountExpr != nullptr || OrderedLoopCountExpr != nullptr) 8938 << getOpenMPDirectiveName(DKind) << TotalNestedLoopCount 8939 << (CurrentNestedLoopCount > 0) << CurrentNestedLoopCount; 8940 if (TotalNestedLoopCount > 1) { 8941 if (CollapseLoopCountExpr && OrderedLoopCountExpr) 8942 SemaRef.Diag(DSA.getConstructLoc(), 8943 diag::note_omp_collapse_ordered_expr) 8944 << 2 << CollapseLoopCountExpr->getSourceRange() 8945 << OrderedLoopCountExpr->getSourceRange(); 8946 else if (CollapseLoopCountExpr) 8947 SemaRef.Diag(CollapseLoopCountExpr->getExprLoc(), 8948 diag::note_omp_collapse_ordered_expr) 8949 << 0 << CollapseLoopCountExpr->getSourceRange(); 8950 else 8951 SemaRef.Diag(OrderedLoopCountExpr->getExprLoc(), 8952 diag::note_omp_collapse_ordered_expr) 8953 << 1 << OrderedLoopCountExpr->getSourceRange(); 8954 } 8955 return true; 8956 } 8957 assert(((For && For->getBody()) || (CXXFor && CXXFor->getBody())) && 8958 "No loop body."); 8959 // Postpone analysis in dependent contexts for ranged for loops. 8960 if (CXXFor && SemaRef.CurContext->isDependentContext()) 8961 return false; 8962 8963 OpenMPIterationSpaceChecker ISC(SemaRef, SupportsNonRectangular, DSA, 8964 For ? For->getForLoc() : CXXFor->getForLoc()); 8965 8966 // Check init. 8967 Stmt *Init = For ? For->getInit() : CXXFor->getBeginStmt(); 8968 if (ISC.checkAndSetInit(Init)) 8969 return true; 8970 8971 bool HasErrors = false; 8972 8973 // Check loop variable's type. 8974 if (ValueDecl *LCDecl = ISC.getLoopDecl()) { 8975 // OpenMP [2.6, Canonical Loop Form] 8976 // Var is one of the following: 8977 // A variable of signed or unsigned integer type. 8978 // For C++, a variable of a random access iterator type. 8979 // For C, a variable of a pointer type. 8980 QualType VarType = LCDecl->getType().getNonReferenceType(); 8981 if (!VarType->isDependentType() && !VarType->isIntegerType() && 8982 !VarType->isPointerType() && 8983 !(SemaRef.getLangOpts().CPlusPlus && VarType->isOverloadableType())) { 8984 SemaRef.Diag(Init->getBeginLoc(), diag::err_omp_loop_variable_type) 8985 << SemaRef.getLangOpts().CPlusPlus; 8986 HasErrors = true; 8987 } 8988 8989 // OpenMP, 2.14.1.1 Data-sharing Attribute Rules for Variables Referenced in 8990 // a Construct 8991 // The loop iteration variable(s) in the associated for-loop(s) of a for or 8992 // parallel for construct is (are) private. 8993 // The loop iteration variable in the associated for-loop of a simd 8994 // construct with just one associated for-loop is linear with a 8995 // constant-linear-step that is the increment of the associated for-loop. 8996 // Exclude loop var from the list of variables with implicitly defined data 8997 // sharing attributes. 8998 VarsWithImplicitDSA.erase(LCDecl); 8999 9000 assert(isOpenMPLoopDirective(DKind) && "DSA for non-loop vars"); 9001 9002 // Check test-expr. 9003 HasErrors |= ISC.checkAndSetCond(For ? For->getCond() : CXXFor->getCond()); 9004 9005 // Check incr-expr. 9006 HasErrors |= ISC.checkAndSetInc(For ? For->getInc() : CXXFor->getInc()); 9007 } 9008 9009 if (ISC.dependent() || SemaRef.CurContext->isDependentContext() || HasErrors) 9010 return HasErrors; 9011 9012 // Build the loop's iteration space representation. 9013 ResultIterSpaces[CurrentNestedLoopCount].PreCond = ISC.buildPreCond( 9014 DSA.getCurScope(), For ? For->getCond() : CXXFor->getCond(), Captures); 9015 ResultIterSpaces[CurrentNestedLoopCount].NumIterations = 9016 ISC.buildNumIterations(DSA.getCurScope(), ResultIterSpaces, 9017 (isOpenMPWorksharingDirective(DKind) || 9018 isOpenMPGenericLoopDirective(DKind) || 9019 isOpenMPTaskLoopDirective(DKind) || 9020 isOpenMPDistributeDirective(DKind) || 9021 isOpenMPLoopTransformationDirective(DKind)), 9022 Captures); 9023 ResultIterSpaces[CurrentNestedLoopCount].CounterVar = 9024 ISC.buildCounterVar(Captures, DSA); 9025 ResultIterSpaces[CurrentNestedLoopCount].PrivateCounterVar = 9026 ISC.buildPrivateCounterVar(); 9027 ResultIterSpaces[CurrentNestedLoopCount].CounterInit = ISC.buildCounterInit(); 9028 ResultIterSpaces[CurrentNestedLoopCount].CounterStep = ISC.buildCounterStep(); 9029 ResultIterSpaces[CurrentNestedLoopCount].InitSrcRange = ISC.getInitSrcRange(); 9030 ResultIterSpaces[CurrentNestedLoopCount].CondSrcRange = 9031 ISC.getConditionSrcRange(); 9032 ResultIterSpaces[CurrentNestedLoopCount].IncSrcRange = 9033 ISC.getIncrementSrcRange(); 9034 ResultIterSpaces[CurrentNestedLoopCount].Subtract = ISC.shouldSubtractStep(); 9035 ResultIterSpaces[CurrentNestedLoopCount].IsStrictCompare = 9036 ISC.isStrictTestOp(); 9037 std::tie(ResultIterSpaces[CurrentNestedLoopCount].MinValue, 9038 ResultIterSpaces[CurrentNestedLoopCount].MaxValue) = 9039 ISC.buildMinMaxValues(DSA.getCurScope(), Captures); 9040 ResultIterSpaces[CurrentNestedLoopCount].FinalCondition = 9041 ISC.buildFinalCondition(DSA.getCurScope()); 9042 ResultIterSpaces[CurrentNestedLoopCount].IsNonRectangularLB = 9043 ISC.doesInitDependOnLC(); 9044 ResultIterSpaces[CurrentNestedLoopCount].IsNonRectangularUB = 9045 ISC.doesCondDependOnLC(); 9046 ResultIterSpaces[CurrentNestedLoopCount].LoopDependentIdx = 9047 ISC.getLoopDependentIdx(); 9048 9049 HasErrors |= 9050 (ResultIterSpaces[CurrentNestedLoopCount].PreCond == nullptr || 9051 ResultIterSpaces[CurrentNestedLoopCount].NumIterations == nullptr || 9052 ResultIterSpaces[CurrentNestedLoopCount].CounterVar == nullptr || 9053 ResultIterSpaces[CurrentNestedLoopCount].PrivateCounterVar == nullptr || 9054 ResultIterSpaces[CurrentNestedLoopCount].CounterInit == nullptr || 9055 ResultIterSpaces[CurrentNestedLoopCount].CounterStep == nullptr); 9056 if (!HasErrors && DSA.isOrderedRegion()) { 9057 if (DSA.getOrderedRegionParam().second->getNumForLoops()) { 9058 if (CurrentNestedLoopCount < 9059 DSA.getOrderedRegionParam().second->getLoopNumIterations().size()) { 9060 DSA.getOrderedRegionParam().second->setLoopNumIterations( 9061 CurrentNestedLoopCount, 9062 ResultIterSpaces[CurrentNestedLoopCount].NumIterations); 9063 DSA.getOrderedRegionParam().second->setLoopCounter( 9064 CurrentNestedLoopCount, 9065 ResultIterSpaces[CurrentNestedLoopCount].CounterVar); 9066 } 9067 } 9068 for (auto &Pair : DSA.getDoacrossDependClauses()) { 9069 if (CurrentNestedLoopCount >= Pair.first->getNumLoops()) { 9070 // Erroneous case - clause has some problems. 9071 continue; 9072 } 9073 if (Pair.first->getDependencyKind() == OMPC_DEPEND_sink && 9074 Pair.second.size() <= CurrentNestedLoopCount) { 9075 // Erroneous case - clause has some problems. 9076 Pair.first->setLoopData(CurrentNestedLoopCount, nullptr); 9077 continue; 9078 } 9079 Expr *CntValue; 9080 if (Pair.first->getDependencyKind() == OMPC_DEPEND_source) 9081 CntValue = ISC.buildOrderedLoopData( 9082 DSA.getCurScope(), 9083 ResultIterSpaces[CurrentNestedLoopCount].CounterVar, Captures, 9084 Pair.first->getDependencyLoc()); 9085 else 9086 CntValue = ISC.buildOrderedLoopData( 9087 DSA.getCurScope(), 9088 ResultIterSpaces[CurrentNestedLoopCount].CounterVar, Captures, 9089 Pair.first->getDependencyLoc(), 9090 Pair.second[CurrentNestedLoopCount].first, 9091 Pair.second[CurrentNestedLoopCount].second); 9092 Pair.first->setLoopData(CurrentNestedLoopCount, CntValue); 9093 } 9094 } 9095 9096 return HasErrors; 9097 } 9098 9099 /// Build 'VarRef = Start. 9100 static ExprResult 9101 buildCounterInit(Sema &SemaRef, Scope *S, SourceLocation Loc, ExprResult VarRef, 9102 ExprResult Start, bool IsNonRectangularLB, 9103 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) { 9104 // Build 'VarRef = Start. 9105 ExprResult NewStart = IsNonRectangularLB 9106 ? Start.get() 9107 : tryBuildCapture(SemaRef, Start.get(), Captures); 9108 if (!NewStart.isUsable()) 9109 return ExprError(); 9110 if (!SemaRef.Context.hasSameType(NewStart.get()->getType(), 9111 VarRef.get()->getType())) { 9112 NewStart = SemaRef.PerformImplicitConversion( 9113 NewStart.get(), VarRef.get()->getType(), Sema::AA_Converting, 9114 /*AllowExplicit=*/true); 9115 if (!NewStart.isUsable()) 9116 return ExprError(); 9117 } 9118 9119 ExprResult Init = 9120 SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), NewStart.get()); 9121 return Init; 9122 } 9123 9124 /// Build 'VarRef = Start + Iter * Step'. 9125 static ExprResult buildCounterUpdate( 9126 Sema &SemaRef, Scope *S, SourceLocation Loc, ExprResult VarRef, 9127 ExprResult Start, ExprResult Iter, ExprResult Step, bool Subtract, 9128 bool IsNonRectangularLB, 9129 llvm::MapVector<const Expr *, DeclRefExpr *> *Captures = nullptr) { 9130 // Add parentheses (for debugging purposes only). 9131 Iter = SemaRef.ActOnParenExpr(Loc, Loc, Iter.get()); 9132 if (!VarRef.isUsable() || !Start.isUsable() || !Iter.isUsable() || 9133 !Step.isUsable()) 9134 return ExprError(); 9135 9136 ExprResult NewStep = Step; 9137 if (Captures) 9138 NewStep = tryBuildCapture(SemaRef, Step.get(), *Captures); 9139 if (NewStep.isInvalid()) 9140 return ExprError(); 9141 ExprResult Update = 9142 SemaRef.BuildBinOp(S, Loc, BO_Mul, Iter.get(), NewStep.get()); 9143 if (!Update.isUsable()) 9144 return ExprError(); 9145 9146 // Try to build 'VarRef = Start, VarRef (+|-)= Iter * Step' or 9147 // 'VarRef = Start (+|-) Iter * Step'. 9148 if (!Start.isUsable()) 9149 return ExprError(); 9150 ExprResult NewStart = SemaRef.ActOnParenExpr(Loc, Loc, Start.get()); 9151 if (!NewStart.isUsable()) 9152 return ExprError(); 9153 if (Captures && !IsNonRectangularLB) 9154 NewStart = tryBuildCapture(SemaRef, Start.get(), *Captures); 9155 if (NewStart.isInvalid()) 9156 return ExprError(); 9157 9158 // First attempt: try to build 'VarRef = Start, VarRef += Iter * Step'. 9159 ExprResult SavedUpdate = Update; 9160 ExprResult UpdateVal; 9161 if (VarRef.get()->getType()->isOverloadableType() || 9162 NewStart.get()->getType()->isOverloadableType() || 9163 Update.get()->getType()->isOverloadableType()) { 9164 Sema::TentativeAnalysisScope Trap(SemaRef); 9165 9166 Update = 9167 SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), NewStart.get()); 9168 if (Update.isUsable()) { 9169 UpdateVal = 9170 SemaRef.BuildBinOp(S, Loc, Subtract ? BO_SubAssign : BO_AddAssign, 9171 VarRef.get(), SavedUpdate.get()); 9172 if (UpdateVal.isUsable()) { 9173 Update = SemaRef.CreateBuiltinBinOp(Loc, BO_Comma, Update.get(), 9174 UpdateVal.get()); 9175 } 9176 } 9177 } 9178 9179 // Second attempt: try to build 'VarRef = Start (+|-) Iter * Step'. 9180 if (!Update.isUsable() || !UpdateVal.isUsable()) { 9181 Update = SemaRef.BuildBinOp(S, Loc, Subtract ? BO_Sub : BO_Add, 9182 NewStart.get(), SavedUpdate.get()); 9183 if (!Update.isUsable()) 9184 return ExprError(); 9185 9186 if (!SemaRef.Context.hasSameType(Update.get()->getType(), 9187 VarRef.get()->getType())) { 9188 Update = SemaRef.PerformImplicitConversion( 9189 Update.get(), VarRef.get()->getType(), Sema::AA_Converting, true); 9190 if (!Update.isUsable()) 9191 return ExprError(); 9192 } 9193 9194 Update = SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), Update.get()); 9195 } 9196 return Update; 9197 } 9198 9199 /// Convert integer expression \a E to make it have at least \a Bits 9200 /// bits. 9201 static ExprResult widenIterationCount(unsigned Bits, Expr *E, Sema &SemaRef) { 9202 if (E == nullptr) 9203 return ExprError(); 9204 ASTContext &C = SemaRef.Context; 9205 QualType OldType = E->getType(); 9206 unsigned HasBits = C.getTypeSize(OldType); 9207 if (HasBits >= Bits) 9208 return ExprResult(E); 9209 // OK to convert to signed, because new type has more bits than old. 9210 QualType NewType = C.getIntTypeForBitwidth(Bits, /* Signed */ true); 9211 return SemaRef.PerformImplicitConversion(E, NewType, Sema::AA_Converting, 9212 true); 9213 } 9214 9215 /// Check if the given expression \a E is a constant integer that fits 9216 /// into \a Bits bits. 9217 static bool fitsInto(unsigned Bits, bool Signed, const Expr *E, Sema &SemaRef) { 9218 if (E == nullptr) 9219 return false; 9220 if (Optional<llvm::APSInt> Result = 9221 E->getIntegerConstantExpr(SemaRef.Context)) 9222 return Signed ? Result->isSignedIntN(Bits) : Result->isIntN(Bits); 9223 return false; 9224 } 9225 9226 /// Build preinits statement for the given declarations. 9227 static Stmt *buildPreInits(ASTContext &Context, 9228 MutableArrayRef<Decl *> PreInits) { 9229 if (!PreInits.empty()) { 9230 return new (Context) DeclStmt( 9231 DeclGroupRef::Create(Context, PreInits.begin(), PreInits.size()), 9232 SourceLocation(), SourceLocation()); 9233 } 9234 return nullptr; 9235 } 9236 9237 /// Build preinits statement for the given declarations. 9238 static Stmt * 9239 buildPreInits(ASTContext &Context, 9240 const llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) { 9241 if (!Captures.empty()) { 9242 SmallVector<Decl *, 16> PreInits; 9243 for (const auto &Pair : Captures) 9244 PreInits.push_back(Pair.second->getDecl()); 9245 return buildPreInits(Context, PreInits); 9246 } 9247 return nullptr; 9248 } 9249 9250 /// Build postupdate expression for the given list of postupdates expressions. 9251 static Expr *buildPostUpdate(Sema &S, ArrayRef<Expr *> PostUpdates) { 9252 Expr *PostUpdate = nullptr; 9253 if (!PostUpdates.empty()) { 9254 for (Expr *E : PostUpdates) { 9255 Expr *ConvE = S.BuildCStyleCastExpr( 9256 E->getExprLoc(), 9257 S.Context.getTrivialTypeSourceInfo(S.Context.VoidTy), 9258 E->getExprLoc(), E) 9259 .get(); 9260 PostUpdate = PostUpdate 9261 ? S.CreateBuiltinBinOp(ConvE->getExprLoc(), BO_Comma, 9262 PostUpdate, ConvE) 9263 .get() 9264 : ConvE; 9265 } 9266 } 9267 return PostUpdate; 9268 } 9269 9270 /// Called on a for stmt to check itself and nested loops (if any). 9271 /// \return Returns 0 if one of the collapsed stmts is not canonical for loop, 9272 /// number of collapsed loops otherwise. 9273 static unsigned 9274 checkOpenMPLoop(OpenMPDirectiveKind DKind, Expr *CollapseLoopCountExpr, 9275 Expr *OrderedLoopCountExpr, Stmt *AStmt, Sema &SemaRef, 9276 DSAStackTy &DSA, 9277 Sema::VarsWithInheritedDSAType &VarsWithImplicitDSA, 9278 OMPLoopBasedDirective::HelperExprs &Built) { 9279 unsigned NestedLoopCount = 1; 9280 bool SupportsNonPerfectlyNested = (SemaRef.LangOpts.OpenMP >= 50) && 9281 !isOpenMPLoopTransformationDirective(DKind); 9282 9283 if (CollapseLoopCountExpr) { 9284 // Found 'collapse' clause - calculate collapse number. 9285 Expr::EvalResult Result; 9286 if (!CollapseLoopCountExpr->isValueDependent() && 9287 CollapseLoopCountExpr->EvaluateAsInt(Result, SemaRef.getASTContext())) { 9288 NestedLoopCount = Result.Val.getInt().getLimitedValue(); 9289 } else { 9290 Built.clear(/*Size=*/1); 9291 return 1; 9292 } 9293 } 9294 unsigned OrderedLoopCount = 1; 9295 if (OrderedLoopCountExpr) { 9296 // Found 'ordered' clause - calculate collapse number. 9297 Expr::EvalResult EVResult; 9298 if (!OrderedLoopCountExpr->isValueDependent() && 9299 OrderedLoopCountExpr->EvaluateAsInt(EVResult, 9300 SemaRef.getASTContext())) { 9301 llvm::APSInt Result = EVResult.Val.getInt(); 9302 if (Result.getLimitedValue() < NestedLoopCount) { 9303 SemaRef.Diag(OrderedLoopCountExpr->getExprLoc(), 9304 diag::err_omp_wrong_ordered_loop_count) 9305 << OrderedLoopCountExpr->getSourceRange(); 9306 SemaRef.Diag(CollapseLoopCountExpr->getExprLoc(), 9307 diag::note_collapse_loop_count) 9308 << CollapseLoopCountExpr->getSourceRange(); 9309 } 9310 OrderedLoopCount = Result.getLimitedValue(); 9311 } else { 9312 Built.clear(/*Size=*/1); 9313 return 1; 9314 } 9315 } 9316 // This is helper routine for loop directives (e.g., 'for', 'simd', 9317 // 'for simd', etc.). 9318 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 9319 unsigned NumLoops = std::max(OrderedLoopCount, NestedLoopCount); 9320 SmallVector<LoopIterationSpace, 4> IterSpaces(NumLoops); 9321 if (!OMPLoopBasedDirective::doForAllLoops( 9322 AStmt->IgnoreContainers(!isOpenMPLoopTransformationDirective(DKind)), 9323 SupportsNonPerfectlyNested, NumLoops, 9324 [DKind, &SemaRef, &DSA, NumLoops, NestedLoopCount, 9325 CollapseLoopCountExpr, OrderedLoopCountExpr, &VarsWithImplicitDSA, 9326 &IterSpaces, &Captures](unsigned Cnt, Stmt *CurStmt) { 9327 if (checkOpenMPIterationSpace( 9328 DKind, CurStmt, SemaRef, DSA, Cnt, NestedLoopCount, 9329 NumLoops, CollapseLoopCountExpr, OrderedLoopCountExpr, 9330 VarsWithImplicitDSA, IterSpaces, Captures)) 9331 return true; 9332 if (Cnt > 0 && Cnt >= NestedLoopCount && 9333 IterSpaces[Cnt].CounterVar) { 9334 // Handle initialization of captured loop iterator variables. 9335 auto *DRE = cast<DeclRefExpr>(IterSpaces[Cnt].CounterVar); 9336 if (isa<OMPCapturedExprDecl>(DRE->getDecl())) { 9337 Captures[DRE] = DRE; 9338 } 9339 } 9340 return false; 9341 }, 9342 [&SemaRef, &Captures](OMPLoopTransformationDirective *Transform) { 9343 Stmt *DependentPreInits = Transform->getPreInits(); 9344 if (!DependentPreInits) 9345 return; 9346 for (Decl *C : cast<DeclStmt>(DependentPreInits)->getDeclGroup()) { 9347 auto *D = cast<VarDecl>(C); 9348 DeclRefExpr *Ref = buildDeclRefExpr(SemaRef, D, D->getType(), 9349 Transform->getBeginLoc()); 9350 Captures[Ref] = Ref; 9351 } 9352 })) 9353 return 0; 9354 9355 Built.clear(/* size */ NestedLoopCount); 9356 9357 if (SemaRef.CurContext->isDependentContext()) 9358 return NestedLoopCount; 9359 9360 // An example of what is generated for the following code: 9361 // 9362 // #pragma omp simd collapse(2) ordered(2) 9363 // for (i = 0; i < NI; ++i) 9364 // for (k = 0; k < NK; ++k) 9365 // for (j = J0; j < NJ; j+=2) { 9366 // <loop body> 9367 // } 9368 // 9369 // We generate the code below. 9370 // Note: the loop body may be outlined in CodeGen. 9371 // Note: some counters may be C++ classes, operator- is used to find number of 9372 // iterations and operator+= to calculate counter value. 9373 // Note: decltype(NumIterations) must be integer type (in 'omp for', only i32 9374 // or i64 is currently supported). 9375 // 9376 // #define NumIterations (NI * ((NJ - J0 - 1 + 2) / 2)) 9377 // for (int[32|64]_t IV = 0; IV < NumIterations; ++IV ) { 9378 // .local.i = IV / ((NJ - J0 - 1 + 2) / 2); 9379 // .local.j = J0 + (IV % ((NJ - J0 - 1 + 2) / 2)) * 2; 9380 // // similar updates for vars in clauses (e.g. 'linear') 9381 // <loop body (using local i and j)> 9382 // } 9383 // i = NI; // assign final values of counters 9384 // j = NJ; 9385 // 9386 9387 // Last iteration number is (I1 * I2 * ... In) - 1, where I1, I2 ... In are 9388 // the iteration counts of the collapsed for loops. 9389 // Precondition tests if there is at least one iteration (all conditions are 9390 // true). 9391 auto PreCond = ExprResult(IterSpaces[0].PreCond); 9392 Expr *N0 = IterSpaces[0].NumIterations; 9393 ExprResult LastIteration32 = 9394 widenIterationCount(/*Bits=*/32, 9395 SemaRef 9396 .PerformImplicitConversion( 9397 N0->IgnoreImpCasts(), N0->getType(), 9398 Sema::AA_Converting, /*AllowExplicit=*/true) 9399 .get(), 9400 SemaRef); 9401 ExprResult LastIteration64 = widenIterationCount( 9402 /*Bits=*/64, 9403 SemaRef 9404 .PerformImplicitConversion(N0->IgnoreImpCasts(), N0->getType(), 9405 Sema::AA_Converting, 9406 /*AllowExplicit=*/true) 9407 .get(), 9408 SemaRef); 9409 9410 if (!LastIteration32.isUsable() || !LastIteration64.isUsable()) 9411 return NestedLoopCount; 9412 9413 ASTContext &C = SemaRef.Context; 9414 bool AllCountsNeedLessThan32Bits = C.getTypeSize(N0->getType()) < 32; 9415 9416 Scope *CurScope = DSA.getCurScope(); 9417 for (unsigned Cnt = 1; Cnt < NestedLoopCount; ++Cnt) { 9418 if (PreCond.isUsable()) { 9419 PreCond = 9420 SemaRef.BuildBinOp(CurScope, PreCond.get()->getExprLoc(), BO_LAnd, 9421 PreCond.get(), IterSpaces[Cnt].PreCond); 9422 } 9423 Expr *N = IterSpaces[Cnt].NumIterations; 9424 SourceLocation Loc = N->getExprLoc(); 9425 AllCountsNeedLessThan32Bits &= C.getTypeSize(N->getType()) < 32; 9426 if (LastIteration32.isUsable()) 9427 LastIteration32 = SemaRef.BuildBinOp( 9428 CurScope, Loc, BO_Mul, LastIteration32.get(), 9429 SemaRef 9430 .PerformImplicitConversion(N->IgnoreImpCasts(), N->getType(), 9431 Sema::AA_Converting, 9432 /*AllowExplicit=*/true) 9433 .get()); 9434 if (LastIteration64.isUsable()) 9435 LastIteration64 = SemaRef.BuildBinOp( 9436 CurScope, Loc, BO_Mul, LastIteration64.get(), 9437 SemaRef 9438 .PerformImplicitConversion(N->IgnoreImpCasts(), N->getType(), 9439 Sema::AA_Converting, 9440 /*AllowExplicit=*/true) 9441 .get()); 9442 } 9443 9444 // Choose either the 32-bit or 64-bit version. 9445 ExprResult LastIteration = LastIteration64; 9446 if (SemaRef.getLangOpts().OpenMPOptimisticCollapse || 9447 (LastIteration32.isUsable() && 9448 C.getTypeSize(LastIteration32.get()->getType()) == 32 && 9449 (AllCountsNeedLessThan32Bits || NestedLoopCount == 1 || 9450 fitsInto( 9451 /*Bits=*/32, 9452 LastIteration32.get()->getType()->hasSignedIntegerRepresentation(), 9453 LastIteration64.get(), SemaRef)))) 9454 LastIteration = LastIteration32; 9455 QualType VType = LastIteration.get()->getType(); 9456 QualType RealVType = VType; 9457 QualType StrideVType = VType; 9458 if (isOpenMPTaskLoopDirective(DKind)) { 9459 VType = 9460 SemaRef.Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/0); 9461 StrideVType = 9462 SemaRef.Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/1); 9463 } 9464 9465 if (!LastIteration.isUsable()) 9466 return 0; 9467 9468 // Save the number of iterations. 9469 ExprResult NumIterations = LastIteration; 9470 { 9471 LastIteration = SemaRef.BuildBinOp( 9472 CurScope, LastIteration.get()->getExprLoc(), BO_Sub, 9473 LastIteration.get(), 9474 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()); 9475 if (!LastIteration.isUsable()) 9476 return 0; 9477 } 9478 9479 // Calculate the last iteration number beforehand instead of doing this on 9480 // each iteration. Do not do this if the number of iterations may be kfold-ed. 9481 bool IsConstant = LastIteration.get()->isIntegerConstantExpr(SemaRef.Context); 9482 ExprResult CalcLastIteration; 9483 if (!IsConstant) { 9484 ExprResult SaveRef = 9485 tryBuildCapture(SemaRef, LastIteration.get(), Captures); 9486 LastIteration = SaveRef; 9487 9488 // Prepare SaveRef + 1. 9489 NumIterations = SemaRef.BuildBinOp( 9490 CurScope, SaveRef.get()->getExprLoc(), BO_Add, SaveRef.get(), 9491 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()); 9492 if (!NumIterations.isUsable()) 9493 return 0; 9494 } 9495 9496 SourceLocation InitLoc = IterSpaces[0].InitSrcRange.getBegin(); 9497 9498 // Build variables passed into runtime, necessary for worksharing directives. 9499 ExprResult LB, UB, IL, ST, EUB, CombLB, CombUB, PrevLB, PrevUB, CombEUB; 9500 if (isOpenMPWorksharingDirective(DKind) || isOpenMPTaskLoopDirective(DKind) || 9501 isOpenMPDistributeDirective(DKind) || 9502 isOpenMPGenericLoopDirective(DKind) || 9503 isOpenMPLoopTransformationDirective(DKind)) { 9504 // Lower bound variable, initialized with zero. 9505 VarDecl *LBDecl = buildVarDecl(SemaRef, InitLoc, VType, ".omp.lb"); 9506 LB = buildDeclRefExpr(SemaRef, LBDecl, VType, InitLoc); 9507 SemaRef.AddInitializerToDecl(LBDecl, 9508 SemaRef.ActOnIntegerConstant(InitLoc, 0).get(), 9509 /*DirectInit*/ false); 9510 9511 // Upper bound variable, initialized with last iteration number. 9512 VarDecl *UBDecl = buildVarDecl(SemaRef, InitLoc, VType, ".omp.ub"); 9513 UB = buildDeclRefExpr(SemaRef, UBDecl, VType, InitLoc); 9514 SemaRef.AddInitializerToDecl(UBDecl, LastIteration.get(), 9515 /*DirectInit*/ false); 9516 9517 // A 32-bit variable-flag where runtime returns 1 for the last iteration. 9518 // This will be used to implement clause 'lastprivate'. 9519 QualType Int32Ty = SemaRef.Context.getIntTypeForBitwidth(32, true); 9520 VarDecl *ILDecl = buildVarDecl(SemaRef, InitLoc, Int32Ty, ".omp.is_last"); 9521 IL = buildDeclRefExpr(SemaRef, ILDecl, Int32Ty, InitLoc); 9522 SemaRef.AddInitializerToDecl(ILDecl, 9523 SemaRef.ActOnIntegerConstant(InitLoc, 0).get(), 9524 /*DirectInit*/ false); 9525 9526 // Stride variable returned by runtime (we initialize it to 1 by default). 9527 VarDecl *STDecl = 9528 buildVarDecl(SemaRef, InitLoc, StrideVType, ".omp.stride"); 9529 ST = buildDeclRefExpr(SemaRef, STDecl, StrideVType, InitLoc); 9530 SemaRef.AddInitializerToDecl(STDecl, 9531 SemaRef.ActOnIntegerConstant(InitLoc, 1).get(), 9532 /*DirectInit*/ false); 9533 9534 // Build expression: UB = min(UB, LastIteration) 9535 // It is necessary for CodeGen of directives with static scheduling. 9536 ExprResult IsUBGreater = SemaRef.BuildBinOp(CurScope, InitLoc, BO_GT, 9537 UB.get(), LastIteration.get()); 9538 ExprResult CondOp = SemaRef.ActOnConditionalOp( 9539 LastIteration.get()->getExprLoc(), InitLoc, IsUBGreater.get(), 9540 LastIteration.get(), UB.get()); 9541 EUB = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, UB.get(), 9542 CondOp.get()); 9543 EUB = SemaRef.ActOnFinishFullExpr(EUB.get(), /*DiscardedValue*/ false); 9544 9545 // If we have a combined directive that combines 'distribute', 'for' or 9546 // 'simd' we need to be able to access the bounds of the schedule of the 9547 // enclosing region. E.g. in 'distribute parallel for' the bounds obtained 9548 // by scheduling 'distribute' have to be passed to the schedule of 'for'. 9549 if (isOpenMPLoopBoundSharingDirective(DKind)) { 9550 // Lower bound variable, initialized with zero. 9551 VarDecl *CombLBDecl = 9552 buildVarDecl(SemaRef, InitLoc, VType, ".omp.comb.lb"); 9553 CombLB = buildDeclRefExpr(SemaRef, CombLBDecl, VType, InitLoc); 9554 SemaRef.AddInitializerToDecl( 9555 CombLBDecl, SemaRef.ActOnIntegerConstant(InitLoc, 0).get(), 9556 /*DirectInit*/ false); 9557 9558 // Upper bound variable, initialized with last iteration number. 9559 VarDecl *CombUBDecl = 9560 buildVarDecl(SemaRef, InitLoc, VType, ".omp.comb.ub"); 9561 CombUB = buildDeclRefExpr(SemaRef, CombUBDecl, VType, InitLoc); 9562 SemaRef.AddInitializerToDecl(CombUBDecl, LastIteration.get(), 9563 /*DirectInit*/ false); 9564 9565 ExprResult CombIsUBGreater = SemaRef.BuildBinOp( 9566 CurScope, InitLoc, BO_GT, CombUB.get(), LastIteration.get()); 9567 ExprResult CombCondOp = 9568 SemaRef.ActOnConditionalOp(InitLoc, InitLoc, CombIsUBGreater.get(), 9569 LastIteration.get(), CombUB.get()); 9570 CombEUB = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, CombUB.get(), 9571 CombCondOp.get()); 9572 CombEUB = 9573 SemaRef.ActOnFinishFullExpr(CombEUB.get(), /*DiscardedValue*/ false); 9574 9575 const CapturedDecl *CD = cast<CapturedStmt>(AStmt)->getCapturedDecl(); 9576 // We expect to have at least 2 more parameters than the 'parallel' 9577 // directive does - the lower and upper bounds of the previous schedule. 9578 assert(CD->getNumParams() >= 4 && 9579 "Unexpected number of parameters in loop combined directive"); 9580 9581 // Set the proper type for the bounds given what we learned from the 9582 // enclosed loops. 9583 ImplicitParamDecl *PrevLBDecl = CD->getParam(/*PrevLB=*/2); 9584 ImplicitParamDecl *PrevUBDecl = CD->getParam(/*PrevUB=*/3); 9585 9586 // Previous lower and upper bounds are obtained from the region 9587 // parameters. 9588 PrevLB = 9589 buildDeclRefExpr(SemaRef, PrevLBDecl, PrevLBDecl->getType(), InitLoc); 9590 PrevUB = 9591 buildDeclRefExpr(SemaRef, PrevUBDecl, PrevUBDecl->getType(), InitLoc); 9592 } 9593 } 9594 9595 // Build the iteration variable and its initialization before loop. 9596 ExprResult IV; 9597 ExprResult Init, CombInit; 9598 { 9599 VarDecl *IVDecl = buildVarDecl(SemaRef, InitLoc, RealVType, ".omp.iv"); 9600 IV = buildDeclRefExpr(SemaRef, IVDecl, RealVType, InitLoc); 9601 Expr *RHS = (isOpenMPWorksharingDirective(DKind) || 9602 isOpenMPGenericLoopDirective(DKind) || 9603 isOpenMPTaskLoopDirective(DKind) || 9604 isOpenMPDistributeDirective(DKind) || 9605 isOpenMPLoopTransformationDirective(DKind)) 9606 ? LB.get() 9607 : SemaRef.ActOnIntegerConstant(SourceLocation(), 0).get(); 9608 Init = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, IV.get(), RHS); 9609 Init = SemaRef.ActOnFinishFullExpr(Init.get(), /*DiscardedValue*/ false); 9610 9611 if (isOpenMPLoopBoundSharingDirective(DKind)) { 9612 Expr *CombRHS = 9613 (isOpenMPWorksharingDirective(DKind) || 9614 isOpenMPGenericLoopDirective(DKind) || 9615 isOpenMPTaskLoopDirective(DKind) || 9616 isOpenMPDistributeDirective(DKind)) 9617 ? CombLB.get() 9618 : SemaRef.ActOnIntegerConstant(SourceLocation(), 0).get(); 9619 CombInit = 9620 SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, IV.get(), CombRHS); 9621 CombInit = 9622 SemaRef.ActOnFinishFullExpr(CombInit.get(), /*DiscardedValue*/ false); 9623 } 9624 } 9625 9626 bool UseStrictCompare = 9627 RealVType->hasUnsignedIntegerRepresentation() && 9628 llvm::all_of(IterSpaces, [](const LoopIterationSpace &LIS) { 9629 return LIS.IsStrictCompare; 9630 }); 9631 // Loop condition (IV < NumIterations) or (IV <= UB or IV < UB + 1 (for 9632 // unsigned IV)) for worksharing loops. 9633 SourceLocation CondLoc = AStmt->getBeginLoc(); 9634 Expr *BoundUB = UB.get(); 9635 if (UseStrictCompare) { 9636 BoundUB = 9637 SemaRef 9638 .BuildBinOp(CurScope, CondLoc, BO_Add, BoundUB, 9639 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()) 9640 .get(); 9641 BoundUB = 9642 SemaRef.ActOnFinishFullExpr(BoundUB, /*DiscardedValue*/ false).get(); 9643 } 9644 ExprResult Cond = 9645 (isOpenMPWorksharingDirective(DKind) || 9646 isOpenMPGenericLoopDirective(DKind) || 9647 isOpenMPTaskLoopDirective(DKind) || isOpenMPDistributeDirective(DKind) || 9648 isOpenMPLoopTransformationDirective(DKind)) 9649 ? SemaRef.BuildBinOp(CurScope, CondLoc, 9650 UseStrictCompare ? BO_LT : BO_LE, IV.get(), 9651 BoundUB) 9652 : SemaRef.BuildBinOp(CurScope, CondLoc, BO_LT, IV.get(), 9653 NumIterations.get()); 9654 ExprResult CombDistCond; 9655 if (isOpenMPLoopBoundSharingDirective(DKind)) { 9656 CombDistCond = SemaRef.BuildBinOp(CurScope, CondLoc, BO_LT, IV.get(), 9657 NumIterations.get()); 9658 } 9659 9660 ExprResult CombCond; 9661 if (isOpenMPLoopBoundSharingDirective(DKind)) { 9662 Expr *BoundCombUB = CombUB.get(); 9663 if (UseStrictCompare) { 9664 BoundCombUB = 9665 SemaRef 9666 .BuildBinOp( 9667 CurScope, CondLoc, BO_Add, BoundCombUB, 9668 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()) 9669 .get(); 9670 BoundCombUB = 9671 SemaRef.ActOnFinishFullExpr(BoundCombUB, /*DiscardedValue*/ false) 9672 .get(); 9673 } 9674 CombCond = 9675 SemaRef.BuildBinOp(CurScope, CondLoc, UseStrictCompare ? BO_LT : BO_LE, 9676 IV.get(), BoundCombUB); 9677 } 9678 // Loop increment (IV = IV + 1) 9679 SourceLocation IncLoc = AStmt->getBeginLoc(); 9680 ExprResult Inc = 9681 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, IV.get(), 9682 SemaRef.ActOnIntegerConstant(IncLoc, 1).get()); 9683 if (!Inc.isUsable()) 9684 return 0; 9685 Inc = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, IV.get(), Inc.get()); 9686 Inc = SemaRef.ActOnFinishFullExpr(Inc.get(), /*DiscardedValue*/ false); 9687 if (!Inc.isUsable()) 9688 return 0; 9689 9690 // Increments for worksharing loops (LB = LB + ST; UB = UB + ST). 9691 // Used for directives with static scheduling. 9692 // In combined construct, add combined version that use CombLB and CombUB 9693 // base variables for the update 9694 ExprResult NextLB, NextUB, CombNextLB, CombNextUB; 9695 if (isOpenMPWorksharingDirective(DKind) || isOpenMPTaskLoopDirective(DKind) || 9696 isOpenMPGenericLoopDirective(DKind) || 9697 isOpenMPDistributeDirective(DKind) || 9698 isOpenMPLoopTransformationDirective(DKind)) { 9699 // LB + ST 9700 NextLB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, LB.get(), ST.get()); 9701 if (!NextLB.isUsable()) 9702 return 0; 9703 // LB = LB + ST 9704 NextLB = 9705 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, LB.get(), NextLB.get()); 9706 NextLB = 9707 SemaRef.ActOnFinishFullExpr(NextLB.get(), /*DiscardedValue*/ false); 9708 if (!NextLB.isUsable()) 9709 return 0; 9710 // UB + ST 9711 NextUB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, UB.get(), ST.get()); 9712 if (!NextUB.isUsable()) 9713 return 0; 9714 // UB = UB + ST 9715 NextUB = 9716 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, UB.get(), NextUB.get()); 9717 NextUB = 9718 SemaRef.ActOnFinishFullExpr(NextUB.get(), /*DiscardedValue*/ false); 9719 if (!NextUB.isUsable()) 9720 return 0; 9721 if (isOpenMPLoopBoundSharingDirective(DKind)) { 9722 CombNextLB = 9723 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, CombLB.get(), ST.get()); 9724 if (!NextLB.isUsable()) 9725 return 0; 9726 // LB = LB + ST 9727 CombNextLB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, CombLB.get(), 9728 CombNextLB.get()); 9729 CombNextLB = SemaRef.ActOnFinishFullExpr(CombNextLB.get(), 9730 /*DiscardedValue*/ false); 9731 if (!CombNextLB.isUsable()) 9732 return 0; 9733 // UB + ST 9734 CombNextUB = 9735 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, CombUB.get(), ST.get()); 9736 if (!CombNextUB.isUsable()) 9737 return 0; 9738 // UB = UB + ST 9739 CombNextUB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, CombUB.get(), 9740 CombNextUB.get()); 9741 CombNextUB = SemaRef.ActOnFinishFullExpr(CombNextUB.get(), 9742 /*DiscardedValue*/ false); 9743 if (!CombNextUB.isUsable()) 9744 return 0; 9745 } 9746 } 9747 9748 // Create increment expression for distribute loop when combined in a same 9749 // directive with for as IV = IV + ST; ensure upper bound expression based 9750 // on PrevUB instead of NumIterations - used to implement 'for' when found 9751 // in combination with 'distribute', like in 'distribute parallel for' 9752 SourceLocation DistIncLoc = AStmt->getBeginLoc(); 9753 ExprResult DistCond, DistInc, PrevEUB, ParForInDistCond; 9754 if (isOpenMPLoopBoundSharingDirective(DKind)) { 9755 DistCond = SemaRef.BuildBinOp( 9756 CurScope, CondLoc, UseStrictCompare ? BO_LT : BO_LE, IV.get(), BoundUB); 9757 assert(DistCond.isUsable() && "distribute cond expr was not built"); 9758 9759 DistInc = 9760 SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Add, IV.get(), ST.get()); 9761 assert(DistInc.isUsable() && "distribute inc expr was not built"); 9762 DistInc = SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Assign, IV.get(), 9763 DistInc.get()); 9764 DistInc = 9765 SemaRef.ActOnFinishFullExpr(DistInc.get(), /*DiscardedValue*/ false); 9766 assert(DistInc.isUsable() && "distribute inc expr was not built"); 9767 9768 // Build expression: UB = min(UB, prevUB) for #for in composite or combined 9769 // construct 9770 ExprResult NewPrevUB = PrevUB; 9771 SourceLocation DistEUBLoc = AStmt->getBeginLoc(); 9772 if (!SemaRef.Context.hasSameType(UB.get()->getType(), 9773 PrevUB.get()->getType())) { 9774 NewPrevUB = SemaRef.BuildCStyleCastExpr( 9775 DistEUBLoc, 9776 SemaRef.Context.getTrivialTypeSourceInfo(UB.get()->getType()), 9777 DistEUBLoc, NewPrevUB.get()); 9778 if (!NewPrevUB.isUsable()) 9779 return 0; 9780 } 9781 ExprResult IsUBGreater = SemaRef.BuildBinOp(CurScope, DistEUBLoc, BO_GT, 9782 UB.get(), NewPrevUB.get()); 9783 ExprResult CondOp = SemaRef.ActOnConditionalOp( 9784 DistEUBLoc, DistEUBLoc, IsUBGreater.get(), NewPrevUB.get(), UB.get()); 9785 PrevEUB = SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Assign, UB.get(), 9786 CondOp.get()); 9787 PrevEUB = 9788 SemaRef.ActOnFinishFullExpr(PrevEUB.get(), /*DiscardedValue*/ false); 9789 9790 // Build IV <= PrevUB or IV < PrevUB + 1 for unsigned IV to be used in 9791 // parallel for is in combination with a distribute directive with 9792 // schedule(static, 1) 9793 Expr *BoundPrevUB = PrevUB.get(); 9794 if (UseStrictCompare) { 9795 BoundPrevUB = 9796 SemaRef 9797 .BuildBinOp( 9798 CurScope, CondLoc, BO_Add, BoundPrevUB, 9799 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()) 9800 .get(); 9801 BoundPrevUB = 9802 SemaRef.ActOnFinishFullExpr(BoundPrevUB, /*DiscardedValue*/ false) 9803 .get(); 9804 } 9805 ParForInDistCond = 9806 SemaRef.BuildBinOp(CurScope, CondLoc, UseStrictCompare ? BO_LT : BO_LE, 9807 IV.get(), BoundPrevUB); 9808 } 9809 9810 // Build updates and final values of the loop counters. 9811 bool HasErrors = false; 9812 Built.Counters.resize(NestedLoopCount); 9813 Built.Inits.resize(NestedLoopCount); 9814 Built.Updates.resize(NestedLoopCount); 9815 Built.Finals.resize(NestedLoopCount); 9816 Built.DependentCounters.resize(NestedLoopCount); 9817 Built.DependentInits.resize(NestedLoopCount); 9818 Built.FinalsConditions.resize(NestedLoopCount); 9819 { 9820 // We implement the following algorithm for obtaining the 9821 // original loop iteration variable values based on the 9822 // value of the collapsed loop iteration variable IV. 9823 // 9824 // Let n+1 be the number of collapsed loops in the nest. 9825 // Iteration variables (I0, I1, .... In) 9826 // Iteration counts (N0, N1, ... Nn) 9827 // 9828 // Acc = IV; 9829 // 9830 // To compute Ik for loop k, 0 <= k <= n, generate: 9831 // Prod = N(k+1) * N(k+2) * ... * Nn; 9832 // Ik = Acc / Prod; 9833 // Acc -= Ik * Prod; 9834 // 9835 ExprResult Acc = IV; 9836 for (unsigned int Cnt = 0; Cnt < NestedLoopCount; ++Cnt) { 9837 LoopIterationSpace &IS = IterSpaces[Cnt]; 9838 SourceLocation UpdLoc = IS.IncSrcRange.getBegin(); 9839 ExprResult Iter; 9840 9841 // Compute prod 9842 ExprResult Prod = SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get(); 9843 for (unsigned int K = Cnt + 1; K < NestedLoopCount; ++K) 9844 Prod = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Mul, Prod.get(), 9845 IterSpaces[K].NumIterations); 9846 9847 // Iter = Acc / Prod 9848 // If there is at least one more inner loop to avoid 9849 // multiplication by 1. 9850 if (Cnt + 1 < NestedLoopCount) 9851 Iter = 9852 SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Div, Acc.get(), Prod.get()); 9853 else 9854 Iter = Acc; 9855 if (!Iter.isUsable()) { 9856 HasErrors = true; 9857 break; 9858 } 9859 9860 // Update Acc: 9861 // Acc -= Iter * Prod 9862 // Check if there is at least one more inner loop to avoid 9863 // multiplication by 1. 9864 if (Cnt + 1 < NestedLoopCount) 9865 Prod = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Mul, Iter.get(), 9866 Prod.get()); 9867 else 9868 Prod = Iter; 9869 Acc = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Sub, Acc.get(), Prod.get()); 9870 9871 // Build update: IS.CounterVar(Private) = IS.Start + Iter * IS.Step 9872 auto *VD = cast<VarDecl>(cast<DeclRefExpr>(IS.CounterVar)->getDecl()); 9873 DeclRefExpr *CounterVar = buildDeclRefExpr( 9874 SemaRef, VD, IS.CounterVar->getType(), IS.CounterVar->getExprLoc(), 9875 /*RefersToCapture=*/true); 9876 ExprResult Init = 9877 buildCounterInit(SemaRef, CurScope, UpdLoc, CounterVar, 9878 IS.CounterInit, IS.IsNonRectangularLB, Captures); 9879 if (!Init.isUsable()) { 9880 HasErrors = true; 9881 break; 9882 } 9883 ExprResult Update = buildCounterUpdate( 9884 SemaRef, CurScope, UpdLoc, CounterVar, IS.CounterInit, Iter, 9885 IS.CounterStep, IS.Subtract, IS.IsNonRectangularLB, &Captures); 9886 if (!Update.isUsable()) { 9887 HasErrors = true; 9888 break; 9889 } 9890 9891 // Build final: IS.CounterVar = IS.Start + IS.NumIters * IS.Step 9892 ExprResult Final = 9893 buildCounterUpdate(SemaRef, CurScope, UpdLoc, CounterVar, 9894 IS.CounterInit, IS.NumIterations, IS.CounterStep, 9895 IS.Subtract, IS.IsNonRectangularLB, &Captures); 9896 if (!Final.isUsable()) { 9897 HasErrors = true; 9898 break; 9899 } 9900 9901 if (!Update.isUsable() || !Final.isUsable()) { 9902 HasErrors = true; 9903 break; 9904 } 9905 // Save results 9906 Built.Counters[Cnt] = IS.CounterVar; 9907 Built.PrivateCounters[Cnt] = IS.PrivateCounterVar; 9908 Built.Inits[Cnt] = Init.get(); 9909 Built.Updates[Cnt] = Update.get(); 9910 Built.Finals[Cnt] = Final.get(); 9911 Built.DependentCounters[Cnt] = nullptr; 9912 Built.DependentInits[Cnt] = nullptr; 9913 Built.FinalsConditions[Cnt] = nullptr; 9914 if (IS.IsNonRectangularLB || IS.IsNonRectangularUB) { 9915 Built.DependentCounters[Cnt] = 9916 Built.Counters[NestedLoopCount - 1 - IS.LoopDependentIdx]; 9917 Built.DependentInits[Cnt] = 9918 Built.Inits[NestedLoopCount - 1 - IS.LoopDependentIdx]; 9919 Built.FinalsConditions[Cnt] = IS.FinalCondition; 9920 } 9921 } 9922 } 9923 9924 if (HasErrors) 9925 return 0; 9926 9927 // Save results 9928 Built.IterationVarRef = IV.get(); 9929 Built.LastIteration = LastIteration.get(); 9930 Built.NumIterations = NumIterations.get(); 9931 Built.CalcLastIteration = SemaRef 9932 .ActOnFinishFullExpr(CalcLastIteration.get(), 9933 /*DiscardedValue=*/false) 9934 .get(); 9935 Built.PreCond = PreCond.get(); 9936 Built.PreInits = buildPreInits(C, Captures); 9937 Built.Cond = Cond.get(); 9938 Built.Init = Init.get(); 9939 Built.Inc = Inc.get(); 9940 Built.LB = LB.get(); 9941 Built.UB = UB.get(); 9942 Built.IL = IL.get(); 9943 Built.ST = ST.get(); 9944 Built.EUB = EUB.get(); 9945 Built.NLB = NextLB.get(); 9946 Built.NUB = NextUB.get(); 9947 Built.PrevLB = PrevLB.get(); 9948 Built.PrevUB = PrevUB.get(); 9949 Built.DistInc = DistInc.get(); 9950 Built.PrevEUB = PrevEUB.get(); 9951 Built.DistCombinedFields.LB = CombLB.get(); 9952 Built.DistCombinedFields.UB = CombUB.get(); 9953 Built.DistCombinedFields.EUB = CombEUB.get(); 9954 Built.DistCombinedFields.Init = CombInit.get(); 9955 Built.DistCombinedFields.Cond = CombCond.get(); 9956 Built.DistCombinedFields.NLB = CombNextLB.get(); 9957 Built.DistCombinedFields.NUB = CombNextUB.get(); 9958 Built.DistCombinedFields.DistCond = CombDistCond.get(); 9959 Built.DistCombinedFields.ParForInDistCond = ParForInDistCond.get(); 9960 9961 return NestedLoopCount; 9962 } 9963 9964 static Expr *getCollapseNumberExpr(ArrayRef<OMPClause *> Clauses) { 9965 auto CollapseClauses = 9966 OMPExecutableDirective::getClausesOfKind<OMPCollapseClause>(Clauses); 9967 if (CollapseClauses.begin() != CollapseClauses.end()) 9968 return (*CollapseClauses.begin())->getNumForLoops(); 9969 return nullptr; 9970 } 9971 9972 static Expr *getOrderedNumberExpr(ArrayRef<OMPClause *> Clauses) { 9973 auto OrderedClauses = 9974 OMPExecutableDirective::getClausesOfKind<OMPOrderedClause>(Clauses); 9975 if (OrderedClauses.begin() != OrderedClauses.end()) 9976 return (*OrderedClauses.begin())->getNumForLoops(); 9977 return nullptr; 9978 } 9979 9980 static bool checkSimdlenSafelenSpecified(Sema &S, 9981 const ArrayRef<OMPClause *> Clauses) { 9982 const OMPSafelenClause *Safelen = nullptr; 9983 const OMPSimdlenClause *Simdlen = nullptr; 9984 9985 for (const OMPClause *Clause : Clauses) { 9986 if (Clause->getClauseKind() == OMPC_safelen) 9987 Safelen = cast<OMPSafelenClause>(Clause); 9988 else if (Clause->getClauseKind() == OMPC_simdlen) 9989 Simdlen = cast<OMPSimdlenClause>(Clause); 9990 if (Safelen && Simdlen) 9991 break; 9992 } 9993 9994 if (Simdlen && Safelen) { 9995 const Expr *SimdlenLength = Simdlen->getSimdlen(); 9996 const Expr *SafelenLength = Safelen->getSafelen(); 9997 if (SimdlenLength->isValueDependent() || SimdlenLength->isTypeDependent() || 9998 SimdlenLength->isInstantiationDependent() || 9999 SimdlenLength->containsUnexpandedParameterPack()) 10000 return false; 10001 if (SafelenLength->isValueDependent() || SafelenLength->isTypeDependent() || 10002 SafelenLength->isInstantiationDependent() || 10003 SafelenLength->containsUnexpandedParameterPack()) 10004 return false; 10005 Expr::EvalResult SimdlenResult, SafelenResult; 10006 SimdlenLength->EvaluateAsInt(SimdlenResult, S.Context); 10007 SafelenLength->EvaluateAsInt(SafelenResult, S.Context); 10008 llvm::APSInt SimdlenRes = SimdlenResult.Val.getInt(); 10009 llvm::APSInt SafelenRes = SafelenResult.Val.getInt(); 10010 // OpenMP 4.5 [2.8.1, simd Construct, Restrictions] 10011 // If both simdlen and safelen clauses are specified, the value of the 10012 // simdlen parameter must be less than or equal to the value of the safelen 10013 // parameter. 10014 if (SimdlenRes > SafelenRes) { 10015 S.Diag(SimdlenLength->getExprLoc(), 10016 diag::err_omp_wrong_simdlen_safelen_values) 10017 << SimdlenLength->getSourceRange() << SafelenLength->getSourceRange(); 10018 return true; 10019 } 10020 } 10021 return false; 10022 } 10023 10024 StmtResult 10025 Sema::ActOnOpenMPSimdDirective(ArrayRef<OMPClause *> Clauses, Stmt *AStmt, 10026 SourceLocation StartLoc, SourceLocation EndLoc, 10027 VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10028 if (!AStmt) 10029 return StmtError(); 10030 10031 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 10032 OMPLoopBasedDirective::HelperExprs B; 10033 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 10034 // define the nested loops number. 10035 unsigned NestedLoopCount = checkOpenMPLoop( 10036 OMPD_simd, getCollapseNumberExpr(Clauses), getOrderedNumberExpr(Clauses), 10037 AStmt, *this, *DSAStack, VarsWithImplicitDSA, B); 10038 if (NestedLoopCount == 0) 10039 return StmtError(); 10040 10041 assert((CurContext->isDependentContext() || B.builtAll()) && 10042 "omp simd loop exprs were not built"); 10043 10044 if (!CurContext->isDependentContext()) { 10045 // Finalize the clauses that need pre-built expressions for CodeGen. 10046 for (OMPClause *C : Clauses) { 10047 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 10048 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 10049 B.NumIterations, *this, CurScope, 10050 DSAStack)) 10051 return StmtError(); 10052 } 10053 } 10054 10055 if (checkSimdlenSafelenSpecified(*this, Clauses)) 10056 return StmtError(); 10057 10058 setFunctionHasBranchProtectedScope(); 10059 return OMPSimdDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount, 10060 Clauses, AStmt, B); 10061 } 10062 10063 StmtResult 10064 Sema::ActOnOpenMPForDirective(ArrayRef<OMPClause *> Clauses, Stmt *AStmt, 10065 SourceLocation StartLoc, SourceLocation EndLoc, 10066 VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10067 if (!AStmt) 10068 return StmtError(); 10069 10070 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 10071 OMPLoopBasedDirective::HelperExprs B; 10072 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 10073 // define the nested loops number. 10074 unsigned NestedLoopCount = checkOpenMPLoop( 10075 OMPD_for, getCollapseNumberExpr(Clauses), getOrderedNumberExpr(Clauses), 10076 AStmt, *this, *DSAStack, VarsWithImplicitDSA, B); 10077 if (NestedLoopCount == 0) 10078 return StmtError(); 10079 10080 assert((CurContext->isDependentContext() || B.builtAll()) && 10081 "omp for loop exprs were not built"); 10082 10083 if (!CurContext->isDependentContext()) { 10084 // Finalize the clauses that need pre-built expressions for CodeGen. 10085 for (OMPClause *C : Clauses) { 10086 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 10087 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 10088 B.NumIterations, *this, CurScope, 10089 DSAStack)) 10090 return StmtError(); 10091 } 10092 } 10093 10094 setFunctionHasBranchProtectedScope(); 10095 return OMPForDirective::Create( 10096 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B, 10097 DSAStack->getTaskgroupReductionRef(), DSAStack->isCancelRegion()); 10098 } 10099 10100 StmtResult Sema::ActOnOpenMPForSimdDirective( 10101 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10102 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10103 if (!AStmt) 10104 return StmtError(); 10105 10106 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 10107 OMPLoopBasedDirective::HelperExprs B; 10108 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 10109 // define the nested loops number. 10110 unsigned NestedLoopCount = 10111 checkOpenMPLoop(OMPD_for_simd, getCollapseNumberExpr(Clauses), 10112 getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack, 10113 VarsWithImplicitDSA, B); 10114 if (NestedLoopCount == 0) 10115 return StmtError(); 10116 10117 assert((CurContext->isDependentContext() || B.builtAll()) && 10118 "omp for simd loop exprs were not built"); 10119 10120 if (!CurContext->isDependentContext()) { 10121 // Finalize the clauses that need pre-built expressions for CodeGen. 10122 for (OMPClause *C : Clauses) { 10123 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 10124 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 10125 B.NumIterations, *this, CurScope, 10126 DSAStack)) 10127 return StmtError(); 10128 } 10129 } 10130 10131 if (checkSimdlenSafelenSpecified(*this, Clauses)) 10132 return StmtError(); 10133 10134 setFunctionHasBranchProtectedScope(); 10135 return OMPForSimdDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount, 10136 Clauses, AStmt, B); 10137 } 10138 10139 StmtResult Sema::ActOnOpenMPSectionsDirective(ArrayRef<OMPClause *> Clauses, 10140 Stmt *AStmt, 10141 SourceLocation StartLoc, 10142 SourceLocation EndLoc) { 10143 if (!AStmt) 10144 return StmtError(); 10145 10146 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 10147 auto BaseStmt = AStmt; 10148 while (auto *CS = dyn_cast_or_null<CapturedStmt>(BaseStmt)) 10149 BaseStmt = CS->getCapturedStmt(); 10150 if (auto *C = dyn_cast_or_null<CompoundStmt>(BaseStmt)) { 10151 auto S = C->children(); 10152 if (S.begin() == S.end()) 10153 return StmtError(); 10154 // All associated statements must be '#pragma omp section' except for 10155 // the first one. 10156 for (Stmt *SectionStmt : llvm::drop_begin(S)) { 10157 if (!SectionStmt || !isa<OMPSectionDirective>(SectionStmt)) { 10158 if (SectionStmt) 10159 Diag(SectionStmt->getBeginLoc(), 10160 diag::err_omp_sections_substmt_not_section); 10161 return StmtError(); 10162 } 10163 cast<OMPSectionDirective>(SectionStmt) 10164 ->setHasCancel(DSAStack->isCancelRegion()); 10165 } 10166 } else { 10167 Diag(AStmt->getBeginLoc(), diag::err_omp_sections_not_compound_stmt); 10168 return StmtError(); 10169 } 10170 10171 setFunctionHasBranchProtectedScope(); 10172 10173 return OMPSectionsDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt, 10174 DSAStack->getTaskgroupReductionRef(), 10175 DSAStack->isCancelRegion()); 10176 } 10177 10178 StmtResult Sema::ActOnOpenMPSectionDirective(Stmt *AStmt, 10179 SourceLocation StartLoc, 10180 SourceLocation EndLoc) { 10181 if (!AStmt) 10182 return StmtError(); 10183 10184 setFunctionHasBranchProtectedScope(); 10185 DSAStack->setParentCancelRegion(DSAStack->isCancelRegion()); 10186 10187 return OMPSectionDirective::Create(Context, StartLoc, EndLoc, AStmt, 10188 DSAStack->isCancelRegion()); 10189 } 10190 10191 static Expr *getDirectCallExpr(Expr *E) { 10192 E = E->IgnoreParenCasts()->IgnoreImplicit(); 10193 if (auto *CE = dyn_cast<CallExpr>(E)) 10194 if (CE->getDirectCallee()) 10195 return E; 10196 return nullptr; 10197 } 10198 10199 StmtResult Sema::ActOnOpenMPDispatchDirective(ArrayRef<OMPClause *> Clauses, 10200 Stmt *AStmt, 10201 SourceLocation StartLoc, 10202 SourceLocation EndLoc) { 10203 if (!AStmt) 10204 return StmtError(); 10205 10206 Stmt *S = cast<CapturedStmt>(AStmt)->getCapturedStmt(); 10207 10208 // 5.1 OpenMP 10209 // expression-stmt : an expression statement with one of the following forms: 10210 // expression = target-call ( [expression-list] ); 10211 // target-call ( [expression-list] ); 10212 10213 SourceLocation TargetCallLoc; 10214 10215 if (!CurContext->isDependentContext()) { 10216 Expr *TargetCall = nullptr; 10217 10218 auto *E = dyn_cast<Expr>(S); 10219 if (!E) { 10220 Diag(S->getBeginLoc(), diag::err_omp_dispatch_statement_call); 10221 return StmtError(); 10222 } 10223 10224 E = E->IgnoreParenCasts()->IgnoreImplicit(); 10225 10226 if (auto *BO = dyn_cast<BinaryOperator>(E)) { 10227 if (BO->getOpcode() == BO_Assign) 10228 TargetCall = getDirectCallExpr(BO->getRHS()); 10229 } else { 10230 if (auto *COCE = dyn_cast<CXXOperatorCallExpr>(E)) 10231 if (COCE->getOperator() == OO_Equal) 10232 TargetCall = getDirectCallExpr(COCE->getArg(1)); 10233 if (!TargetCall) 10234 TargetCall = getDirectCallExpr(E); 10235 } 10236 if (!TargetCall) { 10237 Diag(E->getBeginLoc(), diag::err_omp_dispatch_statement_call); 10238 return StmtError(); 10239 } 10240 TargetCallLoc = TargetCall->getExprLoc(); 10241 } 10242 10243 setFunctionHasBranchProtectedScope(); 10244 10245 return OMPDispatchDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt, 10246 TargetCallLoc); 10247 } 10248 10249 static bool checkGenericLoopLastprivate(Sema &S, ArrayRef<OMPClause *> Clauses, 10250 OpenMPDirectiveKind K, 10251 DSAStackTy *Stack) { 10252 bool ErrorFound = false; 10253 for (OMPClause *C : Clauses) { 10254 if (auto *LPC = dyn_cast<OMPLastprivateClause>(C)) { 10255 for (Expr *RefExpr : LPC->varlists()) { 10256 SourceLocation ELoc; 10257 SourceRange ERange; 10258 Expr *SimpleRefExpr = RefExpr; 10259 auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange); 10260 if (ValueDecl *D = Res.first) { 10261 auto &&Info = Stack->isLoopControlVariable(D); 10262 if (!Info.first) { 10263 S.Diag(ELoc, diag::err_omp_lastprivate_loop_var_non_loop_iteration) 10264 << getOpenMPDirectiveName(K); 10265 ErrorFound = true; 10266 } 10267 } 10268 } 10269 } 10270 } 10271 return ErrorFound; 10272 } 10273 10274 StmtResult Sema::ActOnOpenMPGenericLoopDirective( 10275 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10276 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10277 if (!AStmt) 10278 return StmtError(); 10279 10280 // OpenMP 5.1 [2.11.7, loop construct, Restrictions] 10281 // A list item may not appear in a lastprivate clause unless it is the 10282 // loop iteration variable of a loop that is associated with the construct. 10283 if (checkGenericLoopLastprivate(*this, Clauses, OMPD_loop, DSAStack)) 10284 return StmtError(); 10285 10286 auto *CS = cast<CapturedStmt>(AStmt); 10287 // 1.2.2 OpenMP Language Terminology 10288 // Structured block - An executable statement with a single entry at the 10289 // top and a single exit at the bottom. 10290 // The point of exit cannot be a branch out of the structured block. 10291 // longjmp() and throw() must not violate the entry/exit criteria. 10292 CS->getCapturedDecl()->setNothrow(); 10293 10294 OMPLoopDirective::HelperExprs B; 10295 // In presence of clause 'collapse', it will define the nested loops number. 10296 unsigned NestedLoopCount = checkOpenMPLoop( 10297 OMPD_loop, getCollapseNumberExpr(Clauses), getOrderedNumberExpr(Clauses), 10298 AStmt, *this, *DSAStack, VarsWithImplicitDSA, B); 10299 if (NestedLoopCount == 0) 10300 return StmtError(); 10301 10302 assert((CurContext->isDependentContext() || B.builtAll()) && 10303 "omp loop exprs were not built"); 10304 10305 setFunctionHasBranchProtectedScope(); 10306 return OMPGenericLoopDirective::Create(Context, StartLoc, EndLoc, 10307 NestedLoopCount, Clauses, AStmt, B); 10308 } 10309 10310 StmtResult Sema::ActOnOpenMPTeamsGenericLoopDirective( 10311 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10312 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10313 if (!AStmt) 10314 return StmtError(); 10315 10316 // OpenMP 5.1 [2.11.7, loop construct, Restrictions] 10317 // A list item may not appear in a lastprivate clause unless it is the 10318 // loop iteration variable of a loop that is associated with the construct. 10319 if (checkGenericLoopLastprivate(*this, Clauses, OMPD_teams_loop, DSAStack)) 10320 return StmtError(); 10321 10322 auto *CS = cast<CapturedStmt>(AStmt); 10323 // 1.2.2 OpenMP Language Terminology 10324 // Structured block - An executable statement with a single entry at the 10325 // top and a single exit at the bottom. 10326 // The point of exit cannot be a branch out of the structured block. 10327 // longjmp() and throw() must not violate the entry/exit criteria. 10328 CS->getCapturedDecl()->setNothrow(); 10329 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_teams_loop); 10330 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10331 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10332 // 1.2.2 OpenMP Language Terminology 10333 // Structured block - An executable statement with a single entry at the 10334 // top and a single exit at the bottom. 10335 // The point of exit cannot be a branch out of the structured block. 10336 // longjmp() and throw() must not violate the entry/exit criteria. 10337 CS->getCapturedDecl()->setNothrow(); 10338 } 10339 10340 OMPLoopDirective::HelperExprs B; 10341 // In presence of clause 'collapse', it will define the nested loops number. 10342 unsigned NestedLoopCount = 10343 checkOpenMPLoop(OMPD_teams_loop, getCollapseNumberExpr(Clauses), 10344 /*OrderedLoopCountExpr=*/nullptr, CS, *this, *DSAStack, 10345 VarsWithImplicitDSA, B); 10346 if (NestedLoopCount == 0) 10347 return StmtError(); 10348 10349 assert((CurContext->isDependentContext() || B.builtAll()) && 10350 "omp loop exprs were not built"); 10351 10352 setFunctionHasBranchProtectedScope(); 10353 DSAStack->setParentTeamsRegionLoc(StartLoc); 10354 10355 return OMPTeamsGenericLoopDirective::Create( 10356 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 10357 } 10358 10359 StmtResult Sema::ActOnOpenMPTargetTeamsGenericLoopDirective( 10360 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10361 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10362 if (!AStmt) 10363 return StmtError(); 10364 10365 // OpenMP 5.1 [2.11.7, loop construct, Restrictions] 10366 // A list item may not appear in a lastprivate clause unless it is the 10367 // loop iteration variable of a loop that is associated with the construct. 10368 if (checkGenericLoopLastprivate(*this, Clauses, OMPD_target_teams_loop, 10369 DSAStack)) 10370 return StmtError(); 10371 10372 auto *CS = cast<CapturedStmt>(AStmt); 10373 // 1.2.2 OpenMP Language Terminology 10374 // Structured block - An executable statement with a single entry at the 10375 // top and a single exit at the bottom. 10376 // The point of exit cannot be a branch out of the structured block. 10377 // longjmp() and throw() must not violate the entry/exit criteria. 10378 CS->getCapturedDecl()->setNothrow(); 10379 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_teams_loop); 10380 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10381 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10382 // 1.2.2 OpenMP Language Terminology 10383 // Structured block - An executable statement with a single entry at the 10384 // top and a single exit at the bottom. 10385 // The point of exit cannot be a branch out of the structured block. 10386 // longjmp() and throw() must not violate the entry/exit criteria. 10387 CS->getCapturedDecl()->setNothrow(); 10388 } 10389 10390 OMPLoopDirective::HelperExprs B; 10391 // In presence of clause 'collapse', it will define the nested loops number. 10392 unsigned NestedLoopCount = 10393 checkOpenMPLoop(OMPD_target_teams_loop, getCollapseNumberExpr(Clauses), 10394 /*OrderedLoopCountExpr=*/nullptr, CS, *this, *DSAStack, 10395 VarsWithImplicitDSA, B); 10396 if (NestedLoopCount == 0) 10397 return StmtError(); 10398 10399 assert((CurContext->isDependentContext() || B.builtAll()) && 10400 "omp loop exprs were not built"); 10401 10402 setFunctionHasBranchProtectedScope(); 10403 10404 return OMPTargetTeamsGenericLoopDirective::Create( 10405 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 10406 } 10407 10408 StmtResult Sema::ActOnOpenMPParallelGenericLoopDirective( 10409 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10410 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10411 if (!AStmt) 10412 return StmtError(); 10413 10414 // OpenMP 5.1 [2.11.7, loop construct, Restrictions] 10415 // A list item may not appear in a lastprivate clause unless it is the 10416 // loop iteration variable of a loop that is associated with the construct. 10417 if (checkGenericLoopLastprivate(*this, Clauses, OMPD_parallel_loop, DSAStack)) 10418 return StmtError(); 10419 10420 auto *CS = cast<CapturedStmt>(AStmt); 10421 // 1.2.2 OpenMP Language Terminology 10422 // Structured block - An executable statement with a single entry at the 10423 // top and a single exit at the bottom. 10424 // The point of exit cannot be a branch out of the structured block. 10425 // longjmp() and throw() must not violate the entry/exit criteria. 10426 CS->getCapturedDecl()->setNothrow(); 10427 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_parallel_loop); 10428 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10429 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10430 // 1.2.2 OpenMP Language Terminology 10431 // Structured block - An executable statement with a single entry at the 10432 // top and a single exit at the bottom. 10433 // The point of exit cannot be a branch out of the structured block. 10434 // longjmp() and throw() must not violate the entry/exit criteria. 10435 CS->getCapturedDecl()->setNothrow(); 10436 } 10437 10438 OMPLoopDirective::HelperExprs B; 10439 // In presence of clause 'collapse', it will define the nested loops number. 10440 unsigned NestedLoopCount = 10441 checkOpenMPLoop(OMPD_parallel_loop, getCollapseNumberExpr(Clauses), 10442 /*OrderedLoopCountExpr=*/nullptr, CS, *this, *DSAStack, 10443 VarsWithImplicitDSA, B); 10444 if (NestedLoopCount == 0) 10445 return StmtError(); 10446 10447 assert((CurContext->isDependentContext() || B.builtAll()) && 10448 "omp loop exprs were not built"); 10449 10450 setFunctionHasBranchProtectedScope(); 10451 10452 return OMPParallelGenericLoopDirective::Create( 10453 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 10454 } 10455 10456 StmtResult Sema::ActOnOpenMPTargetParallelGenericLoopDirective( 10457 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10458 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10459 if (!AStmt) 10460 return StmtError(); 10461 10462 // OpenMP 5.1 [2.11.7, loop construct, Restrictions] 10463 // A list item may not appear in a lastprivate clause unless it is the 10464 // loop iteration variable of a loop that is associated with the construct. 10465 if (checkGenericLoopLastprivate(*this, Clauses, OMPD_target_parallel_loop, 10466 DSAStack)) 10467 return StmtError(); 10468 10469 auto *CS = cast<CapturedStmt>(AStmt); 10470 // 1.2.2 OpenMP Language Terminology 10471 // Structured block - An executable statement with a single entry at the 10472 // top and a single exit at the bottom. 10473 // The point of exit cannot be a branch out of the structured block. 10474 // longjmp() and throw() must not violate the entry/exit criteria. 10475 CS->getCapturedDecl()->setNothrow(); 10476 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel_loop); 10477 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10478 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10479 // 1.2.2 OpenMP Language Terminology 10480 // Structured block - An executable statement with a single entry at the 10481 // top and a single exit at the bottom. 10482 // The point of exit cannot be a branch out of the structured block. 10483 // longjmp() and throw() must not violate the entry/exit criteria. 10484 CS->getCapturedDecl()->setNothrow(); 10485 } 10486 10487 OMPLoopDirective::HelperExprs B; 10488 // In presence of clause 'collapse', it will define the nested loops number. 10489 unsigned NestedLoopCount = 10490 checkOpenMPLoop(OMPD_target_parallel_loop, getCollapseNumberExpr(Clauses), 10491 /*OrderedLoopCountExpr=*/nullptr, CS, *this, *DSAStack, 10492 VarsWithImplicitDSA, B); 10493 if (NestedLoopCount == 0) 10494 return StmtError(); 10495 10496 assert((CurContext->isDependentContext() || B.builtAll()) && 10497 "omp loop exprs were not built"); 10498 10499 setFunctionHasBranchProtectedScope(); 10500 10501 return OMPTargetParallelGenericLoopDirective::Create( 10502 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 10503 } 10504 10505 StmtResult Sema::ActOnOpenMPSingleDirective(ArrayRef<OMPClause *> Clauses, 10506 Stmt *AStmt, 10507 SourceLocation StartLoc, 10508 SourceLocation EndLoc) { 10509 if (!AStmt) 10510 return StmtError(); 10511 10512 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 10513 10514 setFunctionHasBranchProtectedScope(); 10515 10516 // OpenMP [2.7.3, single Construct, Restrictions] 10517 // The copyprivate clause must not be used with the nowait clause. 10518 const OMPClause *Nowait = nullptr; 10519 const OMPClause *Copyprivate = nullptr; 10520 for (const OMPClause *Clause : Clauses) { 10521 if (Clause->getClauseKind() == OMPC_nowait) 10522 Nowait = Clause; 10523 else if (Clause->getClauseKind() == OMPC_copyprivate) 10524 Copyprivate = Clause; 10525 if (Copyprivate && Nowait) { 10526 Diag(Copyprivate->getBeginLoc(), 10527 diag::err_omp_single_copyprivate_with_nowait); 10528 Diag(Nowait->getBeginLoc(), diag::note_omp_nowait_clause_here); 10529 return StmtError(); 10530 } 10531 } 10532 10533 return OMPSingleDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt); 10534 } 10535 10536 StmtResult Sema::ActOnOpenMPMasterDirective(Stmt *AStmt, 10537 SourceLocation StartLoc, 10538 SourceLocation EndLoc) { 10539 if (!AStmt) 10540 return StmtError(); 10541 10542 setFunctionHasBranchProtectedScope(); 10543 10544 return OMPMasterDirective::Create(Context, StartLoc, EndLoc, AStmt); 10545 } 10546 10547 StmtResult Sema::ActOnOpenMPMaskedDirective(ArrayRef<OMPClause *> Clauses, 10548 Stmt *AStmt, 10549 SourceLocation StartLoc, 10550 SourceLocation EndLoc) { 10551 if (!AStmt) 10552 return StmtError(); 10553 10554 setFunctionHasBranchProtectedScope(); 10555 10556 return OMPMaskedDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt); 10557 } 10558 10559 StmtResult Sema::ActOnOpenMPCriticalDirective( 10560 const DeclarationNameInfo &DirName, ArrayRef<OMPClause *> Clauses, 10561 Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc) { 10562 if (!AStmt) 10563 return StmtError(); 10564 10565 bool ErrorFound = false; 10566 llvm::APSInt Hint; 10567 SourceLocation HintLoc; 10568 bool DependentHint = false; 10569 for (const OMPClause *C : Clauses) { 10570 if (C->getClauseKind() == OMPC_hint) { 10571 if (!DirName.getName()) { 10572 Diag(C->getBeginLoc(), diag::err_omp_hint_clause_no_name); 10573 ErrorFound = true; 10574 } 10575 Expr *E = cast<OMPHintClause>(C)->getHint(); 10576 if (E->isTypeDependent() || E->isValueDependent() || 10577 E->isInstantiationDependent()) { 10578 DependentHint = true; 10579 } else { 10580 Hint = E->EvaluateKnownConstInt(Context); 10581 HintLoc = C->getBeginLoc(); 10582 } 10583 } 10584 } 10585 if (ErrorFound) 10586 return StmtError(); 10587 const auto Pair = DSAStack->getCriticalWithHint(DirName); 10588 if (Pair.first && DirName.getName() && !DependentHint) { 10589 if (llvm::APSInt::compareValues(Hint, Pair.second) != 0) { 10590 Diag(StartLoc, diag::err_omp_critical_with_hint); 10591 if (HintLoc.isValid()) 10592 Diag(HintLoc, diag::note_omp_critical_hint_here) 10593 << 0 << toString(Hint, /*Radix=*/10, /*Signed=*/false); 10594 else 10595 Diag(StartLoc, diag::note_omp_critical_no_hint) << 0; 10596 if (const auto *C = Pair.first->getSingleClause<OMPHintClause>()) { 10597 Diag(C->getBeginLoc(), diag::note_omp_critical_hint_here) 10598 << 1 10599 << toString(C->getHint()->EvaluateKnownConstInt(Context), 10600 /*Radix=*/10, /*Signed=*/false); 10601 } else { 10602 Diag(Pair.first->getBeginLoc(), diag::note_omp_critical_no_hint) << 1; 10603 } 10604 } 10605 } 10606 10607 setFunctionHasBranchProtectedScope(); 10608 10609 auto *Dir = OMPCriticalDirective::Create(Context, DirName, StartLoc, EndLoc, 10610 Clauses, AStmt); 10611 if (!Pair.first && DirName.getName() && !DependentHint) 10612 DSAStack->addCriticalWithHint(Dir, Hint); 10613 return Dir; 10614 } 10615 10616 StmtResult Sema::ActOnOpenMPParallelForDirective( 10617 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10618 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10619 if (!AStmt) 10620 return StmtError(); 10621 10622 auto *CS = cast<CapturedStmt>(AStmt); 10623 // 1.2.2 OpenMP Language Terminology 10624 // Structured block - An executable statement with a single entry at the 10625 // top and a single exit at the bottom. 10626 // The point of exit cannot be a branch out of the structured block. 10627 // longjmp() and throw() must not violate the entry/exit criteria. 10628 CS->getCapturedDecl()->setNothrow(); 10629 10630 OMPLoopBasedDirective::HelperExprs B; 10631 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 10632 // define the nested loops number. 10633 unsigned NestedLoopCount = 10634 checkOpenMPLoop(OMPD_parallel_for, getCollapseNumberExpr(Clauses), 10635 getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack, 10636 VarsWithImplicitDSA, B); 10637 if (NestedLoopCount == 0) 10638 return StmtError(); 10639 10640 assert((CurContext->isDependentContext() || B.builtAll()) && 10641 "omp parallel for loop exprs were not built"); 10642 10643 if (!CurContext->isDependentContext()) { 10644 // Finalize the clauses that need pre-built expressions for CodeGen. 10645 for (OMPClause *C : Clauses) { 10646 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 10647 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 10648 B.NumIterations, *this, CurScope, 10649 DSAStack)) 10650 return StmtError(); 10651 } 10652 } 10653 10654 setFunctionHasBranchProtectedScope(); 10655 return OMPParallelForDirective::Create( 10656 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B, 10657 DSAStack->getTaskgroupReductionRef(), DSAStack->isCancelRegion()); 10658 } 10659 10660 StmtResult Sema::ActOnOpenMPParallelForSimdDirective( 10661 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10662 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10663 if (!AStmt) 10664 return StmtError(); 10665 10666 auto *CS = cast<CapturedStmt>(AStmt); 10667 // 1.2.2 OpenMP Language Terminology 10668 // Structured block - An executable statement with a single entry at the 10669 // top and a single exit at the bottom. 10670 // The point of exit cannot be a branch out of the structured block. 10671 // longjmp() and throw() must not violate the entry/exit criteria. 10672 CS->getCapturedDecl()->setNothrow(); 10673 10674 OMPLoopBasedDirective::HelperExprs B; 10675 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 10676 // define the nested loops number. 10677 unsigned NestedLoopCount = 10678 checkOpenMPLoop(OMPD_parallel_for_simd, getCollapseNumberExpr(Clauses), 10679 getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack, 10680 VarsWithImplicitDSA, B); 10681 if (NestedLoopCount == 0) 10682 return StmtError(); 10683 10684 if (!CurContext->isDependentContext()) { 10685 // Finalize the clauses that need pre-built expressions for CodeGen. 10686 for (OMPClause *C : Clauses) { 10687 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 10688 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 10689 B.NumIterations, *this, CurScope, 10690 DSAStack)) 10691 return StmtError(); 10692 } 10693 } 10694 10695 if (checkSimdlenSafelenSpecified(*this, Clauses)) 10696 return StmtError(); 10697 10698 setFunctionHasBranchProtectedScope(); 10699 return OMPParallelForSimdDirective::Create( 10700 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 10701 } 10702 10703 StmtResult 10704 Sema::ActOnOpenMPParallelMasterDirective(ArrayRef<OMPClause *> Clauses, 10705 Stmt *AStmt, SourceLocation StartLoc, 10706 SourceLocation EndLoc) { 10707 if (!AStmt) 10708 return StmtError(); 10709 10710 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 10711 auto *CS = cast<CapturedStmt>(AStmt); 10712 // 1.2.2 OpenMP Language Terminology 10713 // Structured block - An executable statement with a single entry at the 10714 // top and a single exit at the bottom. 10715 // The point of exit cannot be a branch out of the structured block. 10716 // longjmp() and throw() must not violate the entry/exit criteria. 10717 CS->getCapturedDecl()->setNothrow(); 10718 10719 setFunctionHasBranchProtectedScope(); 10720 10721 return OMPParallelMasterDirective::Create( 10722 Context, StartLoc, EndLoc, Clauses, AStmt, 10723 DSAStack->getTaskgroupReductionRef()); 10724 } 10725 10726 StmtResult 10727 Sema::ActOnOpenMPParallelMaskedDirective(ArrayRef<OMPClause *> Clauses, 10728 Stmt *AStmt, SourceLocation StartLoc, 10729 SourceLocation EndLoc) { 10730 if (!AStmt) 10731 return StmtError(); 10732 10733 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 10734 auto *CS = cast<CapturedStmt>(AStmt); 10735 // 1.2.2 OpenMP Language Terminology 10736 // Structured block - An executable statement with a single entry at the 10737 // top and a single exit at the bottom. 10738 // The point of exit cannot be a branch out of the structured block. 10739 // longjmp() and throw() must not violate the entry/exit criteria. 10740 CS->getCapturedDecl()->setNothrow(); 10741 10742 setFunctionHasBranchProtectedScope(); 10743 10744 return OMPParallelMaskedDirective::Create( 10745 Context, StartLoc, EndLoc, Clauses, AStmt, 10746 DSAStack->getTaskgroupReductionRef()); 10747 } 10748 10749 StmtResult 10750 Sema::ActOnOpenMPParallelSectionsDirective(ArrayRef<OMPClause *> Clauses, 10751 Stmt *AStmt, SourceLocation StartLoc, 10752 SourceLocation EndLoc) { 10753 if (!AStmt) 10754 return StmtError(); 10755 10756 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 10757 auto BaseStmt = AStmt; 10758 while (auto *CS = dyn_cast_or_null<CapturedStmt>(BaseStmt)) 10759 BaseStmt = CS->getCapturedStmt(); 10760 if (auto *C = dyn_cast_or_null<CompoundStmt>(BaseStmt)) { 10761 auto S = C->children(); 10762 if (S.begin() == S.end()) 10763 return StmtError(); 10764 // All associated statements must be '#pragma omp section' except for 10765 // the first one. 10766 for (Stmt *SectionStmt : llvm::drop_begin(S)) { 10767 if (!SectionStmt || !isa<OMPSectionDirective>(SectionStmt)) { 10768 if (SectionStmt) 10769 Diag(SectionStmt->getBeginLoc(), 10770 diag::err_omp_parallel_sections_substmt_not_section); 10771 return StmtError(); 10772 } 10773 cast<OMPSectionDirective>(SectionStmt) 10774 ->setHasCancel(DSAStack->isCancelRegion()); 10775 } 10776 } else { 10777 Diag(AStmt->getBeginLoc(), 10778 diag::err_omp_parallel_sections_not_compound_stmt); 10779 return StmtError(); 10780 } 10781 10782 setFunctionHasBranchProtectedScope(); 10783 10784 return OMPParallelSectionsDirective::Create( 10785 Context, StartLoc, EndLoc, Clauses, AStmt, 10786 DSAStack->getTaskgroupReductionRef(), DSAStack->isCancelRegion()); 10787 } 10788 10789 /// Find and diagnose mutually exclusive clause kinds. 10790 static bool checkMutuallyExclusiveClauses( 10791 Sema &S, ArrayRef<OMPClause *> Clauses, 10792 ArrayRef<OpenMPClauseKind> MutuallyExclusiveClauses) { 10793 const OMPClause *PrevClause = nullptr; 10794 bool ErrorFound = false; 10795 for (const OMPClause *C : Clauses) { 10796 if (llvm::is_contained(MutuallyExclusiveClauses, C->getClauseKind())) { 10797 if (!PrevClause) { 10798 PrevClause = C; 10799 } else if (PrevClause->getClauseKind() != C->getClauseKind()) { 10800 S.Diag(C->getBeginLoc(), diag::err_omp_clauses_mutually_exclusive) 10801 << getOpenMPClauseName(C->getClauseKind()) 10802 << getOpenMPClauseName(PrevClause->getClauseKind()); 10803 S.Diag(PrevClause->getBeginLoc(), diag::note_omp_previous_clause) 10804 << getOpenMPClauseName(PrevClause->getClauseKind()); 10805 ErrorFound = true; 10806 } 10807 } 10808 } 10809 return ErrorFound; 10810 } 10811 10812 StmtResult Sema::ActOnOpenMPTaskDirective(ArrayRef<OMPClause *> Clauses, 10813 Stmt *AStmt, SourceLocation StartLoc, 10814 SourceLocation EndLoc) { 10815 if (!AStmt) 10816 return StmtError(); 10817 10818 // OpenMP 5.0, 2.10.1 task Construct 10819 // If a detach clause appears on the directive, then a mergeable clause cannot 10820 // appear on the same directive. 10821 if (checkMutuallyExclusiveClauses(*this, Clauses, 10822 {OMPC_detach, OMPC_mergeable})) 10823 return StmtError(); 10824 10825 auto *CS = cast<CapturedStmt>(AStmt); 10826 // 1.2.2 OpenMP Language Terminology 10827 // Structured block - An executable statement with a single entry at the 10828 // top and a single exit at the bottom. 10829 // The point of exit cannot be a branch out of the structured block. 10830 // longjmp() and throw() must not violate the entry/exit criteria. 10831 CS->getCapturedDecl()->setNothrow(); 10832 10833 setFunctionHasBranchProtectedScope(); 10834 10835 return OMPTaskDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt, 10836 DSAStack->isCancelRegion()); 10837 } 10838 10839 StmtResult Sema::ActOnOpenMPTaskyieldDirective(SourceLocation StartLoc, 10840 SourceLocation EndLoc) { 10841 return OMPTaskyieldDirective::Create(Context, StartLoc, EndLoc); 10842 } 10843 10844 StmtResult Sema::ActOnOpenMPBarrierDirective(SourceLocation StartLoc, 10845 SourceLocation EndLoc) { 10846 return OMPBarrierDirective::Create(Context, StartLoc, EndLoc); 10847 } 10848 10849 StmtResult Sema::ActOnOpenMPTaskwaitDirective(ArrayRef<OMPClause *> Clauses, 10850 SourceLocation StartLoc, 10851 SourceLocation EndLoc) { 10852 return OMPTaskwaitDirective::Create(Context, StartLoc, EndLoc, Clauses); 10853 } 10854 10855 StmtResult Sema::ActOnOpenMPTaskgroupDirective(ArrayRef<OMPClause *> Clauses, 10856 Stmt *AStmt, 10857 SourceLocation StartLoc, 10858 SourceLocation EndLoc) { 10859 if (!AStmt) 10860 return StmtError(); 10861 10862 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 10863 10864 setFunctionHasBranchProtectedScope(); 10865 10866 return OMPTaskgroupDirective::Create(Context, StartLoc, EndLoc, Clauses, 10867 AStmt, 10868 DSAStack->getTaskgroupReductionRef()); 10869 } 10870 10871 StmtResult Sema::ActOnOpenMPFlushDirective(ArrayRef<OMPClause *> Clauses, 10872 SourceLocation StartLoc, 10873 SourceLocation EndLoc) { 10874 OMPFlushClause *FC = nullptr; 10875 OMPClause *OrderClause = nullptr; 10876 for (OMPClause *C : Clauses) { 10877 if (C->getClauseKind() == OMPC_flush) 10878 FC = cast<OMPFlushClause>(C); 10879 else 10880 OrderClause = C; 10881 } 10882 OpenMPClauseKind MemOrderKind = OMPC_unknown; 10883 SourceLocation MemOrderLoc; 10884 for (const OMPClause *C : Clauses) { 10885 if (C->getClauseKind() == OMPC_acq_rel || 10886 C->getClauseKind() == OMPC_acquire || 10887 C->getClauseKind() == OMPC_release) { 10888 if (MemOrderKind != OMPC_unknown) { 10889 Diag(C->getBeginLoc(), diag::err_omp_several_mem_order_clauses) 10890 << getOpenMPDirectiveName(OMPD_flush) << 1 10891 << SourceRange(C->getBeginLoc(), C->getEndLoc()); 10892 Diag(MemOrderLoc, diag::note_omp_previous_mem_order_clause) 10893 << getOpenMPClauseName(MemOrderKind); 10894 } else { 10895 MemOrderKind = C->getClauseKind(); 10896 MemOrderLoc = C->getBeginLoc(); 10897 } 10898 } 10899 } 10900 if (FC && OrderClause) { 10901 Diag(FC->getLParenLoc(), diag::err_omp_flush_order_clause_and_list) 10902 << getOpenMPClauseName(OrderClause->getClauseKind()); 10903 Diag(OrderClause->getBeginLoc(), diag::note_omp_flush_order_clause_here) 10904 << getOpenMPClauseName(OrderClause->getClauseKind()); 10905 return StmtError(); 10906 } 10907 return OMPFlushDirective::Create(Context, StartLoc, EndLoc, Clauses); 10908 } 10909 10910 StmtResult Sema::ActOnOpenMPDepobjDirective(ArrayRef<OMPClause *> Clauses, 10911 SourceLocation StartLoc, 10912 SourceLocation EndLoc) { 10913 if (Clauses.empty()) { 10914 Diag(StartLoc, diag::err_omp_depobj_expected); 10915 return StmtError(); 10916 } else if (Clauses[0]->getClauseKind() != OMPC_depobj) { 10917 Diag(Clauses[0]->getBeginLoc(), diag::err_omp_depobj_expected); 10918 return StmtError(); 10919 } 10920 // Only depobj expression and another single clause is allowed. 10921 if (Clauses.size() > 2) { 10922 Diag(Clauses[2]->getBeginLoc(), 10923 diag::err_omp_depobj_single_clause_expected); 10924 return StmtError(); 10925 } else if (Clauses.size() < 1) { 10926 Diag(Clauses[0]->getEndLoc(), diag::err_omp_depobj_single_clause_expected); 10927 return StmtError(); 10928 } 10929 return OMPDepobjDirective::Create(Context, StartLoc, EndLoc, Clauses); 10930 } 10931 10932 StmtResult Sema::ActOnOpenMPScanDirective(ArrayRef<OMPClause *> Clauses, 10933 SourceLocation StartLoc, 10934 SourceLocation EndLoc) { 10935 // Check that exactly one clause is specified. 10936 if (Clauses.size() != 1) { 10937 Diag(Clauses.empty() ? EndLoc : Clauses[1]->getBeginLoc(), 10938 diag::err_omp_scan_single_clause_expected); 10939 return StmtError(); 10940 } 10941 // Check that scan directive is used in the scopeof the OpenMP loop body. 10942 if (Scope *S = DSAStack->getCurScope()) { 10943 Scope *ParentS = S->getParent(); 10944 if (!ParentS || ParentS->getParent() != ParentS->getBreakParent() || 10945 !ParentS->getBreakParent()->isOpenMPLoopScope()) 10946 return StmtError(Diag(StartLoc, diag::err_omp_orphaned_device_directive) 10947 << getOpenMPDirectiveName(OMPD_scan) << 5); 10948 } 10949 // Check that only one instance of scan directives is used in the same outer 10950 // region. 10951 if (DSAStack->doesParentHasScanDirective()) { 10952 Diag(StartLoc, diag::err_omp_several_directives_in_region) << "scan"; 10953 Diag(DSAStack->getParentScanDirectiveLoc(), 10954 diag::note_omp_previous_directive) 10955 << "scan"; 10956 return StmtError(); 10957 } 10958 DSAStack->setParentHasScanDirective(StartLoc); 10959 return OMPScanDirective::Create(Context, StartLoc, EndLoc, Clauses); 10960 } 10961 10962 StmtResult Sema::ActOnOpenMPOrderedDirective(ArrayRef<OMPClause *> Clauses, 10963 Stmt *AStmt, 10964 SourceLocation StartLoc, 10965 SourceLocation EndLoc) { 10966 const OMPClause *DependFound = nullptr; 10967 const OMPClause *DependSourceClause = nullptr; 10968 const OMPClause *DependSinkClause = nullptr; 10969 bool ErrorFound = false; 10970 const OMPThreadsClause *TC = nullptr; 10971 const OMPSIMDClause *SC = nullptr; 10972 for (const OMPClause *C : Clauses) { 10973 if (auto *DC = dyn_cast<OMPDependClause>(C)) { 10974 DependFound = C; 10975 if (DC->getDependencyKind() == OMPC_DEPEND_source) { 10976 if (DependSourceClause) { 10977 Diag(C->getBeginLoc(), diag::err_omp_more_one_clause) 10978 << getOpenMPDirectiveName(OMPD_ordered) 10979 << getOpenMPClauseName(OMPC_depend) << 2; 10980 ErrorFound = true; 10981 } else { 10982 DependSourceClause = C; 10983 } 10984 if (DependSinkClause) { 10985 Diag(C->getBeginLoc(), diag::err_omp_depend_sink_source_not_allowed) 10986 << 0; 10987 ErrorFound = true; 10988 } 10989 } else if (DC->getDependencyKind() == OMPC_DEPEND_sink) { 10990 if (DependSourceClause) { 10991 Diag(C->getBeginLoc(), diag::err_omp_depend_sink_source_not_allowed) 10992 << 1; 10993 ErrorFound = true; 10994 } 10995 DependSinkClause = C; 10996 } 10997 } else if (C->getClauseKind() == OMPC_threads) { 10998 TC = cast<OMPThreadsClause>(C); 10999 } else if (C->getClauseKind() == OMPC_simd) { 11000 SC = cast<OMPSIMDClause>(C); 11001 } 11002 } 11003 if (!ErrorFound && !SC && 11004 isOpenMPSimdDirective(DSAStack->getParentDirective())) { 11005 // OpenMP [2.8.1,simd Construct, Restrictions] 11006 // An ordered construct with the simd clause is the only OpenMP construct 11007 // that can appear in the simd region. 11008 Diag(StartLoc, diag::err_omp_prohibited_region_simd) 11009 << (LangOpts.OpenMP >= 50 ? 1 : 0); 11010 ErrorFound = true; 11011 } else if (DependFound && (TC || SC)) { 11012 Diag(DependFound->getBeginLoc(), diag::err_omp_depend_clause_thread_simd) 11013 << getOpenMPClauseName(TC ? TC->getClauseKind() : SC->getClauseKind()); 11014 ErrorFound = true; 11015 } else if (DependFound && !DSAStack->getParentOrderedRegionParam().first) { 11016 Diag(DependFound->getBeginLoc(), 11017 diag::err_omp_ordered_directive_without_param); 11018 ErrorFound = true; 11019 } else if (TC || Clauses.empty()) { 11020 if (const Expr *Param = DSAStack->getParentOrderedRegionParam().first) { 11021 SourceLocation ErrLoc = TC ? TC->getBeginLoc() : StartLoc; 11022 Diag(ErrLoc, diag::err_omp_ordered_directive_with_param) 11023 << (TC != nullptr); 11024 Diag(Param->getBeginLoc(), diag::note_omp_ordered_param) << 1; 11025 ErrorFound = true; 11026 } 11027 } 11028 if ((!AStmt && !DependFound) || ErrorFound) 11029 return StmtError(); 11030 11031 // OpenMP 5.0, 2.17.9, ordered Construct, Restrictions. 11032 // During execution of an iteration of a worksharing-loop or a loop nest 11033 // within a worksharing-loop, simd, or worksharing-loop SIMD region, a thread 11034 // must not execute more than one ordered region corresponding to an ordered 11035 // construct without a depend clause. 11036 if (!DependFound) { 11037 if (DSAStack->doesParentHasOrderedDirective()) { 11038 Diag(StartLoc, diag::err_omp_several_directives_in_region) << "ordered"; 11039 Diag(DSAStack->getParentOrderedDirectiveLoc(), 11040 diag::note_omp_previous_directive) 11041 << "ordered"; 11042 return StmtError(); 11043 } 11044 DSAStack->setParentHasOrderedDirective(StartLoc); 11045 } 11046 11047 if (AStmt) { 11048 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 11049 11050 setFunctionHasBranchProtectedScope(); 11051 } 11052 11053 return OMPOrderedDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt); 11054 } 11055 11056 namespace { 11057 /// Helper class for checking expression in 'omp atomic [update]' 11058 /// construct. 11059 class OpenMPAtomicUpdateChecker { 11060 /// Error results for atomic update expressions. 11061 enum ExprAnalysisErrorCode { 11062 /// A statement is not an expression statement. 11063 NotAnExpression, 11064 /// Expression is not builtin binary or unary operation. 11065 NotABinaryOrUnaryExpression, 11066 /// Unary operation is not post-/pre- increment/decrement operation. 11067 NotAnUnaryIncDecExpression, 11068 /// An expression is not of scalar type. 11069 NotAScalarType, 11070 /// A binary operation is not an assignment operation. 11071 NotAnAssignmentOp, 11072 /// RHS part of the binary operation is not a binary expression. 11073 NotABinaryExpression, 11074 /// RHS part is not additive/multiplicative/shift/biwise binary 11075 /// expression. 11076 NotABinaryOperator, 11077 /// RHS binary operation does not have reference to the updated LHS 11078 /// part. 11079 NotAnUpdateExpression, 11080 /// No errors is found. 11081 NoError 11082 }; 11083 /// Reference to Sema. 11084 Sema &SemaRef; 11085 /// A location for note diagnostics (when error is found). 11086 SourceLocation NoteLoc; 11087 /// 'x' lvalue part of the source atomic expression. 11088 Expr *X; 11089 /// 'expr' rvalue part of the source atomic expression. 11090 Expr *E; 11091 /// Helper expression of the form 11092 /// 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or 11093 /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'. 11094 Expr *UpdateExpr; 11095 /// Is 'x' a LHS in a RHS part of full update expression. It is 11096 /// important for non-associative operations. 11097 bool IsXLHSInRHSPart; 11098 BinaryOperatorKind Op; 11099 SourceLocation OpLoc; 11100 /// true if the source expression is a postfix unary operation, false 11101 /// if it is a prefix unary operation. 11102 bool IsPostfixUpdate; 11103 11104 public: 11105 OpenMPAtomicUpdateChecker(Sema &SemaRef) 11106 : SemaRef(SemaRef), X(nullptr), E(nullptr), UpdateExpr(nullptr), 11107 IsXLHSInRHSPart(false), Op(BO_PtrMemD), IsPostfixUpdate(false) {} 11108 /// Check specified statement that it is suitable for 'atomic update' 11109 /// constructs and extract 'x', 'expr' and Operation from the original 11110 /// expression. If DiagId and NoteId == 0, then only check is performed 11111 /// without error notification. 11112 /// \param DiagId Diagnostic which should be emitted if error is found. 11113 /// \param NoteId Diagnostic note for the main error message. 11114 /// \return true if statement is not an update expression, false otherwise. 11115 bool checkStatement(Stmt *S, unsigned DiagId = 0, unsigned NoteId = 0); 11116 /// Return the 'x' lvalue part of the source atomic expression. 11117 Expr *getX() const { return X; } 11118 /// Return the 'expr' rvalue part of the source atomic expression. 11119 Expr *getExpr() const { return E; } 11120 /// Return the update expression used in calculation of the updated 11121 /// value. Always has form 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or 11122 /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'. 11123 Expr *getUpdateExpr() const { return UpdateExpr; } 11124 /// Return true if 'x' is LHS in RHS part of full update expression, 11125 /// false otherwise. 11126 bool isXLHSInRHSPart() const { return IsXLHSInRHSPart; } 11127 11128 /// true if the source expression is a postfix unary operation, false 11129 /// if it is a prefix unary operation. 11130 bool isPostfixUpdate() const { return IsPostfixUpdate; } 11131 11132 private: 11133 bool checkBinaryOperation(BinaryOperator *AtomicBinOp, unsigned DiagId = 0, 11134 unsigned NoteId = 0); 11135 }; 11136 11137 bool OpenMPAtomicUpdateChecker::checkBinaryOperation( 11138 BinaryOperator *AtomicBinOp, unsigned DiagId, unsigned NoteId) { 11139 ExprAnalysisErrorCode ErrorFound = NoError; 11140 SourceLocation ErrorLoc, NoteLoc; 11141 SourceRange ErrorRange, NoteRange; 11142 // Allowed constructs are: 11143 // x = x binop expr; 11144 // x = expr binop x; 11145 if (AtomicBinOp->getOpcode() == BO_Assign) { 11146 X = AtomicBinOp->getLHS(); 11147 if (const auto *AtomicInnerBinOp = dyn_cast<BinaryOperator>( 11148 AtomicBinOp->getRHS()->IgnoreParenImpCasts())) { 11149 if (AtomicInnerBinOp->isMultiplicativeOp() || 11150 AtomicInnerBinOp->isAdditiveOp() || AtomicInnerBinOp->isShiftOp() || 11151 AtomicInnerBinOp->isBitwiseOp()) { 11152 Op = AtomicInnerBinOp->getOpcode(); 11153 OpLoc = AtomicInnerBinOp->getOperatorLoc(); 11154 Expr *LHS = AtomicInnerBinOp->getLHS(); 11155 Expr *RHS = AtomicInnerBinOp->getRHS(); 11156 llvm::FoldingSetNodeID XId, LHSId, RHSId; 11157 X->IgnoreParenImpCasts()->Profile(XId, SemaRef.getASTContext(), 11158 /*Canonical=*/true); 11159 LHS->IgnoreParenImpCasts()->Profile(LHSId, SemaRef.getASTContext(), 11160 /*Canonical=*/true); 11161 RHS->IgnoreParenImpCasts()->Profile(RHSId, SemaRef.getASTContext(), 11162 /*Canonical=*/true); 11163 if (XId == LHSId) { 11164 E = RHS; 11165 IsXLHSInRHSPart = true; 11166 } else if (XId == RHSId) { 11167 E = LHS; 11168 IsXLHSInRHSPart = false; 11169 } else { 11170 ErrorLoc = AtomicInnerBinOp->getExprLoc(); 11171 ErrorRange = AtomicInnerBinOp->getSourceRange(); 11172 NoteLoc = X->getExprLoc(); 11173 NoteRange = X->getSourceRange(); 11174 ErrorFound = NotAnUpdateExpression; 11175 } 11176 } else { 11177 ErrorLoc = AtomicInnerBinOp->getExprLoc(); 11178 ErrorRange = AtomicInnerBinOp->getSourceRange(); 11179 NoteLoc = AtomicInnerBinOp->getOperatorLoc(); 11180 NoteRange = SourceRange(NoteLoc, NoteLoc); 11181 ErrorFound = NotABinaryOperator; 11182 } 11183 } else { 11184 NoteLoc = ErrorLoc = AtomicBinOp->getRHS()->getExprLoc(); 11185 NoteRange = ErrorRange = AtomicBinOp->getRHS()->getSourceRange(); 11186 ErrorFound = NotABinaryExpression; 11187 } 11188 } else { 11189 ErrorLoc = AtomicBinOp->getExprLoc(); 11190 ErrorRange = AtomicBinOp->getSourceRange(); 11191 NoteLoc = AtomicBinOp->getOperatorLoc(); 11192 NoteRange = SourceRange(NoteLoc, NoteLoc); 11193 ErrorFound = NotAnAssignmentOp; 11194 } 11195 if (ErrorFound != NoError && DiagId != 0 && NoteId != 0) { 11196 SemaRef.Diag(ErrorLoc, DiagId) << ErrorRange; 11197 SemaRef.Diag(NoteLoc, NoteId) << ErrorFound << NoteRange; 11198 return true; 11199 } 11200 if (SemaRef.CurContext->isDependentContext()) 11201 E = X = UpdateExpr = nullptr; 11202 return ErrorFound != NoError; 11203 } 11204 11205 bool OpenMPAtomicUpdateChecker::checkStatement(Stmt *S, unsigned DiagId, 11206 unsigned NoteId) { 11207 ExprAnalysisErrorCode ErrorFound = NoError; 11208 SourceLocation ErrorLoc, NoteLoc; 11209 SourceRange ErrorRange, NoteRange; 11210 // Allowed constructs are: 11211 // x++; 11212 // x--; 11213 // ++x; 11214 // --x; 11215 // x binop= expr; 11216 // x = x binop expr; 11217 // x = expr binop x; 11218 if (auto *AtomicBody = dyn_cast<Expr>(S)) { 11219 AtomicBody = AtomicBody->IgnoreParenImpCasts(); 11220 if (AtomicBody->getType()->isScalarType() || 11221 AtomicBody->isInstantiationDependent()) { 11222 if (const auto *AtomicCompAssignOp = dyn_cast<CompoundAssignOperator>( 11223 AtomicBody->IgnoreParenImpCasts())) { 11224 // Check for Compound Assignment Operation 11225 Op = BinaryOperator::getOpForCompoundAssignment( 11226 AtomicCompAssignOp->getOpcode()); 11227 OpLoc = AtomicCompAssignOp->getOperatorLoc(); 11228 E = AtomicCompAssignOp->getRHS(); 11229 X = AtomicCompAssignOp->getLHS()->IgnoreParens(); 11230 IsXLHSInRHSPart = true; 11231 } else if (auto *AtomicBinOp = dyn_cast<BinaryOperator>( 11232 AtomicBody->IgnoreParenImpCasts())) { 11233 // Check for Binary Operation 11234 if (checkBinaryOperation(AtomicBinOp, DiagId, NoteId)) 11235 return true; 11236 } else if (const auto *AtomicUnaryOp = dyn_cast<UnaryOperator>( 11237 AtomicBody->IgnoreParenImpCasts())) { 11238 // Check for Unary Operation 11239 if (AtomicUnaryOp->isIncrementDecrementOp()) { 11240 IsPostfixUpdate = AtomicUnaryOp->isPostfix(); 11241 Op = AtomicUnaryOp->isIncrementOp() ? BO_Add : BO_Sub; 11242 OpLoc = AtomicUnaryOp->getOperatorLoc(); 11243 X = AtomicUnaryOp->getSubExpr()->IgnoreParens(); 11244 E = SemaRef.ActOnIntegerConstant(OpLoc, /*uint64_t Val=*/1).get(); 11245 IsXLHSInRHSPart = true; 11246 } else { 11247 ErrorFound = NotAnUnaryIncDecExpression; 11248 ErrorLoc = AtomicUnaryOp->getExprLoc(); 11249 ErrorRange = AtomicUnaryOp->getSourceRange(); 11250 NoteLoc = AtomicUnaryOp->getOperatorLoc(); 11251 NoteRange = SourceRange(NoteLoc, NoteLoc); 11252 } 11253 } else if (!AtomicBody->isInstantiationDependent()) { 11254 ErrorFound = NotABinaryOrUnaryExpression; 11255 NoteLoc = ErrorLoc = AtomicBody->getExprLoc(); 11256 NoteRange = ErrorRange = AtomicBody->getSourceRange(); 11257 } 11258 } else { 11259 ErrorFound = NotAScalarType; 11260 NoteLoc = ErrorLoc = AtomicBody->getBeginLoc(); 11261 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc); 11262 } 11263 } else { 11264 ErrorFound = NotAnExpression; 11265 NoteLoc = ErrorLoc = S->getBeginLoc(); 11266 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc); 11267 } 11268 if (ErrorFound != NoError && DiagId != 0 && NoteId != 0) { 11269 SemaRef.Diag(ErrorLoc, DiagId) << ErrorRange; 11270 SemaRef.Diag(NoteLoc, NoteId) << ErrorFound << NoteRange; 11271 return true; 11272 } 11273 if (SemaRef.CurContext->isDependentContext()) 11274 E = X = UpdateExpr = nullptr; 11275 if (ErrorFound == NoError && E && X) { 11276 // Build an update expression of form 'OpaqueValueExpr(x) binop 11277 // OpaqueValueExpr(expr)' or 'OpaqueValueExpr(expr) binop 11278 // OpaqueValueExpr(x)' and then cast it to the type of the 'x' expression. 11279 auto *OVEX = new (SemaRef.getASTContext()) 11280 OpaqueValueExpr(X->getExprLoc(), X->getType(), VK_PRValue); 11281 auto *OVEExpr = new (SemaRef.getASTContext()) 11282 OpaqueValueExpr(E->getExprLoc(), E->getType(), VK_PRValue); 11283 ExprResult Update = 11284 SemaRef.CreateBuiltinBinOp(OpLoc, Op, IsXLHSInRHSPart ? OVEX : OVEExpr, 11285 IsXLHSInRHSPart ? OVEExpr : OVEX); 11286 if (Update.isInvalid()) 11287 return true; 11288 Update = SemaRef.PerformImplicitConversion(Update.get(), X->getType(), 11289 Sema::AA_Casting); 11290 if (Update.isInvalid()) 11291 return true; 11292 UpdateExpr = Update.get(); 11293 } 11294 return ErrorFound != NoError; 11295 } 11296 11297 /// Get the node id of the fixed point of an expression \a S. 11298 llvm::FoldingSetNodeID getNodeId(ASTContext &Context, const Expr *S) { 11299 llvm::FoldingSetNodeID Id; 11300 S->IgnoreParenImpCasts()->Profile(Id, Context, true); 11301 return Id; 11302 } 11303 11304 /// Check if two expressions are same. 11305 bool checkIfTwoExprsAreSame(ASTContext &Context, const Expr *LHS, 11306 const Expr *RHS) { 11307 return getNodeId(Context, LHS) == getNodeId(Context, RHS); 11308 } 11309 11310 class OpenMPAtomicCompareChecker { 11311 public: 11312 /// All kinds of errors that can occur in `atomic compare` 11313 enum ErrorTy { 11314 /// Empty compound statement. 11315 NoStmt = 0, 11316 /// More than one statement in a compound statement. 11317 MoreThanOneStmt, 11318 /// Not an assignment binary operator. 11319 NotAnAssignment, 11320 /// Not a conditional operator. 11321 NotCondOp, 11322 /// Wrong false expr. According to the spec, 'x' should be at the false 11323 /// expression of a conditional expression. 11324 WrongFalseExpr, 11325 /// The condition of a conditional expression is not a binary operator. 11326 NotABinaryOp, 11327 /// Invalid binary operator (not <, >, or ==). 11328 InvalidBinaryOp, 11329 /// Invalid comparison (not x == e, e == x, x ordop expr, or expr ordop x). 11330 InvalidComparison, 11331 /// X is not a lvalue. 11332 XNotLValue, 11333 /// Not a scalar. 11334 NotScalar, 11335 /// Not an integer. 11336 NotInteger, 11337 /// 'else' statement is not expected. 11338 UnexpectedElse, 11339 /// Not an equality operator. 11340 NotEQ, 11341 /// Invalid assignment (not v == x). 11342 InvalidAssignment, 11343 /// Not if statement 11344 NotIfStmt, 11345 /// More than two statements in a compund statement. 11346 MoreThanTwoStmts, 11347 /// Not a compound statement. 11348 NotCompoundStmt, 11349 /// No else statement. 11350 NoElse, 11351 /// Not 'if (r)'. 11352 InvalidCondition, 11353 /// No error. 11354 NoError, 11355 }; 11356 11357 struct ErrorInfoTy { 11358 ErrorTy Error; 11359 SourceLocation ErrorLoc; 11360 SourceRange ErrorRange; 11361 SourceLocation NoteLoc; 11362 SourceRange NoteRange; 11363 }; 11364 11365 OpenMPAtomicCompareChecker(Sema &S) : ContextRef(S.getASTContext()) {} 11366 11367 /// Check if statement \a S is valid for <tt>atomic compare</tt>. 11368 bool checkStmt(Stmt *S, ErrorInfoTy &ErrorInfo); 11369 11370 Expr *getX() const { return X; } 11371 Expr *getE() const { return E; } 11372 Expr *getD() const { return D; } 11373 Expr *getCond() const { return C; } 11374 bool isXBinopExpr() const { return IsXBinopExpr; } 11375 11376 protected: 11377 /// Reference to ASTContext 11378 ASTContext &ContextRef; 11379 /// 'x' lvalue part of the source atomic expression. 11380 Expr *X = nullptr; 11381 /// 'expr' or 'e' rvalue part of the source atomic expression. 11382 Expr *E = nullptr; 11383 /// 'd' rvalue part of the source atomic expression. 11384 Expr *D = nullptr; 11385 /// 'cond' part of the source atomic expression. It is in one of the following 11386 /// forms: 11387 /// expr ordop x 11388 /// x ordop expr 11389 /// x == e 11390 /// e == x 11391 Expr *C = nullptr; 11392 /// True if the cond expr is in the form of 'x ordop expr'. 11393 bool IsXBinopExpr = true; 11394 11395 /// Check if it is a valid conditional update statement (cond-update-stmt). 11396 bool checkCondUpdateStmt(IfStmt *S, ErrorInfoTy &ErrorInfo); 11397 11398 /// Check if it is a valid conditional expression statement (cond-expr-stmt). 11399 bool checkCondExprStmt(Stmt *S, ErrorInfoTy &ErrorInfo); 11400 11401 /// Check if all captured values have right type. 11402 bool checkType(ErrorInfoTy &ErrorInfo) const; 11403 11404 static bool CheckValue(const Expr *E, ErrorInfoTy &ErrorInfo, 11405 bool ShouldBeLValue) { 11406 if (ShouldBeLValue && !E->isLValue()) { 11407 ErrorInfo.Error = ErrorTy::XNotLValue; 11408 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = E->getExprLoc(); 11409 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = E->getSourceRange(); 11410 return false; 11411 } 11412 11413 if (!E->isInstantiationDependent()) { 11414 QualType QTy = E->getType(); 11415 if (!QTy->isScalarType()) { 11416 ErrorInfo.Error = ErrorTy::NotScalar; 11417 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = E->getExprLoc(); 11418 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = E->getSourceRange(); 11419 return false; 11420 } 11421 11422 if (!QTy->isIntegerType()) { 11423 ErrorInfo.Error = ErrorTy::NotInteger; 11424 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = E->getExprLoc(); 11425 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = E->getSourceRange(); 11426 return false; 11427 } 11428 } 11429 11430 return true; 11431 } 11432 }; 11433 11434 bool OpenMPAtomicCompareChecker::checkCondUpdateStmt(IfStmt *S, 11435 ErrorInfoTy &ErrorInfo) { 11436 auto *Then = S->getThen(); 11437 if (auto *CS = dyn_cast<CompoundStmt>(Then)) { 11438 if (CS->body_empty()) { 11439 ErrorInfo.Error = ErrorTy::NoStmt; 11440 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = CS->getBeginLoc(); 11441 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = CS->getSourceRange(); 11442 return false; 11443 } 11444 if (CS->size() > 1) { 11445 ErrorInfo.Error = ErrorTy::MoreThanOneStmt; 11446 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = CS->getBeginLoc(); 11447 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = S->getSourceRange(); 11448 return false; 11449 } 11450 Then = CS->body_front(); 11451 } 11452 11453 auto *BO = dyn_cast<BinaryOperator>(Then); 11454 if (!BO) { 11455 ErrorInfo.Error = ErrorTy::NotAnAssignment; 11456 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = Then->getBeginLoc(); 11457 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = Then->getSourceRange(); 11458 return false; 11459 } 11460 if (BO->getOpcode() != BO_Assign) { 11461 ErrorInfo.Error = ErrorTy::NotAnAssignment; 11462 ErrorInfo.ErrorLoc = BO->getExprLoc(); 11463 ErrorInfo.NoteLoc = BO->getOperatorLoc(); 11464 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = BO->getSourceRange(); 11465 return false; 11466 } 11467 11468 X = BO->getLHS(); 11469 11470 auto *Cond = dyn_cast<BinaryOperator>(S->getCond()); 11471 if (!Cond) { 11472 ErrorInfo.Error = ErrorTy::NotABinaryOp; 11473 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = S->getCond()->getExprLoc(); 11474 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = S->getCond()->getSourceRange(); 11475 return false; 11476 } 11477 11478 switch (Cond->getOpcode()) { 11479 case BO_EQ: { 11480 C = Cond; 11481 D = BO->getRHS(); 11482 if (checkIfTwoExprsAreSame(ContextRef, X, Cond->getLHS())) { 11483 E = Cond->getRHS(); 11484 } else if (checkIfTwoExprsAreSame(ContextRef, X, Cond->getRHS())) { 11485 E = Cond->getLHS(); 11486 } else { 11487 ErrorInfo.Error = ErrorTy::InvalidComparison; 11488 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = Cond->getExprLoc(); 11489 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = Cond->getSourceRange(); 11490 return false; 11491 } 11492 break; 11493 } 11494 case BO_LT: 11495 case BO_GT: { 11496 E = BO->getRHS(); 11497 if (checkIfTwoExprsAreSame(ContextRef, X, Cond->getLHS()) && 11498 checkIfTwoExprsAreSame(ContextRef, E, Cond->getRHS())) { 11499 C = Cond; 11500 } else if (checkIfTwoExprsAreSame(ContextRef, E, Cond->getLHS()) && 11501 checkIfTwoExprsAreSame(ContextRef, X, Cond->getRHS())) { 11502 C = Cond; 11503 IsXBinopExpr = false; 11504 } else { 11505 ErrorInfo.Error = ErrorTy::InvalidComparison; 11506 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = Cond->getExprLoc(); 11507 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = Cond->getSourceRange(); 11508 return false; 11509 } 11510 break; 11511 } 11512 default: 11513 ErrorInfo.Error = ErrorTy::InvalidBinaryOp; 11514 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = Cond->getExprLoc(); 11515 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = Cond->getSourceRange(); 11516 return false; 11517 } 11518 11519 if (S->getElse()) { 11520 ErrorInfo.Error = ErrorTy::UnexpectedElse; 11521 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = S->getElse()->getBeginLoc(); 11522 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = S->getElse()->getSourceRange(); 11523 return false; 11524 } 11525 11526 return true; 11527 } 11528 11529 bool OpenMPAtomicCompareChecker::checkCondExprStmt(Stmt *S, 11530 ErrorInfoTy &ErrorInfo) { 11531 auto *BO = dyn_cast<BinaryOperator>(S); 11532 if (!BO) { 11533 ErrorInfo.Error = ErrorTy::NotAnAssignment; 11534 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = S->getBeginLoc(); 11535 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = S->getSourceRange(); 11536 return false; 11537 } 11538 if (BO->getOpcode() != BO_Assign) { 11539 ErrorInfo.Error = ErrorTy::NotAnAssignment; 11540 ErrorInfo.ErrorLoc = BO->getExprLoc(); 11541 ErrorInfo.NoteLoc = BO->getOperatorLoc(); 11542 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = BO->getSourceRange(); 11543 return false; 11544 } 11545 11546 X = BO->getLHS(); 11547 11548 auto *CO = dyn_cast<ConditionalOperator>(BO->getRHS()->IgnoreParenImpCasts()); 11549 if (!CO) { 11550 ErrorInfo.Error = ErrorTy::NotCondOp; 11551 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = BO->getRHS()->getExprLoc(); 11552 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = BO->getRHS()->getSourceRange(); 11553 return false; 11554 } 11555 11556 if (!checkIfTwoExprsAreSame(ContextRef, X, CO->getFalseExpr())) { 11557 ErrorInfo.Error = ErrorTy::WrongFalseExpr; 11558 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = CO->getFalseExpr()->getExprLoc(); 11559 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = 11560 CO->getFalseExpr()->getSourceRange(); 11561 return false; 11562 } 11563 11564 auto *Cond = dyn_cast<BinaryOperator>(CO->getCond()); 11565 if (!Cond) { 11566 ErrorInfo.Error = ErrorTy::NotABinaryOp; 11567 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = CO->getCond()->getExprLoc(); 11568 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = 11569 CO->getCond()->getSourceRange(); 11570 return false; 11571 } 11572 11573 switch (Cond->getOpcode()) { 11574 case BO_EQ: { 11575 C = Cond; 11576 D = CO->getTrueExpr(); 11577 if (checkIfTwoExprsAreSame(ContextRef, X, Cond->getLHS())) { 11578 E = Cond->getRHS(); 11579 } else if (checkIfTwoExprsAreSame(ContextRef, X, Cond->getRHS())) { 11580 E = Cond->getLHS(); 11581 } else { 11582 ErrorInfo.Error = ErrorTy::InvalidComparison; 11583 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = Cond->getExprLoc(); 11584 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = Cond->getSourceRange(); 11585 return false; 11586 } 11587 break; 11588 } 11589 case BO_LT: 11590 case BO_GT: { 11591 E = CO->getTrueExpr(); 11592 if (checkIfTwoExprsAreSame(ContextRef, X, Cond->getLHS()) && 11593 checkIfTwoExprsAreSame(ContextRef, E, Cond->getRHS())) { 11594 C = Cond; 11595 } else if (checkIfTwoExprsAreSame(ContextRef, E, Cond->getLHS()) && 11596 checkIfTwoExprsAreSame(ContextRef, X, Cond->getRHS())) { 11597 C = Cond; 11598 IsXBinopExpr = false; 11599 } else { 11600 ErrorInfo.Error = ErrorTy::InvalidComparison; 11601 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = Cond->getExprLoc(); 11602 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = Cond->getSourceRange(); 11603 return false; 11604 } 11605 break; 11606 } 11607 default: 11608 ErrorInfo.Error = ErrorTy::InvalidBinaryOp; 11609 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = Cond->getExprLoc(); 11610 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = Cond->getSourceRange(); 11611 return false; 11612 } 11613 11614 return true; 11615 } 11616 11617 bool OpenMPAtomicCompareChecker::checkType(ErrorInfoTy &ErrorInfo) const { 11618 // 'x' and 'e' cannot be nullptr 11619 assert(X && E && "X and E cannot be nullptr"); 11620 11621 if (!CheckValue(X, ErrorInfo, true)) 11622 return false; 11623 11624 if (!CheckValue(E, ErrorInfo, false)) 11625 return false; 11626 11627 if (D && !CheckValue(D, ErrorInfo, false)) 11628 return false; 11629 11630 return true; 11631 } 11632 11633 bool OpenMPAtomicCompareChecker::checkStmt( 11634 Stmt *S, OpenMPAtomicCompareChecker::ErrorInfoTy &ErrorInfo) { 11635 auto *CS = dyn_cast<CompoundStmt>(S); 11636 if (CS) { 11637 if (CS->body_empty()) { 11638 ErrorInfo.Error = ErrorTy::NoStmt; 11639 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = CS->getBeginLoc(); 11640 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = CS->getSourceRange(); 11641 return false; 11642 } 11643 11644 if (CS->size() != 1) { 11645 ErrorInfo.Error = ErrorTy::MoreThanOneStmt; 11646 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = CS->getBeginLoc(); 11647 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = CS->getSourceRange(); 11648 return false; 11649 } 11650 S = CS->body_front(); 11651 } 11652 11653 auto Res = false; 11654 11655 if (auto *IS = dyn_cast<IfStmt>(S)) { 11656 // Check if the statement is in one of the following forms 11657 // (cond-update-stmt): 11658 // if (expr ordop x) { x = expr; } 11659 // if (x ordop expr) { x = expr; } 11660 // if (x == e) { x = d; } 11661 Res = checkCondUpdateStmt(IS, ErrorInfo); 11662 } else { 11663 // Check if the statement is in one of the following forms (cond-expr-stmt): 11664 // x = expr ordop x ? expr : x; 11665 // x = x ordop expr ? expr : x; 11666 // x = x == e ? d : x; 11667 Res = checkCondExprStmt(S, ErrorInfo); 11668 } 11669 11670 if (!Res) 11671 return false; 11672 11673 return checkType(ErrorInfo); 11674 } 11675 11676 class OpenMPAtomicCompareCaptureChecker final 11677 : public OpenMPAtomicCompareChecker { 11678 public: 11679 OpenMPAtomicCompareCaptureChecker(Sema &S) : OpenMPAtomicCompareChecker(S) {} 11680 11681 Expr *getV() const { return V; } 11682 Expr *getR() const { return R; } 11683 bool isFailOnly() const { return IsFailOnly; } 11684 bool isPostfixUpdate() const { return IsPostfixUpdate; } 11685 11686 /// Check if statement \a S is valid for <tt>atomic compare capture</tt>. 11687 bool checkStmt(Stmt *S, ErrorInfoTy &ErrorInfo); 11688 11689 private: 11690 bool checkType(ErrorInfoTy &ErrorInfo); 11691 11692 // NOTE: Form 3, 4, 5 in the following comments mean the 3rd, 4th, and 5th 11693 // form of 'conditional-update-capture-atomic' structured block on the v5.2 11694 // spec p.p. 82: 11695 // (1) { v = x; cond-update-stmt } 11696 // (2) { cond-update-stmt v = x; } 11697 // (3) if(x == e) { x = d; } else { v = x; } 11698 // (4) { r = x == e; if(r) { x = d; } } 11699 // (5) { r = x == e; if(r) { x = d; } else { v = x; } } 11700 11701 /// Check if it is valid 'if(x == e) { x = d; } else { v = x; }' (form 3) 11702 bool checkForm3(IfStmt *S, ErrorInfoTy &ErrorInfo); 11703 11704 /// Check if it is valid '{ r = x == e; if(r) { x = d; } }', 11705 /// or '{ r = x == e; if(r) { x = d; } else { v = x; } }' (form 4 and 5) 11706 bool checkForm45(Stmt *S, ErrorInfoTy &ErrorInfo); 11707 11708 /// 'v' lvalue part of the source atomic expression. 11709 Expr *V = nullptr; 11710 /// 'r' lvalue part of the source atomic expression. 11711 Expr *R = nullptr; 11712 /// If 'v' is only updated when the comparison fails. 11713 bool IsFailOnly = false; 11714 /// If original value of 'x' must be stored in 'v', not an updated one. 11715 bool IsPostfixUpdate = false; 11716 }; 11717 11718 bool OpenMPAtomicCompareCaptureChecker::checkType(ErrorInfoTy &ErrorInfo) { 11719 if (!OpenMPAtomicCompareChecker::checkType(ErrorInfo)) 11720 return false; 11721 11722 if (V && !CheckValue(V, ErrorInfo, true)) 11723 return false; 11724 11725 if (R && !CheckValue(R, ErrorInfo, true)) 11726 return false; 11727 11728 return true; 11729 } 11730 11731 bool OpenMPAtomicCompareCaptureChecker::checkForm3(IfStmt *S, 11732 ErrorInfoTy &ErrorInfo) { 11733 IsFailOnly = true; 11734 11735 auto *Then = S->getThen(); 11736 if (auto *CS = dyn_cast<CompoundStmt>(Then)) { 11737 if (CS->body_empty()) { 11738 ErrorInfo.Error = ErrorTy::NoStmt; 11739 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = CS->getBeginLoc(); 11740 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = CS->getSourceRange(); 11741 return false; 11742 } 11743 if (CS->size() > 1) { 11744 ErrorInfo.Error = ErrorTy::MoreThanOneStmt; 11745 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = CS->getBeginLoc(); 11746 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = CS->getSourceRange(); 11747 return false; 11748 } 11749 Then = CS->body_front(); 11750 } 11751 11752 auto *BO = dyn_cast<BinaryOperator>(Then); 11753 if (!BO) { 11754 ErrorInfo.Error = ErrorTy::NotAnAssignment; 11755 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = Then->getBeginLoc(); 11756 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = Then->getSourceRange(); 11757 return false; 11758 } 11759 if (BO->getOpcode() != BO_Assign) { 11760 ErrorInfo.Error = ErrorTy::NotAnAssignment; 11761 ErrorInfo.ErrorLoc = BO->getExprLoc(); 11762 ErrorInfo.NoteLoc = BO->getOperatorLoc(); 11763 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = BO->getSourceRange(); 11764 return false; 11765 } 11766 11767 X = BO->getLHS(); 11768 D = BO->getRHS(); 11769 11770 auto *Cond = dyn_cast<BinaryOperator>(S->getCond()); 11771 if (!Cond) { 11772 ErrorInfo.Error = ErrorTy::NotABinaryOp; 11773 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = S->getCond()->getExprLoc(); 11774 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = S->getCond()->getSourceRange(); 11775 return false; 11776 } 11777 if (Cond->getOpcode() != BO_EQ) { 11778 ErrorInfo.Error = ErrorTy::NotEQ; 11779 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = Cond->getExprLoc(); 11780 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = Cond->getSourceRange(); 11781 return false; 11782 } 11783 11784 if (checkIfTwoExprsAreSame(ContextRef, X, Cond->getLHS())) { 11785 E = Cond->getRHS(); 11786 } else if (checkIfTwoExprsAreSame(ContextRef, X, Cond->getRHS())) { 11787 E = Cond->getLHS(); 11788 } else { 11789 ErrorInfo.Error = ErrorTy::InvalidComparison; 11790 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = Cond->getExprLoc(); 11791 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = Cond->getSourceRange(); 11792 return false; 11793 } 11794 11795 C = Cond; 11796 11797 if (!S->getElse()) { 11798 ErrorInfo.Error = ErrorTy::NoElse; 11799 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = S->getBeginLoc(); 11800 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = S->getSourceRange(); 11801 return false; 11802 } 11803 11804 auto *Else = S->getElse(); 11805 if (auto *CS = dyn_cast<CompoundStmt>(Else)) { 11806 if (CS->body_empty()) { 11807 ErrorInfo.Error = ErrorTy::NoStmt; 11808 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = CS->getBeginLoc(); 11809 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = CS->getSourceRange(); 11810 return false; 11811 } 11812 if (CS->size() > 1) { 11813 ErrorInfo.Error = ErrorTy::MoreThanOneStmt; 11814 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = CS->getBeginLoc(); 11815 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = S->getSourceRange(); 11816 return false; 11817 } 11818 Else = CS->body_front(); 11819 } 11820 11821 auto *ElseBO = dyn_cast<BinaryOperator>(Else); 11822 if (!ElseBO) { 11823 ErrorInfo.Error = ErrorTy::NotAnAssignment; 11824 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = Else->getBeginLoc(); 11825 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = Else->getSourceRange(); 11826 return false; 11827 } 11828 if (ElseBO->getOpcode() != BO_Assign) { 11829 ErrorInfo.Error = ErrorTy::NotAnAssignment; 11830 ErrorInfo.ErrorLoc = ElseBO->getExprLoc(); 11831 ErrorInfo.NoteLoc = ElseBO->getOperatorLoc(); 11832 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = ElseBO->getSourceRange(); 11833 return false; 11834 } 11835 11836 if (!checkIfTwoExprsAreSame(ContextRef, X, ElseBO->getRHS())) { 11837 ErrorInfo.Error = ErrorTy::InvalidAssignment; 11838 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = ElseBO->getRHS()->getExprLoc(); 11839 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = 11840 ElseBO->getRHS()->getSourceRange(); 11841 return false; 11842 } 11843 11844 V = ElseBO->getLHS(); 11845 11846 return checkType(ErrorInfo); 11847 } 11848 11849 bool OpenMPAtomicCompareCaptureChecker::checkForm45(Stmt *S, 11850 ErrorInfoTy &ErrorInfo) { 11851 // We don't check here as they should be already done before call this 11852 // function. 11853 auto *CS = cast<CompoundStmt>(S); 11854 assert(CS->size() == 2 && "CompoundStmt size is not expected"); 11855 auto *S1 = cast<BinaryOperator>(CS->body_front()); 11856 auto *S2 = cast<IfStmt>(CS->body_back()); 11857 assert(S1->getOpcode() == BO_Assign && "unexpected binary operator"); 11858 11859 if (!checkIfTwoExprsAreSame(ContextRef, S1->getLHS(), S2->getCond())) { 11860 ErrorInfo.Error = ErrorTy::InvalidCondition; 11861 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = S2->getCond()->getExprLoc(); 11862 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = S1->getLHS()->getSourceRange(); 11863 return false; 11864 } 11865 11866 R = S1->getLHS(); 11867 11868 auto *Then = S2->getThen(); 11869 if (auto *ThenCS = dyn_cast<CompoundStmt>(Then)) { 11870 if (ThenCS->body_empty()) { 11871 ErrorInfo.Error = ErrorTy::NoStmt; 11872 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = ThenCS->getBeginLoc(); 11873 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = ThenCS->getSourceRange(); 11874 return false; 11875 } 11876 if (ThenCS->size() > 1) { 11877 ErrorInfo.Error = ErrorTy::MoreThanOneStmt; 11878 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = ThenCS->getBeginLoc(); 11879 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = ThenCS->getSourceRange(); 11880 return false; 11881 } 11882 Then = ThenCS->body_front(); 11883 } 11884 11885 auto *ThenBO = dyn_cast<BinaryOperator>(Then); 11886 if (!ThenBO) { 11887 ErrorInfo.Error = ErrorTy::NotAnAssignment; 11888 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = S2->getBeginLoc(); 11889 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = S2->getSourceRange(); 11890 return false; 11891 } 11892 if (ThenBO->getOpcode() != BO_Assign) { 11893 ErrorInfo.Error = ErrorTy::NotAnAssignment; 11894 ErrorInfo.ErrorLoc = ThenBO->getExprLoc(); 11895 ErrorInfo.NoteLoc = ThenBO->getOperatorLoc(); 11896 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = ThenBO->getSourceRange(); 11897 return false; 11898 } 11899 11900 X = ThenBO->getLHS(); 11901 D = ThenBO->getRHS(); 11902 11903 auto *BO = cast<BinaryOperator>(S1->getRHS()->IgnoreImpCasts()); 11904 if (BO->getOpcode() != BO_EQ) { 11905 ErrorInfo.Error = ErrorTy::NotEQ; 11906 ErrorInfo.ErrorLoc = BO->getExprLoc(); 11907 ErrorInfo.NoteLoc = BO->getOperatorLoc(); 11908 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = BO->getSourceRange(); 11909 return false; 11910 } 11911 11912 C = BO; 11913 11914 if (checkIfTwoExprsAreSame(ContextRef, X, BO->getLHS())) { 11915 E = BO->getRHS(); 11916 } else if (checkIfTwoExprsAreSame(ContextRef, X, BO->getRHS())) { 11917 E = BO->getLHS(); 11918 } else { 11919 ErrorInfo.Error = ErrorTy::InvalidComparison; 11920 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = BO->getExprLoc(); 11921 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = BO->getSourceRange(); 11922 return false; 11923 } 11924 11925 if (S2->getElse()) { 11926 IsFailOnly = true; 11927 11928 auto *Else = S2->getElse(); 11929 if (auto *ElseCS = dyn_cast<CompoundStmt>(Else)) { 11930 if (ElseCS->body_empty()) { 11931 ErrorInfo.Error = ErrorTy::NoStmt; 11932 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = ElseCS->getBeginLoc(); 11933 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = ElseCS->getSourceRange(); 11934 return false; 11935 } 11936 if (ElseCS->size() > 1) { 11937 ErrorInfo.Error = ErrorTy::MoreThanOneStmt; 11938 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = ElseCS->getBeginLoc(); 11939 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = ElseCS->getSourceRange(); 11940 return false; 11941 } 11942 Else = ElseCS->body_front(); 11943 } 11944 11945 auto *ElseBO = dyn_cast<BinaryOperator>(Else); 11946 if (!ElseBO) { 11947 ErrorInfo.Error = ErrorTy::NotAnAssignment; 11948 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = Else->getBeginLoc(); 11949 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = Else->getSourceRange(); 11950 return false; 11951 } 11952 if (ElseBO->getOpcode() != BO_Assign) { 11953 ErrorInfo.Error = ErrorTy::NotAnAssignment; 11954 ErrorInfo.ErrorLoc = ElseBO->getExprLoc(); 11955 ErrorInfo.NoteLoc = ElseBO->getOperatorLoc(); 11956 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = ElseBO->getSourceRange(); 11957 return false; 11958 } 11959 if (!checkIfTwoExprsAreSame(ContextRef, X, ElseBO->getRHS())) { 11960 ErrorInfo.Error = ErrorTy::InvalidAssignment; 11961 ErrorInfo.ErrorLoc = ElseBO->getRHS()->getExprLoc(); 11962 ErrorInfo.NoteLoc = X->getExprLoc(); 11963 ErrorInfo.ErrorRange = ElseBO->getRHS()->getSourceRange(); 11964 ErrorInfo.NoteRange = X->getSourceRange(); 11965 return false; 11966 } 11967 11968 V = ElseBO->getLHS(); 11969 } 11970 11971 return checkType(ErrorInfo); 11972 } 11973 11974 bool OpenMPAtomicCompareCaptureChecker::checkStmt(Stmt *S, 11975 ErrorInfoTy &ErrorInfo) { 11976 // if(x == e) { x = d; } else { v = x; } 11977 if (auto *IS = dyn_cast<IfStmt>(S)) 11978 return checkForm3(IS, ErrorInfo); 11979 11980 auto *CS = dyn_cast<CompoundStmt>(S); 11981 if (!CS) { 11982 ErrorInfo.Error = ErrorTy::NotCompoundStmt; 11983 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = S->getBeginLoc(); 11984 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = S->getSourceRange(); 11985 return false; 11986 } 11987 if (CS->body_empty()) { 11988 ErrorInfo.Error = ErrorTy::NoStmt; 11989 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = CS->getBeginLoc(); 11990 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = CS->getSourceRange(); 11991 return false; 11992 } 11993 11994 // { if(x == e) { x = d; } else { v = x; } } 11995 if (CS->size() == 1) { 11996 auto *IS = dyn_cast<IfStmt>(CS->body_front()); 11997 if (!IS) { 11998 ErrorInfo.Error = ErrorTy::NotIfStmt; 11999 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = CS->body_front()->getBeginLoc(); 12000 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = 12001 CS->body_front()->getSourceRange(); 12002 return false; 12003 } 12004 12005 return checkForm3(IS, ErrorInfo); 12006 } else if (CS->size() == 2) { 12007 auto *S1 = CS->body_front(); 12008 auto *S2 = CS->body_back(); 12009 12010 Stmt *UpdateStmt = nullptr; 12011 Stmt *CondUpdateStmt = nullptr; 12012 12013 if (auto *BO = dyn_cast<BinaryOperator>(S1)) { 12014 // { v = x; cond-update-stmt } or form 45. 12015 UpdateStmt = S1; 12016 CondUpdateStmt = S2; 12017 // Check if form 45. 12018 if (isa<BinaryOperator>(BO->getRHS()->IgnoreImpCasts()) && 12019 isa<IfStmt>(S2)) 12020 return checkForm45(CS, ErrorInfo); 12021 // It cannot be set before we the check for form45. 12022 IsPostfixUpdate = true; 12023 } else { 12024 // { cond-update-stmt v = x; } 12025 UpdateStmt = S2; 12026 CondUpdateStmt = S1; 12027 } 12028 12029 auto CheckCondUpdateStmt = [this, &ErrorInfo](Stmt *CUS) { 12030 auto *IS = dyn_cast<IfStmt>(CUS); 12031 if (!IS) { 12032 ErrorInfo.Error = ErrorTy::NotIfStmt; 12033 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = CUS->getBeginLoc(); 12034 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = CUS->getSourceRange(); 12035 return false; 12036 } 12037 12038 if (!checkCondUpdateStmt(IS, ErrorInfo)) 12039 return false; 12040 12041 return true; 12042 }; 12043 12044 // CheckUpdateStmt has to be called *after* CheckCondUpdateStmt. 12045 auto CheckUpdateStmt = [this, &ErrorInfo](Stmt *US) { 12046 auto *BO = dyn_cast<BinaryOperator>(US); 12047 if (!BO) { 12048 ErrorInfo.Error = ErrorTy::NotAnAssignment; 12049 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = US->getBeginLoc(); 12050 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = US->getSourceRange(); 12051 return false; 12052 } 12053 if (BO->getOpcode() != BO_Assign) { 12054 ErrorInfo.Error = ErrorTy::NotAnAssignment; 12055 ErrorInfo.ErrorLoc = BO->getExprLoc(); 12056 ErrorInfo.NoteLoc = BO->getOperatorLoc(); 12057 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = BO->getSourceRange(); 12058 return false; 12059 } 12060 if (!checkIfTwoExprsAreSame(ContextRef, this->X, BO->getRHS())) { 12061 ErrorInfo.Error = ErrorTy::InvalidAssignment; 12062 ErrorInfo.ErrorLoc = BO->getRHS()->getExprLoc(); 12063 ErrorInfo.NoteLoc = this->X->getExprLoc(); 12064 ErrorInfo.ErrorRange = BO->getRHS()->getSourceRange(); 12065 ErrorInfo.NoteRange = this->X->getSourceRange(); 12066 return false; 12067 } 12068 12069 this->V = BO->getLHS(); 12070 12071 return true; 12072 }; 12073 12074 if (!CheckCondUpdateStmt(CondUpdateStmt)) 12075 return false; 12076 if (!CheckUpdateStmt(UpdateStmt)) 12077 return false; 12078 } else { 12079 ErrorInfo.Error = ErrorTy::MoreThanTwoStmts; 12080 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = CS->getBeginLoc(); 12081 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = CS->getSourceRange(); 12082 return false; 12083 } 12084 12085 return checkType(ErrorInfo); 12086 } 12087 } // namespace 12088 12089 StmtResult Sema::ActOnOpenMPAtomicDirective(ArrayRef<OMPClause *> Clauses, 12090 Stmt *AStmt, 12091 SourceLocation StartLoc, 12092 SourceLocation EndLoc) { 12093 // Register location of the first atomic directive. 12094 DSAStack->addAtomicDirectiveLoc(StartLoc); 12095 if (!AStmt) 12096 return StmtError(); 12097 12098 // 1.2.2 OpenMP Language Terminology 12099 // Structured block - An executable statement with a single entry at the 12100 // top and a single exit at the bottom. 12101 // The point of exit cannot be a branch out of the structured block. 12102 // longjmp() and throw() must not violate the entry/exit criteria. 12103 OpenMPClauseKind AtomicKind = OMPC_unknown; 12104 SourceLocation AtomicKindLoc; 12105 OpenMPClauseKind MemOrderKind = OMPC_unknown; 12106 SourceLocation MemOrderLoc; 12107 bool MutexClauseEncountered = false; 12108 llvm::SmallSet<OpenMPClauseKind, 2> EncounteredAtomicKinds; 12109 for (const OMPClause *C : Clauses) { 12110 switch (C->getClauseKind()) { 12111 case OMPC_read: 12112 case OMPC_write: 12113 case OMPC_update: 12114 MutexClauseEncountered = true; 12115 LLVM_FALLTHROUGH; 12116 case OMPC_capture: 12117 case OMPC_compare: { 12118 if (AtomicKind != OMPC_unknown && MutexClauseEncountered) { 12119 Diag(C->getBeginLoc(), diag::err_omp_atomic_several_clauses) 12120 << SourceRange(C->getBeginLoc(), C->getEndLoc()); 12121 Diag(AtomicKindLoc, diag::note_omp_previous_mem_order_clause) 12122 << getOpenMPClauseName(AtomicKind); 12123 } else { 12124 AtomicKind = C->getClauseKind(); 12125 AtomicKindLoc = C->getBeginLoc(); 12126 if (!EncounteredAtomicKinds.insert(C->getClauseKind()).second) { 12127 Diag(C->getBeginLoc(), diag::err_omp_atomic_several_clauses) 12128 << SourceRange(C->getBeginLoc(), C->getEndLoc()); 12129 Diag(AtomicKindLoc, diag::note_omp_previous_mem_order_clause) 12130 << getOpenMPClauseName(AtomicKind); 12131 } 12132 } 12133 break; 12134 } 12135 case OMPC_seq_cst: 12136 case OMPC_acq_rel: 12137 case OMPC_acquire: 12138 case OMPC_release: 12139 case OMPC_relaxed: { 12140 if (MemOrderKind != OMPC_unknown) { 12141 Diag(C->getBeginLoc(), diag::err_omp_several_mem_order_clauses) 12142 << getOpenMPDirectiveName(OMPD_atomic) << 0 12143 << SourceRange(C->getBeginLoc(), C->getEndLoc()); 12144 Diag(MemOrderLoc, diag::note_omp_previous_mem_order_clause) 12145 << getOpenMPClauseName(MemOrderKind); 12146 } else { 12147 MemOrderKind = C->getClauseKind(); 12148 MemOrderLoc = C->getBeginLoc(); 12149 } 12150 break; 12151 } 12152 // The following clauses are allowed, but we don't need to do anything here. 12153 case OMPC_hint: 12154 break; 12155 default: 12156 llvm_unreachable("unknown clause is encountered"); 12157 } 12158 } 12159 bool IsCompareCapture = false; 12160 if (EncounteredAtomicKinds.contains(OMPC_compare) && 12161 EncounteredAtomicKinds.contains(OMPC_capture)) { 12162 IsCompareCapture = true; 12163 AtomicKind = OMPC_compare; 12164 } 12165 // OpenMP 5.0, 2.17.7 atomic Construct, Restrictions 12166 // If atomic-clause is read then memory-order-clause must not be acq_rel or 12167 // release. 12168 // If atomic-clause is write then memory-order-clause must not be acq_rel or 12169 // acquire. 12170 // If atomic-clause is update or not present then memory-order-clause must not 12171 // be acq_rel or acquire. 12172 if ((AtomicKind == OMPC_read && 12173 (MemOrderKind == OMPC_acq_rel || MemOrderKind == OMPC_release)) || 12174 ((AtomicKind == OMPC_write || AtomicKind == OMPC_update || 12175 AtomicKind == OMPC_unknown) && 12176 (MemOrderKind == OMPC_acq_rel || MemOrderKind == OMPC_acquire))) { 12177 SourceLocation Loc = AtomicKindLoc; 12178 if (AtomicKind == OMPC_unknown) 12179 Loc = StartLoc; 12180 Diag(Loc, diag::err_omp_atomic_incompatible_mem_order_clause) 12181 << getOpenMPClauseName(AtomicKind) 12182 << (AtomicKind == OMPC_unknown ? 1 : 0) 12183 << getOpenMPClauseName(MemOrderKind); 12184 Diag(MemOrderLoc, diag::note_omp_previous_mem_order_clause) 12185 << getOpenMPClauseName(MemOrderKind); 12186 } 12187 12188 Stmt *Body = AStmt; 12189 if (auto *EWC = dyn_cast<ExprWithCleanups>(Body)) 12190 Body = EWC->getSubExpr(); 12191 12192 Expr *X = nullptr; 12193 Expr *V = nullptr; 12194 Expr *E = nullptr; 12195 Expr *UE = nullptr; 12196 Expr *D = nullptr; 12197 Expr *CE = nullptr; 12198 Expr *R = nullptr; 12199 bool IsXLHSInRHSPart = false; 12200 bool IsPostfixUpdate = false; 12201 bool IsFailOnly = false; 12202 // OpenMP [2.12.6, atomic Construct] 12203 // In the next expressions: 12204 // * x and v (as applicable) are both l-value expressions with scalar type. 12205 // * During the execution of an atomic region, multiple syntactic 12206 // occurrences of x must designate the same storage location. 12207 // * Neither of v and expr (as applicable) may access the storage location 12208 // designated by x. 12209 // * Neither of x and expr (as applicable) may access the storage location 12210 // designated by v. 12211 // * expr is an expression with scalar type. 12212 // * binop is one of +, *, -, /, &, ^, |, <<, or >>. 12213 // * binop, binop=, ++, and -- are not overloaded operators. 12214 // * The expression x binop expr must be numerically equivalent to x binop 12215 // (expr). This requirement is satisfied if the operators in expr have 12216 // precedence greater than binop, or by using parentheses around expr or 12217 // subexpressions of expr. 12218 // * The expression expr binop x must be numerically equivalent to (expr) 12219 // binop x. This requirement is satisfied if the operators in expr have 12220 // precedence equal to or greater than binop, or by using parentheses around 12221 // expr or subexpressions of expr. 12222 // * For forms that allow multiple occurrences of x, the number of times 12223 // that x is evaluated is unspecified. 12224 if (AtomicKind == OMPC_read) { 12225 enum { 12226 NotAnExpression, 12227 NotAnAssignmentOp, 12228 NotAScalarType, 12229 NotAnLValue, 12230 NoError 12231 } ErrorFound = NoError; 12232 SourceLocation ErrorLoc, NoteLoc; 12233 SourceRange ErrorRange, NoteRange; 12234 // If clause is read: 12235 // v = x; 12236 if (const auto *AtomicBody = dyn_cast<Expr>(Body)) { 12237 const auto *AtomicBinOp = 12238 dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts()); 12239 if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) { 12240 X = AtomicBinOp->getRHS()->IgnoreParenImpCasts(); 12241 V = AtomicBinOp->getLHS()->IgnoreParenImpCasts(); 12242 if ((X->isInstantiationDependent() || X->getType()->isScalarType()) && 12243 (V->isInstantiationDependent() || V->getType()->isScalarType())) { 12244 if (!X->isLValue() || !V->isLValue()) { 12245 const Expr *NotLValueExpr = X->isLValue() ? V : X; 12246 ErrorFound = NotAnLValue; 12247 ErrorLoc = AtomicBinOp->getExprLoc(); 12248 ErrorRange = AtomicBinOp->getSourceRange(); 12249 NoteLoc = NotLValueExpr->getExprLoc(); 12250 NoteRange = NotLValueExpr->getSourceRange(); 12251 } 12252 } else if (!X->isInstantiationDependent() || 12253 !V->isInstantiationDependent()) { 12254 const Expr *NotScalarExpr = 12255 (X->isInstantiationDependent() || X->getType()->isScalarType()) 12256 ? V 12257 : X; 12258 ErrorFound = NotAScalarType; 12259 ErrorLoc = AtomicBinOp->getExprLoc(); 12260 ErrorRange = AtomicBinOp->getSourceRange(); 12261 NoteLoc = NotScalarExpr->getExprLoc(); 12262 NoteRange = NotScalarExpr->getSourceRange(); 12263 } 12264 } else if (!AtomicBody->isInstantiationDependent()) { 12265 ErrorFound = NotAnAssignmentOp; 12266 ErrorLoc = AtomicBody->getExprLoc(); 12267 ErrorRange = AtomicBody->getSourceRange(); 12268 NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc() 12269 : AtomicBody->getExprLoc(); 12270 NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange() 12271 : AtomicBody->getSourceRange(); 12272 } 12273 } else { 12274 ErrorFound = NotAnExpression; 12275 NoteLoc = ErrorLoc = Body->getBeginLoc(); 12276 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc); 12277 } 12278 if (ErrorFound != NoError) { 12279 Diag(ErrorLoc, diag::err_omp_atomic_read_not_expression_statement) 12280 << ErrorRange; 12281 Diag(NoteLoc, diag::note_omp_atomic_read_write) 12282 << ErrorFound << NoteRange; 12283 return StmtError(); 12284 } 12285 if (CurContext->isDependentContext()) 12286 V = X = nullptr; 12287 } else if (AtomicKind == OMPC_write) { 12288 enum { 12289 NotAnExpression, 12290 NotAnAssignmentOp, 12291 NotAScalarType, 12292 NotAnLValue, 12293 NoError 12294 } ErrorFound = NoError; 12295 SourceLocation ErrorLoc, NoteLoc; 12296 SourceRange ErrorRange, NoteRange; 12297 // If clause is write: 12298 // x = expr; 12299 if (const auto *AtomicBody = dyn_cast<Expr>(Body)) { 12300 const auto *AtomicBinOp = 12301 dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts()); 12302 if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) { 12303 X = AtomicBinOp->getLHS(); 12304 E = AtomicBinOp->getRHS(); 12305 if ((X->isInstantiationDependent() || X->getType()->isScalarType()) && 12306 (E->isInstantiationDependent() || E->getType()->isScalarType())) { 12307 if (!X->isLValue()) { 12308 ErrorFound = NotAnLValue; 12309 ErrorLoc = AtomicBinOp->getExprLoc(); 12310 ErrorRange = AtomicBinOp->getSourceRange(); 12311 NoteLoc = X->getExprLoc(); 12312 NoteRange = X->getSourceRange(); 12313 } 12314 } else if (!X->isInstantiationDependent() || 12315 !E->isInstantiationDependent()) { 12316 const Expr *NotScalarExpr = 12317 (X->isInstantiationDependent() || X->getType()->isScalarType()) 12318 ? E 12319 : X; 12320 ErrorFound = NotAScalarType; 12321 ErrorLoc = AtomicBinOp->getExprLoc(); 12322 ErrorRange = AtomicBinOp->getSourceRange(); 12323 NoteLoc = NotScalarExpr->getExprLoc(); 12324 NoteRange = NotScalarExpr->getSourceRange(); 12325 } 12326 } else if (!AtomicBody->isInstantiationDependent()) { 12327 ErrorFound = NotAnAssignmentOp; 12328 ErrorLoc = AtomicBody->getExprLoc(); 12329 ErrorRange = AtomicBody->getSourceRange(); 12330 NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc() 12331 : AtomicBody->getExprLoc(); 12332 NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange() 12333 : AtomicBody->getSourceRange(); 12334 } 12335 } else { 12336 ErrorFound = NotAnExpression; 12337 NoteLoc = ErrorLoc = Body->getBeginLoc(); 12338 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc); 12339 } 12340 if (ErrorFound != NoError) { 12341 Diag(ErrorLoc, diag::err_omp_atomic_write_not_expression_statement) 12342 << ErrorRange; 12343 Diag(NoteLoc, diag::note_omp_atomic_read_write) 12344 << ErrorFound << NoteRange; 12345 return StmtError(); 12346 } 12347 if (CurContext->isDependentContext()) 12348 E = X = nullptr; 12349 } else if (AtomicKind == OMPC_update || AtomicKind == OMPC_unknown) { 12350 // If clause is update: 12351 // x++; 12352 // x--; 12353 // ++x; 12354 // --x; 12355 // x binop= expr; 12356 // x = x binop expr; 12357 // x = expr binop x; 12358 OpenMPAtomicUpdateChecker Checker(*this); 12359 if (Checker.checkStatement( 12360 Body, 12361 (AtomicKind == OMPC_update) 12362 ? diag::err_omp_atomic_update_not_expression_statement 12363 : diag::err_omp_atomic_not_expression_statement, 12364 diag::note_omp_atomic_update)) 12365 return StmtError(); 12366 if (!CurContext->isDependentContext()) { 12367 E = Checker.getExpr(); 12368 X = Checker.getX(); 12369 UE = Checker.getUpdateExpr(); 12370 IsXLHSInRHSPart = Checker.isXLHSInRHSPart(); 12371 } 12372 } else if (AtomicKind == OMPC_capture) { 12373 enum { 12374 NotAnAssignmentOp, 12375 NotACompoundStatement, 12376 NotTwoSubstatements, 12377 NotASpecificExpression, 12378 NoError 12379 } ErrorFound = NoError; 12380 SourceLocation ErrorLoc, NoteLoc; 12381 SourceRange ErrorRange, NoteRange; 12382 if (const auto *AtomicBody = dyn_cast<Expr>(Body)) { 12383 // If clause is a capture: 12384 // v = x++; 12385 // v = x--; 12386 // v = ++x; 12387 // v = --x; 12388 // v = x binop= expr; 12389 // v = x = x binop expr; 12390 // v = x = expr binop x; 12391 const auto *AtomicBinOp = 12392 dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts()); 12393 if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) { 12394 V = AtomicBinOp->getLHS(); 12395 Body = AtomicBinOp->getRHS()->IgnoreParenImpCasts(); 12396 OpenMPAtomicUpdateChecker Checker(*this); 12397 if (Checker.checkStatement( 12398 Body, diag::err_omp_atomic_capture_not_expression_statement, 12399 diag::note_omp_atomic_update)) 12400 return StmtError(); 12401 E = Checker.getExpr(); 12402 X = Checker.getX(); 12403 UE = Checker.getUpdateExpr(); 12404 IsXLHSInRHSPart = Checker.isXLHSInRHSPart(); 12405 IsPostfixUpdate = Checker.isPostfixUpdate(); 12406 } else if (!AtomicBody->isInstantiationDependent()) { 12407 ErrorLoc = AtomicBody->getExprLoc(); 12408 ErrorRange = AtomicBody->getSourceRange(); 12409 NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc() 12410 : AtomicBody->getExprLoc(); 12411 NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange() 12412 : AtomicBody->getSourceRange(); 12413 ErrorFound = NotAnAssignmentOp; 12414 } 12415 if (ErrorFound != NoError) { 12416 Diag(ErrorLoc, diag::err_omp_atomic_capture_not_expression_statement) 12417 << ErrorRange; 12418 Diag(NoteLoc, diag::note_omp_atomic_capture) << ErrorFound << NoteRange; 12419 return StmtError(); 12420 } 12421 if (CurContext->isDependentContext()) 12422 UE = V = E = X = nullptr; 12423 } else { 12424 // If clause is a capture: 12425 // { v = x; x = expr; } 12426 // { v = x; x++; } 12427 // { v = x; x--; } 12428 // { v = x; ++x; } 12429 // { v = x; --x; } 12430 // { v = x; x binop= expr; } 12431 // { v = x; x = x binop expr; } 12432 // { v = x; x = expr binop x; } 12433 // { x++; v = x; } 12434 // { x--; v = x; } 12435 // { ++x; v = x; } 12436 // { --x; v = x; } 12437 // { x binop= expr; v = x; } 12438 // { x = x binop expr; v = x; } 12439 // { x = expr binop x; v = x; } 12440 if (auto *CS = dyn_cast<CompoundStmt>(Body)) { 12441 // Check that this is { expr1; expr2; } 12442 if (CS->size() == 2) { 12443 Stmt *First = CS->body_front(); 12444 Stmt *Second = CS->body_back(); 12445 if (auto *EWC = dyn_cast<ExprWithCleanups>(First)) 12446 First = EWC->getSubExpr()->IgnoreParenImpCasts(); 12447 if (auto *EWC = dyn_cast<ExprWithCleanups>(Second)) 12448 Second = EWC->getSubExpr()->IgnoreParenImpCasts(); 12449 // Need to find what subexpression is 'v' and what is 'x'. 12450 OpenMPAtomicUpdateChecker Checker(*this); 12451 bool IsUpdateExprFound = !Checker.checkStatement(Second); 12452 BinaryOperator *BinOp = nullptr; 12453 if (IsUpdateExprFound) { 12454 BinOp = dyn_cast<BinaryOperator>(First); 12455 IsUpdateExprFound = BinOp && BinOp->getOpcode() == BO_Assign; 12456 } 12457 if (IsUpdateExprFound && !CurContext->isDependentContext()) { 12458 // { v = x; x++; } 12459 // { v = x; x--; } 12460 // { v = x; ++x; } 12461 // { v = x; --x; } 12462 // { v = x; x binop= expr; } 12463 // { v = x; x = x binop expr; } 12464 // { v = x; x = expr binop x; } 12465 // Check that the first expression has form v = x. 12466 Expr *PossibleX = BinOp->getRHS()->IgnoreParenImpCasts(); 12467 llvm::FoldingSetNodeID XId, PossibleXId; 12468 Checker.getX()->Profile(XId, Context, /*Canonical=*/true); 12469 PossibleX->Profile(PossibleXId, Context, /*Canonical=*/true); 12470 IsUpdateExprFound = XId == PossibleXId; 12471 if (IsUpdateExprFound) { 12472 V = BinOp->getLHS(); 12473 X = Checker.getX(); 12474 E = Checker.getExpr(); 12475 UE = Checker.getUpdateExpr(); 12476 IsXLHSInRHSPart = Checker.isXLHSInRHSPart(); 12477 IsPostfixUpdate = true; 12478 } 12479 } 12480 if (!IsUpdateExprFound) { 12481 IsUpdateExprFound = !Checker.checkStatement(First); 12482 BinOp = nullptr; 12483 if (IsUpdateExprFound) { 12484 BinOp = dyn_cast<BinaryOperator>(Second); 12485 IsUpdateExprFound = BinOp && BinOp->getOpcode() == BO_Assign; 12486 } 12487 if (IsUpdateExprFound && !CurContext->isDependentContext()) { 12488 // { x++; v = x; } 12489 // { x--; v = x; } 12490 // { ++x; v = x; } 12491 // { --x; v = x; } 12492 // { x binop= expr; v = x; } 12493 // { x = x binop expr; v = x; } 12494 // { x = expr binop x; v = x; } 12495 // Check that the second expression has form v = x. 12496 Expr *PossibleX = BinOp->getRHS()->IgnoreParenImpCasts(); 12497 llvm::FoldingSetNodeID XId, PossibleXId; 12498 Checker.getX()->Profile(XId, Context, /*Canonical=*/true); 12499 PossibleX->Profile(PossibleXId, Context, /*Canonical=*/true); 12500 IsUpdateExprFound = XId == PossibleXId; 12501 if (IsUpdateExprFound) { 12502 V = BinOp->getLHS(); 12503 X = Checker.getX(); 12504 E = Checker.getExpr(); 12505 UE = Checker.getUpdateExpr(); 12506 IsXLHSInRHSPart = Checker.isXLHSInRHSPart(); 12507 IsPostfixUpdate = false; 12508 } 12509 } 12510 } 12511 if (!IsUpdateExprFound) { 12512 // { v = x; x = expr; } 12513 auto *FirstExpr = dyn_cast<Expr>(First); 12514 auto *SecondExpr = dyn_cast<Expr>(Second); 12515 if (!FirstExpr || !SecondExpr || 12516 !(FirstExpr->isInstantiationDependent() || 12517 SecondExpr->isInstantiationDependent())) { 12518 auto *FirstBinOp = dyn_cast<BinaryOperator>(First); 12519 if (!FirstBinOp || FirstBinOp->getOpcode() != BO_Assign) { 12520 ErrorFound = NotAnAssignmentOp; 12521 NoteLoc = ErrorLoc = FirstBinOp ? FirstBinOp->getOperatorLoc() 12522 : First->getBeginLoc(); 12523 NoteRange = ErrorRange = FirstBinOp 12524 ? FirstBinOp->getSourceRange() 12525 : SourceRange(ErrorLoc, ErrorLoc); 12526 } else { 12527 auto *SecondBinOp = dyn_cast<BinaryOperator>(Second); 12528 if (!SecondBinOp || SecondBinOp->getOpcode() != BO_Assign) { 12529 ErrorFound = NotAnAssignmentOp; 12530 NoteLoc = ErrorLoc = SecondBinOp 12531 ? SecondBinOp->getOperatorLoc() 12532 : Second->getBeginLoc(); 12533 NoteRange = ErrorRange = 12534 SecondBinOp ? SecondBinOp->getSourceRange() 12535 : SourceRange(ErrorLoc, ErrorLoc); 12536 } else { 12537 Expr *PossibleXRHSInFirst = 12538 FirstBinOp->getRHS()->IgnoreParenImpCasts(); 12539 Expr *PossibleXLHSInSecond = 12540 SecondBinOp->getLHS()->IgnoreParenImpCasts(); 12541 llvm::FoldingSetNodeID X1Id, X2Id; 12542 PossibleXRHSInFirst->Profile(X1Id, Context, 12543 /*Canonical=*/true); 12544 PossibleXLHSInSecond->Profile(X2Id, Context, 12545 /*Canonical=*/true); 12546 IsUpdateExprFound = X1Id == X2Id; 12547 if (IsUpdateExprFound) { 12548 V = FirstBinOp->getLHS(); 12549 X = SecondBinOp->getLHS(); 12550 E = SecondBinOp->getRHS(); 12551 UE = nullptr; 12552 IsXLHSInRHSPart = false; 12553 IsPostfixUpdate = true; 12554 } else { 12555 ErrorFound = NotASpecificExpression; 12556 ErrorLoc = FirstBinOp->getExprLoc(); 12557 ErrorRange = FirstBinOp->getSourceRange(); 12558 NoteLoc = SecondBinOp->getLHS()->getExprLoc(); 12559 NoteRange = SecondBinOp->getRHS()->getSourceRange(); 12560 } 12561 } 12562 } 12563 } 12564 } 12565 } else { 12566 NoteLoc = ErrorLoc = Body->getBeginLoc(); 12567 NoteRange = ErrorRange = 12568 SourceRange(Body->getBeginLoc(), Body->getBeginLoc()); 12569 ErrorFound = NotTwoSubstatements; 12570 } 12571 } else { 12572 NoteLoc = ErrorLoc = Body->getBeginLoc(); 12573 NoteRange = ErrorRange = 12574 SourceRange(Body->getBeginLoc(), Body->getBeginLoc()); 12575 ErrorFound = NotACompoundStatement; 12576 } 12577 } 12578 if (ErrorFound != NoError) { 12579 Diag(ErrorLoc, diag::err_omp_atomic_capture_not_compound_statement) 12580 << ErrorRange; 12581 Diag(NoteLoc, diag::note_omp_atomic_capture) << ErrorFound << NoteRange; 12582 return StmtError(); 12583 } 12584 if (CurContext->isDependentContext()) 12585 UE = V = E = X = nullptr; 12586 } else if (AtomicKind == OMPC_compare) { 12587 if (IsCompareCapture) { 12588 OpenMPAtomicCompareCaptureChecker::ErrorInfoTy ErrorInfo; 12589 OpenMPAtomicCompareCaptureChecker Checker(*this); 12590 if (!Checker.checkStmt(Body, ErrorInfo)) { 12591 Diag(ErrorInfo.ErrorLoc, diag::err_omp_atomic_compare_capture) 12592 << ErrorInfo.ErrorRange; 12593 Diag(ErrorInfo.NoteLoc, diag::note_omp_atomic_compare) 12594 << ErrorInfo.Error << ErrorInfo.NoteRange; 12595 return StmtError(); 12596 } 12597 X = Checker.getX(); 12598 E = Checker.getE(); 12599 D = Checker.getD(); 12600 CE = Checker.getCond(); 12601 V = Checker.getV(); 12602 R = Checker.getR(); 12603 // We reuse IsXLHSInRHSPart to tell if it is in the form 'x ordop expr'. 12604 IsXLHSInRHSPart = Checker.isXBinopExpr(); 12605 IsFailOnly = Checker.isFailOnly(); 12606 IsPostfixUpdate = Checker.isPostfixUpdate(); 12607 } else { 12608 OpenMPAtomicCompareChecker::ErrorInfoTy ErrorInfo; 12609 OpenMPAtomicCompareChecker Checker(*this); 12610 if (!Checker.checkStmt(Body, ErrorInfo)) { 12611 Diag(ErrorInfo.ErrorLoc, diag::err_omp_atomic_compare) 12612 << ErrorInfo.ErrorRange; 12613 Diag(ErrorInfo.NoteLoc, diag::note_omp_atomic_compare) 12614 << ErrorInfo.Error << ErrorInfo.NoteRange; 12615 return StmtError(); 12616 } 12617 X = Checker.getX(); 12618 E = Checker.getE(); 12619 D = Checker.getD(); 12620 CE = Checker.getCond(); 12621 // We reuse IsXLHSInRHSPart to tell if it is in the form 'x ordop expr'. 12622 IsXLHSInRHSPart = Checker.isXBinopExpr(); 12623 } 12624 } 12625 12626 setFunctionHasBranchProtectedScope(); 12627 12628 return OMPAtomicDirective::Create( 12629 Context, StartLoc, EndLoc, Clauses, AStmt, 12630 {X, V, R, E, UE, D, CE, IsXLHSInRHSPart, IsPostfixUpdate, IsFailOnly}); 12631 } 12632 12633 StmtResult Sema::ActOnOpenMPTargetDirective(ArrayRef<OMPClause *> Clauses, 12634 Stmt *AStmt, 12635 SourceLocation StartLoc, 12636 SourceLocation EndLoc) { 12637 if (!AStmt) 12638 return StmtError(); 12639 12640 auto *CS = cast<CapturedStmt>(AStmt); 12641 // 1.2.2 OpenMP Language Terminology 12642 // Structured block - An executable statement with a single entry at the 12643 // top and a single exit at the bottom. 12644 // The point of exit cannot be a branch out of the structured block. 12645 // longjmp() and throw() must not violate the entry/exit criteria. 12646 CS->getCapturedDecl()->setNothrow(); 12647 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target); 12648 ThisCaptureLevel > 1; --ThisCaptureLevel) { 12649 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 12650 // 1.2.2 OpenMP Language Terminology 12651 // Structured block - An executable statement with a single entry at the 12652 // top and a single exit at the bottom. 12653 // The point of exit cannot be a branch out of the structured block. 12654 // longjmp() and throw() must not violate the entry/exit criteria. 12655 CS->getCapturedDecl()->setNothrow(); 12656 } 12657 12658 // OpenMP [2.16, Nesting of Regions] 12659 // If specified, a teams construct must be contained within a target 12660 // construct. That target construct must contain no statements or directives 12661 // outside of the teams construct. 12662 if (DSAStack->hasInnerTeamsRegion()) { 12663 const Stmt *S = CS->IgnoreContainers(/*IgnoreCaptured=*/true); 12664 bool OMPTeamsFound = true; 12665 if (const auto *CS = dyn_cast<CompoundStmt>(S)) { 12666 auto I = CS->body_begin(); 12667 while (I != CS->body_end()) { 12668 const auto *OED = dyn_cast<OMPExecutableDirective>(*I); 12669 if (!OED || !isOpenMPTeamsDirective(OED->getDirectiveKind()) || 12670 OMPTeamsFound) { 12671 12672 OMPTeamsFound = false; 12673 break; 12674 } 12675 ++I; 12676 } 12677 assert(I != CS->body_end() && "Not found statement"); 12678 S = *I; 12679 } else { 12680 const auto *OED = dyn_cast<OMPExecutableDirective>(S); 12681 OMPTeamsFound = OED && isOpenMPTeamsDirective(OED->getDirectiveKind()); 12682 } 12683 if (!OMPTeamsFound) { 12684 Diag(StartLoc, diag::err_omp_target_contains_not_only_teams); 12685 Diag(DSAStack->getInnerTeamsRegionLoc(), 12686 diag::note_omp_nested_teams_construct_here); 12687 Diag(S->getBeginLoc(), diag::note_omp_nested_statement_here) 12688 << isa<OMPExecutableDirective>(S); 12689 return StmtError(); 12690 } 12691 } 12692 12693 setFunctionHasBranchProtectedScope(); 12694 12695 return OMPTargetDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt); 12696 } 12697 12698 StmtResult 12699 Sema::ActOnOpenMPTargetParallelDirective(ArrayRef<OMPClause *> Clauses, 12700 Stmt *AStmt, SourceLocation StartLoc, 12701 SourceLocation EndLoc) { 12702 if (!AStmt) 12703 return StmtError(); 12704 12705 auto *CS = cast<CapturedStmt>(AStmt); 12706 // 1.2.2 OpenMP Language Terminology 12707 // Structured block - An executable statement with a single entry at the 12708 // top and a single exit at the bottom. 12709 // The point of exit cannot be a branch out of the structured block. 12710 // longjmp() and throw() must not violate the entry/exit criteria. 12711 CS->getCapturedDecl()->setNothrow(); 12712 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel); 12713 ThisCaptureLevel > 1; --ThisCaptureLevel) { 12714 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 12715 // 1.2.2 OpenMP Language Terminology 12716 // Structured block - An executable statement with a single entry at the 12717 // top and a single exit at the bottom. 12718 // The point of exit cannot be a branch out of the structured block. 12719 // longjmp() and throw() must not violate the entry/exit criteria. 12720 CS->getCapturedDecl()->setNothrow(); 12721 } 12722 12723 setFunctionHasBranchProtectedScope(); 12724 12725 return OMPTargetParallelDirective::Create( 12726 Context, StartLoc, EndLoc, Clauses, AStmt, 12727 DSAStack->getTaskgroupReductionRef(), DSAStack->isCancelRegion()); 12728 } 12729 12730 StmtResult Sema::ActOnOpenMPTargetParallelForDirective( 12731 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 12732 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 12733 if (!AStmt) 12734 return StmtError(); 12735 12736 auto *CS = cast<CapturedStmt>(AStmt); 12737 // 1.2.2 OpenMP Language Terminology 12738 // Structured block - An executable statement with a single entry at the 12739 // top and a single exit at the bottom. 12740 // The point of exit cannot be a branch out of the structured block. 12741 // longjmp() and throw() must not violate the entry/exit criteria. 12742 CS->getCapturedDecl()->setNothrow(); 12743 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel_for); 12744 ThisCaptureLevel > 1; --ThisCaptureLevel) { 12745 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 12746 // 1.2.2 OpenMP Language Terminology 12747 // Structured block - An executable statement with a single entry at the 12748 // top and a single exit at the bottom. 12749 // The point of exit cannot be a branch out of the structured block. 12750 // longjmp() and throw() must not violate the entry/exit criteria. 12751 CS->getCapturedDecl()->setNothrow(); 12752 } 12753 12754 OMPLoopBasedDirective::HelperExprs B; 12755 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 12756 // define the nested loops number. 12757 unsigned NestedLoopCount = 12758 checkOpenMPLoop(OMPD_target_parallel_for, getCollapseNumberExpr(Clauses), 12759 getOrderedNumberExpr(Clauses), CS, *this, *DSAStack, 12760 VarsWithImplicitDSA, B); 12761 if (NestedLoopCount == 0) 12762 return StmtError(); 12763 12764 assert((CurContext->isDependentContext() || B.builtAll()) && 12765 "omp target parallel for loop exprs were not built"); 12766 12767 if (!CurContext->isDependentContext()) { 12768 // Finalize the clauses that need pre-built expressions for CodeGen. 12769 for (OMPClause *C : Clauses) { 12770 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 12771 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 12772 B.NumIterations, *this, CurScope, 12773 DSAStack)) 12774 return StmtError(); 12775 } 12776 } 12777 12778 setFunctionHasBranchProtectedScope(); 12779 return OMPTargetParallelForDirective::Create( 12780 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B, 12781 DSAStack->getTaskgroupReductionRef(), DSAStack->isCancelRegion()); 12782 } 12783 12784 /// Check for existence of a map clause in the list of clauses. 12785 static bool hasClauses(ArrayRef<OMPClause *> Clauses, 12786 const OpenMPClauseKind K) { 12787 return llvm::any_of( 12788 Clauses, [K](const OMPClause *C) { return C->getClauseKind() == K; }); 12789 } 12790 12791 template <typename... Params> 12792 static bool hasClauses(ArrayRef<OMPClause *> Clauses, const OpenMPClauseKind K, 12793 const Params... ClauseTypes) { 12794 return hasClauses(Clauses, K) || hasClauses(Clauses, ClauseTypes...); 12795 } 12796 12797 /// Check if the variables in the mapping clause are externally visible. 12798 static bool isClauseMappable(ArrayRef<OMPClause *> Clauses) { 12799 for (const OMPClause *C : Clauses) { 12800 if (auto *TC = dyn_cast<OMPToClause>(C)) 12801 return llvm::all_of(TC->all_decls(), [](ValueDecl *VD) { 12802 return !VD || !VD->hasAttr<OMPDeclareTargetDeclAttr>() || 12803 (VD->isExternallyVisible() && 12804 VD->getVisibility() != HiddenVisibility); 12805 }); 12806 else if (auto *FC = dyn_cast<OMPFromClause>(C)) 12807 return llvm::all_of(FC->all_decls(), [](ValueDecl *VD) { 12808 return !VD || !VD->hasAttr<OMPDeclareTargetDeclAttr>() || 12809 (VD->isExternallyVisible() && 12810 VD->getVisibility() != HiddenVisibility); 12811 }); 12812 } 12813 12814 return true; 12815 } 12816 12817 StmtResult Sema::ActOnOpenMPTargetDataDirective(ArrayRef<OMPClause *> Clauses, 12818 Stmt *AStmt, 12819 SourceLocation StartLoc, 12820 SourceLocation EndLoc) { 12821 if (!AStmt) 12822 return StmtError(); 12823 12824 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 12825 12826 // OpenMP [2.12.2, target data Construct, Restrictions] 12827 // At least one map, use_device_addr or use_device_ptr clause must appear on 12828 // the directive. 12829 if (!hasClauses(Clauses, OMPC_map, OMPC_use_device_ptr) && 12830 (LangOpts.OpenMP < 50 || !hasClauses(Clauses, OMPC_use_device_addr))) { 12831 StringRef Expected; 12832 if (LangOpts.OpenMP < 50) 12833 Expected = "'map' or 'use_device_ptr'"; 12834 else 12835 Expected = "'map', 'use_device_ptr', or 'use_device_addr'"; 12836 Diag(StartLoc, diag::err_omp_no_clause_for_directive) 12837 << Expected << getOpenMPDirectiveName(OMPD_target_data); 12838 return StmtError(); 12839 } 12840 12841 setFunctionHasBranchProtectedScope(); 12842 12843 return OMPTargetDataDirective::Create(Context, StartLoc, EndLoc, Clauses, 12844 AStmt); 12845 } 12846 12847 StmtResult 12848 Sema::ActOnOpenMPTargetEnterDataDirective(ArrayRef<OMPClause *> Clauses, 12849 SourceLocation StartLoc, 12850 SourceLocation EndLoc, Stmt *AStmt) { 12851 if (!AStmt) 12852 return StmtError(); 12853 12854 auto *CS = cast<CapturedStmt>(AStmt); 12855 // 1.2.2 OpenMP Language Terminology 12856 // Structured block - An executable statement with a single entry at the 12857 // top and a single exit at the bottom. 12858 // The point of exit cannot be a branch out of the structured block. 12859 // longjmp() and throw() must not violate the entry/exit criteria. 12860 CS->getCapturedDecl()->setNothrow(); 12861 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_enter_data); 12862 ThisCaptureLevel > 1; --ThisCaptureLevel) { 12863 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 12864 // 1.2.2 OpenMP Language Terminology 12865 // Structured block - An executable statement with a single entry at the 12866 // top and a single exit at the bottom. 12867 // The point of exit cannot be a branch out of the structured block. 12868 // longjmp() and throw() must not violate the entry/exit criteria. 12869 CS->getCapturedDecl()->setNothrow(); 12870 } 12871 12872 // OpenMP [2.10.2, Restrictions, p. 99] 12873 // At least one map clause must appear on the directive. 12874 if (!hasClauses(Clauses, OMPC_map)) { 12875 Diag(StartLoc, diag::err_omp_no_clause_for_directive) 12876 << "'map'" << getOpenMPDirectiveName(OMPD_target_enter_data); 12877 return StmtError(); 12878 } 12879 12880 return OMPTargetEnterDataDirective::Create(Context, StartLoc, EndLoc, Clauses, 12881 AStmt); 12882 } 12883 12884 StmtResult 12885 Sema::ActOnOpenMPTargetExitDataDirective(ArrayRef<OMPClause *> Clauses, 12886 SourceLocation StartLoc, 12887 SourceLocation EndLoc, Stmt *AStmt) { 12888 if (!AStmt) 12889 return StmtError(); 12890 12891 auto *CS = cast<CapturedStmt>(AStmt); 12892 // 1.2.2 OpenMP Language Terminology 12893 // Structured block - An executable statement with a single entry at the 12894 // top and a single exit at the bottom. 12895 // The point of exit cannot be a branch out of the structured block. 12896 // longjmp() and throw() must not violate the entry/exit criteria. 12897 CS->getCapturedDecl()->setNothrow(); 12898 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_exit_data); 12899 ThisCaptureLevel > 1; --ThisCaptureLevel) { 12900 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 12901 // 1.2.2 OpenMP Language Terminology 12902 // Structured block - An executable statement with a single entry at the 12903 // top and a single exit at the bottom. 12904 // The point of exit cannot be a branch out of the structured block. 12905 // longjmp() and throw() must not violate the entry/exit criteria. 12906 CS->getCapturedDecl()->setNothrow(); 12907 } 12908 12909 // OpenMP [2.10.3, Restrictions, p. 102] 12910 // At least one map clause must appear on the directive. 12911 if (!hasClauses(Clauses, OMPC_map)) { 12912 Diag(StartLoc, diag::err_omp_no_clause_for_directive) 12913 << "'map'" << getOpenMPDirectiveName(OMPD_target_exit_data); 12914 return StmtError(); 12915 } 12916 12917 return OMPTargetExitDataDirective::Create(Context, StartLoc, EndLoc, Clauses, 12918 AStmt); 12919 } 12920 12921 StmtResult Sema::ActOnOpenMPTargetUpdateDirective(ArrayRef<OMPClause *> Clauses, 12922 SourceLocation StartLoc, 12923 SourceLocation EndLoc, 12924 Stmt *AStmt) { 12925 if (!AStmt) 12926 return StmtError(); 12927 12928 auto *CS = cast<CapturedStmt>(AStmt); 12929 // 1.2.2 OpenMP Language Terminology 12930 // Structured block - An executable statement with a single entry at the 12931 // top and a single exit at the bottom. 12932 // The point of exit cannot be a branch out of the structured block. 12933 // longjmp() and throw() must not violate the entry/exit criteria. 12934 CS->getCapturedDecl()->setNothrow(); 12935 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_update); 12936 ThisCaptureLevel > 1; --ThisCaptureLevel) { 12937 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 12938 // 1.2.2 OpenMP Language Terminology 12939 // Structured block - An executable statement with a single entry at the 12940 // top and a single exit at the bottom. 12941 // The point of exit cannot be a branch out of the structured block. 12942 // longjmp() and throw() must not violate the entry/exit criteria. 12943 CS->getCapturedDecl()->setNothrow(); 12944 } 12945 12946 if (!hasClauses(Clauses, OMPC_to, OMPC_from)) { 12947 Diag(StartLoc, diag::err_omp_at_least_one_motion_clause_required); 12948 return StmtError(); 12949 } 12950 12951 if (!isClauseMappable(Clauses)) { 12952 Diag(StartLoc, diag::err_omp_cannot_update_with_internal_linkage); 12953 return StmtError(); 12954 } 12955 12956 return OMPTargetUpdateDirective::Create(Context, StartLoc, EndLoc, Clauses, 12957 AStmt); 12958 } 12959 12960 StmtResult Sema::ActOnOpenMPTeamsDirective(ArrayRef<OMPClause *> Clauses, 12961 Stmt *AStmt, SourceLocation StartLoc, 12962 SourceLocation EndLoc) { 12963 if (!AStmt) 12964 return StmtError(); 12965 12966 auto *CS = cast<CapturedStmt>(AStmt); 12967 // 1.2.2 OpenMP Language Terminology 12968 // Structured block - An executable statement with a single entry at the 12969 // top and a single exit at the bottom. 12970 // The point of exit cannot be a branch out of the structured block. 12971 // longjmp() and throw() must not violate the entry/exit criteria. 12972 CS->getCapturedDecl()->setNothrow(); 12973 12974 setFunctionHasBranchProtectedScope(); 12975 12976 DSAStack->setParentTeamsRegionLoc(StartLoc); 12977 12978 return OMPTeamsDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt); 12979 } 12980 12981 StmtResult 12982 Sema::ActOnOpenMPCancellationPointDirective(SourceLocation StartLoc, 12983 SourceLocation EndLoc, 12984 OpenMPDirectiveKind CancelRegion) { 12985 if (DSAStack->isParentNowaitRegion()) { 12986 Diag(StartLoc, diag::err_omp_parent_cancel_region_nowait) << 0; 12987 return StmtError(); 12988 } 12989 if (DSAStack->isParentOrderedRegion()) { 12990 Diag(StartLoc, diag::err_omp_parent_cancel_region_ordered) << 0; 12991 return StmtError(); 12992 } 12993 return OMPCancellationPointDirective::Create(Context, StartLoc, EndLoc, 12994 CancelRegion); 12995 } 12996 12997 StmtResult Sema::ActOnOpenMPCancelDirective(ArrayRef<OMPClause *> Clauses, 12998 SourceLocation StartLoc, 12999 SourceLocation EndLoc, 13000 OpenMPDirectiveKind CancelRegion) { 13001 if (DSAStack->isParentNowaitRegion()) { 13002 Diag(StartLoc, diag::err_omp_parent_cancel_region_nowait) << 1; 13003 return StmtError(); 13004 } 13005 if (DSAStack->isParentOrderedRegion()) { 13006 Diag(StartLoc, diag::err_omp_parent_cancel_region_ordered) << 1; 13007 return StmtError(); 13008 } 13009 DSAStack->setParentCancelRegion(/*Cancel=*/true); 13010 return OMPCancelDirective::Create(Context, StartLoc, EndLoc, Clauses, 13011 CancelRegion); 13012 } 13013 13014 static bool checkReductionClauseWithNogroup(Sema &S, 13015 ArrayRef<OMPClause *> Clauses) { 13016 const OMPClause *ReductionClause = nullptr; 13017 const OMPClause *NogroupClause = nullptr; 13018 for (const OMPClause *C : Clauses) { 13019 if (C->getClauseKind() == OMPC_reduction) { 13020 ReductionClause = C; 13021 if (NogroupClause) 13022 break; 13023 continue; 13024 } 13025 if (C->getClauseKind() == OMPC_nogroup) { 13026 NogroupClause = C; 13027 if (ReductionClause) 13028 break; 13029 continue; 13030 } 13031 } 13032 if (ReductionClause && NogroupClause) { 13033 S.Diag(ReductionClause->getBeginLoc(), diag::err_omp_reduction_with_nogroup) 13034 << SourceRange(NogroupClause->getBeginLoc(), 13035 NogroupClause->getEndLoc()); 13036 return true; 13037 } 13038 return false; 13039 } 13040 13041 StmtResult Sema::ActOnOpenMPTaskLoopDirective( 13042 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 13043 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 13044 if (!AStmt) 13045 return StmtError(); 13046 13047 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 13048 OMPLoopBasedDirective::HelperExprs B; 13049 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 13050 // define the nested loops number. 13051 unsigned NestedLoopCount = 13052 checkOpenMPLoop(OMPD_taskloop, getCollapseNumberExpr(Clauses), 13053 /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack, 13054 VarsWithImplicitDSA, B); 13055 if (NestedLoopCount == 0) 13056 return StmtError(); 13057 13058 assert((CurContext->isDependentContext() || B.builtAll()) && 13059 "omp for loop exprs were not built"); 13060 13061 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 13062 // The grainsize clause and num_tasks clause are mutually exclusive and may 13063 // not appear on the same taskloop directive. 13064 if (checkMutuallyExclusiveClauses(*this, Clauses, 13065 {OMPC_grainsize, OMPC_num_tasks})) 13066 return StmtError(); 13067 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 13068 // If a reduction clause is present on the taskloop directive, the nogroup 13069 // clause must not be specified. 13070 if (checkReductionClauseWithNogroup(*this, Clauses)) 13071 return StmtError(); 13072 13073 setFunctionHasBranchProtectedScope(); 13074 return OMPTaskLoopDirective::Create(Context, StartLoc, EndLoc, 13075 NestedLoopCount, Clauses, AStmt, B, 13076 DSAStack->isCancelRegion()); 13077 } 13078 13079 StmtResult Sema::ActOnOpenMPTaskLoopSimdDirective( 13080 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 13081 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 13082 if (!AStmt) 13083 return StmtError(); 13084 13085 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 13086 OMPLoopBasedDirective::HelperExprs B; 13087 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 13088 // define the nested loops number. 13089 unsigned NestedLoopCount = 13090 checkOpenMPLoop(OMPD_taskloop_simd, getCollapseNumberExpr(Clauses), 13091 /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack, 13092 VarsWithImplicitDSA, B); 13093 if (NestedLoopCount == 0) 13094 return StmtError(); 13095 13096 assert((CurContext->isDependentContext() || B.builtAll()) && 13097 "omp for loop exprs were not built"); 13098 13099 if (!CurContext->isDependentContext()) { 13100 // Finalize the clauses that need pre-built expressions for CodeGen. 13101 for (OMPClause *C : Clauses) { 13102 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 13103 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 13104 B.NumIterations, *this, CurScope, 13105 DSAStack)) 13106 return StmtError(); 13107 } 13108 } 13109 13110 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 13111 // The grainsize clause and num_tasks clause are mutually exclusive and may 13112 // not appear on the same taskloop directive. 13113 if (checkMutuallyExclusiveClauses(*this, Clauses, 13114 {OMPC_grainsize, OMPC_num_tasks})) 13115 return StmtError(); 13116 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 13117 // If a reduction clause is present on the taskloop directive, the nogroup 13118 // clause must not be specified. 13119 if (checkReductionClauseWithNogroup(*this, Clauses)) 13120 return StmtError(); 13121 if (checkSimdlenSafelenSpecified(*this, Clauses)) 13122 return StmtError(); 13123 13124 setFunctionHasBranchProtectedScope(); 13125 return OMPTaskLoopSimdDirective::Create(Context, StartLoc, EndLoc, 13126 NestedLoopCount, Clauses, AStmt, B); 13127 } 13128 13129 StmtResult Sema::ActOnOpenMPMasterTaskLoopDirective( 13130 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 13131 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 13132 if (!AStmt) 13133 return StmtError(); 13134 13135 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 13136 OMPLoopBasedDirective::HelperExprs B; 13137 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 13138 // define the nested loops number. 13139 unsigned NestedLoopCount = 13140 checkOpenMPLoop(OMPD_master_taskloop, getCollapseNumberExpr(Clauses), 13141 /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack, 13142 VarsWithImplicitDSA, B); 13143 if (NestedLoopCount == 0) 13144 return StmtError(); 13145 13146 assert((CurContext->isDependentContext() || B.builtAll()) && 13147 "omp for loop exprs were not built"); 13148 13149 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 13150 // The grainsize clause and num_tasks clause are mutually exclusive and may 13151 // not appear on the same taskloop directive. 13152 if (checkMutuallyExclusiveClauses(*this, Clauses, 13153 {OMPC_grainsize, OMPC_num_tasks})) 13154 return StmtError(); 13155 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 13156 // If a reduction clause is present on the taskloop directive, the nogroup 13157 // clause must not be specified. 13158 if (checkReductionClauseWithNogroup(*this, Clauses)) 13159 return StmtError(); 13160 13161 setFunctionHasBranchProtectedScope(); 13162 return OMPMasterTaskLoopDirective::Create(Context, StartLoc, EndLoc, 13163 NestedLoopCount, Clauses, AStmt, B, 13164 DSAStack->isCancelRegion()); 13165 } 13166 13167 StmtResult Sema::ActOnOpenMPMaskedTaskLoopDirective( 13168 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 13169 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 13170 if (!AStmt) 13171 return StmtError(); 13172 13173 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 13174 OMPLoopBasedDirective::HelperExprs B; 13175 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 13176 // define the nested loops number. 13177 unsigned NestedLoopCount = 13178 checkOpenMPLoop(OMPD_masked_taskloop, getCollapseNumberExpr(Clauses), 13179 /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack, 13180 VarsWithImplicitDSA, B); 13181 if (NestedLoopCount == 0) 13182 return StmtError(); 13183 13184 assert((CurContext->isDependentContext() || B.builtAll()) && 13185 "omp for loop exprs were not built"); 13186 13187 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 13188 // The grainsize clause and num_tasks clause are mutually exclusive and may 13189 // not appear on the same taskloop directive. 13190 if (checkMutuallyExclusiveClauses(*this, Clauses, 13191 {OMPC_grainsize, OMPC_num_tasks})) 13192 return StmtError(); 13193 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 13194 // If a reduction clause is present on the taskloop directive, the nogroup 13195 // clause must not be specified. 13196 if (checkReductionClauseWithNogroup(*this, Clauses)) 13197 return StmtError(); 13198 13199 setFunctionHasBranchProtectedScope(); 13200 return OMPMaskedTaskLoopDirective::Create(Context, StartLoc, EndLoc, 13201 NestedLoopCount, Clauses, AStmt, B, 13202 DSAStack->isCancelRegion()); 13203 } 13204 13205 StmtResult Sema::ActOnOpenMPMasterTaskLoopSimdDirective( 13206 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 13207 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 13208 if (!AStmt) 13209 return StmtError(); 13210 13211 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 13212 OMPLoopBasedDirective::HelperExprs B; 13213 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 13214 // define the nested loops number. 13215 unsigned NestedLoopCount = 13216 checkOpenMPLoop(OMPD_master_taskloop_simd, getCollapseNumberExpr(Clauses), 13217 /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack, 13218 VarsWithImplicitDSA, B); 13219 if (NestedLoopCount == 0) 13220 return StmtError(); 13221 13222 assert((CurContext->isDependentContext() || B.builtAll()) && 13223 "omp for loop exprs were not built"); 13224 13225 if (!CurContext->isDependentContext()) { 13226 // Finalize the clauses that need pre-built expressions for CodeGen. 13227 for (OMPClause *C : Clauses) { 13228 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 13229 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 13230 B.NumIterations, *this, CurScope, 13231 DSAStack)) 13232 return StmtError(); 13233 } 13234 } 13235 13236 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 13237 // The grainsize clause and num_tasks clause are mutually exclusive and may 13238 // not appear on the same taskloop directive. 13239 if (checkMutuallyExclusiveClauses(*this, Clauses, 13240 {OMPC_grainsize, OMPC_num_tasks})) 13241 return StmtError(); 13242 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 13243 // If a reduction clause is present on the taskloop directive, the nogroup 13244 // clause must not be specified. 13245 if (checkReductionClauseWithNogroup(*this, Clauses)) 13246 return StmtError(); 13247 if (checkSimdlenSafelenSpecified(*this, Clauses)) 13248 return StmtError(); 13249 13250 setFunctionHasBranchProtectedScope(); 13251 return OMPMasterTaskLoopSimdDirective::Create( 13252 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 13253 } 13254 13255 StmtResult Sema::ActOnOpenMPMaskedTaskLoopSimdDirective( 13256 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 13257 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 13258 if (!AStmt) 13259 return StmtError(); 13260 13261 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 13262 OMPLoopBasedDirective::HelperExprs B; 13263 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 13264 // define the nested loops number. 13265 unsigned NestedLoopCount = 13266 checkOpenMPLoop(OMPD_masked_taskloop_simd, getCollapseNumberExpr(Clauses), 13267 /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack, 13268 VarsWithImplicitDSA, B); 13269 if (NestedLoopCount == 0) 13270 return StmtError(); 13271 13272 assert((CurContext->isDependentContext() || B.builtAll()) && 13273 "omp for loop exprs were not built"); 13274 13275 if (!CurContext->isDependentContext()) { 13276 // Finalize the clauses that need pre-built expressions for CodeGen. 13277 for (OMPClause *C : Clauses) { 13278 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 13279 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 13280 B.NumIterations, *this, CurScope, 13281 DSAStack)) 13282 return StmtError(); 13283 } 13284 } 13285 13286 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 13287 // The grainsize clause and num_tasks clause are mutually exclusive and may 13288 // not appear on the same taskloop directive. 13289 if (checkMutuallyExclusiveClauses(*this, Clauses, 13290 {OMPC_grainsize, OMPC_num_tasks})) 13291 return StmtError(); 13292 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 13293 // If a reduction clause is present on the taskloop directive, the nogroup 13294 // clause must not be specified. 13295 if (checkReductionClauseWithNogroup(*this, Clauses)) 13296 return StmtError(); 13297 if (checkSimdlenSafelenSpecified(*this, Clauses)) 13298 return StmtError(); 13299 13300 setFunctionHasBranchProtectedScope(); 13301 return OMPMaskedTaskLoopSimdDirective::Create( 13302 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 13303 } 13304 13305 StmtResult Sema::ActOnOpenMPParallelMasterTaskLoopDirective( 13306 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 13307 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 13308 if (!AStmt) 13309 return StmtError(); 13310 13311 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 13312 auto *CS = cast<CapturedStmt>(AStmt); 13313 // 1.2.2 OpenMP Language Terminology 13314 // Structured block - An executable statement with a single entry at the 13315 // top and a single exit at the bottom. 13316 // The point of exit cannot be a branch out of the structured block. 13317 // longjmp() and throw() must not violate the entry/exit criteria. 13318 CS->getCapturedDecl()->setNothrow(); 13319 for (int ThisCaptureLevel = 13320 getOpenMPCaptureLevels(OMPD_parallel_master_taskloop); 13321 ThisCaptureLevel > 1; --ThisCaptureLevel) { 13322 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 13323 // 1.2.2 OpenMP Language Terminology 13324 // Structured block - An executable statement with a single entry at the 13325 // top and a single exit at the bottom. 13326 // The point of exit cannot be a branch out of the structured block. 13327 // longjmp() and throw() must not violate the entry/exit criteria. 13328 CS->getCapturedDecl()->setNothrow(); 13329 } 13330 13331 OMPLoopBasedDirective::HelperExprs B; 13332 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 13333 // define the nested loops number. 13334 unsigned NestedLoopCount = checkOpenMPLoop( 13335 OMPD_parallel_master_taskloop, getCollapseNumberExpr(Clauses), 13336 /*OrderedLoopCountExpr=*/nullptr, CS, *this, *DSAStack, 13337 VarsWithImplicitDSA, B); 13338 if (NestedLoopCount == 0) 13339 return StmtError(); 13340 13341 assert((CurContext->isDependentContext() || B.builtAll()) && 13342 "omp for loop exprs were not built"); 13343 13344 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 13345 // The grainsize clause and num_tasks clause are mutually exclusive and may 13346 // not appear on the same taskloop directive. 13347 if (checkMutuallyExclusiveClauses(*this, Clauses, 13348 {OMPC_grainsize, OMPC_num_tasks})) 13349 return StmtError(); 13350 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 13351 // If a reduction clause is present on the taskloop directive, the nogroup 13352 // clause must not be specified. 13353 if (checkReductionClauseWithNogroup(*this, Clauses)) 13354 return StmtError(); 13355 13356 setFunctionHasBranchProtectedScope(); 13357 return OMPParallelMasterTaskLoopDirective::Create( 13358 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B, 13359 DSAStack->isCancelRegion()); 13360 } 13361 13362 StmtResult Sema::ActOnOpenMPParallelMasterTaskLoopSimdDirective( 13363 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 13364 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 13365 if (!AStmt) 13366 return StmtError(); 13367 13368 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 13369 auto *CS = cast<CapturedStmt>(AStmt); 13370 // 1.2.2 OpenMP Language Terminology 13371 // Structured block - An executable statement with a single entry at the 13372 // top and a single exit at the bottom. 13373 // The point of exit cannot be a branch out of the structured block. 13374 // longjmp() and throw() must not violate the entry/exit criteria. 13375 CS->getCapturedDecl()->setNothrow(); 13376 for (int ThisCaptureLevel = 13377 getOpenMPCaptureLevels(OMPD_parallel_master_taskloop_simd); 13378 ThisCaptureLevel > 1; --ThisCaptureLevel) { 13379 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 13380 // 1.2.2 OpenMP Language Terminology 13381 // Structured block - An executable statement with a single entry at the 13382 // top and a single exit at the bottom. 13383 // The point of exit cannot be a branch out of the structured block. 13384 // longjmp() and throw() must not violate the entry/exit criteria. 13385 CS->getCapturedDecl()->setNothrow(); 13386 } 13387 13388 OMPLoopBasedDirective::HelperExprs B; 13389 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 13390 // define the nested loops number. 13391 unsigned NestedLoopCount = checkOpenMPLoop( 13392 OMPD_parallel_master_taskloop_simd, getCollapseNumberExpr(Clauses), 13393 /*OrderedLoopCountExpr=*/nullptr, CS, *this, *DSAStack, 13394 VarsWithImplicitDSA, B); 13395 if (NestedLoopCount == 0) 13396 return StmtError(); 13397 13398 assert((CurContext->isDependentContext() || B.builtAll()) && 13399 "omp for loop exprs were not built"); 13400 13401 if (!CurContext->isDependentContext()) { 13402 // Finalize the clauses that need pre-built expressions for CodeGen. 13403 for (OMPClause *C : Clauses) { 13404 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 13405 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 13406 B.NumIterations, *this, CurScope, 13407 DSAStack)) 13408 return StmtError(); 13409 } 13410 } 13411 13412 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 13413 // The grainsize clause and num_tasks clause are mutually exclusive and may 13414 // not appear on the same taskloop directive. 13415 if (checkMutuallyExclusiveClauses(*this, Clauses, 13416 {OMPC_grainsize, OMPC_num_tasks})) 13417 return StmtError(); 13418 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 13419 // If a reduction clause is present on the taskloop directive, the nogroup 13420 // clause must not be specified. 13421 if (checkReductionClauseWithNogroup(*this, Clauses)) 13422 return StmtError(); 13423 if (checkSimdlenSafelenSpecified(*this, Clauses)) 13424 return StmtError(); 13425 13426 setFunctionHasBranchProtectedScope(); 13427 return OMPParallelMasterTaskLoopSimdDirective::Create( 13428 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 13429 } 13430 13431 StmtResult Sema::ActOnOpenMPDistributeDirective( 13432 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 13433 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 13434 if (!AStmt) 13435 return StmtError(); 13436 13437 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 13438 OMPLoopBasedDirective::HelperExprs B; 13439 // In presence of clause 'collapse' with number of loops, it will 13440 // define the nested loops number. 13441 unsigned NestedLoopCount = 13442 checkOpenMPLoop(OMPD_distribute, getCollapseNumberExpr(Clauses), 13443 nullptr /*ordered not a clause on distribute*/, AStmt, 13444 *this, *DSAStack, VarsWithImplicitDSA, B); 13445 if (NestedLoopCount == 0) 13446 return StmtError(); 13447 13448 assert((CurContext->isDependentContext() || B.builtAll()) && 13449 "omp for loop exprs were not built"); 13450 13451 setFunctionHasBranchProtectedScope(); 13452 return OMPDistributeDirective::Create(Context, StartLoc, EndLoc, 13453 NestedLoopCount, Clauses, AStmt, B); 13454 } 13455 13456 StmtResult Sema::ActOnOpenMPDistributeParallelForDirective( 13457 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 13458 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 13459 if (!AStmt) 13460 return StmtError(); 13461 13462 auto *CS = cast<CapturedStmt>(AStmt); 13463 // 1.2.2 OpenMP Language Terminology 13464 // Structured block - An executable statement with a single entry at the 13465 // top and a single exit at the bottom. 13466 // The point of exit cannot be a branch out of the structured block. 13467 // longjmp() and throw() must not violate the entry/exit criteria. 13468 CS->getCapturedDecl()->setNothrow(); 13469 for (int ThisCaptureLevel = 13470 getOpenMPCaptureLevels(OMPD_distribute_parallel_for); 13471 ThisCaptureLevel > 1; --ThisCaptureLevel) { 13472 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 13473 // 1.2.2 OpenMP Language Terminology 13474 // Structured block - An executable statement with a single entry at the 13475 // top and a single exit at the bottom. 13476 // The point of exit cannot be a branch out of the structured block. 13477 // longjmp() and throw() must not violate the entry/exit criteria. 13478 CS->getCapturedDecl()->setNothrow(); 13479 } 13480 13481 OMPLoopBasedDirective::HelperExprs B; 13482 // In presence of clause 'collapse' with number of loops, it will 13483 // define the nested loops number. 13484 unsigned NestedLoopCount = checkOpenMPLoop( 13485 OMPD_distribute_parallel_for, getCollapseNumberExpr(Clauses), 13486 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 13487 VarsWithImplicitDSA, B); 13488 if (NestedLoopCount == 0) 13489 return StmtError(); 13490 13491 assert((CurContext->isDependentContext() || B.builtAll()) && 13492 "omp for loop exprs were not built"); 13493 13494 setFunctionHasBranchProtectedScope(); 13495 return OMPDistributeParallelForDirective::Create( 13496 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B, 13497 DSAStack->getTaskgroupReductionRef(), DSAStack->isCancelRegion()); 13498 } 13499 13500 StmtResult Sema::ActOnOpenMPDistributeParallelForSimdDirective( 13501 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 13502 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 13503 if (!AStmt) 13504 return StmtError(); 13505 13506 auto *CS = cast<CapturedStmt>(AStmt); 13507 // 1.2.2 OpenMP Language Terminology 13508 // Structured block - An executable statement with a single entry at the 13509 // top and a single exit at the bottom. 13510 // The point of exit cannot be a branch out of the structured block. 13511 // longjmp() and throw() must not violate the entry/exit criteria. 13512 CS->getCapturedDecl()->setNothrow(); 13513 for (int ThisCaptureLevel = 13514 getOpenMPCaptureLevels(OMPD_distribute_parallel_for_simd); 13515 ThisCaptureLevel > 1; --ThisCaptureLevel) { 13516 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 13517 // 1.2.2 OpenMP Language Terminology 13518 // Structured block - An executable statement with a single entry at the 13519 // top and a single exit at the bottom. 13520 // The point of exit cannot be a branch out of the structured block. 13521 // longjmp() and throw() must not violate the entry/exit criteria. 13522 CS->getCapturedDecl()->setNothrow(); 13523 } 13524 13525 OMPLoopBasedDirective::HelperExprs B; 13526 // In presence of clause 'collapse' with number of loops, it will 13527 // define the nested loops number. 13528 unsigned NestedLoopCount = checkOpenMPLoop( 13529 OMPD_distribute_parallel_for_simd, getCollapseNumberExpr(Clauses), 13530 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 13531 VarsWithImplicitDSA, B); 13532 if (NestedLoopCount == 0) 13533 return StmtError(); 13534 13535 assert((CurContext->isDependentContext() || B.builtAll()) && 13536 "omp for loop exprs were not built"); 13537 13538 if (!CurContext->isDependentContext()) { 13539 // Finalize the clauses that need pre-built expressions for CodeGen. 13540 for (OMPClause *C : Clauses) { 13541 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 13542 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 13543 B.NumIterations, *this, CurScope, 13544 DSAStack)) 13545 return StmtError(); 13546 } 13547 } 13548 13549 if (checkSimdlenSafelenSpecified(*this, Clauses)) 13550 return StmtError(); 13551 13552 setFunctionHasBranchProtectedScope(); 13553 return OMPDistributeParallelForSimdDirective::Create( 13554 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 13555 } 13556 13557 StmtResult Sema::ActOnOpenMPDistributeSimdDirective( 13558 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 13559 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 13560 if (!AStmt) 13561 return StmtError(); 13562 13563 auto *CS = cast<CapturedStmt>(AStmt); 13564 // 1.2.2 OpenMP Language Terminology 13565 // Structured block - An executable statement with a single entry at the 13566 // top and a single exit at the bottom. 13567 // The point of exit cannot be a branch out of the structured block. 13568 // longjmp() and throw() must not violate the entry/exit criteria. 13569 CS->getCapturedDecl()->setNothrow(); 13570 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_distribute_simd); 13571 ThisCaptureLevel > 1; --ThisCaptureLevel) { 13572 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 13573 // 1.2.2 OpenMP Language Terminology 13574 // Structured block - An executable statement with a single entry at the 13575 // top and a single exit at the bottom. 13576 // The point of exit cannot be a branch out of the structured block. 13577 // longjmp() and throw() must not violate the entry/exit criteria. 13578 CS->getCapturedDecl()->setNothrow(); 13579 } 13580 13581 OMPLoopBasedDirective::HelperExprs B; 13582 // In presence of clause 'collapse' with number of loops, it will 13583 // define the nested loops number. 13584 unsigned NestedLoopCount = 13585 checkOpenMPLoop(OMPD_distribute_simd, getCollapseNumberExpr(Clauses), 13586 nullptr /*ordered not a clause on distribute*/, CS, *this, 13587 *DSAStack, VarsWithImplicitDSA, B); 13588 if (NestedLoopCount == 0) 13589 return StmtError(); 13590 13591 assert((CurContext->isDependentContext() || B.builtAll()) && 13592 "omp for loop exprs were not built"); 13593 13594 if (!CurContext->isDependentContext()) { 13595 // Finalize the clauses that need pre-built expressions for CodeGen. 13596 for (OMPClause *C : Clauses) { 13597 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 13598 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 13599 B.NumIterations, *this, CurScope, 13600 DSAStack)) 13601 return StmtError(); 13602 } 13603 } 13604 13605 if (checkSimdlenSafelenSpecified(*this, Clauses)) 13606 return StmtError(); 13607 13608 setFunctionHasBranchProtectedScope(); 13609 return OMPDistributeSimdDirective::Create(Context, StartLoc, EndLoc, 13610 NestedLoopCount, Clauses, AStmt, B); 13611 } 13612 13613 StmtResult Sema::ActOnOpenMPTargetParallelForSimdDirective( 13614 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 13615 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 13616 if (!AStmt) 13617 return StmtError(); 13618 13619 auto *CS = cast<CapturedStmt>(AStmt); 13620 // 1.2.2 OpenMP Language Terminology 13621 // Structured block - An executable statement with a single entry at the 13622 // top and a single exit at the bottom. 13623 // The point of exit cannot be a branch out of the structured block. 13624 // longjmp() and throw() must not violate the entry/exit criteria. 13625 CS->getCapturedDecl()->setNothrow(); 13626 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel_for); 13627 ThisCaptureLevel > 1; --ThisCaptureLevel) { 13628 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 13629 // 1.2.2 OpenMP Language Terminology 13630 // Structured block - An executable statement with a single entry at the 13631 // top and a single exit at the bottom. 13632 // The point of exit cannot be a branch out of the structured block. 13633 // longjmp() and throw() must not violate the entry/exit criteria. 13634 CS->getCapturedDecl()->setNothrow(); 13635 } 13636 13637 OMPLoopBasedDirective::HelperExprs B; 13638 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 13639 // define the nested loops number. 13640 unsigned NestedLoopCount = checkOpenMPLoop( 13641 OMPD_target_parallel_for_simd, getCollapseNumberExpr(Clauses), 13642 getOrderedNumberExpr(Clauses), CS, *this, *DSAStack, VarsWithImplicitDSA, 13643 B); 13644 if (NestedLoopCount == 0) 13645 return StmtError(); 13646 13647 assert((CurContext->isDependentContext() || B.builtAll()) && 13648 "omp target parallel for simd loop exprs were not built"); 13649 13650 if (!CurContext->isDependentContext()) { 13651 // Finalize the clauses that need pre-built expressions for CodeGen. 13652 for (OMPClause *C : Clauses) { 13653 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 13654 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 13655 B.NumIterations, *this, CurScope, 13656 DSAStack)) 13657 return StmtError(); 13658 } 13659 } 13660 if (checkSimdlenSafelenSpecified(*this, Clauses)) 13661 return StmtError(); 13662 13663 setFunctionHasBranchProtectedScope(); 13664 return OMPTargetParallelForSimdDirective::Create( 13665 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 13666 } 13667 13668 StmtResult Sema::ActOnOpenMPTargetSimdDirective( 13669 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 13670 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 13671 if (!AStmt) 13672 return StmtError(); 13673 13674 auto *CS = cast<CapturedStmt>(AStmt); 13675 // 1.2.2 OpenMP Language Terminology 13676 // Structured block - An executable statement with a single entry at the 13677 // top and a single exit at the bottom. 13678 // The point of exit cannot be a branch out of the structured block. 13679 // longjmp() and throw() must not violate the entry/exit criteria. 13680 CS->getCapturedDecl()->setNothrow(); 13681 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_simd); 13682 ThisCaptureLevel > 1; --ThisCaptureLevel) { 13683 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 13684 // 1.2.2 OpenMP Language Terminology 13685 // Structured block - An executable statement with a single entry at the 13686 // top and a single exit at the bottom. 13687 // The point of exit cannot be a branch out of the structured block. 13688 // longjmp() and throw() must not violate the entry/exit criteria. 13689 CS->getCapturedDecl()->setNothrow(); 13690 } 13691 13692 OMPLoopBasedDirective::HelperExprs B; 13693 // In presence of clause 'collapse' with number of loops, it will define the 13694 // nested loops number. 13695 unsigned NestedLoopCount = 13696 checkOpenMPLoop(OMPD_target_simd, getCollapseNumberExpr(Clauses), 13697 getOrderedNumberExpr(Clauses), CS, *this, *DSAStack, 13698 VarsWithImplicitDSA, B); 13699 if (NestedLoopCount == 0) 13700 return StmtError(); 13701 13702 assert((CurContext->isDependentContext() || B.builtAll()) && 13703 "omp target simd loop exprs were not built"); 13704 13705 if (!CurContext->isDependentContext()) { 13706 // Finalize the clauses that need pre-built expressions for CodeGen. 13707 for (OMPClause *C : Clauses) { 13708 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 13709 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 13710 B.NumIterations, *this, CurScope, 13711 DSAStack)) 13712 return StmtError(); 13713 } 13714 } 13715 13716 if (checkSimdlenSafelenSpecified(*this, Clauses)) 13717 return StmtError(); 13718 13719 setFunctionHasBranchProtectedScope(); 13720 return OMPTargetSimdDirective::Create(Context, StartLoc, EndLoc, 13721 NestedLoopCount, Clauses, AStmt, B); 13722 } 13723 13724 StmtResult Sema::ActOnOpenMPTeamsDistributeDirective( 13725 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 13726 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 13727 if (!AStmt) 13728 return StmtError(); 13729 13730 auto *CS = cast<CapturedStmt>(AStmt); 13731 // 1.2.2 OpenMP Language Terminology 13732 // Structured block - An executable statement with a single entry at the 13733 // top and a single exit at the bottom. 13734 // The point of exit cannot be a branch out of the structured block. 13735 // longjmp() and throw() must not violate the entry/exit criteria. 13736 CS->getCapturedDecl()->setNothrow(); 13737 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_teams_distribute); 13738 ThisCaptureLevel > 1; --ThisCaptureLevel) { 13739 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 13740 // 1.2.2 OpenMP Language Terminology 13741 // Structured block - An executable statement with a single entry at the 13742 // top and a single exit at the bottom. 13743 // The point of exit cannot be a branch out of the structured block. 13744 // longjmp() and throw() must not violate the entry/exit criteria. 13745 CS->getCapturedDecl()->setNothrow(); 13746 } 13747 13748 OMPLoopBasedDirective::HelperExprs B; 13749 // In presence of clause 'collapse' with number of loops, it will 13750 // define the nested loops number. 13751 unsigned NestedLoopCount = 13752 checkOpenMPLoop(OMPD_teams_distribute, getCollapseNumberExpr(Clauses), 13753 nullptr /*ordered not a clause on distribute*/, CS, *this, 13754 *DSAStack, VarsWithImplicitDSA, B); 13755 if (NestedLoopCount == 0) 13756 return StmtError(); 13757 13758 assert((CurContext->isDependentContext() || B.builtAll()) && 13759 "omp teams distribute loop exprs were not built"); 13760 13761 setFunctionHasBranchProtectedScope(); 13762 13763 DSAStack->setParentTeamsRegionLoc(StartLoc); 13764 13765 return OMPTeamsDistributeDirective::Create( 13766 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 13767 } 13768 13769 StmtResult Sema::ActOnOpenMPTeamsDistributeSimdDirective( 13770 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 13771 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 13772 if (!AStmt) 13773 return StmtError(); 13774 13775 auto *CS = cast<CapturedStmt>(AStmt); 13776 // 1.2.2 OpenMP Language Terminology 13777 // Structured block - An executable statement with a single entry at the 13778 // top and a single exit at the bottom. 13779 // The point of exit cannot be a branch out of the structured block. 13780 // longjmp() and throw() must not violate the entry/exit criteria. 13781 CS->getCapturedDecl()->setNothrow(); 13782 for (int ThisCaptureLevel = 13783 getOpenMPCaptureLevels(OMPD_teams_distribute_simd); 13784 ThisCaptureLevel > 1; --ThisCaptureLevel) { 13785 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 13786 // 1.2.2 OpenMP Language Terminology 13787 // Structured block - An executable statement with a single entry at the 13788 // top and a single exit at the bottom. 13789 // The point of exit cannot be a branch out of the structured block. 13790 // longjmp() and throw() must not violate the entry/exit criteria. 13791 CS->getCapturedDecl()->setNothrow(); 13792 } 13793 13794 OMPLoopBasedDirective::HelperExprs B; 13795 // In presence of clause 'collapse' with number of loops, it will 13796 // define the nested loops number. 13797 unsigned NestedLoopCount = checkOpenMPLoop( 13798 OMPD_teams_distribute_simd, getCollapseNumberExpr(Clauses), 13799 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 13800 VarsWithImplicitDSA, B); 13801 13802 if (NestedLoopCount == 0) 13803 return StmtError(); 13804 13805 assert((CurContext->isDependentContext() || B.builtAll()) && 13806 "omp teams distribute simd loop exprs were not built"); 13807 13808 if (!CurContext->isDependentContext()) { 13809 // Finalize the clauses that need pre-built expressions for CodeGen. 13810 for (OMPClause *C : Clauses) { 13811 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 13812 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 13813 B.NumIterations, *this, CurScope, 13814 DSAStack)) 13815 return StmtError(); 13816 } 13817 } 13818 13819 if (checkSimdlenSafelenSpecified(*this, Clauses)) 13820 return StmtError(); 13821 13822 setFunctionHasBranchProtectedScope(); 13823 13824 DSAStack->setParentTeamsRegionLoc(StartLoc); 13825 13826 return OMPTeamsDistributeSimdDirective::Create( 13827 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 13828 } 13829 13830 StmtResult Sema::ActOnOpenMPTeamsDistributeParallelForSimdDirective( 13831 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 13832 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 13833 if (!AStmt) 13834 return StmtError(); 13835 13836 auto *CS = cast<CapturedStmt>(AStmt); 13837 // 1.2.2 OpenMP Language Terminology 13838 // Structured block - An executable statement with a single entry at the 13839 // top and a single exit at the bottom. 13840 // The point of exit cannot be a branch out of the structured block. 13841 // longjmp() and throw() must not violate the entry/exit criteria. 13842 CS->getCapturedDecl()->setNothrow(); 13843 13844 for (int ThisCaptureLevel = 13845 getOpenMPCaptureLevels(OMPD_teams_distribute_parallel_for_simd); 13846 ThisCaptureLevel > 1; --ThisCaptureLevel) { 13847 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 13848 // 1.2.2 OpenMP Language Terminology 13849 // Structured block - An executable statement with a single entry at the 13850 // top and a single exit at the bottom. 13851 // The point of exit cannot be a branch out of the structured block. 13852 // longjmp() and throw() must not violate the entry/exit criteria. 13853 CS->getCapturedDecl()->setNothrow(); 13854 } 13855 13856 OMPLoopBasedDirective::HelperExprs B; 13857 // In presence of clause 'collapse' with number of loops, it will 13858 // define the nested loops number. 13859 unsigned NestedLoopCount = checkOpenMPLoop( 13860 OMPD_teams_distribute_parallel_for_simd, getCollapseNumberExpr(Clauses), 13861 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 13862 VarsWithImplicitDSA, B); 13863 13864 if (NestedLoopCount == 0) 13865 return StmtError(); 13866 13867 assert((CurContext->isDependentContext() || B.builtAll()) && 13868 "omp for loop exprs were not built"); 13869 13870 if (!CurContext->isDependentContext()) { 13871 // Finalize the clauses that need pre-built expressions for CodeGen. 13872 for (OMPClause *C : Clauses) { 13873 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 13874 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 13875 B.NumIterations, *this, CurScope, 13876 DSAStack)) 13877 return StmtError(); 13878 } 13879 } 13880 13881 if (checkSimdlenSafelenSpecified(*this, Clauses)) 13882 return StmtError(); 13883 13884 setFunctionHasBranchProtectedScope(); 13885 13886 DSAStack->setParentTeamsRegionLoc(StartLoc); 13887 13888 return OMPTeamsDistributeParallelForSimdDirective::Create( 13889 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 13890 } 13891 13892 StmtResult Sema::ActOnOpenMPTeamsDistributeParallelForDirective( 13893 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 13894 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 13895 if (!AStmt) 13896 return StmtError(); 13897 13898 auto *CS = cast<CapturedStmt>(AStmt); 13899 // 1.2.2 OpenMP Language Terminology 13900 // Structured block - An executable statement with a single entry at the 13901 // top and a single exit at the bottom. 13902 // The point of exit cannot be a branch out of the structured block. 13903 // longjmp() and throw() must not violate the entry/exit criteria. 13904 CS->getCapturedDecl()->setNothrow(); 13905 13906 for (int ThisCaptureLevel = 13907 getOpenMPCaptureLevels(OMPD_teams_distribute_parallel_for); 13908 ThisCaptureLevel > 1; --ThisCaptureLevel) { 13909 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 13910 // 1.2.2 OpenMP Language Terminology 13911 // Structured block - An executable statement with a single entry at the 13912 // top and a single exit at the bottom. 13913 // The point of exit cannot be a branch out of the structured block. 13914 // longjmp() and throw() must not violate the entry/exit criteria. 13915 CS->getCapturedDecl()->setNothrow(); 13916 } 13917 13918 OMPLoopBasedDirective::HelperExprs B; 13919 // In presence of clause 'collapse' with number of loops, it will 13920 // define the nested loops number. 13921 unsigned NestedLoopCount = checkOpenMPLoop( 13922 OMPD_teams_distribute_parallel_for, getCollapseNumberExpr(Clauses), 13923 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 13924 VarsWithImplicitDSA, B); 13925 13926 if (NestedLoopCount == 0) 13927 return StmtError(); 13928 13929 assert((CurContext->isDependentContext() || B.builtAll()) && 13930 "omp for loop exprs were not built"); 13931 13932 setFunctionHasBranchProtectedScope(); 13933 13934 DSAStack->setParentTeamsRegionLoc(StartLoc); 13935 13936 return OMPTeamsDistributeParallelForDirective::Create( 13937 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B, 13938 DSAStack->getTaskgroupReductionRef(), DSAStack->isCancelRegion()); 13939 } 13940 13941 StmtResult Sema::ActOnOpenMPTargetTeamsDirective(ArrayRef<OMPClause *> Clauses, 13942 Stmt *AStmt, 13943 SourceLocation StartLoc, 13944 SourceLocation EndLoc) { 13945 if (!AStmt) 13946 return StmtError(); 13947 13948 auto *CS = cast<CapturedStmt>(AStmt); 13949 // 1.2.2 OpenMP Language Terminology 13950 // Structured block - An executable statement with a single entry at the 13951 // top and a single exit at the bottom. 13952 // The point of exit cannot be a branch out of the structured block. 13953 // longjmp() and throw() must not violate the entry/exit criteria. 13954 CS->getCapturedDecl()->setNothrow(); 13955 13956 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_teams); 13957 ThisCaptureLevel > 1; --ThisCaptureLevel) { 13958 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 13959 // 1.2.2 OpenMP Language Terminology 13960 // Structured block - An executable statement with a single entry at the 13961 // top and a single exit at the bottom. 13962 // The point of exit cannot be a branch out of the structured block. 13963 // longjmp() and throw() must not violate the entry/exit criteria. 13964 CS->getCapturedDecl()->setNothrow(); 13965 } 13966 setFunctionHasBranchProtectedScope(); 13967 13968 return OMPTargetTeamsDirective::Create(Context, StartLoc, EndLoc, Clauses, 13969 AStmt); 13970 } 13971 13972 StmtResult Sema::ActOnOpenMPTargetTeamsDistributeDirective( 13973 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 13974 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 13975 if (!AStmt) 13976 return StmtError(); 13977 13978 auto *CS = cast<CapturedStmt>(AStmt); 13979 // 1.2.2 OpenMP Language Terminology 13980 // Structured block - An executable statement with a single entry at the 13981 // top and a single exit at the bottom. 13982 // The point of exit cannot be a branch out of the structured block. 13983 // longjmp() and throw() must not violate the entry/exit criteria. 13984 CS->getCapturedDecl()->setNothrow(); 13985 for (int ThisCaptureLevel = 13986 getOpenMPCaptureLevels(OMPD_target_teams_distribute); 13987 ThisCaptureLevel > 1; --ThisCaptureLevel) { 13988 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 13989 // 1.2.2 OpenMP Language Terminology 13990 // Structured block - An executable statement with a single entry at the 13991 // top and a single exit at the bottom. 13992 // The point of exit cannot be a branch out of the structured block. 13993 // longjmp() and throw() must not violate the entry/exit criteria. 13994 CS->getCapturedDecl()->setNothrow(); 13995 } 13996 13997 OMPLoopBasedDirective::HelperExprs B; 13998 // In presence of clause 'collapse' with number of loops, it will 13999 // define the nested loops number. 14000 unsigned NestedLoopCount = checkOpenMPLoop( 14001 OMPD_target_teams_distribute, getCollapseNumberExpr(Clauses), 14002 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 14003 VarsWithImplicitDSA, B); 14004 if (NestedLoopCount == 0) 14005 return StmtError(); 14006 14007 assert((CurContext->isDependentContext() || B.builtAll()) && 14008 "omp target teams distribute loop exprs were not built"); 14009 14010 setFunctionHasBranchProtectedScope(); 14011 return OMPTargetTeamsDistributeDirective::Create( 14012 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 14013 } 14014 14015 StmtResult Sema::ActOnOpenMPTargetTeamsDistributeParallelForDirective( 14016 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 14017 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 14018 if (!AStmt) 14019 return StmtError(); 14020 14021 auto *CS = cast<CapturedStmt>(AStmt); 14022 // 1.2.2 OpenMP Language Terminology 14023 // Structured block - An executable statement with a single entry at the 14024 // top and a single exit at the bottom. 14025 // The point of exit cannot be a branch out of the structured block. 14026 // longjmp() and throw() must not violate the entry/exit criteria. 14027 CS->getCapturedDecl()->setNothrow(); 14028 for (int ThisCaptureLevel = 14029 getOpenMPCaptureLevels(OMPD_target_teams_distribute_parallel_for); 14030 ThisCaptureLevel > 1; --ThisCaptureLevel) { 14031 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 14032 // 1.2.2 OpenMP Language Terminology 14033 // Structured block - An executable statement with a single entry at the 14034 // top and a single exit at the bottom. 14035 // The point of exit cannot be a branch out of the structured block. 14036 // longjmp() and throw() must not violate the entry/exit criteria. 14037 CS->getCapturedDecl()->setNothrow(); 14038 } 14039 14040 OMPLoopBasedDirective::HelperExprs B; 14041 // In presence of clause 'collapse' with number of loops, it will 14042 // define the nested loops number. 14043 unsigned NestedLoopCount = checkOpenMPLoop( 14044 OMPD_target_teams_distribute_parallel_for, getCollapseNumberExpr(Clauses), 14045 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 14046 VarsWithImplicitDSA, B); 14047 if (NestedLoopCount == 0) 14048 return StmtError(); 14049 14050 assert((CurContext->isDependentContext() || B.builtAll()) && 14051 "omp target teams distribute parallel for loop exprs were not built"); 14052 14053 if (!CurContext->isDependentContext()) { 14054 // Finalize the clauses that need pre-built expressions for CodeGen. 14055 for (OMPClause *C : Clauses) { 14056 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 14057 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 14058 B.NumIterations, *this, CurScope, 14059 DSAStack)) 14060 return StmtError(); 14061 } 14062 } 14063 14064 setFunctionHasBranchProtectedScope(); 14065 return OMPTargetTeamsDistributeParallelForDirective::Create( 14066 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B, 14067 DSAStack->getTaskgroupReductionRef(), DSAStack->isCancelRegion()); 14068 } 14069 14070 StmtResult Sema::ActOnOpenMPTargetTeamsDistributeParallelForSimdDirective( 14071 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 14072 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 14073 if (!AStmt) 14074 return StmtError(); 14075 14076 auto *CS = cast<CapturedStmt>(AStmt); 14077 // 1.2.2 OpenMP Language Terminology 14078 // Structured block - An executable statement with a single entry at the 14079 // top and a single exit at the bottom. 14080 // The point of exit cannot be a branch out of the structured block. 14081 // longjmp() and throw() must not violate the entry/exit criteria. 14082 CS->getCapturedDecl()->setNothrow(); 14083 for (int ThisCaptureLevel = getOpenMPCaptureLevels( 14084 OMPD_target_teams_distribute_parallel_for_simd); 14085 ThisCaptureLevel > 1; --ThisCaptureLevel) { 14086 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 14087 // 1.2.2 OpenMP Language Terminology 14088 // Structured block - An executable statement with a single entry at the 14089 // top and a single exit at the bottom. 14090 // The point of exit cannot be a branch out of the structured block. 14091 // longjmp() and throw() must not violate the entry/exit criteria. 14092 CS->getCapturedDecl()->setNothrow(); 14093 } 14094 14095 OMPLoopBasedDirective::HelperExprs B; 14096 // In presence of clause 'collapse' with number of loops, it will 14097 // define the nested loops number. 14098 unsigned NestedLoopCount = 14099 checkOpenMPLoop(OMPD_target_teams_distribute_parallel_for_simd, 14100 getCollapseNumberExpr(Clauses), 14101 nullptr /*ordered not a clause on distribute*/, CS, *this, 14102 *DSAStack, VarsWithImplicitDSA, B); 14103 if (NestedLoopCount == 0) 14104 return StmtError(); 14105 14106 assert((CurContext->isDependentContext() || B.builtAll()) && 14107 "omp target teams distribute parallel for simd loop exprs were not " 14108 "built"); 14109 14110 if (!CurContext->isDependentContext()) { 14111 // Finalize the clauses that need pre-built expressions for CodeGen. 14112 for (OMPClause *C : Clauses) { 14113 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 14114 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 14115 B.NumIterations, *this, CurScope, 14116 DSAStack)) 14117 return StmtError(); 14118 } 14119 } 14120 14121 if (checkSimdlenSafelenSpecified(*this, Clauses)) 14122 return StmtError(); 14123 14124 setFunctionHasBranchProtectedScope(); 14125 return OMPTargetTeamsDistributeParallelForSimdDirective::Create( 14126 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 14127 } 14128 14129 StmtResult Sema::ActOnOpenMPTargetTeamsDistributeSimdDirective( 14130 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 14131 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 14132 if (!AStmt) 14133 return StmtError(); 14134 14135 auto *CS = cast<CapturedStmt>(AStmt); 14136 // 1.2.2 OpenMP Language Terminology 14137 // Structured block - An executable statement with a single entry at the 14138 // top and a single exit at the bottom. 14139 // The point of exit cannot be a branch out of the structured block. 14140 // longjmp() and throw() must not violate the entry/exit criteria. 14141 CS->getCapturedDecl()->setNothrow(); 14142 for (int ThisCaptureLevel = 14143 getOpenMPCaptureLevels(OMPD_target_teams_distribute_simd); 14144 ThisCaptureLevel > 1; --ThisCaptureLevel) { 14145 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 14146 // 1.2.2 OpenMP Language Terminology 14147 // Structured block - An executable statement with a single entry at the 14148 // top and a single exit at the bottom. 14149 // The point of exit cannot be a branch out of the structured block. 14150 // longjmp() and throw() must not violate the entry/exit criteria. 14151 CS->getCapturedDecl()->setNothrow(); 14152 } 14153 14154 OMPLoopBasedDirective::HelperExprs B; 14155 // In presence of clause 'collapse' with number of loops, it will 14156 // define the nested loops number. 14157 unsigned NestedLoopCount = checkOpenMPLoop( 14158 OMPD_target_teams_distribute_simd, getCollapseNumberExpr(Clauses), 14159 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 14160 VarsWithImplicitDSA, B); 14161 if (NestedLoopCount == 0) 14162 return StmtError(); 14163 14164 assert((CurContext->isDependentContext() || B.builtAll()) && 14165 "omp target teams distribute simd loop exprs were not built"); 14166 14167 if (!CurContext->isDependentContext()) { 14168 // Finalize the clauses that need pre-built expressions for CodeGen. 14169 for (OMPClause *C : Clauses) { 14170 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 14171 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 14172 B.NumIterations, *this, CurScope, 14173 DSAStack)) 14174 return StmtError(); 14175 } 14176 } 14177 14178 if (checkSimdlenSafelenSpecified(*this, Clauses)) 14179 return StmtError(); 14180 14181 setFunctionHasBranchProtectedScope(); 14182 return OMPTargetTeamsDistributeSimdDirective::Create( 14183 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 14184 } 14185 14186 bool Sema::checkTransformableLoopNest( 14187 OpenMPDirectiveKind Kind, Stmt *AStmt, int NumLoops, 14188 SmallVectorImpl<OMPLoopBasedDirective::HelperExprs> &LoopHelpers, 14189 Stmt *&Body, 14190 SmallVectorImpl<SmallVector<llvm::PointerUnion<Stmt *, Decl *>, 0>> 14191 &OriginalInits) { 14192 OriginalInits.emplace_back(); 14193 bool Result = OMPLoopBasedDirective::doForAllLoops( 14194 AStmt->IgnoreContainers(), /*TryImperfectlyNestedLoops=*/false, NumLoops, 14195 [this, &LoopHelpers, &Body, &OriginalInits, Kind](unsigned Cnt, 14196 Stmt *CurStmt) { 14197 VarsWithInheritedDSAType TmpDSA; 14198 unsigned SingleNumLoops = 14199 checkOpenMPLoop(Kind, nullptr, nullptr, CurStmt, *this, *DSAStack, 14200 TmpDSA, LoopHelpers[Cnt]); 14201 if (SingleNumLoops == 0) 14202 return true; 14203 assert(SingleNumLoops == 1 && "Expect single loop iteration space"); 14204 if (auto *For = dyn_cast<ForStmt>(CurStmt)) { 14205 OriginalInits.back().push_back(For->getInit()); 14206 Body = For->getBody(); 14207 } else { 14208 assert(isa<CXXForRangeStmt>(CurStmt) && 14209 "Expected canonical for or range-based for loops."); 14210 auto *CXXFor = cast<CXXForRangeStmt>(CurStmt); 14211 OriginalInits.back().push_back(CXXFor->getBeginStmt()); 14212 Body = CXXFor->getBody(); 14213 } 14214 OriginalInits.emplace_back(); 14215 return false; 14216 }, 14217 [&OriginalInits](OMPLoopBasedDirective *Transform) { 14218 Stmt *DependentPreInits; 14219 if (auto *Dir = dyn_cast<OMPTileDirective>(Transform)) 14220 DependentPreInits = Dir->getPreInits(); 14221 else if (auto *Dir = dyn_cast<OMPUnrollDirective>(Transform)) 14222 DependentPreInits = Dir->getPreInits(); 14223 else 14224 llvm_unreachable("Unhandled loop transformation"); 14225 if (!DependentPreInits) 14226 return; 14227 llvm::append_range(OriginalInits.back(), 14228 cast<DeclStmt>(DependentPreInits)->getDeclGroup()); 14229 }); 14230 assert(OriginalInits.back().empty() && "No preinit after innermost loop"); 14231 OriginalInits.pop_back(); 14232 return Result; 14233 } 14234 14235 StmtResult Sema::ActOnOpenMPTileDirective(ArrayRef<OMPClause *> Clauses, 14236 Stmt *AStmt, SourceLocation StartLoc, 14237 SourceLocation EndLoc) { 14238 auto SizesClauses = 14239 OMPExecutableDirective::getClausesOfKind<OMPSizesClause>(Clauses); 14240 if (SizesClauses.empty()) { 14241 // A missing 'sizes' clause is already reported by the parser. 14242 return StmtError(); 14243 } 14244 const OMPSizesClause *SizesClause = *SizesClauses.begin(); 14245 unsigned NumLoops = SizesClause->getNumSizes(); 14246 14247 // Empty statement should only be possible if there already was an error. 14248 if (!AStmt) 14249 return StmtError(); 14250 14251 // Verify and diagnose loop nest. 14252 SmallVector<OMPLoopBasedDirective::HelperExprs, 4> LoopHelpers(NumLoops); 14253 Stmt *Body = nullptr; 14254 SmallVector<SmallVector<llvm::PointerUnion<Stmt *, Decl *>, 0>, 4> 14255 OriginalInits; 14256 if (!checkTransformableLoopNest(OMPD_tile, AStmt, NumLoops, LoopHelpers, Body, 14257 OriginalInits)) 14258 return StmtError(); 14259 14260 // Delay tiling to when template is completely instantiated. 14261 if (CurContext->isDependentContext()) 14262 return OMPTileDirective::Create(Context, StartLoc, EndLoc, Clauses, 14263 NumLoops, AStmt, nullptr, nullptr); 14264 14265 SmallVector<Decl *, 4> PreInits; 14266 14267 // Create iteration variables for the generated loops. 14268 SmallVector<VarDecl *, 4> FloorIndVars; 14269 SmallVector<VarDecl *, 4> TileIndVars; 14270 FloorIndVars.resize(NumLoops); 14271 TileIndVars.resize(NumLoops); 14272 for (unsigned I = 0; I < NumLoops; ++I) { 14273 OMPLoopBasedDirective::HelperExprs &LoopHelper = LoopHelpers[I]; 14274 14275 assert(LoopHelper.Counters.size() == 1 && 14276 "Expect single-dimensional loop iteration space"); 14277 auto *OrigCntVar = cast<DeclRefExpr>(LoopHelper.Counters.front()); 14278 std::string OrigVarName = OrigCntVar->getNameInfo().getAsString(); 14279 DeclRefExpr *IterVarRef = cast<DeclRefExpr>(LoopHelper.IterationVarRef); 14280 QualType CntTy = IterVarRef->getType(); 14281 14282 // Iteration variable for the floor (i.e. outer) loop. 14283 { 14284 std::string FloorCntName = 14285 (Twine(".floor_") + llvm::utostr(I) + ".iv." + OrigVarName).str(); 14286 VarDecl *FloorCntDecl = 14287 buildVarDecl(*this, {}, CntTy, FloorCntName, nullptr, OrigCntVar); 14288 FloorIndVars[I] = FloorCntDecl; 14289 } 14290 14291 // Iteration variable for the tile (i.e. inner) loop. 14292 { 14293 std::string TileCntName = 14294 (Twine(".tile_") + llvm::utostr(I) + ".iv." + OrigVarName).str(); 14295 14296 // Reuse the iteration variable created by checkOpenMPLoop. It is also 14297 // used by the expressions to derive the original iteration variable's 14298 // value from the logical iteration number. 14299 auto *TileCntDecl = cast<VarDecl>(IterVarRef->getDecl()); 14300 TileCntDecl->setDeclName(&PP.getIdentifierTable().get(TileCntName)); 14301 TileIndVars[I] = TileCntDecl; 14302 } 14303 for (auto &P : OriginalInits[I]) { 14304 if (auto *D = P.dyn_cast<Decl *>()) 14305 PreInits.push_back(D); 14306 else if (auto *PI = dyn_cast_or_null<DeclStmt>(P.dyn_cast<Stmt *>())) 14307 PreInits.append(PI->decl_begin(), PI->decl_end()); 14308 } 14309 if (auto *PI = cast_or_null<DeclStmt>(LoopHelper.PreInits)) 14310 PreInits.append(PI->decl_begin(), PI->decl_end()); 14311 // Gather declarations for the data members used as counters. 14312 for (Expr *CounterRef : LoopHelper.Counters) { 14313 auto *CounterDecl = cast<DeclRefExpr>(CounterRef)->getDecl(); 14314 if (isa<OMPCapturedExprDecl>(CounterDecl)) 14315 PreInits.push_back(CounterDecl); 14316 } 14317 } 14318 14319 // Once the original iteration values are set, append the innermost body. 14320 Stmt *Inner = Body; 14321 14322 // Create tile loops from the inside to the outside. 14323 for (int I = NumLoops - 1; I >= 0; --I) { 14324 OMPLoopBasedDirective::HelperExprs &LoopHelper = LoopHelpers[I]; 14325 Expr *NumIterations = LoopHelper.NumIterations; 14326 auto *OrigCntVar = cast<DeclRefExpr>(LoopHelper.Counters[0]); 14327 QualType CntTy = OrigCntVar->getType(); 14328 Expr *DimTileSize = SizesClause->getSizesRefs()[I]; 14329 Scope *CurScope = getCurScope(); 14330 14331 // Commonly used variables. 14332 DeclRefExpr *TileIV = buildDeclRefExpr(*this, TileIndVars[I], CntTy, 14333 OrigCntVar->getExprLoc()); 14334 DeclRefExpr *FloorIV = buildDeclRefExpr(*this, FloorIndVars[I], CntTy, 14335 OrigCntVar->getExprLoc()); 14336 14337 // For init-statement: auto .tile.iv = .floor.iv 14338 AddInitializerToDecl(TileIndVars[I], DefaultLvalueConversion(FloorIV).get(), 14339 /*DirectInit=*/false); 14340 Decl *CounterDecl = TileIndVars[I]; 14341 StmtResult InitStmt = new (Context) 14342 DeclStmt(DeclGroupRef::Create(Context, &CounterDecl, 1), 14343 OrigCntVar->getBeginLoc(), OrigCntVar->getEndLoc()); 14344 if (!InitStmt.isUsable()) 14345 return StmtError(); 14346 14347 // For cond-expression: .tile.iv < min(.floor.iv + DimTileSize, 14348 // NumIterations) 14349 ExprResult EndOfTile = BuildBinOp(CurScope, LoopHelper.Cond->getExprLoc(), 14350 BO_Add, FloorIV, DimTileSize); 14351 if (!EndOfTile.isUsable()) 14352 return StmtError(); 14353 ExprResult IsPartialTile = 14354 BuildBinOp(CurScope, LoopHelper.Cond->getExprLoc(), BO_LT, 14355 NumIterations, EndOfTile.get()); 14356 if (!IsPartialTile.isUsable()) 14357 return StmtError(); 14358 ExprResult MinTileAndIterSpace = ActOnConditionalOp( 14359 LoopHelper.Cond->getBeginLoc(), LoopHelper.Cond->getEndLoc(), 14360 IsPartialTile.get(), NumIterations, EndOfTile.get()); 14361 if (!MinTileAndIterSpace.isUsable()) 14362 return StmtError(); 14363 ExprResult CondExpr = BuildBinOp(CurScope, LoopHelper.Cond->getExprLoc(), 14364 BO_LT, TileIV, MinTileAndIterSpace.get()); 14365 if (!CondExpr.isUsable()) 14366 return StmtError(); 14367 14368 // For incr-statement: ++.tile.iv 14369 ExprResult IncrStmt = 14370 BuildUnaryOp(CurScope, LoopHelper.Inc->getExprLoc(), UO_PreInc, TileIV); 14371 if (!IncrStmt.isUsable()) 14372 return StmtError(); 14373 14374 // Statements to set the original iteration variable's value from the 14375 // logical iteration number. 14376 // Generated for loop is: 14377 // Original_for_init; 14378 // for (auto .tile.iv = .floor.iv; .tile.iv < min(.floor.iv + DimTileSize, 14379 // NumIterations); ++.tile.iv) { 14380 // Original_Body; 14381 // Original_counter_update; 14382 // } 14383 // FIXME: If the innermost body is an loop itself, inserting these 14384 // statements stops it being recognized as a perfectly nested loop (e.g. 14385 // for applying tiling again). If this is the case, sink the expressions 14386 // further into the inner loop. 14387 SmallVector<Stmt *, 4> BodyParts; 14388 BodyParts.append(LoopHelper.Updates.begin(), LoopHelper.Updates.end()); 14389 BodyParts.push_back(Inner); 14390 Inner = CompoundStmt::Create(Context, BodyParts, Inner->getBeginLoc(), 14391 Inner->getEndLoc()); 14392 Inner = new (Context) 14393 ForStmt(Context, InitStmt.get(), CondExpr.get(), nullptr, 14394 IncrStmt.get(), Inner, LoopHelper.Init->getBeginLoc(), 14395 LoopHelper.Init->getBeginLoc(), LoopHelper.Inc->getEndLoc()); 14396 } 14397 14398 // Create floor loops from the inside to the outside. 14399 for (int I = NumLoops - 1; I >= 0; --I) { 14400 auto &LoopHelper = LoopHelpers[I]; 14401 Expr *NumIterations = LoopHelper.NumIterations; 14402 DeclRefExpr *OrigCntVar = cast<DeclRefExpr>(LoopHelper.Counters[0]); 14403 QualType CntTy = OrigCntVar->getType(); 14404 Expr *DimTileSize = SizesClause->getSizesRefs()[I]; 14405 Scope *CurScope = getCurScope(); 14406 14407 // Commonly used variables. 14408 DeclRefExpr *FloorIV = buildDeclRefExpr(*this, FloorIndVars[I], CntTy, 14409 OrigCntVar->getExprLoc()); 14410 14411 // For init-statement: auto .floor.iv = 0 14412 AddInitializerToDecl( 14413 FloorIndVars[I], 14414 ActOnIntegerConstant(LoopHelper.Init->getExprLoc(), 0).get(), 14415 /*DirectInit=*/false); 14416 Decl *CounterDecl = FloorIndVars[I]; 14417 StmtResult InitStmt = new (Context) 14418 DeclStmt(DeclGroupRef::Create(Context, &CounterDecl, 1), 14419 OrigCntVar->getBeginLoc(), OrigCntVar->getEndLoc()); 14420 if (!InitStmt.isUsable()) 14421 return StmtError(); 14422 14423 // For cond-expression: .floor.iv < NumIterations 14424 ExprResult CondExpr = BuildBinOp(CurScope, LoopHelper.Cond->getExprLoc(), 14425 BO_LT, FloorIV, NumIterations); 14426 if (!CondExpr.isUsable()) 14427 return StmtError(); 14428 14429 // For incr-statement: .floor.iv += DimTileSize 14430 ExprResult IncrStmt = BuildBinOp(CurScope, LoopHelper.Inc->getExprLoc(), 14431 BO_AddAssign, FloorIV, DimTileSize); 14432 if (!IncrStmt.isUsable()) 14433 return StmtError(); 14434 14435 Inner = new (Context) 14436 ForStmt(Context, InitStmt.get(), CondExpr.get(), nullptr, 14437 IncrStmt.get(), Inner, LoopHelper.Init->getBeginLoc(), 14438 LoopHelper.Init->getBeginLoc(), LoopHelper.Inc->getEndLoc()); 14439 } 14440 14441 return OMPTileDirective::Create(Context, StartLoc, EndLoc, Clauses, NumLoops, 14442 AStmt, Inner, 14443 buildPreInits(Context, PreInits)); 14444 } 14445 14446 StmtResult Sema::ActOnOpenMPUnrollDirective(ArrayRef<OMPClause *> Clauses, 14447 Stmt *AStmt, 14448 SourceLocation StartLoc, 14449 SourceLocation EndLoc) { 14450 // Empty statement should only be possible if there already was an error. 14451 if (!AStmt) 14452 return StmtError(); 14453 14454 if (checkMutuallyExclusiveClauses(*this, Clauses, {OMPC_partial, OMPC_full})) 14455 return StmtError(); 14456 14457 const OMPFullClause *FullClause = 14458 OMPExecutableDirective::getSingleClause<OMPFullClause>(Clauses); 14459 const OMPPartialClause *PartialClause = 14460 OMPExecutableDirective::getSingleClause<OMPPartialClause>(Clauses); 14461 assert(!(FullClause && PartialClause) && 14462 "mutual exclusivity must have been checked before"); 14463 14464 constexpr unsigned NumLoops = 1; 14465 Stmt *Body = nullptr; 14466 SmallVector<OMPLoopBasedDirective::HelperExprs, NumLoops> LoopHelpers( 14467 NumLoops); 14468 SmallVector<SmallVector<llvm::PointerUnion<Stmt *, Decl *>, 0>, NumLoops + 1> 14469 OriginalInits; 14470 if (!checkTransformableLoopNest(OMPD_unroll, AStmt, NumLoops, LoopHelpers, 14471 Body, OriginalInits)) 14472 return StmtError(); 14473 14474 unsigned NumGeneratedLoops = PartialClause ? 1 : 0; 14475 14476 // Delay unrolling to when template is completely instantiated. 14477 if (CurContext->isDependentContext()) 14478 return OMPUnrollDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt, 14479 NumGeneratedLoops, nullptr, nullptr); 14480 14481 OMPLoopBasedDirective::HelperExprs &LoopHelper = LoopHelpers.front(); 14482 14483 if (FullClause) { 14484 if (!VerifyPositiveIntegerConstantInClause( 14485 LoopHelper.NumIterations, OMPC_full, /*StrictlyPositive=*/false, 14486 /*SuppressExprDiags=*/true) 14487 .isUsable()) { 14488 Diag(AStmt->getBeginLoc(), diag::err_omp_unroll_full_variable_trip_count); 14489 Diag(FullClause->getBeginLoc(), diag::note_omp_directive_here) 14490 << "#pragma omp unroll full"; 14491 return StmtError(); 14492 } 14493 } 14494 14495 // The generated loop may only be passed to other loop-associated directive 14496 // when a partial clause is specified. Without the requirement it is 14497 // sufficient to generate loop unroll metadata at code-generation. 14498 if (NumGeneratedLoops == 0) 14499 return OMPUnrollDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt, 14500 NumGeneratedLoops, nullptr, nullptr); 14501 14502 // Otherwise, we need to provide a de-sugared/transformed AST that can be 14503 // associated with another loop directive. 14504 // 14505 // The canonical loop analysis return by checkTransformableLoopNest assumes 14506 // the following structure to be the same loop without transformations or 14507 // directives applied: \code OriginalInits; LoopHelper.PreInits; 14508 // LoopHelper.Counters; 14509 // for (; IV < LoopHelper.NumIterations; ++IV) { 14510 // LoopHelper.Updates; 14511 // Body; 14512 // } 14513 // \endcode 14514 // where IV is a variable declared and initialized to 0 in LoopHelper.PreInits 14515 // and referenced by LoopHelper.IterationVarRef. 14516 // 14517 // The unrolling directive transforms this into the following loop: 14518 // \code 14519 // OriginalInits; \ 14520 // LoopHelper.PreInits; > NewPreInits 14521 // LoopHelper.Counters; / 14522 // for (auto UIV = 0; UIV < LoopHelper.NumIterations; UIV+=Factor) { 14523 // #pragma clang loop unroll_count(Factor) 14524 // for (IV = UIV; IV < UIV + Factor && UIV < LoopHelper.NumIterations; ++IV) 14525 // { 14526 // LoopHelper.Updates; 14527 // Body; 14528 // } 14529 // } 14530 // \endcode 14531 // where UIV is a new logical iteration counter. IV must be the same VarDecl 14532 // as the original LoopHelper.IterationVarRef because LoopHelper.Updates 14533 // references it. If the partially unrolled loop is associated with another 14534 // loop directive (like an OMPForDirective), it will use checkOpenMPLoop to 14535 // analyze this loop, i.e. the outer loop must fulfill the constraints of an 14536 // OpenMP canonical loop. The inner loop is not an associable canonical loop 14537 // and only exists to defer its unrolling to LLVM's LoopUnroll instead of 14538 // doing it in the frontend (by adding loop metadata). NewPreInits becomes a 14539 // property of the OMPLoopBasedDirective instead of statements in 14540 // CompoundStatement. This is to allow the loop to become a non-outermost loop 14541 // of a canonical loop nest where these PreInits are emitted before the 14542 // outermost directive. 14543 14544 // Determine the PreInit declarations. 14545 SmallVector<Decl *, 4> PreInits; 14546 assert(OriginalInits.size() == 1 && 14547 "Expecting a single-dimensional loop iteration space"); 14548 for (auto &P : OriginalInits[0]) { 14549 if (auto *D = P.dyn_cast<Decl *>()) 14550 PreInits.push_back(D); 14551 else if (auto *PI = dyn_cast_or_null<DeclStmt>(P.dyn_cast<Stmt *>())) 14552 PreInits.append(PI->decl_begin(), PI->decl_end()); 14553 } 14554 if (auto *PI = cast_or_null<DeclStmt>(LoopHelper.PreInits)) 14555 PreInits.append(PI->decl_begin(), PI->decl_end()); 14556 // Gather declarations for the data members used as counters. 14557 for (Expr *CounterRef : LoopHelper.Counters) { 14558 auto *CounterDecl = cast<DeclRefExpr>(CounterRef)->getDecl(); 14559 if (isa<OMPCapturedExprDecl>(CounterDecl)) 14560 PreInits.push_back(CounterDecl); 14561 } 14562 14563 auto *IterationVarRef = cast<DeclRefExpr>(LoopHelper.IterationVarRef); 14564 QualType IVTy = IterationVarRef->getType(); 14565 assert(LoopHelper.Counters.size() == 1 && 14566 "Expecting a single-dimensional loop iteration space"); 14567 auto *OrigVar = cast<DeclRefExpr>(LoopHelper.Counters.front()); 14568 14569 // Determine the unroll factor. 14570 uint64_t Factor; 14571 SourceLocation FactorLoc; 14572 if (Expr *FactorVal = PartialClause->getFactor()) { 14573 Factor = FactorVal->getIntegerConstantExpr(Context)->getZExtValue(); 14574 FactorLoc = FactorVal->getExprLoc(); 14575 } else { 14576 // TODO: Use a better profitability model. 14577 Factor = 2; 14578 } 14579 assert(Factor > 0 && "Expected positive unroll factor"); 14580 auto MakeFactorExpr = [this, Factor, IVTy, FactorLoc]() { 14581 return IntegerLiteral::Create( 14582 Context, llvm::APInt(Context.getIntWidth(IVTy), Factor), IVTy, 14583 FactorLoc); 14584 }; 14585 14586 // Iteration variable SourceLocations. 14587 SourceLocation OrigVarLoc = OrigVar->getExprLoc(); 14588 SourceLocation OrigVarLocBegin = OrigVar->getBeginLoc(); 14589 SourceLocation OrigVarLocEnd = OrigVar->getEndLoc(); 14590 14591 // Internal variable names. 14592 std::string OrigVarName = OrigVar->getNameInfo().getAsString(); 14593 std::string OuterIVName = (Twine(".unrolled.iv.") + OrigVarName).str(); 14594 std::string InnerIVName = (Twine(".unroll_inner.iv.") + OrigVarName).str(); 14595 std::string InnerTripCountName = 14596 (Twine(".unroll_inner.tripcount.") + OrigVarName).str(); 14597 14598 // Create the iteration variable for the unrolled loop. 14599 VarDecl *OuterIVDecl = 14600 buildVarDecl(*this, {}, IVTy, OuterIVName, nullptr, OrigVar); 14601 auto MakeOuterRef = [this, OuterIVDecl, IVTy, OrigVarLoc]() { 14602 return buildDeclRefExpr(*this, OuterIVDecl, IVTy, OrigVarLoc); 14603 }; 14604 14605 // Iteration variable for the inner loop: Reuse the iteration variable created 14606 // by checkOpenMPLoop. 14607 auto *InnerIVDecl = cast<VarDecl>(IterationVarRef->getDecl()); 14608 InnerIVDecl->setDeclName(&PP.getIdentifierTable().get(InnerIVName)); 14609 auto MakeInnerRef = [this, InnerIVDecl, IVTy, OrigVarLoc]() { 14610 return buildDeclRefExpr(*this, InnerIVDecl, IVTy, OrigVarLoc); 14611 }; 14612 14613 // Make a copy of the NumIterations expression for each use: By the AST 14614 // constraints, every expression object in a DeclContext must be unique. 14615 CaptureVars CopyTransformer(*this); 14616 auto MakeNumIterations = [&CopyTransformer, &LoopHelper]() -> Expr * { 14617 return AssertSuccess( 14618 CopyTransformer.TransformExpr(LoopHelper.NumIterations)); 14619 }; 14620 14621 // Inner For init-statement: auto .unroll_inner.iv = .unrolled.iv 14622 ExprResult LValueConv = DefaultLvalueConversion(MakeOuterRef()); 14623 AddInitializerToDecl(InnerIVDecl, LValueConv.get(), /*DirectInit=*/false); 14624 StmtResult InnerInit = new (Context) 14625 DeclStmt(DeclGroupRef(InnerIVDecl), OrigVarLocBegin, OrigVarLocEnd); 14626 if (!InnerInit.isUsable()) 14627 return StmtError(); 14628 14629 // Inner For cond-expression: 14630 // \code 14631 // .unroll_inner.iv < .unrolled.iv + Factor && 14632 // .unroll_inner.iv < NumIterations 14633 // \endcode 14634 // This conjunction of two conditions allows ScalarEvolution to derive the 14635 // maximum trip count of the inner loop. 14636 ExprResult EndOfTile = BuildBinOp(CurScope, LoopHelper.Cond->getExprLoc(), 14637 BO_Add, MakeOuterRef(), MakeFactorExpr()); 14638 if (!EndOfTile.isUsable()) 14639 return StmtError(); 14640 ExprResult InnerCond1 = BuildBinOp(CurScope, LoopHelper.Cond->getExprLoc(), 14641 BO_LT, MakeInnerRef(), EndOfTile.get()); 14642 if (!InnerCond1.isUsable()) 14643 return StmtError(); 14644 ExprResult InnerCond2 = 14645 BuildBinOp(CurScope, LoopHelper.Cond->getExprLoc(), BO_LT, MakeInnerRef(), 14646 MakeNumIterations()); 14647 if (!InnerCond2.isUsable()) 14648 return StmtError(); 14649 ExprResult InnerCond = 14650 BuildBinOp(CurScope, LoopHelper.Cond->getExprLoc(), BO_LAnd, 14651 InnerCond1.get(), InnerCond2.get()); 14652 if (!InnerCond.isUsable()) 14653 return StmtError(); 14654 14655 // Inner For incr-statement: ++.unroll_inner.iv 14656 ExprResult InnerIncr = BuildUnaryOp(CurScope, LoopHelper.Inc->getExprLoc(), 14657 UO_PreInc, MakeInnerRef()); 14658 if (!InnerIncr.isUsable()) 14659 return StmtError(); 14660 14661 // Inner For statement. 14662 SmallVector<Stmt *> InnerBodyStmts; 14663 InnerBodyStmts.append(LoopHelper.Updates.begin(), LoopHelper.Updates.end()); 14664 InnerBodyStmts.push_back(Body); 14665 CompoundStmt *InnerBody = CompoundStmt::Create( 14666 Context, InnerBodyStmts, Body->getBeginLoc(), Body->getEndLoc()); 14667 ForStmt *InnerFor = new (Context) 14668 ForStmt(Context, InnerInit.get(), InnerCond.get(), nullptr, 14669 InnerIncr.get(), InnerBody, LoopHelper.Init->getBeginLoc(), 14670 LoopHelper.Init->getBeginLoc(), LoopHelper.Inc->getEndLoc()); 14671 14672 // Unroll metadata for the inner loop. 14673 // This needs to take into account the remainder portion of the unrolled loop, 14674 // hence `unroll(full)` does not apply here, even though the LoopUnroll pass 14675 // supports multiple loop exits. Instead, unroll using a factor equivalent to 14676 // the maximum trip count, which will also generate a remainder loop. Just 14677 // `unroll(enable)` (which could have been useful if the user has not 14678 // specified a concrete factor; even though the outer loop cannot be 14679 // influenced anymore, would avoid more code bloat than necessary) will refuse 14680 // the loop because "Won't unroll; remainder loop could not be generated when 14681 // assuming runtime trip count". Even if it did work, it must not choose a 14682 // larger unroll factor than the maximum loop length, or it would always just 14683 // execute the remainder loop. 14684 LoopHintAttr *UnrollHintAttr = 14685 LoopHintAttr::CreateImplicit(Context, LoopHintAttr::UnrollCount, 14686 LoopHintAttr::Numeric, MakeFactorExpr()); 14687 AttributedStmt *InnerUnrolled = 14688 AttributedStmt::Create(Context, StartLoc, {UnrollHintAttr}, InnerFor); 14689 14690 // Outer For init-statement: auto .unrolled.iv = 0 14691 AddInitializerToDecl( 14692 OuterIVDecl, ActOnIntegerConstant(LoopHelper.Init->getExprLoc(), 0).get(), 14693 /*DirectInit=*/false); 14694 StmtResult OuterInit = new (Context) 14695 DeclStmt(DeclGroupRef(OuterIVDecl), OrigVarLocBegin, OrigVarLocEnd); 14696 if (!OuterInit.isUsable()) 14697 return StmtError(); 14698 14699 // Outer For cond-expression: .unrolled.iv < NumIterations 14700 ExprResult OuterConde = 14701 BuildBinOp(CurScope, LoopHelper.Cond->getExprLoc(), BO_LT, MakeOuterRef(), 14702 MakeNumIterations()); 14703 if (!OuterConde.isUsable()) 14704 return StmtError(); 14705 14706 // Outer For incr-statement: .unrolled.iv += Factor 14707 ExprResult OuterIncr = 14708 BuildBinOp(CurScope, LoopHelper.Inc->getExprLoc(), BO_AddAssign, 14709 MakeOuterRef(), MakeFactorExpr()); 14710 if (!OuterIncr.isUsable()) 14711 return StmtError(); 14712 14713 // Outer For statement. 14714 ForStmt *OuterFor = new (Context) 14715 ForStmt(Context, OuterInit.get(), OuterConde.get(), nullptr, 14716 OuterIncr.get(), InnerUnrolled, LoopHelper.Init->getBeginLoc(), 14717 LoopHelper.Init->getBeginLoc(), LoopHelper.Inc->getEndLoc()); 14718 14719 return OMPUnrollDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt, 14720 NumGeneratedLoops, OuterFor, 14721 buildPreInits(Context, PreInits)); 14722 } 14723 14724 OMPClause *Sema::ActOnOpenMPSingleExprClause(OpenMPClauseKind Kind, Expr *Expr, 14725 SourceLocation StartLoc, 14726 SourceLocation LParenLoc, 14727 SourceLocation EndLoc) { 14728 OMPClause *Res = nullptr; 14729 switch (Kind) { 14730 case OMPC_final: 14731 Res = ActOnOpenMPFinalClause(Expr, StartLoc, LParenLoc, EndLoc); 14732 break; 14733 case OMPC_num_threads: 14734 Res = ActOnOpenMPNumThreadsClause(Expr, StartLoc, LParenLoc, EndLoc); 14735 break; 14736 case OMPC_safelen: 14737 Res = ActOnOpenMPSafelenClause(Expr, StartLoc, LParenLoc, EndLoc); 14738 break; 14739 case OMPC_simdlen: 14740 Res = ActOnOpenMPSimdlenClause(Expr, StartLoc, LParenLoc, EndLoc); 14741 break; 14742 case OMPC_allocator: 14743 Res = ActOnOpenMPAllocatorClause(Expr, StartLoc, LParenLoc, EndLoc); 14744 break; 14745 case OMPC_collapse: 14746 Res = ActOnOpenMPCollapseClause(Expr, StartLoc, LParenLoc, EndLoc); 14747 break; 14748 case OMPC_ordered: 14749 Res = ActOnOpenMPOrderedClause(StartLoc, EndLoc, LParenLoc, Expr); 14750 break; 14751 case OMPC_num_teams: 14752 Res = ActOnOpenMPNumTeamsClause(Expr, StartLoc, LParenLoc, EndLoc); 14753 break; 14754 case OMPC_thread_limit: 14755 Res = ActOnOpenMPThreadLimitClause(Expr, StartLoc, LParenLoc, EndLoc); 14756 break; 14757 case OMPC_priority: 14758 Res = ActOnOpenMPPriorityClause(Expr, StartLoc, LParenLoc, EndLoc); 14759 break; 14760 case OMPC_grainsize: 14761 Res = ActOnOpenMPGrainsizeClause(Expr, StartLoc, LParenLoc, EndLoc); 14762 break; 14763 case OMPC_num_tasks: 14764 Res = ActOnOpenMPNumTasksClause(Expr, StartLoc, LParenLoc, EndLoc); 14765 break; 14766 case OMPC_hint: 14767 Res = ActOnOpenMPHintClause(Expr, StartLoc, LParenLoc, EndLoc); 14768 break; 14769 case OMPC_depobj: 14770 Res = ActOnOpenMPDepobjClause(Expr, StartLoc, LParenLoc, EndLoc); 14771 break; 14772 case OMPC_detach: 14773 Res = ActOnOpenMPDetachClause(Expr, StartLoc, LParenLoc, EndLoc); 14774 break; 14775 case OMPC_novariants: 14776 Res = ActOnOpenMPNovariantsClause(Expr, StartLoc, LParenLoc, EndLoc); 14777 break; 14778 case OMPC_nocontext: 14779 Res = ActOnOpenMPNocontextClause(Expr, StartLoc, LParenLoc, EndLoc); 14780 break; 14781 case OMPC_filter: 14782 Res = ActOnOpenMPFilterClause(Expr, StartLoc, LParenLoc, EndLoc); 14783 break; 14784 case OMPC_partial: 14785 Res = ActOnOpenMPPartialClause(Expr, StartLoc, LParenLoc, EndLoc); 14786 break; 14787 case OMPC_align: 14788 Res = ActOnOpenMPAlignClause(Expr, StartLoc, LParenLoc, EndLoc); 14789 break; 14790 case OMPC_device: 14791 case OMPC_if: 14792 case OMPC_default: 14793 case OMPC_proc_bind: 14794 case OMPC_schedule: 14795 case OMPC_private: 14796 case OMPC_firstprivate: 14797 case OMPC_lastprivate: 14798 case OMPC_shared: 14799 case OMPC_reduction: 14800 case OMPC_task_reduction: 14801 case OMPC_in_reduction: 14802 case OMPC_linear: 14803 case OMPC_aligned: 14804 case OMPC_copyin: 14805 case OMPC_copyprivate: 14806 case OMPC_nowait: 14807 case OMPC_untied: 14808 case OMPC_mergeable: 14809 case OMPC_threadprivate: 14810 case OMPC_sizes: 14811 case OMPC_allocate: 14812 case OMPC_flush: 14813 case OMPC_read: 14814 case OMPC_write: 14815 case OMPC_update: 14816 case OMPC_capture: 14817 case OMPC_compare: 14818 case OMPC_seq_cst: 14819 case OMPC_acq_rel: 14820 case OMPC_acquire: 14821 case OMPC_release: 14822 case OMPC_relaxed: 14823 case OMPC_depend: 14824 case OMPC_threads: 14825 case OMPC_simd: 14826 case OMPC_map: 14827 case OMPC_nogroup: 14828 case OMPC_dist_schedule: 14829 case OMPC_defaultmap: 14830 case OMPC_unknown: 14831 case OMPC_uniform: 14832 case OMPC_to: 14833 case OMPC_from: 14834 case OMPC_use_device_ptr: 14835 case OMPC_use_device_addr: 14836 case OMPC_is_device_ptr: 14837 case OMPC_unified_address: 14838 case OMPC_unified_shared_memory: 14839 case OMPC_reverse_offload: 14840 case OMPC_dynamic_allocators: 14841 case OMPC_atomic_default_mem_order: 14842 case OMPC_device_type: 14843 case OMPC_match: 14844 case OMPC_nontemporal: 14845 case OMPC_order: 14846 case OMPC_destroy: 14847 case OMPC_inclusive: 14848 case OMPC_exclusive: 14849 case OMPC_uses_allocators: 14850 case OMPC_affinity: 14851 case OMPC_when: 14852 case OMPC_bind: 14853 default: 14854 llvm_unreachable("Clause is not allowed."); 14855 } 14856 return Res; 14857 } 14858 14859 // An OpenMP directive such as 'target parallel' has two captured regions: 14860 // for the 'target' and 'parallel' respectively. This function returns 14861 // the region in which to capture expressions associated with a clause. 14862 // A return value of OMPD_unknown signifies that the expression should not 14863 // be captured. 14864 static OpenMPDirectiveKind getOpenMPCaptureRegionForClause( 14865 OpenMPDirectiveKind DKind, OpenMPClauseKind CKind, unsigned OpenMPVersion, 14866 OpenMPDirectiveKind NameModifier = OMPD_unknown) { 14867 OpenMPDirectiveKind CaptureRegion = OMPD_unknown; 14868 switch (CKind) { 14869 case OMPC_if: 14870 switch (DKind) { 14871 case OMPD_target_parallel_for_simd: 14872 if (OpenMPVersion >= 50 && 14873 (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)) { 14874 CaptureRegion = OMPD_parallel; 14875 break; 14876 } 14877 LLVM_FALLTHROUGH; 14878 case OMPD_target_parallel: 14879 case OMPD_target_parallel_for: 14880 case OMPD_target_parallel_loop: 14881 // If this clause applies to the nested 'parallel' region, capture within 14882 // the 'target' region, otherwise do not capture. 14883 if (NameModifier == OMPD_unknown || NameModifier == OMPD_parallel) 14884 CaptureRegion = OMPD_target; 14885 break; 14886 case OMPD_target_teams_distribute_parallel_for_simd: 14887 if (OpenMPVersion >= 50 && 14888 (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)) { 14889 CaptureRegion = OMPD_parallel; 14890 break; 14891 } 14892 LLVM_FALLTHROUGH; 14893 case OMPD_target_teams_distribute_parallel_for: 14894 // If this clause applies to the nested 'parallel' region, capture within 14895 // the 'teams' region, otherwise do not capture. 14896 if (NameModifier == OMPD_unknown || NameModifier == OMPD_parallel) 14897 CaptureRegion = OMPD_teams; 14898 break; 14899 case OMPD_teams_distribute_parallel_for_simd: 14900 if (OpenMPVersion >= 50 && 14901 (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)) { 14902 CaptureRegion = OMPD_parallel; 14903 break; 14904 } 14905 LLVM_FALLTHROUGH; 14906 case OMPD_teams_distribute_parallel_for: 14907 CaptureRegion = OMPD_teams; 14908 break; 14909 case OMPD_target_update: 14910 case OMPD_target_enter_data: 14911 case OMPD_target_exit_data: 14912 CaptureRegion = OMPD_task; 14913 break; 14914 case OMPD_parallel_master_taskloop: 14915 if (NameModifier == OMPD_unknown || NameModifier == OMPD_taskloop) 14916 CaptureRegion = OMPD_parallel; 14917 break; 14918 case OMPD_parallel_master_taskloop_simd: 14919 if ((OpenMPVersion <= 45 && NameModifier == OMPD_unknown) || 14920 NameModifier == OMPD_taskloop) { 14921 CaptureRegion = OMPD_parallel; 14922 break; 14923 } 14924 if (OpenMPVersion <= 45) 14925 break; 14926 if (NameModifier == OMPD_unknown || NameModifier == OMPD_simd) 14927 CaptureRegion = OMPD_taskloop; 14928 break; 14929 case OMPD_parallel_for_simd: 14930 if (OpenMPVersion <= 45) 14931 break; 14932 if (NameModifier == OMPD_unknown || NameModifier == OMPD_simd) 14933 CaptureRegion = OMPD_parallel; 14934 break; 14935 case OMPD_taskloop_simd: 14936 case OMPD_master_taskloop_simd: 14937 case OMPD_masked_taskloop_simd: 14938 if (OpenMPVersion <= 45) 14939 break; 14940 if (NameModifier == OMPD_unknown || NameModifier == OMPD_simd) 14941 CaptureRegion = OMPD_taskloop; 14942 break; 14943 case OMPD_distribute_parallel_for_simd: 14944 if (OpenMPVersion <= 45) 14945 break; 14946 if (NameModifier == OMPD_unknown || NameModifier == OMPD_simd) 14947 CaptureRegion = OMPD_parallel; 14948 break; 14949 case OMPD_target_simd: 14950 if (OpenMPVersion >= 50 && 14951 (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)) 14952 CaptureRegion = OMPD_target; 14953 break; 14954 case OMPD_teams_distribute_simd: 14955 case OMPD_target_teams_distribute_simd: 14956 if (OpenMPVersion >= 50 && 14957 (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)) 14958 CaptureRegion = OMPD_teams; 14959 break; 14960 case OMPD_cancel: 14961 case OMPD_parallel: 14962 case OMPD_parallel_master: 14963 case OMPD_parallel_masked: 14964 case OMPD_parallel_sections: 14965 case OMPD_parallel_for: 14966 case OMPD_parallel_loop: 14967 case OMPD_target: 14968 case OMPD_target_teams: 14969 case OMPD_target_teams_distribute: 14970 case OMPD_target_teams_loop: 14971 case OMPD_distribute_parallel_for: 14972 case OMPD_task: 14973 case OMPD_taskloop: 14974 case OMPD_master_taskloop: 14975 case OMPD_masked_taskloop: 14976 case OMPD_target_data: 14977 case OMPD_simd: 14978 case OMPD_for_simd: 14979 case OMPD_distribute_simd: 14980 // Do not capture if-clause expressions. 14981 break; 14982 case OMPD_threadprivate: 14983 case OMPD_allocate: 14984 case OMPD_taskyield: 14985 case OMPD_barrier: 14986 case OMPD_taskwait: 14987 case OMPD_cancellation_point: 14988 case OMPD_flush: 14989 case OMPD_depobj: 14990 case OMPD_scan: 14991 case OMPD_declare_reduction: 14992 case OMPD_declare_mapper: 14993 case OMPD_declare_simd: 14994 case OMPD_declare_variant: 14995 case OMPD_begin_declare_variant: 14996 case OMPD_end_declare_variant: 14997 case OMPD_declare_target: 14998 case OMPD_end_declare_target: 14999 case OMPD_loop: 15000 case OMPD_teams_loop: 15001 case OMPD_teams: 15002 case OMPD_tile: 15003 case OMPD_unroll: 15004 case OMPD_for: 15005 case OMPD_sections: 15006 case OMPD_section: 15007 case OMPD_single: 15008 case OMPD_master: 15009 case OMPD_masked: 15010 case OMPD_critical: 15011 case OMPD_taskgroup: 15012 case OMPD_distribute: 15013 case OMPD_ordered: 15014 case OMPD_atomic: 15015 case OMPD_teams_distribute: 15016 case OMPD_requires: 15017 case OMPD_metadirective: 15018 llvm_unreachable("Unexpected OpenMP directive with if-clause"); 15019 case OMPD_unknown: 15020 default: 15021 llvm_unreachable("Unknown OpenMP directive"); 15022 } 15023 break; 15024 case OMPC_num_threads: 15025 switch (DKind) { 15026 case OMPD_target_parallel: 15027 case OMPD_target_parallel_for: 15028 case OMPD_target_parallel_for_simd: 15029 case OMPD_target_parallel_loop: 15030 CaptureRegion = OMPD_target; 15031 break; 15032 case OMPD_teams_distribute_parallel_for: 15033 case OMPD_teams_distribute_parallel_for_simd: 15034 case OMPD_target_teams_distribute_parallel_for: 15035 case OMPD_target_teams_distribute_parallel_for_simd: 15036 CaptureRegion = OMPD_teams; 15037 break; 15038 case OMPD_parallel: 15039 case OMPD_parallel_master: 15040 case OMPD_parallel_masked: 15041 case OMPD_parallel_sections: 15042 case OMPD_parallel_for: 15043 case OMPD_parallel_for_simd: 15044 case OMPD_parallel_loop: 15045 case OMPD_distribute_parallel_for: 15046 case OMPD_distribute_parallel_for_simd: 15047 case OMPD_parallel_master_taskloop: 15048 case OMPD_parallel_master_taskloop_simd: 15049 // Do not capture num_threads-clause expressions. 15050 break; 15051 case OMPD_target_data: 15052 case OMPD_target_enter_data: 15053 case OMPD_target_exit_data: 15054 case OMPD_target_update: 15055 case OMPD_target: 15056 case OMPD_target_simd: 15057 case OMPD_target_teams: 15058 case OMPD_target_teams_distribute: 15059 case OMPD_target_teams_distribute_simd: 15060 case OMPD_cancel: 15061 case OMPD_task: 15062 case OMPD_taskloop: 15063 case OMPD_taskloop_simd: 15064 case OMPD_master_taskloop: 15065 case OMPD_masked_taskloop: 15066 case OMPD_master_taskloop_simd: 15067 case OMPD_masked_taskloop_simd: 15068 case OMPD_threadprivate: 15069 case OMPD_allocate: 15070 case OMPD_taskyield: 15071 case OMPD_barrier: 15072 case OMPD_taskwait: 15073 case OMPD_cancellation_point: 15074 case OMPD_flush: 15075 case OMPD_depobj: 15076 case OMPD_scan: 15077 case OMPD_declare_reduction: 15078 case OMPD_declare_mapper: 15079 case OMPD_declare_simd: 15080 case OMPD_declare_variant: 15081 case OMPD_begin_declare_variant: 15082 case OMPD_end_declare_variant: 15083 case OMPD_declare_target: 15084 case OMPD_end_declare_target: 15085 case OMPD_loop: 15086 case OMPD_teams_loop: 15087 case OMPD_target_teams_loop: 15088 case OMPD_teams: 15089 case OMPD_simd: 15090 case OMPD_tile: 15091 case OMPD_unroll: 15092 case OMPD_for: 15093 case OMPD_for_simd: 15094 case OMPD_sections: 15095 case OMPD_section: 15096 case OMPD_single: 15097 case OMPD_master: 15098 case OMPD_masked: 15099 case OMPD_critical: 15100 case OMPD_taskgroup: 15101 case OMPD_distribute: 15102 case OMPD_ordered: 15103 case OMPD_atomic: 15104 case OMPD_distribute_simd: 15105 case OMPD_teams_distribute: 15106 case OMPD_teams_distribute_simd: 15107 case OMPD_requires: 15108 case OMPD_metadirective: 15109 llvm_unreachable("Unexpected OpenMP directive with num_threads-clause"); 15110 case OMPD_unknown: 15111 default: 15112 llvm_unreachable("Unknown OpenMP directive"); 15113 } 15114 break; 15115 case OMPC_num_teams: 15116 switch (DKind) { 15117 case OMPD_target_teams: 15118 case OMPD_target_teams_distribute: 15119 case OMPD_target_teams_distribute_simd: 15120 case OMPD_target_teams_distribute_parallel_for: 15121 case OMPD_target_teams_distribute_parallel_for_simd: 15122 case OMPD_target_teams_loop: 15123 CaptureRegion = OMPD_target; 15124 break; 15125 case OMPD_teams_distribute_parallel_for: 15126 case OMPD_teams_distribute_parallel_for_simd: 15127 case OMPD_teams: 15128 case OMPD_teams_distribute: 15129 case OMPD_teams_distribute_simd: 15130 case OMPD_teams_loop: 15131 // Do not capture num_teams-clause expressions. 15132 break; 15133 case OMPD_distribute_parallel_for: 15134 case OMPD_distribute_parallel_for_simd: 15135 case OMPD_task: 15136 case OMPD_taskloop: 15137 case OMPD_taskloop_simd: 15138 case OMPD_master_taskloop: 15139 case OMPD_masked_taskloop: 15140 case OMPD_master_taskloop_simd: 15141 case OMPD_masked_taskloop_simd: 15142 case OMPD_parallel_master_taskloop: 15143 case OMPD_parallel_master_taskloop_simd: 15144 case OMPD_target_data: 15145 case OMPD_target_enter_data: 15146 case OMPD_target_exit_data: 15147 case OMPD_target_update: 15148 case OMPD_cancel: 15149 case OMPD_parallel: 15150 case OMPD_parallel_master: 15151 case OMPD_parallel_masked: 15152 case OMPD_parallel_sections: 15153 case OMPD_parallel_for: 15154 case OMPD_parallel_for_simd: 15155 case OMPD_parallel_loop: 15156 case OMPD_target: 15157 case OMPD_target_simd: 15158 case OMPD_target_parallel: 15159 case OMPD_target_parallel_for: 15160 case OMPD_target_parallel_for_simd: 15161 case OMPD_target_parallel_loop: 15162 case OMPD_threadprivate: 15163 case OMPD_allocate: 15164 case OMPD_taskyield: 15165 case OMPD_barrier: 15166 case OMPD_taskwait: 15167 case OMPD_cancellation_point: 15168 case OMPD_flush: 15169 case OMPD_depobj: 15170 case OMPD_scan: 15171 case OMPD_declare_reduction: 15172 case OMPD_declare_mapper: 15173 case OMPD_declare_simd: 15174 case OMPD_declare_variant: 15175 case OMPD_begin_declare_variant: 15176 case OMPD_end_declare_variant: 15177 case OMPD_declare_target: 15178 case OMPD_end_declare_target: 15179 case OMPD_loop: 15180 case OMPD_simd: 15181 case OMPD_tile: 15182 case OMPD_unroll: 15183 case OMPD_for: 15184 case OMPD_for_simd: 15185 case OMPD_sections: 15186 case OMPD_section: 15187 case OMPD_single: 15188 case OMPD_master: 15189 case OMPD_masked: 15190 case OMPD_critical: 15191 case OMPD_taskgroup: 15192 case OMPD_distribute: 15193 case OMPD_ordered: 15194 case OMPD_atomic: 15195 case OMPD_distribute_simd: 15196 case OMPD_requires: 15197 case OMPD_metadirective: 15198 llvm_unreachable("Unexpected OpenMP directive with num_teams-clause"); 15199 case OMPD_unknown: 15200 default: 15201 llvm_unreachable("Unknown OpenMP directive"); 15202 } 15203 break; 15204 case OMPC_thread_limit: 15205 switch (DKind) { 15206 case OMPD_target_teams: 15207 case OMPD_target_teams_distribute: 15208 case OMPD_target_teams_distribute_simd: 15209 case OMPD_target_teams_distribute_parallel_for: 15210 case OMPD_target_teams_distribute_parallel_for_simd: 15211 case OMPD_target_teams_loop: 15212 CaptureRegion = OMPD_target; 15213 break; 15214 case OMPD_teams_distribute_parallel_for: 15215 case OMPD_teams_distribute_parallel_for_simd: 15216 case OMPD_teams: 15217 case OMPD_teams_distribute: 15218 case OMPD_teams_distribute_simd: 15219 case OMPD_teams_loop: 15220 // Do not capture thread_limit-clause expressions. 15221 break; 15222 case OMPD_distribute_parallel_for: 15223 case OMPD_distribute_parallel_for_simd: 15224 case OMPD_task: 15225 case OMPD_taskloop: 15226 case OMPD_taskloop_simd: 15227 case OMPD_master_taskloop: 15228 case OMPD_masked_taskloop: 15229 case OMPD_master_taskloop_simd: 15230 case OMPD_masked_taskloop_simd: 15231 case OMPD_parallel_master_taskloop: 15232 case OMPD_parallel_master_taskloop_simd: 15233 case OMPD_target_data: 15234 case OMPD_target_enter_data: 15235 case OMPD_target_exit_data: 15236 case OMPD_target_update: 15237 case OMPD_cancel: 15238 case OMPD_parallel: 15239 case OMPD_parallel_master: 15240 case OMPD_parallel_masked: 15241 case OMPD_parallel_sections: 15242 case OMPD_parallel_for: 15243 case OMPD_parallel_for_simd: 15244 case OMPD_parallel_loop: 15245 case OMPD_target: 15246 case OMPD_target_simd: 15247 case OMPD_target_parallel: 15248 case OMPD_target_parallel_for: 15249 case OMPD_target_parallel_for_simd: 15250 case OMPD_target_parallel_loop: 15251 case OMPD_threadprivate: 15252 case OMPD_allocate: 15253 case OMPD_taskyield: 15254 case OMPD_barrier: 15255 case OMPD_taskwait: 15256 case OMPD_cancellation_point: 15257 case OMPD_flush: 15258 case OMPD_depobj: 15259 case OMPD_scan: 15260 case OMPD_declare_reduction: 15261 case OMPD_declare_mapper: 15262 case OMPD_declare_simd: 15263 case OMPD_declare_variant: 15264 case OMPD_begin_declare_variant: 15265 case OMPD_end_declare_variant: 15266 case OMPD_declare_target: 15267 case OMPD_end_declare_target: 15268 case OMPD_loop: 15269 case OMPD_simd: 15270 case OMPD_tile: 15271 case OMPD_unroll: 15272 case OMPD_for: 15273 case OMPD_for_simd: 15274 case OMPD_sections: 15275 case OMPD_section: 15276 case OMPD_single: 15277 case OMPD_master: 15278 case OMPD_masked: 15279 case OMPD_critical: 15280 case OMPD_taskgroup: 15281 case OMPD_distribute: 15282 case OMPD_ordered: 15283 case OMPD_atomic: 15284 case OMPD_distribute_simd: 15285 case OMPD_requires: 15286 case OMPD_metadirective: 15287 llvm_unreachable("Unexpected OpenMP directive with thread_limit-clause"); 15288 case OMPD_unknown: 15289 default: 15290 llvm_unreachable("Unknown OpenMP directive"); 15291 } 15292 break; 15293 case OMPC_schedule: 15294 switch (DKind) { 15295 case OMPD_parallel_for: 15296 case OMPD_parallel_for_simd: 15297 case OMPD_distribute_parallel_for: 15298 case OMPD_distribute_parallel_for_simd: 15299 case OMPD_teams_distribute_parallel_for: 15300 case OMPD_teams_distribute_parallel_for_simd: 15301 case OMPD_target_parallel_for: 15302 case OMPD_target_parallel_for_simd: 15303 case OMPD_target_teams_distribute_parallel_for: 15304 case OMPD_target_teams_distribute_parallel_for_simd: 15305 CaptureRegion = OMPD_parallel; 15306 break; 15307 case OMPD_for: 15308 case OMPD_for_simd: 15309 // Do not capture schedule-clause expressions. 15310 break; 15311 case OMPD_task: 15312 case OMPD_taskloop: 15313 case OMPD_taskloop_simd: 15314 case OMPD_master_taskloop: 15315 case OMPD_masked_taskloop: 15316 case OMPD_master_taskloop_simd: 15317 case OMPD_masked_taskloop_simd: 15318 case OMPD_parallel_master_taskloop: 15319 case OMPD_parallel_master_taskloop_simd: 15320 case OMPD_target_data: 15321 case OMPD_target_enter_data: 15322 case OMPD_target_exit_data: 15323 case OMPD_target_update: 15324 case OMPD_teams: 15325 case OMPD_teams_distribute: 15326 case OMPD_teams_distribute_simd: 15327 case OMPD_target_teams_distribute: 15328 case OMPD_target_teams_distribute_simd: 15329 case OMPD_target: 15330 case OMPD_target_simd: 15331 case OMPD_target_parallel: 15332 case OMPD_cancel: 15333 case OMPD_parallel: 15334 case OMPD_parallel_master: 15335 case OMPD_parallel_masked: 15336 case OMPD_parallel_sections: 15337 case OMPD_threadprivate: 15338 case OMPD_allocate: 15339 case OMPD_taskyield: 15340 case OMPD_barrier: 15341 case OMPD_taskwait: 15342 case OMPD_cancellation_point: 15343 case OMPD_flush: 15344 case OMPD_depobj: 15345 case OMPD_scan: 15346 case OMPD_declare_reduction: 15347 case OMPD_declare_mapper: 15348 case OMPD_declare_simd: 15349 case OMPD_declare_variant: 15350 case OMPD_begin_declare_variant: 15351 case OMPD_end_declare_variant: 15352 case OMPD_declare_target: 15353 case OMPD_end_declare_target: 15354 case OMPD_loop: 15355 case OMPD_teams_loop: 15356 case OMPD_target_teams_loop: 15357 case OMPD_parallel_loop: 15358 case OMPD_target_parallel_loop: 15359 case OMPD_simd: 15360 case OMPD_tile: 15361 case OMPD_unroll: 15362 case OMPD_sections: 15363 case OMPD_section: 15364 case OMPD_single: 15365 case OMPD_master: 15366 case OMPD_masked: 15367 case OMPD_critical: 15368 case OMPD_taskgroup: 15369 case OMPD_distribute: 15370 case OMPD_ordered: 15371 case OMPD_atomic: 15372 case OMPD_distribute_simd: 15373 case OMPD_target_teams: 15374 case OMPD_requires: 15375 case OMPD_metadirective: 15376 llvm_unreachable("Unexpected OpenMP directive with schedule clause"); 15377 case OMPD_unknown: 15378 default: 15379 llvm_unreachable("Unknown OpenMP directive"); 15380 } 15381 break; 15382 case OMPC_dist_schedule: 15383 switch (DKind) { 15384 case OMPD_teams_distribute_parallel_for: 15385 case OMPD_teams_distribute_parallel_for_simd: 15386 case OMPD_teams_distribute: 15387 case OMPD_teams_distribute_simd: 15388 case OMPD_target_teams_distribute_parallel_for: 15389 case OMPD_target_teams_distribute_parallel_for_simd: 15390 case OMPD_target_teams_distribute: 15391 case OMPD_target_teams_distribute_simd: 15392 CaptureRegion = OMPD_teams; 15393 break; 15394 case OMPD_distribute_parallel_for: 15395 case OMPD_distribute_parallel_for_simd: 15396 case OMPD_distribute: 15397 case OMPD_distribute_simd: 15398 // Do not capture dist_schedule-clause expressions. 15399 break; 15400 case OMPD_parallel_for: 15401 case OMPD_parallel_for_simd: 15402 case OMPD_target_parallel_for_simd: 15403 case OMPD_target_parallel_for: 15404 case OMPD_task: 15405 case OMPD_taskloop: 15406 case OMPD_taskloop_simd: 15407 case OMPD_master_taskloop: 15408 case OMPD_masked_taskloop: 15409 case OMPD_master_taskloop_simd: 15410 case OMPD_masked_taskloop_simd: 15411 case OMPD_parallel_master_taskloop: 15412 case OMPD_parallel_master_taskloop_simd: 15413 case OMPD_target_data: 15414 case OMPD_target_enter_data: 15415 case OMPD_target_exit_data: 15416 case OMPD_target_update: 15417 case OMPD_teams: 15418 case OMPD_target: 15419 case OMPD_target_simd: 15420 case OMPD_target_parallel: 15421 case OMPD_cancel: 15422 case OMPD_parallel: 15423 case OMPD_parallel_master: 15424 case OMPD_parallel_masked: 15425 case OMPD_parallel_sections: 15426 case OMPD_threadprivate: 15427 case OMPD_allocate: 15428 case OMPD_taskyield: 15429 case OMPD_barrier: 15430 case OMPD_taskwait: 15431 case OMPD_cancellation_point: 15432 case OMPD_flush: 15433 case OMPD_depobj: 15434 case OMPD_scan: 15435 case OMPD_declare_reduction: 15436 case OMPD_declare_mapper: 15437 case OMPD_declare_simd: 15438 case OMPD_declare_variant: 15439 case OMPD_begin_declare_variant: 15440 case OMPD_end_declare_variant: 15441 case OMPD_declare_target: 15442 case OMPD_end_declare_target: 15443 case OMPD_loop: 15444 case OMPD_teams_loop: 15445 case OMPD_target_teams_loop: 15446 case OMPD_parallel_loop: 15447 case OMPD_target_parallel_loop: 15448 case OMPD_simd: 15449 case OMPD_tile: 15450 case OMPD_unroll: 15451 case OMPD_for: 15452 case OMPD_for_simd: 15453 case OMPD_sections: 15454 case OMPD_section: 15455 case OMPD_single: 15456 case OMPD_master: 15457 case OMPD_masked: 15458 case OMPD_critical: 15459 case OMPD_taskgroup: 15460 case OMPD_ordered: 15461 case OMPD_atomic: 15462 case OMPD_target_teams: 15463 case OMPD_requires: 15464 case OMPD_metadirective: 15465 llvm_unreachable("Unexpected OpenMP directive with dist_schedule clause"); 15466 case OMPD_unknown: 15467 default: 15468 llvm_unreachable("Unknown OpenMP directive"); 15469 } 15470 break; 15471 case OMPC_device: 15472 switch (DKind) { 15473 case OMPD_target_update: 15474 case OMPD_target_enter_data: 15475 case OMPD_target_exit_data: 15476 case OMPD_target: 15477 case OMPD_target_simd: 15478 case OMPD_target_teams: 15479 case OMPD_target_parallel: 15480 case OMPD_target_teams_distribute: 15481 case OMPD_target_teams_distribute_simd: 15482 case OMPD_target_parallel_for: 15483 case OMPD_target_parallel_for_simd: 15484 case OMPD_target_parallel_loop: 15485 case OMPD_target_teams_distribute_parallel_for: 15486 case OMPD_target_teams_distribute_parallel_for_simd: 15487 case OMPD_target_teams_loop: 15488 case OMPD_dispatch: 15489 CaptureRegion = OMPD_task; 15490 break; 15491 case OMPD_target_data: 15492 case OMPD_interop: 15493 // Do not capture device-clause expressions. 15494 break; 15495 case OMPD_teams_distribute_parallel_for: 15496 case OMPD_teams_distribute_parallel_for_simd: 15497 case OMPD_teams: 15498 case OMPD_teams_distribute: 15499 case OMPD_teams_distribute_simd: 15500 case OMPD_distribute_parallel_for: 15501 case OMPD_distribute_parallel_for_simd: 15502 case OMPD_task: 15503 case OMPD_taskloop: 15504 case OMPD_taskloop_simd: 15505 case OMPD_master_taskloop: 15506 case OMPD_masked_taskloop: 15507 case OMPD_master_taskloop_simd: 15508 case OMPD_masked_taskloop_simd: 15509 case OMPD_parallel_master_taskloop: 15510 case OMPD_parallel_master_taskloop_simd: 15511 case OMPD_cancel: 15512 case OMPD_parallel: 15513 case OMPD_parallel_master: 15514 case OMPD_parallel_masked: 15515 case OMPD_parallel_sections: 15516 case OMPD_parallel_for: 15517 case OMPD_parallel_for_simd: 15518 case OMPD_threadprivate: 15519 case OMPD_allocate: 15520 case OMPD_taskyield: 15521 case OMPD_barrier: 15522 case OMPD_taskwait: 15523 case OMPD_cancellation_point: 15524 case OMPD_flush: 15525 case OMPD_depobj: 15526 case OMPD_scan: 15527 case OMPD_declare_reduction: 15528 case OMPD_declare_mapper: 15529 case OMPD_declare_simd: 15530 case OMPD_declare_variant: 15531 case OMPD_begin_declare_variant: 15532 case OMPD_end_declare_variant: 15533 case OMPD_declare_target: 15534 case OMPD_end_declare_target: 15535 case OMPD_loop: 15536 case OMPD_teams_loop: 15537 case OMPD_parallel_loop: 15538 case OMPD_simd: 15539 case OMPD_tile: 15540 case OMPD_unroll: 15541 case OMPD_for: 15542 case OMPD_for_simd: 15543 case OMPD_sections: 15544 case OMPD_section: 15545 case OMPD_single: 15546 case OMPD_master: 15547 case OMPD_masked: 15548 case OMPD_critical: 15549 case OMPD_taskgroup: 15550 case OMPD_distribute: 15551 case OMPD_ordered: 15552 case OMPD_atomic: 15553 case OMPD_distribute_simd: 15554 case OMPD_requires: 15555 case OMPD_metadirective: 15556 llvm_unreachable("Unexpected OpenMP directive with device-clause"); 15557 case OMPD_unknown: 15558 default: 15559 llvm_unreachable("Unknown OpenMP directive"); 15560 } 15561 break; 15562 case OMPC_grainsize: 15563 case OMPC_num_tasks: 15564 case OMPC_final: 15565 case OMPC_priority: 15566 switch (DKind) { 15567 case OMPD_task: 15568 case OMPD_taskloop: 15569 case OMPD_taskloop_simd: 15570 case OMPD_master_taskloop: 15571 case OMPD_masked_taskloop: 15572 case OMPD_master_taskloop_simd: 15573 case OMPD_masked_taskloop_simd: 15574 break; 15575 case OMPD_parallel_master_taskloop: 15576 case OMPD_parallel_master_taskloop_simd: 15577 CaptureRegion = OMPD_parallel; 15578 break; 15579 case OMPD_target_update: 15580 case OMPD_target_enter_data: 15581 case OMPD_target_exit_data: 15582 case OMPD_target: 15583 case OMPD_target_simd: 15584 case OMPD_target_teams: 15585 case OMPD_target_parallel: 15586 case OMPD_target_teams_distribute: 15587 case OMPD_target_teams_distribute_simd: 15588 case OMPD_target_parallel_for: 15589 case OMPD_target_parallel_for_simd: 15590 case OMPD_target_teams_distribute_parallel_for: 15591 case OMPD_target_teams_distribute_parallel_for_simd: 15592 case OMPD_target_data: 15593 case OMPD_teams_distribute_parallel_for: 15594 case OMPD_teams_distribute_parallel_for_simd: 15595 case OMPD_teams: 15596 case OMPD_teams_distribute: 15597 case OMPD_teams_distribute_simd: 15598 case OMPD_distribute_parallel_for: 15599 case OMPD_distribute_parallel_for_simd: 15600 case OMPD_cancel: 15601 case OMPD_parallel: 15602 case OMPD_parallel_master: 15603 case OMPD_parallel_masked: 15604 case OMPD_parallel_sections: 15605 case OMPD_parallel_for: 15606 case OMPD_parallel_for_simd: 15607 case OMPD_threadprivate: 15608 case OMPD_allocate: 15609 case OMPD_taskyield: 15610 case OMPD_barrier: 15611 case OMPD_taskwait: 15612 case OMPD_cancellation_point: 15613 case OMPD_flush: 15614 case OMPD_depobj: 15615 case OMPD_scan: 15616 case OMPD_declare_reduction: 15617 case OMPD_declare_mapper: 15618 case OMPD_declare_simd: 15619 case OMPD_declare_variant: 15620 case OMPD_begin_declare_variant: 15621 case OMPD_end_declare_variant: 15622 case OMPD_declare_target: 15623 case OMPD_end_declare_target: 15624 case OMPD_loop: 15625 case OMPD_teams_loop: 15626 case OMPD_target_teams_loop: 15627 case OMPD_parallel_loop: 15628 case OMPD_target_parallel_loop: 15629 case OMPD_simd: 15630 case OMPD_tile: 15631 case OMPD_unroll: 15632 case OMPD_for: 15633 case OMPD_for_simd: 15634 case OMPD_sections: 15635 case OMPD_section: 15636 case OMPD_single: 15637 case OMPD_master: 15638 case OMPD_masked: 15639 case OMPD_critical: 15640 case OMPD_taskgroup: 15641 case OMPD_distribute: 15642 case OMPD_ordered: 15643 case OMPD_atomic: 15644 case OMPD_distribute_simd: 15645 case OMPD_requires: 15646 case OMPD_metadirective: 15647 llvm_unreachable("Unexpected OpenMP directive with grainsize-clause"); 15648 case OMPD_unknown: 15649 default: 15650 llvm_unreachable("Unknown OpenMP directive"); 15651 } 15652 break; 15653 case OMPC_novariants: 15654 case OMPC_nocontext: 15655 switch (DKind) { 15656 case OMPD_dispatch: 15657 CaptureRegion = OMPD_task; 15658 break; 15659 default: 15660 llvm_unreachable("Unexpected OpenMP directive"); 15661 } 15662 break; 15663 case OMPC_filter: 15664 // Do not capture filter-clause expressions. 15665 break; 15666 case OMPC_when: 15667 if (DKind == OMPD_metadirective) { 15668 CaptureRegion = OMPD_metadirective; 15669 } else if (DKind == OMPD_unknown) { 15670 llvm_unreachable("Unknown OpenMP directive"); 15671 } else { 15672 llvm_unreachable("Unexpected OpenMP directive with when clause"); 15673 } 15674 break; 15675 case OMPC_firstprivate: 15676 case OMPC_lastprivate: 15677 case OMPC_reduction: 15678 case OMPC_task_reduction: 15679 case OMPC_in_reduction: 15680 case OMPC_linear: 15681 case OMPC_default: 15682 case OMPC_proc_bind: 15683 case OMPC_safelen: 15684 case OMPC_simdlen: 15685 case OMPC_sizes: 15686 case OMPC_allocator: 15687 case OMPC_collapse: 15688 case OMPC_private: 15689 case OMPC_shared: 15690 case OMPC_aligned: 15691 case OMPC_copyin: 15692 case OMPC_copyprivate: 15693 case OMPC_ordered: 15694 case OMPC_nowait: 15695 case OMPC_untied: 15696 case OMPC_mergeable: 15697 case OMPC_threadprivate: 15698 case OMPC_allocate: 15699 case OMPC_flush: 15700 case OMPC_depobj: 15701 case OMPC_read: 15702 case OMPC_write: 15703 case OMPC_update: 15704 case OMPC_capture: 15705 case OMPC_compare: 15706 case OMPC_seq_cst: 15707 case OMPC_acq_rel: 15708 case OMPC_acquire: 15709 case OMPC_release: 15710 case OMPC_relaxed: 15711 case OMPC_depend: 15712 case OMPC_threads: 15713 case OMPC_simd: 15714 case OMPC_map: 15715 case OMPC_nogroup: 15716 case OMPC_hint: 15717 case OMPC_defaultmap: 15718 case OMPC_unknown: 15719 case OMPC_uniform: 15720 case OMPC_to: 15721 case OMPC_from: 15722 case OMPC_use_device_ptr: 15723 case OMPC_use_device_addr: 15724 case OMPC_is_device_ptr: 15725 case OMPC_unified_address: 15726 case OMPC_unified_shared_memory: 15727 case OMPC_reverse_offload: 15728 case OMPC_dynamic_allocators: 15729 case OMPC_atomic_default_mem_order: 15730 case OMPC_device_type: 15731 case OMPC_match: 15732 case OMPC_nontemporal: 15733 case OMPC_order: 15734 case OMPC_destroy: 15735 case OMPC_detach: 15736 case OMPC_inclusive: 15737 case OMPC_exclusive: 15738 case OMPC_uses_allocators: 15739 case OMPC_affinity: 15740 case OMPC_bind: 15741 default: 15742 llvm_unreachable("Unexpected OpenMP clause."); 15743 } 15744 return CaptureRegion; 15745 } 15746 15747 OMPClause *Sema::ActOnOpenMPIfClause(OpenMPDirectiveKind NameModifier, 15748 Expr *Condition, SourceLocation StartLoc, 15749 SourceLocation LParenLoc, 15750 SourceLocation NameModifierLoc, 15751 SourceLocation ColonLoc, 15752 SourceLocation EndLoc) { 15753 Expr *ValExpr = Condition; 15754 Stmt *HelperValStmt = nullptr; 15755 OpenMPDirectiveKind CaptureRegion = OMPD_unknown; 15756 if (!Condition->isValueDependent() && !Condition->isTypeDependent() && 15757 !Condition->isInstantiationDependent() && 15758 !Condition->containsUnexpandedParameterPack()) { 15759 ExprResult Val = CheckBooleanCondition(StartLoc, Condition); 15760 if (Val.isInvalid()) 15761 return nullptr; 15762 15763 ValExpr = Val.get(); 15764 15765 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 15766 CaptureRegion = getOpenMPCaptureRegionForClause( 15767 DKind, OMPC_if, LangOpts.OpenMP, NameModifier); 15768 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 15769 ValExpr = MakeFullExpr(ValExpr).get(); 15770 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 15771 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 15772 HelperValStmt = buildPreInits(Context, Captures); 15773 } 15774 } 15775 15776 return new (Context) 15777 OMPIfClause(NameModifier, ValExpr, HelperValStmt, CaptureRegion, StartLoc, 15778 LParenLoc, NameModifierLoc, ColonLoc, EndLoc); 15779 } 15780 15781 OMPClause *Sema::ActOnOpenMPFinalClause(Expr *Condition, 15782 SourceLocation StartLoc, 15783 SourceLocation LParenLoc, 15784 SourceLocation EndLoc) { 15785 Expr *ValExpr = Condition; 15786 Stmt *HelperValStmt = nullptr; 15787 OpenMPDirectiveKind CaptureRegion = OMPD_unknown; 15788 if (!Condition->isValueDependent() && !Condition->isTypeDependent() && 15789 !Condition->isInstantiationDependent() && 15790 !Condition->containsUnexpandedParameterPack()) { 15791 ExprResult Val = CheckBooleanCondition(StartLoc, Condition); 15792 if (Val.isInvalid()) 15793 return nullptr; 15794 15795 ValExpr = MakeFullExpr(Val.get()).get(); 15796 15797 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 15798 CaptureRegion = 15799 getOpenMPCaptureRegionForClause(DKind, OMPC_final, LangOpts.OpenMP); 15800 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 15801 ValExpr = MakeFullExpr(ValExpr).get(); 15802 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 15803 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 15804 HelperValStmt = buildPreInits(Context, Captures); 15805 } 15806 } 15807 15808 return new (Context) OMPFinalClause(ValExpr, HelperValStmt, CaptureRegion, 15809 StartLoc, LParenLoc, EndLoc); 15810 } 15811 15812 ExprResult Sema::PerformOpenMPImplicitIntegerConversion(SourceLocation Loc, 15813 Expr *Op) { 15814 if (!Op) 15815 return ExprError(); 15816 15817 class IntConvertDiagnoser : public ICEConvertDiagnoser { 15818 public: 15819 IntConvertDiagnoser() 15820 : ICEConvertDiagnoser(/*AllowScopedEnumerations*/ false, false, true) {} 15821 SemaDiagnosticBuilder diagnoseNotInt(Sema &S, SourceLocation Loc, 15822 QualType T) override { 15823 return S.Diag(Loc, diag::err_omp_not_integral) << T; 15824 } 15825 SemaDiagnosticBuilder diagnoseIncomplete(Sema &S, SourceLocation Loc, 15826 QualType T) override { 15827 return S.Diag(Loc, diag::err_omp_incomplete_type) << T; 15828 } 15829 SemaDiagnosticBuilder diagnoseExplicitConv(Sema &S, SourceLocation Loc, 15830 QualType T, 15831 QualType ConvTy) override { 15832 return S.Diag(Loc, diag::err_omp_explicit_conversion) << T << ConvTy; 15833 } 15834 SemaDiagnosticBuilder noteExplicitConv(Sema &S, CXXConversionDecl *Conv, 15835 QualType ConvTy) override { 15836 return S.Diag(Conv->getLocation(), diag::note_omp_conversion_here) 15837 << ConvTy->isEnumeralType() << ConvTy; 15838 } 15839 SemaDiagnosticBuilder diagnoseAmbiguous(Sema &S, SourceLocation Loc, 15840 QualType T) override { 15841 return S.Diag(Loc, diag::err_omp_ambiguous_conversion) << T; 15842 } 15843 SemaDiagnosticBuilder noteAmbiguous(Sema &S, CXXConversionDecl *Conv, 15844 QualType ConvTy) override { 15845 return S.Diag(Conv->getLocation(), diag::note_omp_conversion_here) 15846 << ConvTy->isEnumeralType() << ConvTy; 15847 } 15848 SemaDiagnosticBuilder diagnoseConversion(Sema &, SourceLocation, QualType, 15849 QualType) override { 15850 llvm_unreachable("conversion functions are permitted"); 15851 } 15852 } ConvertDiagnoser; 15853 return PerformContextualImplicitConversion(Loc, Op, ConvertDiagnoser); 15854 } 15855 15856 static bool 15857 isNonNegativeIntegerValue(Expr *&ValExpr, Sema &SemaRef, OpenMPClauseKind CKind, 15858 bool StrictlyPositive, bool BuildCapture = false, 15859 OpenMPDirectiveKind DKind = OMPD_unknown, 15860 OpenMPDirectiveKind *CaptureRegion = nullptr, 15861 Stmt **HelperValStmt = nullptr) { 15862 if (!ValExpr->isTypeDependent() && !ValExpr->isValueDependent() && 15863 !ValExpr->isInstantiationDependent()) { 15864 SourceLocation Loc = ValExpr->getExprLoc(); 15865 ExprResult Value = 15866 SemaRef.PerformOpenMPImplicitIntegerConversion(Loc, ValExpr); 15867 if (Value.isInvalid()) 15868 return false; 15869 15870 ValExpr = Value.get(); 15871 // The expression must evaluate to a non-negative integer value. 15872 if (Optional<llvm::APSInt> Result = 15873 ValExpr->getIntegerConstantExpr(SemaRef.Context)) { 15874 if (Result->isSigned() && 15875 !((!StrictlyPositive && Result->isNonNegative()) || 15876 (StrictlyPositive && Result->isStrictlyPositive()))) { 15877 SemaRef.Diag(Loc, diag::err_omp_negative_expression_in_clause) 15878 << getOpenMPClauseName(CKind) << (StrictlyPositive ? 1 : 0) 15879 << ValExpr->getSourceRange(); 15880 return false; 15881 } 15882 } 15883 if (!BuildCapture) 15884 return true; 15885 *CaptureRegion = 15886 getOpenMPCaptureRegionForClause(DKind, CKind, SemaRef.LangOpts.OpenMP); 15887 if (*CaptureRegion != OMPD_unknown && 15888 !SemaRef.CurContext->isDependentContext()) { 15889 ValExpr = SemaRef.MakeFullExpr(ValExpr).get(); 15890 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 15891 ValExpr = tryBuildCapture(SemaRef, ValExpr, Captures).get(); 15892 *HelperValStmt = buildPreInits(SemaRef.Context, Captures); 15893 } 15894 } 15895 return true; 15896 } 15897 15898 OMPClause *Sema::ActOnOpenMPNumThreadsClause(Expr *NumThreads, 15899 SourceLocation StartLoc, 15900 SourceLocation LParenLoc, 15901 SourceLocation EndLoc) { 15902 Expr *ValExpr = NumThreads; 15903 Stmt *HelperValStmt = nullptr; 15904 15905 // OpenMP [2.5, Restrictions] 15906 // The num_threads expression must evaluate to a positive integer value. 15907 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_num_threads, 15908 /*StrictlyPositive=*/true)) 15909 return nullptr; 15910 15911 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 15912 OpenMPDirectiveKind CaptureRegion = 15913 getOpenMPCaptureRegionForClause(DKind, OMPC_num_threads, LangOpts.OpenMP); 15914 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 15915 ValExpr = MakeFullExpr(ValExpr).get(); 15916 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 15917 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 15918 HelperValStmt = buildPreInits(Context, Captures); 15919 } 15920 15921 return new (Context) OMPNumThreadsClause( 15922 ValExpr, HelperValStmt, CaptureRegion, StartLoc, LParenLoc, EndLoc); 15923 } 15924 15925 ExprResult Sema::VerifyPositiveIntegerConstantInClause(Expr *E, 15926 OpenMPClauseKind CKind, 15927 bool StrictlyPositive, 15928 bool SuppressExprDiags) { 15929 if (!E) 15930 return ExprError(); 15931 if (E->isValueDependent() || E->isTypeDependent() || 15932 E->isInstantiationDependent() || E->containsUnexpandedParameterPack()) 15933 return E; 15934 15935 llvm::APSInt Result; 15936 ExprResult ICE; 15937 if (SuppressExprDiags) { 15938 // Use a custom diagnoser that suppresses 'note' diagnostics about the 15939 // expression. 15940 struct SuppressedDiagnoser : public Sema::VerifyICEDiagnoser { 15941 SuppressedDiagnoser() : VerifyICEDiagnoser(/*Suppress=*/true) {} 15942 Sema::SemaDiagnosticBuilder diagnoseNotICE(Sema &S, 15943 SourceLocation Loc) override { 15944 llvm_unreachable("Diagnostic suppressed"); 15945 } 15946 } Diagnoser; 15947 ICE = VerifyIntegerConstantExpression(E, &Result, Diagnoser, AllowFold); 15948 } else { 15949 ICE = VerifyIntegerConstantExpression(E, &Result, /*FIXME*/ AllowFold); 15950 } 15951 if (ICE.isInvalid()) 15952 return ExprError(); 15953 15954 if ((StrictlyPositive && !Result.isStrictlyPositive()) || 15955 (!StrictlyPositive && !Result.isNonNegative())) { 15956 Diag(E->getExprLoc(), diag::err_omp_negative_expression_in_clause) 15957 << getOpenMPClauseName(CKind) << (StrictlyPositive ? 1 : 0) 15958 << E->getSourceRange(); 15959 return ExprError(); 15960 } 15961 if ((CKind == OMPC_aligned || CKind == OMPC_align) && !Result.isPowerOf2()) { 15962 Diag(E->getExprLoc(), diag::warn_omp_alignment_not_power_of_two) 15963 << E->getSourceRange(); 15964 return ExprError(); 15965 } 15966 if (CKind == OMPC_collapse && DSAStack->getAssociatedLoops() == 1) 15967 DSAStack->setAssociatedLoops(Result.getExtValue()); 15968 else if (CKind == OMPC_ordered) 15969 DSAStack->setAssociatedLoops(Result.getExtValue()); 15970 return ICE; 15971 } 15972 15973 OMPClause *Sema::ActOnOpenMPSafelenClause(Expr *Len, SourceLocation StartLoc, 15974 SourceLocation LParenLoc, 15975 SourceLocation EndLoc) { 15976 // OpenMP [2.8.1, simd construct, Description] 15977 // The parameter of the safelen clause must be a constant 15978 // positive integer expression. 15979 ExprResult Safelen = VerifyPositiveIntegerConstantInClause(Len, OMPC_safelen); 15980 if (Safelen.isInvalid()) 15981 return nullptr; 15982 return new (Context) 15983 OMPSafelenClause(Safelen.get(), StartLoc, LParenLoc, EndLoc); 15984 } 15985 15986 OMPClause *Sema::ActOnOpenMPSimdlenClause(Expr *Len, SourceLocation StartLoc, 15987 SourceLocation LParenLoc, 15988 SourceLocation EndLoc) { 15989 // OpenMP [2.8.1, simd construct, Description] 15990 // The parameter of the simdlen clause must be a constant 15991 // positive integer expression. 15992 ExprResult Simdlen = VerifyPositiveIntegerConstantInClause(Len, OMPC_simdlen); 15993 if (Simdlen.isInvalid()) 15994 return nullptr; 15995 return new (Context) 15996 OMPSimdlenClause(Simdlen.get(), StartLoc, LParenLoc, EndLoc); 15997 } 15998 15999 /// Tries to find omp_allocator_handle_t type. 16000 static bool findOMPAllocatorHandleT(Sema &S, SourceLocation Loc, 16001 DSAStackTy *Stack) { 16002 QualType OMPAllocatorHandleT = Stack->getOMPAllocatorHandleT(); 16003 if (!OMPAllocatorHandleT.isNull()) 16004 return true; 16005 // Build the predefined allocator expressions. 16006 bool ErrorFound = false; 16007 for (int I = 0; I < OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; ++I) { 16008 auto AllocatorKind = static_cast<OMPAllocateDeclAttr::AllocatorTypeTy>(I); 16009 StringRef Allocator = 16010 OMPAllocateDeclAttr::ConvertAllocatorTypeTyToStr(AllocatorKind); 16011 DeclarationName AllocatorName = &S.getASTContext().Idents.get(Allocator); 16012 auto *VD = dyn_cast_or_null<ValueDecl>( 16013 S.LookupSingleName(S.TUScope, AllocatorName, Loc, Sema::LookupAnyName)); 16014 if (!VD) { 16015 ErrorFound = true; 16016 break; 16017 } 16018 QualType AllocatorType = 16019 VD->getType().getNonLValueExprType(S.getASTContext()); 16020 ExprResult Res = S.BuildDeclRefExpr(VD, AllocatorType, VK_LValue, Loc); 16021 if (!Res.isUsable()) { 16022 ErrorFound = true; 16023 break; 16024 } 16025 if (OMPAllocatorHandleT.isNull()) 16026 OMPAllocatorHandleT = AllocatorType; 16027 if (!S.getASTContext().hasSameType(OMPAllocatorHandleT, AllocatorType)) { 16028 ErrorFound = true; 16029 break; 16030 } 16031 Stack->setAllocator(AllocatorKind, Res.get()); 16032 } 16033 if (ErrorFound) { 16034 S.Diag(Loc, diag::err_omp_implied_type_not_found) 16035 << "omp_allocator_handle_t"; 16036 return false; 16037 } 16038 OMPAllocatorHandleT.addConst(); 16039 Stack->setOMPAllocatorHandleT(OMPAllocatorHandleT); 16040 return true; 16041 } 16042 16043 OMPClause *Sema::ActOnOpenMPAllocatorClause(Expr *A, SourceLocation StartLoc, 16044 SourceLocation LParenLoc, 16045 SourceLocation EndLoc) { 16046 // OpenMP [2.11.3, allocate Directive, Description] 16047 // allocator is an expression of omp_allocator_handle_t type. 16048 if (!findOMPAllocatorHandleT(*this, A->getExprLoc(), DSAStack)) 16049 return nullptr; 16050 16051 ExprResult Allocator = DefaultLvalueConversion(A); 16052 if (Allocator.isInvalid()) 16053 return nullptr; 16054 Allocator = PerformImplicitConversion(Allocator.get(), 16055 DSAStack->getOMPAllocatorHandleT(), 16056 Sema::AA_Initializing, 16057 /*AllowExplicit=*/true); 16058 if (Allocator.isInvalid()) 16059 return nullptr; 16060 return new (Context) 16061 OMPAllocatorClause(Allocator.get(), StartLoc, LParenLoc, EndLoc); 16062 } 16063 16064 OMPClause *Sema::ActOnOpenMPCollapseClause(Expr *NumForLoops, 16065 SourceLocation StartLoc, 16066 SourceLocation LParenLoc, 16067 SourceLocation EndLoc) { 16068 // OpenMP [2.7.1, loop construct, Description] 16069 // OpenMP [2.8.1, simd construct, Description] 16070 // OpenMP [2.9.6, distribute construct, Description] 16071 // The parameter of the collapse clause must be a constant 16072 // positive integer expression. 16073 ExprResult NumForLoopsResult = 16074 VerifyPositiveIntegerConstantInClause(NumForLoops, OMPC_collapse); 16075 if (NumForLoopsResult.isInvalid()) 16076 return nullptr; 16077 return new (Context) 16078 OMPCollapseClause(NumForLoopsResult.get(), StartLoc, LParenLoc, EndLoc); 16079 } 16080 16081 OMPClause *Sema::ActOnOpenMPOrderedClause(SourceLocation StartLoc, 16082 SourceLocation EndLoc, 16083 SourceLocation LParenLoc, 16084 Expr *NumForLoops) { 16085 // OpenMP [2.7.1, loop construct, Description] 16086 // OpenMP [2.8.1, simd construct, Description] 16087 // OpenMP [2.9.6, distribute construct, Description] 16088 // The parameter of the ordered clause must be a constant 16089 // positive integer expression if any. 16090 if (NumForLoops && LParenLoc.isValid()) { 16091 ExprResult NumForLoopsResult = 16092 VerifyPositiveIntegerConstantInClause(NumForLoops, OMPC_ordered); 16093 if (NumForLoopsResult.isInvalid()) 16094 return nullptr; 16095 NumForLoops = NumForLoopsResult.get(); 16096 } else { 16097 NumForLoops = nullptr; 16098 } 16099 auto *Clause = OMPOrderedClause::Create( 16100 Context, NumForLoops, NumForLoops ? DSAStack->getAssociatedLoops() : 0, 16101 StartLoc, LParenLoc, EndLoc); 16102 DSAStack->setOrderedRegion(/*IsOrdered=*/true, NumForLoops, Clause); 16103 return Clause; 16104 } 16105 16106 OMPClause *Sema::ActOnOpenMPSimpleClause( 16107 OpenMPClauseKind Kind, unsigned Argument, SourceLocation ArgumentLoc, 16108 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) { 16109 OMPClause *Res = nullptr; 16110 switch (Kind) { 16111 case OMPC_default: 16112 Res = ActOnOpenMPDefaultClause(static_cast<DefaultKind>(Argument), 16113 ArgumentLoc, StartLoc, LParenLoc, EndLoc); 16114 break; 16115 case OMPC_proc_bind: 16116 Res = ActOnOpenMPProcBindClause(static_cast<ProcBindKind>(Argument), 16117 ArgumentLoc, StartLoc, LParenLoc, EndLoc); 16118 break; 16119 case OMPC_atomic_default_mem_order: 16120 Res = ActOnOpenMPAtomicDefaultMemOrderClause( 16121 static_cast<OpenMPAtomicDefaultMemOrderClauseKind>(Argument), 16122 ArgumentLoc, StartLoc, LParenLoc, EndLoc); 16123 break; 16124 case OMPC_order: 16125 Res = ActOnOpenMPOrderClause(static_cast<OpenMPOrderClauseKind>(Argument), 16126 ArgumentLoc, StartLoc, LParenLoc, EndLoc); 16127 break; 16128 case OMPC_update: 16129 Res = ActOnOpenMPUpdateClause(static_cast<OpenMPDependClauseKind>(Argument), 16130 ArgumentLoc, StartLoc, LParenLoc, EndLoc); 16131 break; 16132 case OMPC_bind: 16133 Res = ActOnOpenMPBindClause(static_cast<OpenMPBindClauseKind>(Argument), 16134 ArgumentLoc, StartLoc, LParenLoc, EndLoc); 16135 break; 16136 case OMPC_if: 16137 case OMPC_final: 16138 case OMPC_num_threads: 16139 case OMPC_safelen: 16140 case OMPC_simdlen: 16141 case OMPC_sizes: 16142 case OMPC_allocator: 16143 case OMPC_collapse: 16144 case OMPC_schedule: 16145 case OMPC_private: 16146 case OMPC_firstprivate: 16147 case OMPC_lastprivate: 16148 case OMPC_shared: 16149 case OMPC_reduction: 16150 case OMPC_task_reduction: 16151 case OMPC_in_reduction: 16152 case OMPC_linear: 16153 case OMPC_aligned: 16154 case OMPC_copyin: 16155 case OMPC_copyprivate: 16156 case OMPC_ordered: 16157 case OMPC_nowait: 16158 case OMPC_untied: 16159 case OMPC_mergeable: 16160 case OMPC_threadprivate: 16161 case OMPC_allocate: 16162 case OMPC_flush: 16163 case OMPC_depobj: 16164 case OMPC_read: 16165 case OMPC_write: 16166 case OMPC_capture: 16167 case OMPC_compare: 16168 case OMPC_seq_cst: 16169 case OMPC_acq_rel: 16170 case OMPC_acquire: 16171 case OMPC_release: 16172 case OMPC_relaxed: 16173 case OMPC_depend: 16174 case OMPC_device: 16175 case OMPC_threads: 16176 case OMPC_simd: 16177 case OMPC_map: 16178 case OMPC_num_teams: 16179 case OMPC_thread_limit: 16180 case OMPC_priority: 16181 case OMPC_grainsize: 16182 case OMPC_nogroup: 16183 case OMPC_num_tasks: 16184 case OMPC_hint: 16185 case OMPC_dist_schedule: 16186 case OMPC_defaultmap: 16187 case OMPC_unknown: 16188 case OMPC_uniform: 16189 case OMPC_to: 16190 case OMPC_from: 16191 case OMPC_use_device_ptr: 16192 case OMPC_use_device_addr: 16193 case OMPC_is_device_ptr: 16194 case OMPC_has_device_addr: 16195 case OMPC_unified_address: 16196 case OMPC_unified_shared_memory: 16197 case OMPC_reverse_offload: 16198 case OMPC_dynamic_allocators: 16199 case OMPC_device_type: 16200 case OMPC_match: 16201 case OMPC_nontemporal: 16202 case OMPC_destroy: 16203 case OMPC_novariants: 16204 case OMPC_nocontext: 16205 case OMPC_detach: 16206 case OMPC_inclusive: 16207 case OMPC_exclusive: 16208 case OMPC_uses_allocators: 16209 case OMPC_affinity: 16210 case OMPC_when: 16211 default: 16212 llvm_unreachable("Clause is not allowed."); 16213 } 16214 return Res; 16215 } 16216 16217 static std::string 16218 getListOfPossibleValues(OpenMPClauseKind K, unsigned First, unsigned Last, 16219 ArrayRef<unsigned> Exclude = llvm::None) { 16220 SmallString<256> Buffer; 16221 llvm::raw_svector_ostream Out(Buffer); 16222 unsigned Skipped = Exclude.size(); 16223 auto S = Exclude.begin(), E = Exclude.end(); 16224 for (unsigned I = First; I < Last; ++I) { 16225 if (std::find(S, E, I) != E) { 16226 --Skipped; 16227 continue; 16228 } 16229 Out << "'" << getOpenMPSimpleClauseTypeName(K, I) << "'"; 16230 if (I + Skipped + 2 == Last) 16231 Out << " or "; 16232 else if (I + Skipped + 1 != Last) 16233 Out << ", "; 16234 } 16235 return std::string(Out.str()); 16236 } 16237 16238 OMPClause *Sema::ActOnOpenMPDefaultClause(DefaultKind Kind, 16239 SourceLocation KindKwLoc, 16240 SourceLocation StartLoc, 16241 SourceLocation LParenLoc, 16242 SourceLocation EndLoc) { 16243 if (Kind == OMP_DEFAULT_unknown) { 16244 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value) 16245 << getListOfPossibleValues(OMPC_default, /*First=*/0, 16246 /*Last=*/unsigned(OMP_DEFAULT_unknown)) 16247 << getOpenMPClauseName(OMPC_default); 16248 return nullptr; 16249 } 16250 16251 switch (Kind) { 16252 case OMP_DEFAULT_none: 16253 DSAStack->setDefaultDSANone(KindKwLoc); 16254 break; 16255 case OMP_DEFAULT_shared: 16256 DSAStack->setDefaultDSAShared(KindKwLoc); 16257 break; 16258 case OMP_DEFAULT_firstprivate: 16259 DSAStack->setDefaultDSAFirstPrivate(KindKwLoc); 16260 break; 16261 case OMP_DEFAULT_private: 16262 DSAStack->setDefaultDSAPrivate(KindKwLoc); 16263 break; 16264 default: 16265 llvm_unreachable("DSA unexpected in OpenMP default clause"); 16266 } 16267 16268 return new (Context) 16269 OMPDefaultClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc); 16270 } 16271 16272 OMPClause *Sema::ActOnOpenMPProcBindClause(ProcBindKind Kind, 16273 SourceLocation KindKwLoc, 16274 SourceLocation StartLoc, 16275 SourceLocation LParenLoc, 16276 SourceLocation EndLoc) { 16277 if (Kind == OMP_PROC_BIND_unknown) { 16278 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value) 16279 << getListOfPossibleValues(OMPC_proc_bind, 16280 /*First=*/unsigned(OMP_PROC_BIND_master), 16281 /*Last=*/ 16282 unsigned(LangOpts.OpenMP > 50 16283 ? OMP_PROC_BIND_primary 16284 : OMP_PROC_BIND_spread) + 16285 1) 16286 << getOpenMPClauseName(OMPC_proc_bind); 16287 return nullptr; 16288 } 16289 if (Kind == OMP_PROC_BIND_primary && LangOpts.OpenMP < 51) 16290 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value) 16291 << getListOfPossibleValues(OMPC_proc_bind, 16292 /*First=*/unsigned(OMP_PROC_BIND_master), 16293 /*Last=*/ 16294 unsigned(OMP_PROC_BIND_spread) + 1) 16295 << getOpenMPClauseName(OMPC_proc_bind); 16296 return new (Context) 16297 OMPProcBindClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc); 16298 } 16299 16300 OMPClause *Sema::ActOnOpenMPAtomicDefaultMemOrderClause( 16301 OpenMPAtomicDefaultMemOrderClauseKind Kind, SourceLocation KindKwLoc, 16302 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) { 16303 if (Kind == OMPC_ATOMIC_DEFAULT_MEM_ORDER_unknown) { 16304 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value) 16305 << getListOfPossibleValues( 16306 OMPC_atomic_default_mem_order, /*First=*/0, 16307 /*Last=*/OMPC_ATOMIC_DEFAULT_MEM_ORDER_unknown) 16308 << getOpenMPClauseName(OMPC_atomic_default_mem_order); 16309 return nullptr; 16310 } 16311 return new (Context) OMPAtomicDefaultMemOrderClause(Kind, KindKwLoc, StartLoc, 16312 LParenLoc, EndLoc); 16313 } 16314 16315 OMPClause *Sema::ActOnOpenMPOrderClause(OpenMPOrderClauseKind Kind, 16316 SourceLocation KindKwLoc, 16317 SourceLocation StartLoc, 16318 SourceLocation LParenLoc, 16319 SourceLocation EndLoc) { 16320 if (Kind == OMPC_ORDER_unknown) { 16321 static_assert(OMPC_ORDER_unknown > 0, 16322 "OMPC_ORDER_unknown not greater than 0"); 16323 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value) 16324 << getListOfPossibleValues(OMPC_order, /*First=*/0, 16325 /*Last=*/OMPC_ORDER_unknown) 16326 << getOpenMPClauseName(OMPC_order); 16327 return nullptr; 16328 } 16329 return new (Context) 16330 OMPOrderClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc); 16331 } 16332 16333 OMPClause *Sema::ActOnOpenMPUpdateClause(OpenMPDependClauseKind Kind, 16334 SourceLocation KindKwLoc, 16335 SourceLocation StartLoc, 16336 SourceLocation LParenLoc, 16337 SourceLocation EndLoc) { 16338 if (Kind == OMPC_DEPEND_unknown || Kind == OMPC_DEPEND_source || 16339 Kind == OMPC_DEPEND_sink || Kind == OMPC_DEPEND_depobj) { 16340 SmallVector<unsigned> Except = { 16341 OMPC_DEPEND_source, OMPC_DEPEND_sink, OMPC_DEPEND_depobj, 16342 OMPC_DEPEND_outallmemory, OMPC_DEPEND_inoutallmemory}; 16343 if (LangOpts.OpenMP < 51) 16344 Except.push_back(OMPC_DEPEND_inoutset); 16345 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value) 16346 << getListOfPossibleValues(OMPC_depend, /*First=*/0, 16347 /*Last=*/OMPC_DEPEND_unknown, Except) 16348 << getOpenMPClauseName(OMPC_update); 16349 return nullptr; 16350 } 16351 return OMPUpdateClause::Create(Context, StartLoc, LParenLoc, KindKwLoc, Kind, 16352 EndLoc); 16353 } 16354 16355 OMPClause *Sema::ActOnOpenMPSizesClause(ArrayRef<Expr *> SizeExprs, 16356 SourceLocation StartLoc, 16357 SourceLocation LParenLoc, 16358 SourceLocation EndLoc) { 16359 for (Expr *SizeExpr : SizeExprs) { 16360 ExprResult NumForLoopsResult = VerifyPositiveIntegerConstantInClause( 16361 SizeExpr, OMPC_sizes, /*StrictlyPositive=*/true); 16362 if (!NumForLoopsResult.isUsable()) 16363 return nullptr; 16364 } 16365 16366 DSAStack->setAssociatedLoops(SizeExprs.size()); 16367 return OMPSizesClause::Create(Context, StartLoc, LParenLoc, EndLoc, 16368 SizeExprs); 16369 } 16370 16371 OMPClause *Sema::ActOnOpenMPFullClause(SourceLocation StartLoc, 16372 SourceLocation EndLoc) { 16373 return OMPFullClause::Create(Context, StartLoc, EndLoc); 16374 } 16375 16376 OMPClause *Sema::ActOnOpenMPPartialClause(Expr *FactorExpr, 16377 SourceLocation StartLoc, 16378 SourceLocation LParenLoc, 16379 SourceLocation EndLoc) { 16380 if (FactorExpr) { 16381 // If an argument is specified, it must be a constant (or an unevaluated 16382 // template expression). 16383 ExprResult FactorResult = VerifyPositiveIntegerConstantInClause( 16384 FactorExpr, OMPC_partial, /*StrictlyPositive=*/true); 16385 if (FactorResult.isInvalid()) 16386 return nullptr; 16387 FactorExpr = FactorResult.get(); 16388 } 16389 16390 return OMPPartialClause::Create(Context, StartLoc, LParenLoc, EndLoc, 16391 FactorExpr); 16392 } 16393 16394 OMPClause *Sema::ActOnOpenMPAlignClause(Expr *A, SourceLocation StartLoc, 16395 SourceLocation LParenLoc, 16396 SourceLocation EndLoc) { 16397 ExprResult AlignVal; 16398 AlignVal = VerifyPositiveIntegerConstantInClause(A, OMPC_align); 16399 if (AlignVal.isInvalid()) 16400 return nullptr; 16401 return OMPAlignClause::Create(Context, AlignVal.get(), StartLoc, LParenLoc, 16402 EndLoc); 16403 } 16404 16405 OMPClause *Sema::ActOnOpenMPSingleExprWithArgClause( 16406 OpenMPClauseKind Kind, ArrayRef<unsigned> Argument, Expr *Expr, 16407 SourceLocation StartLoc, SourceLocation LParenLoc, 16408 ArrayRef<SourceLocation> ArgumentLoc, SourceLocation DelimLoc, 16409 SourceLocation EndLoc) { 16410 OMPClause *Res = nullptr; 16411 switch (Kind) { 16412 case OMPC_schedule: 16413 enum { Modifier1, Modifier2, ScheduleKind, NumberOfElements }; 16414 assert(Argument.size() == NumberOfElements && 16415 ArgumentLoc.size() == NumberOfElements); 16416 Res = ActOnOpenMPScheduleClause( 16417 static_cast<OpenMPScheduleClauseModifier>(Argument[Modifier1]), 16418 static_cast<OpenMPScheduleClauseModifier>(Argument[Modifier2]), 16419 static_cast<OpenMPScheduleClauseKind>(Argument[ScheduleKind]), Expr, 16420 StartLoc, LParenLoc, ArgumentLoc[Modifier1], ArgumentLoc[Modifier2], 16421 ArgumentLoc[ScheduleKind], DelimLoc, EndLoc); 16422 break; 16423 case OMPC_if: 16424 assert(Argument.size() == 1 && ArgumentLoc.size() == 1); 16425 Res = ActOnOpenMPIfClause(static_cast<OpenMPDirectiveKind>(Argument.back()), 16426 Expr, StartLoc, LParenLoc, ArgumentLoc.back(), 16427 DelimLoc, EndLoc); 16428 break; 16429 case OMPC_dist_schedule: 16430 Res = ActOnOpenMPDistScheduleClause( 16431 static_cast<OpenMPDistScheduleClauseKind>(Argument.back()), Expr, 16432 StartLoc, LParenLoc, ArgumentLoc.back(), DelimLoc, EndLoc); 16433 break; 16434 case OMPC_defaultmap: 16435 enum { Modifier, DefaultmapKind }; 16436 Res = ActOnOpenMPDefaultmapClause( 16437 static_cast<OpenMPDefaultmapClauseModifier>(Argument[Modifier]), 16438 static_cast<OpenMPDefaultmapClauseKind>(Argument[DefaultmapKind]), 16439 StartLoc, LParenLoc, ArgumentLoc[Modifier], ArgumentLoc[DefaultmapKind], 16440 EndLoc); 16441 break; 16442 case OMPC_device: 16443 assert(Argument.size() == 1 && ArgumentLoc.size() == 1); 16444 Res = ActOnOpenMPDeviceClause( 16445 static_cast<OpenMPDeviceClauseModifier>(Argument.back()), Expr, 16446 StartLoc, LParenLoc, ArgumentLoc.back(), EndLoc); 16447 break; 16448 case OMPC_final: 16449 case OMPC_num_threads: 16450 case OMPC_safelen: 16451 case OMPC_simdlen: 16452 case OMPC_sizes: 16453 case OMPC_allocator: 16454 case OMPC_collapse: 16455 case OMPC_default: 16456 case OMPC_proc_bind: 16457 case OMPC_private: 16458 case OMPC_firstprivate: 16459 case OMPC_lastprivate: 16460 case OMPC_shared: 16461 case OMPC_reduction: 16462 case OMPC_task_reduction: 16463 case OMPC_in_reduction: 16464 case OMPC_linear: 16465 case OMPC_aligned: 16466 case OMPC_copyin: 16467 case OMPC_copyprivate: 16468 case OMPC_ordered: 16469 case OMPC_nowait: 16470 case OMPC_untied: 16471 case OMPC_mergeable: 16472 case OMPC_threadprivate: 16473 case OMPC_allocate: 16474 case OMPC_flush: 16475 case OMPC_depobj: 16476 case OMPC_read: 16477 case OMPC_write: 16478 case OMPC_update: 16479 case OMPC_capture: 16480 case OMPC_compare: 16481 case OMPC_seq_cst: 16482 case OMPC_acq_rel: 16483 case OMPC_acquire: 16484 case OMPC_release: 16485 case OMPC_relaxed: 16486 case OMPC_depend: 16487 case OMPC_threads: 16488 case OMPC_simd: 16489 case OMPC_map: 16490 case OMPC_num_teams: 16491 case OMPC_thread_limit: 16492 case OMPC_priority: 16493 case OMPC_grainsize: 16494 case OMPC_nogroup: 16495 case OMPC_num_tasks: 16496 case OMPC_hint: 16497 case OMPC_unknown: 16498 case OMPC_uniform: 16499 case OMPC_to: 16500 case OMPC_from: 16501 case OMPC_use_device_ptr: 16502 case OMPC_use_device_addr: 16503 case OMPC_is_device_ptr: 16504 case OMPC_has_device_addr: 16505 case OMPC_unified_address: 16506 case OMPC_unified_shared_memory: 16507 case OMPC_reverse_offload: 16508 case OMPC_dynamic_allocators: 16509 case OMPC_atomic_default_mem_order: 16510 case OMPC_device_type: 16511 case OMPC_match: 16512 case OMPC_nontemporal: 16513 case OMPC_order: 16514 case OMPC_destroy: 16515 case OMPC_novariants: 16516 case OMPC_nocontext: 16517 case OMPC_detach: 16518 case OMPC_inclusive: 16519 case OMPC_exclusive: 16520 case OMPC_uses_allocators: 16521 case OMPC_affinity: 16522 case OMPC_when: 16523 case OMPC_bind: 16524 default: 16525 llvm_unreachable("Clause is not allowed."); 16526 } 16527 return Res; 16528 } 16529 16530 static bool checkScheduleModifiers(Sema &S, OpenMPScheduleClauseModifier M1, 16531 OpenMPScheduleClauseModifier M2, 16532 SourceLocation M1Loc, SourceLocation M2Loc) { 16533 if (M1 == OMPC_SCHEDULE_MODIFIER_unknown && M1Loc.isValid()) { 16534 SmallVector<unsigned, 2> Excluded; 16535 if (M2 != OMPC_SCHEDULE_MODIFIER_unknown) 16536 Excluded.push_back(M2); 16537 if (M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) 16538 Excluded.push_back(OMPC_SCHEDULE_MODIFIER_monotonic); 16539 if (M2 == OMPC_SCHEDULE_MODIFIER_monotonic) 16540 Excluded.push_back(OMPC_SCHEDULE_MODIFIER_nonmonotonic); 16541 S.Diag(M1Loc, diag::err_omp_unexpected_clause_value) 16542 << getListOfPossibleValues(OMPC_schedule, 16543 /*First=*/OMPC_SCHEDULE_MODIFIER_unknown + 1, 16544 /*Last=*/OMPC_SCHEDULE_MODIFIER_last, 16545 Excluded) 16546 << getOpenMPClauseName(OMPC_schedule); 16547 return true; 16548 } 16549 return false; 16550 } 16551 16552 OMPClause *Sema::ActOnOpenMPScheduleClause( 16553 OpenMPScheduleClauseModifier M1, OpenMPScheduleClauseModifier M2, 16554 OpenMPScheduleClauseKind Kind, Expr *ChunkSize, SourceLocation StartLoc, 16555 SourceLocation LParenLoc, SourceLocation M1Loc, SourceLocation M2Loc, 16556 SourceLocation KindLoc, SourceLocation CommaLoc, SourceLocation EndLoc) { 16557 if (checkScheduleModifiers(*this, M1, M2, M1Loc, M2Loc) || 16558 checkScheduleModifiers(*this, M2, M1, M2Loc, M1Loc)) 16559 return nullptr; 16560 // OpenMP, 2.7.1, Loop Construct, Restrictions 16561 // Either the monotonic modifier or the nonmonotonic modifier can be specified 16562 // but not both. 16563 if ((M1 == M2 && M1 != OMPC_SCHEDULE_MODIFIER_unknown) || 16564 (M1 == OMPC_SCHEDULE_MODIFIER_monotonic && 16565 M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) || 16566 (M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic && 16567 M2 == OMPC_SCHEDULE_MODIFIER_monotonic)) { 16568 Diag(M2Loc, diag::err_omp_unexpected_schedule_modifier) 16569 << getOpenMPSimpleClauseTypeName(OMPC_schedule, M2) 16570 << getOpenMPSimpleClauseTypeName(OMPC_schedule, M1); 16571 return nullptr; 16572 } 16573 if (Kind == OMPC_SCHEDULE_unknown) { 16574 std::string Values; 16575 if (M1Loc.isInvalid() && M2Loc.isInvalid()) { 16576 unsigned Exclude[] = {OMPC_SCHEDULE_unknown}; 16577 Values = getListOfPossibleValues(OMPC_schedule, /*First=*/0, 16578 /*Last=*/OMPC_SCHEDULE_MODIFIER_last, 16579 Exclude); 16580 } else { 16581 Values = getListOfPossibleValues(OMPC_schedule, /*First=*/0, 16582 /*Last=*/OMPC_SCHEDULE_unknown); 16583 } 16584 Diag(KindLoc, diag::err_omp_unexpected_clause_value) 16585 << Values << getOpenMPClauseName(OMPC_schedule); 16586 return nullptr; 16587 } 16588 // OpenMP, 2.7.1, Loop Construct, Restrictions 16589 // The nonmonotonic modifier can only be specified with schedule(dynamic) or 16590 // schedule(guided). 16591 // OpenMP 5.0 does not have this restriction. 16592 if (LangOpts.OpenMP < 50 && 16593 (M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic || 16594 M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) && 16595 Kind != OMPC_SCHEDULE_dynamic && Kind != OMPC_SCHEDULE_guided) { 16596 Diag(M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic ? M1Loc : M2Loc, 16597 diag::err_omp_schedule_nonmonotonic_static); 16598 return nullptr; 16599 } 16600 Expr *ValExpr = ChunkSize; 16601 Stmt *HelperValStmt = nullptr; 16602 if (ChunkSize) { 16603 if (!ChunkSize->isValueDependent() && !ChunkSize->isTypeDependent() && 16604 !ChunkSize->isInstantiationDependent() && 16605 !ChunkSize->containsUnexpandedParameterPack()) { 16606 SourceLocation ChunkSizeLoc = ChunkSize->getBeginLoc(); 16607 ExprResult Val = 16608 PerformOpenMPImplicitIntegerConversion(ChunkSizeLoc, ChunkSize); 16609 if (Val.isInvalid()) 16610 return nullptr; 16611 16612 ValExpr = Val.get(); 16613 16614 // OpenMP [2.7.1, Restrictions] 16615 // chunk_size must be a loop invariant integer expression with a positive 16616 // value. 16617 if (Optional<llvm::APSInt> Result = 16618 ValExpr->getIntegerConstantExpr(Context)) { 16619 if (Result->isSigned() && !Result->isStrictlyPositive()) { 16620 Diag(ChunkSizeLoc, diag::err_omp_negative_expression_in_clause) 16621 << "schedule" << 1 << ChunkSize->getSourceRange(); 16622 return nullptr; 16623 } 16624 } else if (getOpenMPCaptureRegionForClause( 16625 DSAStack->getCurrentDirective(), OMPC_schedule, 16626 LangOpts.OpenMP) != OMPD_unknown && 16627 !CurContext->isDependentContext()) { 16628 ValExpr = MakeFullExpr(ValExpr).get(); 16629 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 16630 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 16631 HelperValStmt = buildPreInits(Context, Captures); 16632 } 16633 } 16634 } 16635 16636 return new (Context) 16637 OMPScheduleClause(StartLoc, LParenLoc, KindLoc, CommaLoc, EndLoc, Kind, 16638 ValExpr, HelperValStmt, M1, M1Loc, M2, M2Loc); 16639 } 16640 16641 OMPClause *Sema::ActOnOpenMPClause(OpenMPClauseKind Kind, 16642 SourceLocation StartLoc, 16643 SourceLocation EndLoc) { 16644 OMPClause *Res = nullptr; 16645 switch (Kind) { 16646 case OMPC_ordered: 16647 Res = ActOnOpenMPOrderedClause(StartLoc, EndLoc); 16648 break; 16649 case OMPC_nowait: 16650 Res = ActOnOpenMPNowaitClause(StartLoc, EndLoc); 16651 break; 16652 case OMPC_untied: 16653 Res = ActOnOpenMPUntiedClause(StartLoc, EndLoc); 16654 break; 16655 case OMPC_mergeable: 16656 Res = ActOnOpenMPMergeableClause(StartLoc, EndLoc); 16657 break; 16658 case OMPC_read: 16659 Res = ActOnOpenMPReadClause(StartLoc, EndLoc); 16660 break; 16661 case OMPC_write: 16662 Res = ActOnOpenMPWriteClause(StartLoc, EndLoc); 16663 break; 16664 case OMPC_update: 16665 Res = ActOnOpenMPUpdateClause(StartLoc, EndLoc); 16666 break; 16667 case OMPC_capture: 16668 Res = ActOnOpenMPCaptureClause(StartLoc, EndLoc); 16669 break; 16670 case OMPC_compare: 16671 Res = ActOnOpenMPCompareClause(StartLoc, EndLoc); 16672 break; 16673 case OMPC_seq_cst: 16674 Res = ActOnOpenMPSeqCstClause(StartLoc, EndLoc); 16675 break; 16676 case OMPC_acq_rel: 16677 Res = ActOnOpenMPAcqRelClause(StartLoc, EndLoc); 16678 break; 16679 case OMPC_acquire: 16680 Res = ActOnOpenMPAcquireClause(StartLoc, EndLoc); 16681 break; 16682 case OMPC_release: 16683 Res = ActOnOpenMPReleaseClause(StartLoc, EndLoc); 16684 break; 16685 case OMPC_relaxed: 16686 Res = ActOnOpenMPRelaxedClause(StartLoc, EndLoc); 16687 break; 16688 case OMPC_threads: 16689 Res = ActOnOpenMPThreadsClause(StartLoc, EndLoc); 16690 break; 16691 case OMPC_simd: 16692 Res = ActOnOpenMPSIMDClause(StartLoc, EndLoc); 16693 break; 16694 case OMPC_nogroup: 16695 Res = ActOnOpenMPNogroupClause(StartLoc, EndLoc); 16696 break; 16697 case OMPC_unified_address: 16698 Res = ActOnOpenMPUnifiedAddressClause(StartLoc, EndLoc); 16699 break; 16700 case OMPC_unified_shared_memory: 16701 Res = ActOnOpenMPUnifiedSharedMemoryClause(StartLoc, EndLoc); 16702 break; 16703 case OMPC_reverse_offload: 16704 Res = ActOnOpenMPReverseOffloadClause(StartLoc, EndLoc); 16705 break; 16706 case OMPC_dynamic_allocators: 16707 Res = ActOnOpenMPDynamicAllocatorsClause(StartLoc, EndLoc); 16708 break; 16709 case OMPC_destroy: 16710 Res = ActOnOpenMPDestroyClause(/*InteropVar=*/nullptr, StartLoc, 16711 /*LParenLoc=*/SourceLocation(), 16712 /*VarLoc=*/SourceLocation(), EndLoc); 16713 break; 16714 case OMPC_full: 16715 Res = ActOnOpenMPFullClause(StartLoc, EndLoc); 16716 break; 16717 case OMPC_partial: 16718 Res = ActOnOpenMPPartialClause(nullptr, StartLoc, /*LParenLoc=*/{}, EndLoc); 16719 break; 16720 case OMPC_if: 16721 case OMPC_final: 16722 case OMPC_num_threads: 16723 case OMPC_safelen: 16724 case OMPC_simdlen: 16725 case OMPC_sizes: 16726 case OMPC_allocator: 16727 case OMPC_collapse: 16728 case OMPC_schedule: 16729 case OMPC_private: 16730 case OMPC_firstprivate: 16731 case OMPC_lastprivate: 16732 case OMPC_shared: 16733 case OMPC_reduction: 16734 case OMPC_task_reduction: 16735 case OMPC_in_reduction: 16736 case OMPC_linear: 16737 case OMPC_aligned: 16738 case OMPC_copyin: 16739 case OMPC_copyprivate: 16740 case OMPC_default: 16741 case OMPC_proc_bind: 16742 case OMPC_threadprivate: 16743 case OMPC_allocate: 16744 case OMPC_flush: 16745 case OMPC_depobj: 16746 case OMPC_depend: 16747 case OMPC_device: 16748 case OMPC_map: 16749 case OMPC_num_teams: 16750 case OMPC_thread_limit: 16751 case OMPC_priority: 16752 case OMPC_grainsize: 16753 case OMPC_num_tasks: 16754 case OMPC_hint: 16755 case OMPC_dist_schedule: 16756 case OMPC_defaultmap: 16757 case OMPC_unknown: 16758 case OMPC_uniform: 16759 case OMPC_to: 16760 case OMPC_from: 16761 case OMPC_use_device_ptr: 16762 case OMPC_use_device_addr: 16763 case OMPC_is_device_ptr: 16764 case OMPC_has_device_addr: 16765 case OMPC_atomic_default_mem_order: 16766 case OMPC_device_type: 16767 case OMPC_match: 16768 case OMPC_nontemporal: 16769 case OMPC_order: 16770 case OMPC_novariants: 16771 case OMPC_nocontext: 16772 case OMPC_detach: 16773 case OMPC_inclusive: 16774 case OMPC_exclusive: 16775 case OMPC_uses_allocators: 16776 case OMPC_affinity: 16777 case OMPC_when: 16778 default: 16779 llvm_unreachable("Clause is not allowed."); 16780 } 16781 return Res; 16782 } 16783 16784 OMPClause *Sema::ActOnOpenMPNowaitClause(SourceLocation StartLoc, 16785 SourceLocation EndLoc) { 16786 DSAStack->setNowaitRegion(); 16787 return new (Context) OMPNowaitClause(StartLoc, EndLoc); 16788 } 16789 16790 OMPClause *Sema::ActOnOpenMPUntiedClause(SourceLocation StartLoc, 16791 SourceLocation EndLoc) { 16792 DSAStack->setUntiedRegion(); 16793 return new (Context) OMPUntiedClause(StartLoc, EndLoc); 16794 } 16795 16796 OMPClause *Sema::ActOnOpenMPMergeableClause(SourceLocation StartLoc, 16797 SourceLocation EndLoc) { 16798 return new (Context) OMPMergeableClause(StartLoc, EndLoc); 16799 } 16800 16801 OMPClause *Sema::ActOnOpenMPReadClause(SourceLocation StartLoc, 16802 SourceLocation EndLoc) { 16803 return new (Context) OMPReadClause(StartLoc, EndLoc); 16804 } 16805 16806 OMPClause *Sema::ActOnOpenMPWriteClause(SourceLocation StartLoc, 16807 SourceLocation EndLoc) { 16808 return new (Context) OMPWriteClause(StartLoc, EndLoc); 16809 } 16810 16811 OMPClause *Sema::ActOnOpenMPUpdateClause(SourceLocation StartLoc, 16812 SourceLocation EndLoc) { 16813 return OMPUpdateClause::Create(Context, StartLoc, EndLoc); 16814 } 16815 16816 OMPClause *Sema::ActOnOpenMPCaptureClause(SourceLocation StartLoc, 16817 SourceLocation EndLoc) { 16818 return new (Context) OMPCaptureClause(StartLoc, EndLoc); 16819 } 16820 16821 OMPClause *Sema::ActOnOpenMPCompareClause(SourceLocation StartLoc, 16822 SourceLocation EndLoc) { 16823 return new (Context) OMPCompareClause(StartLoc, EndLoc); 16824 } 16825 16826 OMPClause *Sema::ActOnOpenMPSeqCstClause(SourceLocation StartLoc, 16827 SourceLocation EndLoc) { 16828 return new (Context) OMPSeqCstClause(StartLoc, EndLoc); 16829 } 16830 16831 OMPClause *Sema::ActOnOpenMPAcqRelClause(SourceLocation StartLoc, 16832 SourceLocation EndLoc) { 16833 return new (Context) OMPAcqRelClause(StartLoc, EndLoc); 16834 } 16835 16836 OMPClause *Sema::ActOnOpenMPAcquireClause(SourceLocation StartLoc, 16837 SourceLocation EndLoc) { 16838 return new (Context) OMPAcquireClause(StartLoc, EndLoc); 16839 } 16840 16841 OMPClause *Sema::ActOnOpenMPReleaseClause(SourceLocation StartLoc, 16842 SourceLocation EndLoc) { 16843 return new (Context) OMPReleaseClause(StartLoc, EndLoc); 16844 } 16845 16846 OMPClause *Sema::ActOnOpenMPRelaxedClause(SourceLocation StartLoc, 16847 SourceLocation EndLoc) { 16848 return new (Context) OMPRelaxedClause(StartLoc, EndLoc); 16849 } 16850 16851 OMPClause *Sema::ActOnOpenMPThreadsClause(SourceLocation StartLoc, 16852 SourceLocation EndLoc) { 16853 return new (Context) OMPThreadsClause(StartLoc, EndLoc); 16854 } 16855 16856 OMPClause *Sema::ActOnOpenMPSIMDClause(SourceLocation StartLoc, 16857 SourceLocation EndLoc) { 16858 return new (Context) OMPSIMDClause(StartLoc, EndLoc); 16859 } 16860 16861 OMPClause *Sema::ActOnOpenMPNogroupClause(SourceLocation StartLoc, 16862 SourceLocation EndLoc) { 16863 return new (Context) OMPNogroupClause(StartLoc, EndLoc); 16864 } 16865 16866 OMPClause *Sema::ActOnOpenMPUnifiedAddressClause(SourceLocation StartLoc, 16867 SourceLocation EndLoc) { 16868 return new (Context) OMPUnifiedAddressClause(StartLoc, EndLoc); 16869 } 16870 16871 OMPClause *Sema::ActOnOpenMPUnifiedSharedMemoryClause(SourceLocation StartLoc, 16872 SourceLocation EndLoc) { 16873 return new (Context) OMPUnifiedSharedMemoryClause(StartLoc, EndLoc); 16874 } 16875 16876 OMPClause *Sema::ActOnOpenMPReverseOffloadClause(SourceLocation StartLoc, 16877 SourceLocation EndLoc) { 16878 return new (Context) OMPReverseOffloadClause(StartLoc, EndLoc); 16879 } 16880 16881 OMPClause *Sema::ActOnOpenMPDynamicAllocatorsClause(SourceLocation StartLoc, 16882 SourceLocation EndLoc) { 16883 return new (Context) OMPDynamicAllocatorsClause(StartLoc, EndLoc); 16884 } 16885 16886 StmtResult Sema::ActOnOpenMPInteropDirective(ArrayRef<OMPClause *> Clauses, 16887 SourceLocation StartLoc, 16888 SourceLocation EndLoc) { 16889 16890 // OpenMP 5.1 [2.15.1, interop Construct, Restrictions] 16891 // At least one action-clause must appear on a directive. 16892 if (!hasClauses(Clauses, OMPC_init, OMPC_use, OMPC_destroy, OMPC_nowait)) { 16893 StringRef Expected = "'init', 'use', 'destroy', or 'nowait'"; 16894 Diag(StartLoc, diag::err_omp_no_clause_for_directive) 16895 << Expected << getOpenMPDirectiveName(OMPD_interop); 16896 return StmtError(); 16897 } 16898 16899 // OpenMP 5.1 [2.15.1, interop Construct, Restrictions] 16900 // A depend clause can only appear on the directive if a targetsync 16901 // interop-type is present or the interop-var was initialized with 16902 // the targetsync interop-type. 16903 16904 // If there is any 'init' clause diagnose if there is no 'init' clause with 16905 // interop-type of 'targetsync'. Cases involving other directives cannot be 16906 // diagnosed. 16907 const OMPDependClause *DependClause = nullptr; 16908 bool HasInitClause = false; 16909 bool IsTargetSync = false; 16910 for (const OMPClause *C : Clauses) { 16911 if (IsTargetSync) 16912 break; 16913 if (const auto *InitClause = dyn_cast<OMPInitClause>(C)) { 16914 HasInitClause = true; 16915 if (InitClause->getIsTargetSync()) 16916 IsTargetSync = true; 16917 } else if (const auto *DC = dyn_cast<OMPDependClause>(C)) { 16918 DependClause = DC; 16919 } 16920 } 16921 if (DependClause && HasInitClause && !IsTargetSync) { 16922 Diag(DependClause->getBeginLoc(), diag::err_omp_interop_bad_depend_clause); 16923 return StmtError(); 16924 } 16925 16926 // OpenMP 5.1 [2.15.1, interop Construct, Restrictions] 16927 // Each interop-var may be specified for at most one action-clause of each 16928 // interop construct. 16929 llvm::SmallPtrSet<const VarDecl *, 4> InteropVars; 16930 for (const OMPClause *C : Clauses) { 16931 OpenMPClauseKind ClauseKind = C->getClauseKind(); 16932 const DeclRefExpr *DRE = nullptr; 16933 SourceLocation VarLoc; 16934 16935 if (ClauseKind == OMPC_init) { 16936 const auto *IC = cast<OMPInitClause>(C); 16937 VarLoc = IC->getVarLoc(); 16938 DRE = dyn_cast_or_null<DeclRefExpr>(IC->getInteropVar()); 16939 } else if (ClauseKind == OMPC_use) { 16940 const auto *UC = cast<OMPUseClause>(C); 16941 VarLoc = UC->getVarLoc(); 16942 DRE = dyn_cast_or_null<DeclRefExpr>(UC->getInteropVar()); 16943 } else if (ClauseKind == OMPC_destroy) { 16944 const auto *DC = cast<OMPDestroyClause>(C); 16945 VarLoc = DC->getVarLoc(); 16946 DRE = dyn_cast_or_null<DeclRefExpr>(DC->getInteropVar()); 16947 } 16948 16949 if (!DRE) 16950 continue; 16951 16952 if (const auto *VD = dyn_cast<VarDecl>(DRE->getDecl())) { 16953 if (!InteropVars.insert(VD->getCanonicalDecl()).second) { 16954 Diag(VarLoc, diag::err_omp_interop_var_multiple_actions) << VD; 16955 return StmtError(); 16956 } 16957 } 16958 } 16959 16960 return OMPInteropDirective::Create(Context, StartLoc, EndLoc, Clauses); 16961 } 16962 16963 static bool isValidInteropVariable(Sema &SemaRef, Expr *InteropVarExpr, 16964 SourceLocation VarLoc, 16965 OpenMPClauseKind Kind) { 16966 if (InteropVarExpr->isValueDependent() || InteropVarExpr->isTypeDependent() || 16967 InteropVarExpr->isInstantiationDependent() || 16968 InteropVarExpr->containsUnexpandedParameterPack()) 16969 return true; 16970 16971 const auto *DRE = dyn_cast<DeclRefExpr>(InteropVarExpr); 16972 if (!DRE || !isa<VarDecl>(DRE->getDecl())) { 16973 SemaRef.Diag(VarLoc, diag::err_omp_interop_variable_expected) << 0; 16974 return false; 16975 } 16976 16977 // Interop variable should be of type omp_interop_t. 16978 bool HasError = false; 16979 QualType InteropType; 16980 LookupResult Result(SemaRef, &SemaRef.Context.Idents.get("omp_interop_t"), 16981 VarLoc, Sema::LookupOrdinaryName); 16982 if (SemaRef.LookupName(Result, SemaRef.getCurScope())) { 16983 NamedDecl *ND = Result.getFoundDecl(); 16984 if (const auto *TD = dyn_cast<TypeDecl>(ND)) { 16985 InteropType = QualType(TD->getTypeForDecl(), 0); 16986 } else { 16987 HasError = true; 16988 } 16989 } else { 16990 HasError = true; 16991 } 16992 16993 if (HasError) { 16994 SemaRef.Diag(VarLoc, diag::err_omp_implied_type_not_found) 16995 << "omp_interop_t"; 16996 return false; 16997 } 16998 16999 QualType VarType = InteropVarExpr->getType().getUnqualifiedType(); 17000 if (!SemaRef.Context.hasSameType(InteropType, VarType)) { 17001 SemaRef.Diag(VarLoc, diag::err_omp_interop_variable_wrong_type); 17002 return false; 17003 } 17004 17005 // OpenMP 5.1 [2.15.1, interop Construct, Restrictions] 17006 // The interop-var passed to init or destroy must be non-const. 17007 if ((Kind == OMPC_init || Kind == OMPC_destroy) && 17008 isConstNotMutableType(SemaRef, InteropVarExpr->getType())) { 17009 SemaRef.Diag(VarLoc, diag::err_omp_interop_variable_expected) 17010 << /*non-const*/ 1; 17011 return false; 17012 } 17013 return true; 17014 } 17015 17016 OMPClause * 17017 Sema::ActOnOpenMPInitClause(Expr *InteropVar, ArrayRef<Expr *> PrefExprs, 17018 bool IsTarget, bool IsTargetSync, 17019 SourceLocation StartLoc, SourceLocation LParenLoc, 17020 SourceLocation VarLoc, SourceLocation EndLoc) { 17021 17022 if (!isValidInteropVariable(*this, InteropVar, VarLoc, OMPC_init)) 17023 return nullptr; 17024 17025 // Check prefer_type values. These foreign-runtime-id values are either 17026 // string literals or constant integral expressions. 17027 for (const Expr *E : PrefExprs) { 17028 if (E->isValueDependent() || E->isTypeDependent() || 17029 E->isInstantiationDependent() || E->containsUnexpandedParameterPack()) 17030 continue; 17031 if (E->isIntegerConstantExpr(Context)) 17032 continue; 17033 if (isa<StringLiteral>(E)) 17034 continue; 17035 Diag(E->getExprLoc(), diag::err_omp_interop_prefer_type); 17036 return nullptr; 17037 } 17038 17039 return OMPInitClause::Create(Context, InteropVar, PrefExprs, IsTarget, 17040 IsTargetSync, StartLoc, LParenLoc, VarLoc, 17041 EndLoc); 17042 } 17043 17044 OMPClause *Sema::ActOnOpenMPUseClause(Expr *InteropVar, SourceLocation StartLoc, 17045 SourceLocation LParenLoc, 17046 SourceLocation VarLoc, 17047 SourceLocation EndLoc) { 17048 17049 if (!isValidInteropVariable(*this, InteropVar, VarLoc, OMPC_use)) 17050 return nullptr; 17051 17052 return new (Context) 17053 OMPUseClause(InteropVar, StartLoc, LParenLoc, VarLoc, EndLoc); 17054 } 17055 17056 OMPClause *Sema::ActOnOpenMPDestroyClause(Expr *InteropVar, 17057 SourceLocation StartLoc, 17058 SourceLocation LParenLoc, 17059 SourceLocation VarLoc, 17060 SourceLocation EndLoc) { 17061 if (InteropVar && 17062 !isValidInteropVariable(*this, InteropVar, VarLoc, OMPC_destroy)) 17063 return nullptr; 17064 17065 return new (Context) 17066 OMPDestroyClause(InteropVar, StartLoc, LParenLoc, VarLoc, EndLoc); 17067 } 17068 17069 OMPClause *Sema::ActOnOpenMPNovariantsClause(Expr *Condition, 17070 SourceLocation StartLoc, 17071 SourceLocation LParenLoc, 17072 SourceLocation EndLoc) { 17073 Expr *ValExpr = Condition; 17074 Stmt *HelperValStmt = nullptr; 17075 OpenMPDirectiveKind CaptureRegion = OMPD_unknown; 17076 if (!Condition->isValueDependent() && !Condition->isTypeDependent() && 17077 !Condition->isInstantiationDependent() && 17078 !Condition->containsUnexpandedParameterPack()) { 17079 ExprResult Val = CheckBooleanCondition(StartLoc, Condition); 17080 if (Val.isInvalid()) 17081 return nullptr; 17082 17083 ValExpr = MakeFullExpr(Val.get()).get(); 17084 17085 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 17086 CaptureRegion = getOpenMPCaptureRegionForClause(DKind, OMPC_novariants, 17087 LangOpts.OpenMP); 17088 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 17089 ValExpr = MakeFullExpr(ValExpr).get(); 17090 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 17091 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 17092 HelperValStmt = buildPreInits(Context, Captures); 17093 } 17094 } 17095 17096 return new (Context) OMPNovariantsClause( 17097 ValExpr, HelperValStmt, CaptureRegion, StartLoc, LParenLoc, EndLoc); 17098 } 17099 17100 OMPClause *Sema::ActOnOpenMPNocontextClause(Expr *Condition, 17101 SourceLocation StartLoc, 17102 SourceLocation LParenLoc, 17103 SourceLocation EndLoc) { 17104 Expr *ValExpr = Condition; 17105 Stmt *HelperValStmt = nullptr; 17106 OpenMPDirectiveKind CaptureRegion = OMPD_unknown; 17107 if (!Condition->isValueDependent() && !Condition->isTypeDependent() && 17108 !Condition->isInstantiationDependent() && 17109 !Condition->containsUnexpandedParameterPack()) { 17110 ExprResult Val = CheckBooleanCondition(StartLoc, Condition); 17111 if (Val.isInvalid()) 17112 return nullptr; 17113 17114 ValExpr = MakeFullExpr(Val.get()).get(); 17115 17116 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 17117 CaptureRegion = 17118 getOpenMPCaptureRegionForClause(DKind, OMPC_nocontext, LangOpts.OpenMP); 17119 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 17120 ValExpr = MakeFullExpr(ValExpr).get(); 17121 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 17122 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 17123 HelperValStmt = buildPreInits(Context, Captures); 17124 } 17125 } 17126 17127 return new (Context) OMPNocontextClause(ValExpr, HelperValStmt, CaptureRegion, 17128 StartLoc, LParenLoc, EndLoc); 17129 } 17130 17131 OMPClause *Sema::ActOnOpenMPFilterClause(Expr *ThreadID, 17132 SourceLocation StartLoc, 17133 SourceLocation LParenLoc, 17134 SourceLocation EndLoc) { 17135 Expr *ValExpr = ThreadID; 17136 Stmt *HelperValStmt = nullptr; 17137 17138 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 17139 OpenMPDirectiveKind CaptureRegion = 17140 getOpenMPCaptureRegionForClause(DKind, OMPC_filter, LangOpts.OpenMP); 17141 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 17142 ValExpr = MakeFullExpr(ValExpr).get(); 17143 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 17144 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 17145 HelperValStmt = buildPreInits(Context, Captures); 17146 } 17147 17148 return new (Context) OMPFilterClause(ValExpr, HelperValStmt, CaptureRegion, 17149 StartLoc, LParenLoc, EndLoc); 17150 } 17151 17152 OMPClause *Sema::ActOnOpenMPVarListClause(OpenMPClauseKind Kind, 17153 ArrayRef<Expr *> VarList, 17154 const OMPVarListLocTy &Locs, 17155 OpenMPVarListDataTy &Data) { 17156 SourceLocation StartLoc = Locs.StartLoc; 17157 SourceLocation LParenLoc = Locs.LParenLoc; 17158 SourceLocation EndLoc = Locs.EndLoc; 17159 OMPClause *Res = nullptr; 17160 int ExtraModifier = Data.ExtraModifier; 17161 SourceLocation ExtraModifierLoc = Data.ExtraModifierLoc; 17162 SourceLocation ColonLoc = Data.ColonLoc; 17163 switch (Kind) { 17164 case OMPC_private: 17165 Res = ActOnOpenMPPrivateClause(VarList, StartLoc, LParenLoc, EndLoc); 17166 break; 17167 case OMPC_firstprivate: 17168 Res = ActOnOpenMPFirstprivateClause(VarList, StartLoc, LParenLoc, EndLoc); 17169 break; 17170 case OMPC_lastprivate: 17171 assert(0 <= ExtraModifier && ExtraModifier <= OMPC_LASTPRIVATE_unknown && 17172 "Unexpected lastprivate modifier."); 17173 Res = ActOnOpenMPLastprivateClause( 17174 VarList, static_cast<OpenMPLastprivateModifier>(ExtraModifier), 17175 ExtraModifierLoc, ColonLoc, StartLoc, LParenLoc, EndLoc); 17176 break; 17177 case OMPC_shared: 17178 Res = ActOnOpenMPSharedClause(VarList, StartLoc, LParenLoc, EndLoc); 17179 break; 17180 case OMPC_reduction: 17181 assert(0 <= ExtraModifier && ExtraModifier <= OMPC_REDUCTION_unknown && 17182 "Unexpected lastprivate modifier."); 17183 Res = ActOnOpenMPReductionClause( 17184 VarList, static_cast<OpenMPReductionClauseModifier>(ExtraModifier), 17185 StartLoc, LParenLoc, ExtraModifierLoc, ColonLoc, EndLoc, 17186 Data.ReductionOrMapperIdScopeSpec, Data.ReductionOrMapperId); 17187 break; 17188 case OMPC_task_reduction: 17189 Res = ActOnOpenMPTaskReductionClause( 17190 VarList, StartLoc, LParenLoc, ColonLoc, EndLoc, 17191 Data.ReductionOrMapperIdScopeSpec, Data.ReductionOrMapperId); 17192 break; 17193 case OMPC_in_reduction: 17194 Res = ActOnOpenMPInReductionClause( 17195 VarList, StartLoc, LParenLoc, ColonLoc, EndLoc, 17196 Data.ReductionOrMapperIdScopeSpec, Data.ReductionOrMapperId); 17197 break; 17198 case OMPC_linear: 17199 assert(0 <= ExtraModifier && ExtraModifier <= OMPC_LINEAR_unknown && 17200 "Unexpected linear modifier."); 17201 Res = ActOnOpenMPLinearClause( 17202 VarList, Data.DepModOrTailExpr, StartLoc, LParenLoc, 17203 static_cast<OpenMPLinearClauseKind>(ExtraModifier), ExtraModifierLoc, 17204 ColonLoc, EndLoc); 17205 break; 17206 case OMPC_aligned: 17207 Res = ActOnOpenMPAlignedClause(VarList, Data.DepModOrTailExpr, StartLoc, 17208 LParenLoc, ColonLoc, EndLoc); 17209 break; 17210 case OMPC_copyin: 17211 Res = ActOnOpenMPCopyinClause(VarList, StartLoc, LParenLoc, EndLoc); 17212 break; 17213 case OMPC_copyprivate: 17214 Res = ActOnOpenMPCopyprivateClause(VarList, StartLoc, LParenLoc, EndLoc); 17215 break; 17216 case OMPC_flush: 17217 Res = ActOnOpenMPFlushClause(VarList, StartLoc, LParenLoc, EndLoc); 17218 break; 17219 case OMPC_depend: 17220 assert(0 <= ExtraModifier && ExtraModifier <= OMPC_DEPEND_unknown && 17221 "Unexpected depend modifier."); 17222 Res = ActOnOpenMPDependClause( 17223 {static_cast<OpenMPDependClauseKind>(ExtraModifier), ExtraModifierLoc, 17224 ColonLoc, Data.OmpAllMemoryLoc}, 17225 Data.DepModOrTailExpr, VarList, StartLoc, LParenLoc, EndLoc); 17226 break; 17227 case OMPC_map: 17228 assert(0 <= ExtraModifier && ExtraModifier <= OMPC_MAP_unknown && 17229 "Unexpected map modifier."); 17230 Res = ActOnOpenMPMapClause( 17231 Data.MapTypeModifiers, Data.MapTypeModifiersLoc, 17232 Data.ReductionOrMapperIdScopeSpec, Data.ReductionOrMapperId, 17233 static_cast<OpenMPMapClauseKind>(ExtraModifier), Data.IsMapTypeImplicit, 17234 ExtraModifierLoc, ColonLoc, VarList, Locs); 17235 break; 17236 case OMPC_to: 17237 Res = 17238 ActOnOpenMPToClause(Data.MotionModifiers, Data.MotionModifiersLoc, 17239 Data.ReductionOrMapperIdScopeSpec, 17240 Data.ReductionOrMapperId, ColonLoc, VarList, Locs); 17241 break; 17242 case OMPC_from: 17243 Res = ActOnOpenMPFromClause(Data.MotionModifiers, Data.MotionModifiersLoc, 17244 Data.ReductionOrMapperIdScopeSpec, 17245 Data.ReductionOrMapperId, ColonLoc, VarList, 17246 Locs); 17247 break; 17248 case OMPC_use_device_ptr: 17249 Res = ActOnOpenMPUseDevicePtrClause(VarList, Locs); 17250 break; 17251 case OMPC_use_device_addr: 17252 Res = ActOnOpenMPUseDeviceAddrClause(VarList, Locs); 17253 break; 17254 case OMPC_is_device_ptr: 17255 Res = ActOnOpenMPIsDevicePtrClause(VarList, Locs); 17256 break; 17257 case OMPC_has_device_addr: 17258 Res = ActOnOpenMPHasDeviceAddrClause(VarList, Locs); 17259 break; 17260 case OMPC_allocate: 17261 Res = ActOnOpenMPAllocateClause(Data.DepModOrTailExpr, VarList, StartLoc, 17262 LParenLoc, ColonLoc, EndLoc); 17263 break; 17264 case OMPC_nontemporal: 17265 Res = ActOnOpenMPNontemporalClause(VarList, StartLoc, LParenLoc, EndLoc); 17266 break; 17267 case OMPC_inclusive: 17268 Res = ActOnOpenMPInclusiveClause(VarList, StartLoc, LParenLoc, EndLoc); 17269 break; 17270 case OMPC_exclusive: 17271 Res = ActOnOpenMPExclusiveClause(VarList, StartLoc, LParenLoc, EndLoc); 17272 break; 17273 case OMPC_affinity: 17274 Res = ActOnOpenMPAffinityClause(StartLoc, LParenLoc, ColonLoc, EndLoc, 17275 Data.DepModOrTailExpr, VarList); 17276 break; 17277 case OMPC_if: 17278 case OMPC_depobj: 17279 case OMPC_final: 17280 case OMPC_num_threads: 17281 case OMPC_safelen: 17282 case OMPC_simdlen: 17283 case OMPC_sizes: 17284 case OMPC_allocator: 17285 case OMPC_collapse: 17286 case OMPC_default: 17287 case OMPC_proc_bind: 17288 case OMPC_schedule: 17289 case OMPC_ordered: 17290 case OMPC_nowait: 17291 case OMPC_untied: 17292 case OMPC_mergeable: 17293 case OMPC_threadprivate: 17294 case OMPC_read: 17295 case OMPC_write: 17296 case OMPC_update: 17297 case OMPC_capture: 17298 case OMPC_compare: 17299 case OMPC_seq_cst: 17300 case OMPC_acq_rel: 17301 case OMPC_acquire: 17302 case OMPC_release: 17303 case OMPC_relaxed: 17304 case OMPC_device: 17305 case OMPC_threads: 17306 case OMPC_simd: 17307 case OMPC_num_teams: 17308 case OMPC_thread_limit: 17309 case OMPC_priority: 17310 case OMPC_grainsize: 17311 case OMPC_nogroup: 17312 case OMPC_num_tasks: 17313 case OMPC_hint: 17314 case OMPC_dist_schedule: 17315 case OMPC_defaultmap: 17316 case OMPC_unknown: 17317 case OMPC_uniform: 17318 case OMPC_unified_address: 17319 case OMPC_unified_shared_memory: 17320 case OMPC_reverse_offload: 17321 case OMPC_dynamic_allocators: 17322 case OMPC_atomic_default_mem_order: 17323 case OMPC_device_type: 17324 case OMPC_match: 17325 case OMPC_order: 17326 case OMPC_destroy: 17327 case OMPC_novariants: 17328 case OMPC_nocontext: 17329 case OMPC_detach: 17330 case OMPC_uses_allocators: 17331 case OMPC_when: 17332 case OMPC_bind: 17333 default: 17334 llvm_unreachable("Clause is not allowed."); 17335 } 17336 return Res; 17337 } 17338 17339 ExprResult Sema::getOpenMPCapturedExpr(VarDecl *Capture, ExprValueKind VK, 17340 ExprObjectKind OK, SourceLocation Loc) { 17341 ExprResult Res = BuildDeclRefExpr( 17342 Capture, Capture->getType().getNonReferenceType(), VK_LValue, Loc); 17343 if (!Res.isUsable()) 17344 return ExprError(); 17345 if (OK == OK_Ordinary && !getLangOpts().CPlusPlus) { 17346 Res = CreateBuiltinUnaryOp(Loc, UO_Deref, Res.get()); 17347 if (!Res.isUsable()) 17348 return ExprError(); 17349 } 17350 if (VK != VK_LValue && Res.get()->isGLValue()) { 17351 Res = DefaultLvalueConversion(Res.get()); 17352 if (!Res.isUsable()) 17353 return ExprError(); 17354 } 17355 return Res; 17356 } 17357 17358 OMPClause *Sema::ActOnOpenMPPrivateClause(ArrayRef<Expr *> VarList, 17359 SourceLocation StartLoc, 17360 SourceLocation LParenLoc, 17361 SourceLocation EndLoc) { 17362 SmallVector<Expr *, 8> Vars; 17363 SmallVector<Expr *, 8> PrivateCopies; 17364 for (Expr *RefExpr : VarList) { 17365 assert(RefExpr && "NULL expr in OpenMP private clause."); 17366 SourceLocation ELoc; 17367 SourceRange ERange; 17368 Expr *SimpleRefExpr = RefExpr; 17369 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 17370 if (Res.second) { 17371 // It will be analyzed later. 17372 Vars.push_back(RefExpr); 17373 PrivateCopies.push_back(nullptr); 17374 } 17375 ValueDecl *D = Res.first; 17376 if (!D) 17377 continue; 17378 17379 QualType Type = D->getType(); 17380 auto *VD = dyn_cast<VarDecl>(D); 17381 17382 // OpenMP [2.9.3.3, Restrictions, C/C++, p.3] 17383 // A variable that appears in a private clause must not have an incomplete 17384 // type or a reference type. 17385 if (RequireCompleteType(ELoc, Type, diag::err_omp_private_incomplete_type)) 17386 continue; 17387 Type = Type.getNonReferenceType(); 17388 17389 // OpenMP 5.0 [2.19.3, List Item Privatization, Restrictions] 17390 // A variable that is privatized must not have a const-qualified type 17391 // unless it is of class type with a mutable member. This restriction does 17392 // not apply to the firstprivate clause. 17393 // 17394 // OpenMP 3.1 [2.9.3.3, private clause, Restrictions] 17395 // A variable that appears in a private clause must not have a 17396 // const-qualified type unless it is of class type with a mutable member. 17397 if (rejectConstNotMutableType(*this, D, Type, OMPC_private, ELoc)) 17398 continue; 17399 17400 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 17401 // in a Construct] 17402 // Variables with the predetermined data-sharing attributes may not be 17403 // listed in data-sharing attributes clauses, except for the cases 17404 // listed below. For these exceptions only, listing a predetermined 17405 // variable in a data-sharing attribute clause is allowed and overrides 17406 // the variable's predetermined data-sharing attributes. 17407 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false); 17408 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_private) { 17409 Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind) 17410 << getOpenMPClauseName(OMPC_private); 17411 reportOriginalDsa(*this, DSAStack, D, DVar); 17412 continue; 17413 } 17414 17415 OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective(); 17416 // Variably modified types are not supported for tasks. 17417 if (!Type->isAnyPointerType() && Type->isVariablyModifiedType() && 17418 isOpenMPTaskingDirective(CurrDir)) { 17419 Diag(ELoc, diag::err_omp_variably_modified_type_not_supported) 17420 << getOpenMPClauseName(OMPC_private) << Type 17421 << getOpenMPDirectiveName(CurrDir); 17422 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) == 17423 VarDecl::DeclarationOnly; 17424 Diag(D->getLocation(), 17425 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 17426 << D; 17427 continue; 17428 } 17429 17430 // OpenMP 4.5 [2.15.5.1, Restrictions, p.3] 17431 // A list item cannot appear in both a map clause and a data-sharing 17432 // attribute clause on the same construct 17433 // 17434 // OpenMP 5.0 [2.19.7.1, Restrictions, p.7] 17435 // A list item cannot appear in both a map clause and a data-sharing 17436 // attribute clause on the same construct unless the construct is a 17437 // combined construct. 17438 if ((LangOpts.OpenMP <= 45 && isOpenMPTargetExecutionDirective(CurrDir)) || 17439 CurrDir == OMPD_target) { 17440 OpenMPClauseKind ConflictKind; 17441 if (DSAStack->checkMappableExprComponentListsForDecl( 17442 VD, /*CurrentRegionOnly=*/true, 17443 [&](OMPClauseMappableExprCommon::MappableExprComponentListRef, 17444 OpenMPClauseKind WhereFoundClauseKind) -> bool { 17445 ConflictKind = WhereFoundClauseKind; 17446 return true; 17447 })) { 17448 Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa) 17449 << getOpenMPClauseName(OMPC_private) 17450 << getOpenMPClauseName(ConflictKind) 17451 << getOpenMPDirectiveName(CurrDir); 17452 reportOriginalDsa(*this, DSAStack, D, DVar); 17453 continue; 17454 } 17455 } 17456 17457 // OpenMP [2.9.3.3, Restrictions, C/C++, p.1] 17458 // A variable of class type (or array thereof) that appears in a private 17459 // clause requires an accessible, unambiguous default constructor for the 17460 // class type. 17461 // Generate helper private variable and initialize it with the default 17462 // value. The address of the original variable is replaced by the address of 17463 // the new private variable in CodeGen. This new variable is not added to 17464 // IdResolver, so the code in the OpenMP region uses original variable for 17465 // proper diagnostics. 17466 Type = Type.getUnqualifiedType(); 17467 VarDecl *VDPrivate = 17468 buildVarDecl(*this, ELoc, Type, D->getName(), 17469 D->hasAttrs() ? &D->getAttrs() : nullptr, 17470 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr); 17471 ActOnUninitializedDecl(VDPrivate); 17472 if (VDPrivate->isInvalidDecl()) 17473 continue; 17474 DeclRefExpr *VDPrivateRefExpr = buildDeclRefExpr( 17475 *this, VDPrivate, RefExpr->getType().getUnqualifiedType(), ELoc); 17476 17477 DeclRefExpr *Ref = nullptr; 17478 if (!VD && !CurContext->isDependentContext()) 17479 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false); 17480 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_private, Ref); 17481 Vars.push_back((VD || CurContext->isDependentContext()) 17482 ? RefExpr->IgnoreParens() 17483 : Ref); 17484 PrivateCopies.push_back(VDPrivateRefExpr); 17485 } 17486 17487 if (Vars.empty()) 17488 return nullptr; 17489 17490 return OMPPrivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars, 17491 PrivateCopies); 17492 } 17493 17494 OMPClause *Sema::ActOnOpenMPFirstprivateClause(ArrayRef<Expr *> VarList, 17495 SourceLocation StartLoc, 17496 SourceLocation LParenLoc, 17497 SourceLocation EndLoc) { 17498 SmallVector<Expr *, 8> Vars; 17499 SmallVector<Expr *, 8> PrivateCopies; 17500 SmallVector<Expr *, 8> Inits; 17501 SmallVector<Decl *, 4> ExprCaptures; 17502 bool IsImplicitClause = 17503 StartLoc.isInvalid() && LParenLoc.isInvalid() && EndLoc.isInvalid(); 17504 SourceLocation ImplicitClauseLoc = DSAStack->getConstructLoc(); 17505 17506 for (Expr *RefExpr : VarList) { 17507 assert(RefExpr && "NULL expr in OpenMP firstprivate clause."); 17508 SourceLocation ELoc; 17509 SourceRange ERange; 17510 Expr *SimpleRefExpr = RefExpr; 17511 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 17512 if (Res.second) { 17513 // It will be analyzed later. 17514 Vars.push_back(RefExpr); 17515 PrivateCopies.push_back(nullptr); 17516 Inits.push_back(nullptr); 17517 } 17518 ValueDecl *D = Res.first; 17519 if (!D) 17520 continue; 17521 17522 ELoc = IsImplicitClause ? ImplicitClauseLoc : ELoc; 17523 QualType Type = D->getType(); 17524 auto *VD = dyn_cast<VarDecl>(D); 17525 17526 // OpenMP [2.9.3.3, Restrictions, C/C++, p.3] 17527 // A variable that appears in a private clause must not have an incomplete 17528 // type or a reference type. 17529 if (RequireCompleteType(ELoc, Type, 17530 diag::err_omp_firstprivate_incomplete_type)) 17531 continue; 17532 Type = Type.getNonReferenceType(); 17533 17534 // OpenMP [2.9.3.4, Restrictions, C/C++, p.1] 17535 // A variable of class type (or array thereof) that appears in a private 17536 // clause requires an accessible, unambiguous copy constructor for the 17537 // class type. 17538 QualType ElemType = Context.getBaseElementType(Type).getNonReferenceType(); 17539 17540 // If an implicit firstprivate variable found it was checked already. 17541 DSAStackTy::DSAVarData TopDVar; 17542 if (!IsImplicitClause) { 17543 DSAStackTy::DSAVarData DVar = 17544 DSAStack->getTopDSA(D, /*FromParent=*/false); 17545 TopDVar = DVar; 17546 OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective(); 17547 bool IsConstant = ElemType.isConstant(Context); 17548 // OpenMP [2.4.13, Data-sharing Attribute Clauses] 17549 // A list item that specifies a given variable may not appear in more 17550 // than one clause on the same directive, except that a variable may be 17551 // specified in both firstprivate and lastprivate clauses. 17552 // OpenMP 4.5 [2.10.8, Distribute Construct, p.3] 17553 // A list item may appear in a firstprivate or lastprivate clause but not 17554 // both. 17555 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_firstprivate && 17556 (isOpenMPDistributeDirective(CurrDir) || 17557 DVar.CKind != OMPC_lastprivate) && 17558 DVar.RefExpr) { 17559 Diag(ELoc, diag::err_omp_wrong_dsa) 17560 << getOpenMPClauseName(DVar.CKind) 17561 << getOpenMPClauseName(OMPC_firstprivate); 17562 reportOriginalDsa(*this, DSAStack, D, DVar); 17563 continue; 17564 } 17565 17566 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 17567 // in a Construct] 17568 // Variables with the predetermined data-sharing attributes may not be 17569 // listed in data-sharing attributes clauses, except for the cases 17570 // listed below. For these exceptions only, listing a predetermined 17571 // variable in a data-sharing attribute clause is allowed and overrides 17572 // the variable's predetermined data-sharing attributes. 17573 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 17574 // in a Construct, C/C++, p.2] 17575 // Variables with const-qualified type having no mutable member may be 17576 // listed in a firstprivate clause, even if they are static data members. 17577 if (!(IsConstant || (VD && VD->isStaticDataMember())) && !DVar.RefExpr && 17578 DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_shared) { 17579 Diag(ELoc, diag::err_omp_wrong_dsa) 17580 << getOpenMPClauseName(DVar.CKind) 17581 << getOpenMPClauseName(OMPC_firstprivate); 17582 reportOriginalDsa(*this, DSAStack, D, DVar); 17583 continue; 17584 } 17585 17586 // OpenMP [2.9.3.4, Restrictions, p.2] 17587 // A list item that is private within a parallel region must not appear 17588 // in a firstprivate clause on a worksharing construct if any of the 17589 // worksharing regions arising from the worksharing construct ever bind 17590 // to any of the parallel regions arising from the parallel construct. 17591 // OpenMP 4.5 [2.15.3.4, Restrictions, p.3] 17592 // A list item that is private within a teams region must not appear in a 17593 // firstprivate clause on a distribute construct if any of the distribute 17594 // regions arising from the distribute construct ever bind to any of the 17595 // teams regions arising from the teams construct. 17596 // OpenMP 4.5 [2.15.3.4, Restrictions, p.3] 17597 // A list item that appears in a reduction clause of a teams construct 17598 // must not appear in a firstprivate clause on a distribute construct if 17599 // any of the distribute regions arising from the distribute construct 17600 // ever bind to any of the teams regions arising from the teams construct. 17601 if ((isOpenMPWorksharingDirective(CurrDir) || 17602 isOpenMPDistributeDirective(CurrDir)) && 17603 !isOpenMPParallelDirective(CurrDir) && 17604 !isOpenMPTeamsDirective(CurrDir)) { 17605 DVar = DSAStack->getImplicitDSA(D, true); 17606 if (DVar.CKind != OMPC_shared && 17607 (isOpenMPParallelDirective(DVar.DKind) || 17608 isOpenMPTeamsDirective(DVar.DKind) || 17609 DVar.DKind == OMPD_unknown)) { 17610 Diag(ELoc, diag::err_omp_required_access) 17611 << getOpenMPClauseName(OMPC_firstprivate) 17612 << getOpenMPClauseName(OMPC_shared); 17613 reportOriginalDsa(*this, DSAStack, D, DVar); 17614 continue; 17615 } 17616 } 17617 // OpenMP [2.9.3.4, Restrictions, p.3] 17618 // A list item that appears in a reduction clause of a parallel construct 17619 // must not appear in a firstprivate clause on a worksharing or task 17620 // construct if any of the worksharing or task regions arising from the 17621 // worksharing or task construct ever bind to any of the parallel regions 17622 // arising from the parallel construct. 17623 // OpenMP [2.9.3.4, Restrictions, p.4] 17624 // A list item that appears in a reduction clause in worksharing 17625 // construct must not appear in a firstprivate clause in a task construct 17626 // encountered during execution of any of the worksharing regions arising 17627 // from the worksharing construct. 17628 if (isOpenMPTaskingDirective(CurrDir)) { 17629 DVar = DSAStack->hasInnermostDSA( 17630 D, 17631 [](OpenMPClauseKind C, bool AppliedToPointee) { 17632 return C == OMPC_reduction && !AppliedToPointee; 17633 }, 17634 [](OpenMPDirectiveKind K) { 17635 return isOpenMPParallelDirective(K) || 17636 isOpenMPWorksharingDirective(K) || 17637 isOpenMPTeamsDirective(K); 17638 }, 17639 /*FromParent=*/true); 17640 if (DVar.CKind == OMPC_reduction && 17641 (isOpenMPParallelDirective(DVar.DKind) || 17642 isOpenMPWorksharingDirective(DVar.DKind) || 17643 isOpenMPTeamsDirective(DVar.DKind))) { 17644 Diag(ELoc, diag::err_omp_parallel_reduction_in_task_firstprivate) 17645 << getOpenMPDirectiveName(DVar.DKind); 17646 reportOriginalDsa(*this, DSAStack, D, DVar); 17647 continue; 17648 } 17649 } 17650 17651 // OpenMP 4.5 [2.15.5.1, Restrictions, p.3] 17652 // A list item cannot appear in both a map clause and a data-sharing 17653 // attribute clause on the same construct 17654 // 17655 // OpenMP 5.0 [2.19.7.1, Restrictions, p.7] 17656 // A list item cannot appear in both a map clause and a data-sharing 17657 // attribute clause on the same construct unless the construct is a 17658 // combined construct. 17659 if ((LangOpts.OpenMP <= 45 && 17660 isOpenMPTargetExecutionDirective(CurrDir)) || 17661 CurrDir == OMPD_target) { 17662 OpenMPClauseKind ConflictKind; 17663 if (DSAStack->checkMappableExprComponentListsForDecl( 17664 VD, /*CurrentRegionOnly=*/true, 17665 [&ConflictKind]( 17666 OMPClauseMappableExprCommon::MappableExprComponentListRef, 17667 OpenMPClauseKind WhereFoundClauseKind) { 17668 ConflictKind = WhereFoundClauseKind; 17669 return true; 17670 })) { 17671 Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa) 17672 << getOpenMPClauseName(OMPC_firstprivate) 17673 << getOpenMPClauseName(ConflictKind) 17674 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 17675 reportOriginalDsa(*this, DSAStack, D, DVar); 17676 continue; 17677 } 17678 } 17679 } 17680 17681 // Variably modified types are not supported for tasks. 17682 if (!Type->isAnyPointerType() && Type->isVariablyModifiedType() && 17683 isOpenMPTaskingDirective(DSAStack->getCurrentDirective())) { 17684 Diag(ELoc, diag::err_omp_variably_modified_type_not_supported) 17685 << getOpenMPClauseName(OMPC_firstprivate) << Type 17686 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 17687 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) == 17688 VarDecl::DeclarationOnly; 17689 Diag(D->getLocation(), 17690 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 17691 << D; 17692 continue; 17693 } 17694 17695 Type = Type.getUnqualifiedType(); 17696 VarDecl *VDPrivate = 17697 buildVarDecl(*this, ELoc, Type, D->getName(), 17698 D->hasAttrs() ? &D->getAttrs() : nullptr, 17699 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr); 17700 // Generate helper private variable and initialize it with the value of the 17701 // original variable. The address of the original variable is replaced by 17702 // the address of the new private variable in the CodeGen. This new variable 17703 // is not added to IdResolver, so the code in the OpenMP region uses 17704 // original variable for proper diagnostics and variable capturing. 17705 Expr *VDInitRefExpr = nullptr; 17706 // For arrays generate initializer for single element and replace it by the 17707 // original array element in CodeGen. 17708 if (Type->isArrayType()) { 17709 VarDecl *VDInit = 17710 buildVarDecl(*this, RefExpr->getExprLoc(), ElemType, D->getName()); 17711 VDInitRefExpr = buildDeclRefExpr(*this, VDInit, ElemType, ELoc); 17712 Expr *Init = DefaultLvalueConversion(VDInitRefExpr).get(); 17713 ElemType = ElemType.getUnqualifiedType(); 17714 VarDecl *VDInitTemp = buildVarDecl(*this, RefExpr->getExprLoc(), ElemType, 17715 ".firstprivate.temp"); 17716 InitializedEntity Entity = 17717 InitializedEntity::InitializeVariable(VDInitTemp); 17718 InitializationKind Kind = InitializationKind::CreateCopy(ELoc, ELoc); 17719 17720 InitializationSequence InitSeq(*this, Entity, Kind, Init); 17721 ExprResult Result = InitSeq.Perform(*this, Entity, Kind, Init); 17722 if (Result.isInvalid()) 17723 VDPrivate->setInvalidDecl(); 17724 else 17725 VDPrivate->setInit(Result.getAs<Expr>()); 17726 // Remove temp variable declaration. 17727 Context.Deallocate(VDInitTemp); 17728 } else { 17729 VarDecl *VDInit = buildVarDecl(*this, RefExpr->getExprLoc(), Type, 17730 ".firstprivate.temp"); 17731 VDInitRefExpr = buildDeclRefExpr(*this, VDInit, RefExpr->getType(), 17732 RefExpr->getExprLoc()); 17733 AddInitializerToDecl(VDPrivate, 17734 DefaultLvalueConversion(VDInitRefExpr).get(), 17735 /*DirectInit=*/false); 17736 } 17737 if (VDPrivate->isInvalidDecl()) { 17738 if (IsImplicitClause) { 17739 Diag(RefExpr->getExprLoc(), 17740 diag::note_omp_task_predetermined_firstprivate_here); 17741 } 17742 continue; 17743 } 17744 CurContext->addDecl(VDPrivate); 17745 DeclRefExpr *VDPrivateRefExpr = buildDeclRefExpr( 17746 *this, VDPrivate, RefExpr->getType().getUnqualifiedType(), 17747 RefExpr->getExprLoc()); 17748 DeclRefExpr *Ref = nullptr; 17749 if (!VD && !CurContext->isDependentContext()) { 17750 if (TopDVar.CKind == OMPC_lastprivate) { 17751 Ref = TopDVar.PrivateCopy; 17752 } else { 17753 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true); 17754 if (!isOpenMPCapturedDecl(D)) 17755 ExprCaptures.push_back(Ref->getDecl()); 17756 } 17757 } 17758 if (!IsImplicitClause) 17759 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_firstprivate, Ref); 17760 Vars.push_back((VD || CurContext->isDependentContext()) 17761 ? RefExpr->IgnoreParens() 17762 : Ref); 17763 PrivateCopies.push_back(VDPrivateRefExpr); 17764 Inits.push_back(VDInitRefExpr); 17765 } 17766 17767 if (Vars.empty()) 17768 return nullptr; 17769 17770 return OMPFirstprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, 17771 Vars, PrivateCopies, Inits, 17772 buildPreInits(Context, ExprCaptures)); 17773 } 17774 17775 OMPClause *Sema::ActOnOpenMPLastprivateClause( 17776 ArrayRef<Expr *> VarList, OpenMPLastprivateModifier LPKind, 17777 SourceLocation LPKindLoc, SourceLocation ColonLoc, SourceLocation StartLoc, 17778 SourceLocation LParenLoc, SourceLocation EndLoc) { 17779 if (LPKind == OMPC_LASTPRIVATE_unknown && LPKindLoc.isValid()) { 17780 assert(ColonLoc.isValid() && "Colon location must be valid."); 17781 Diag(LPKindLoc, diag::err_omp_unexpected_clause_value) 17782 << getListOfPossibleValues(OMPC_lastprivate, /*First=*/0, 17783 /*Last=*/OMPC_LASTPRIVATE_unknown) 17784 << getOpenMPClauseName(OMPC_lastprivate); 17785 return nullptr; 17786 } 17787 17788 SmallVector<Expr *, 8> Vars; 17789 SmallVector<Expr *, 8> SrcExprs; 17790 SmallVector<Expr *, 8> DstExprs; 17791 SmallVector<Expr *, 8> AssignmentOps; 17792 SmallVector<Decl *, 4> ExprCaptures; 17793 SmallVector<Expr *, 4> ExprPostUpdates; 17794 for (Expr *RefExpr : VarList) { 17795 assert(RefExpr && "NULL expr in OpenMP lastprivate clause."); 17796 SourceLocation ELoc; 17797 SourceRange ERange; 17798 Expr *SimpleRefExpr = RefExpr; 17799 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 17800 if (Res.second) { 17801 // It will be analyzed later. 17802 Vars.push_back(RefExpr); 17803 SrcExprs.push_back(nullptr); 17804 DstExprs.push_back(nullptr); 17805 AssignmentOps.push_back(nullptr); 17806 } 17807 ValueDecl *D = Res.first; 17808 if (!D) 17809 continue; 17810 17811 QualType Type = D->getType(); 17812 auto *VD = dyn_cast<VarDecl>(D); 17813 17814 // OpenMP [2.14.3.5, Restrictions, C/C++, p.2] 17815 // A variable that appears in a lastprivate clause must not have an 17816 // incomplete type or a reference type. 17817 if (RequireCompleteType(ELoc, Type, 17818 diag::err_omp_lastprivate_incomplete_type)) 17819 continue; 17820 Type = Type.getNonReferenceType(); 17821 17822 // OpenMP 5.0 [2.19.3, List Item Privatization, Restrictions] 17823 // A variable that is privatized must not have a const-qualified type 17824 // unless it is of class type with a mutable member. This restriction does 17825 // not apply to the firstprivate clause. 17826 // 17827 // OpenMP 3.1 [2.9.3.5, lastprivate clause, Restrictions] 17828 // A variable that appears in a lastprivate clause must not have a 17829 // const-qualified type unless it is of class type with a mutable member. 17830 if (rejectConstNotMutableType(*this, D, Type, OMPC_lastprivate, ELoc)) 17831 continue; 17832 17833 // OpenMP 5.0 [2.19.4.5 lastprivate Clause, Restrictions] 17834 // A list item that appears in a lastprivate clause with the conditional 17835 // modifier must be a scalar variable. 17836 if (LPKind == OMPC_LASTPRIVATE_conditional && !Type->isScalarType()) { 17837 Diag(ELoc, diag::err_omp_lastprivate_conditional_non_scalar); 17838 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) == 17839 VarDecl::DeclarationOnly; 17840 Diag(D->getLocation(), 17841 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 17842 << D; 17843 continue; 17844 } 17845 17846 OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective(); 17847 // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables Referenced 17848 // in a Construct] 17849 // Variables with the predetermined data-sharing attributes may not be 17850 // listed in data-sharing attributes clauses, except for the cases 17851 // listed below. 17852 // OpenMP 4.5 [2.10.8, Distribute Construct, p.3] 17853 // A list item may appear in a firstprivate or lastprivate clause but not 17854 // both. 17855 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false); 17856 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_lastprivate && 17857 (isOpenMPDistributeDirective(CurrDir) || 17858 DVar.CKind != OMPC_firstprivate) && 17859 (DVar.CKind != OMPC_private || DVar.RefExpr != nullptr)) { 17860 Diag(ELoc, diag::err_omp_wrong_dsa) 17861 << getOpenMPClauseName(DVar.CKind) 17862 << getOpenMPClauseName(OMPC_lastprivate); 17863 reportOriginalDsa(*this, DSAStack, D, DVar); 17864 continue; 17865 } 17866 17867 // OpenMP [2.14.3.5, Restrictions, p.2] 17868 // A list item that is private within a parallel region, or that appears in 17869 // the reduction clause of a parallel construct, must not appear in a 17870 // lastprivate clause on a worksharing construct if any of the corresponding 17871 // worksharing regions ever binds to any of the corresponding parallel 17872 // regions. 17873 DSAStackTy::DSAVarData TopDVar = DVar; 17874 if (isOpenMPWorksharingDirective(CurrDir) && 17875 !isOpenMPParallelDirective(CurrDir) && 17876 !isOpenMPTeamsDirective(CurrDir)) { 17877 DVar = DSAStack->getImplicitDSA(D, true); 17878 if (DVar.CKind != OMPC_shared) { 17879 Diag(ELoc, diag::err_omp_required_access) 17880 << getOpenMPClauseName(OMPC_lastprivate) 17881 << getOpenMPClauseName(OMPC_shared); 17882 reportOriginalDsa(*this, DSAStack, D, DVar); 17883 continue; 17884 } 17885 } 17886 17887 // OpenMP [2.14.3.5, Restrictions, C++, p.1,2] 17888 // A variable of class type (or array thereof) that appears in a 17889 // lastprivate clause requires an accessible, unambiguous default 17890 // constructor for the class type, unless the list item is also specified 17891 // in a firstprivate clause. 17892 // A variable of class type (or array thereof) that appears in a 17893 // lastprivate clause requires an accessible, unambiguous copy assignment 17894 // operator for the class type. 17895 Type = Context.getBaseElementType(Type).getNonReferenceType(); 17896 VarDecl *SrcVD = buildVarDecl(*this, ERange.getBegin(), 17897 Type.getUnqualifiedType(), ".lastprivate.src", 17898 D->hasAttrs() ? &D->getAttrs() : nullptr); 17899 DeclRefExpr *PseudoSrcExpr = 17900 buildDeclRefExpr(*this, SrcVD, Type.getUnqualifiedType(), ELoc); 17901 VarDecl *DstVD = 17902 buildVarDecl(*this, ERange.getBegin(), Type, ".lastprivate.dst", 17903 D->hasAttrs() ? &D->getAttrs() : nullptr); 17904 DeclRefExpr *PseudoDstExpr = buildDeclRefExpr(*this, DstVD, Type, ELoc); 17905 // For arrays generate assignment operation for single element and replace 17906 // it by the original array element in CodeGen. 17907 ExprResult AssignmentOp = BuildBinOp(/*S=*/nullptr, ELoc, BO_Assign, 17908 PseudoDstExpr, PseudoSrcExpr); 17909 if (AssignmentOp.isInvalid()) 17910 continue; 17911 AssignmentOp = 17912 ActOnFinishFullExpr(AssignmentOp.get(), ELoc, /*DiscardedValue*/ false); 17913 if (AssignmentOp.isInvalid()) 17914 continue; 17915 17916 DeclRefExpr *Ref = nullptr; 17917 if (!VD && !CurContext->isDependentContext()) { 17918 if (TopDVar.CKind == OMPC_firstprivate) { 17919 Ref = TopDVar.PrivateCopy; 17920 } else { 17921 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false); 17922 if (!isOpenMPCapturedDecl(D)) 17923 ExprCaptures.push_back(Ref->getDecl()); 17924 } 17925 if ((TopDVar.CKind == OMPC_firstprivate && !TopDVar.PrivateCopy) || 17926 (!isOpenMPCapturedDecl(D) && 17927 Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>())) { 17928 ExprResult RefRes = DefaultLvalueConversion(Ref); 17929 if (!RefRes.isUsable()) 17930 continue; 17931 ExprResult PostUpdateRes = 17932 BuildBinOp(DSAStack->getCurScope(), ELoc, BO_Assign, SimpleRefExpr, 17933 RefRes.get()); 17934 if (!PostUpdateRes.isUsable()) 17935 continue; 17936 ExprPostUpdates.push_back( 17937 IgnoredValueConversions(PostUpdateRes.get()).get()); 17938 } 17939 } 17940 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_lastprivate, Ref); 17941 Vars.push_back((VD || CurContext->isDependentContext()) 17942 ? RefExpr->IgnoreParens() 17943 : Ref); 17944 SrcExprs.push_back(PseudoSrcExpr); 17945 DstExprs.push_back(PseudoDstExpr); 17946 AssignmentOps.push_back(AssignmentOp.get()); 17947 } 17948 17949 if (Vars.empty()) 17950 return nullptr; 17951 17952 return OMPLastprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, 17953 Vars, SrcExprs, DstExprs, AssignmentOps, 17954 LPKind, LPKindLoc, ColonLoc, 17955 buildPreInits(Context, ExprCaptures), 17956 buildPostUpdate(*this, ExprPostUpdates)); 17957 } 17958 17959 OMPClause *Sema::ActOnOpenMPSharedClause(ArrayRef<Expr *> VarList, 17960 SourceLocation StartLoc, 17961 SourceLocation LParenLoc, 17962 SourceLocation EndLoc) { 17963 SmallVector<Expr *, 8> Vars; 17964 for (Expr *RefExpr : VarList) { 17965 assert(RefExpr && "NULL expr in OpenMP lastprivate clause."); 17966 SourceLocation ELoc; 17967 SourceRange ERange; 17968 Expr *SimpleRefExpr = RefExpr; 17969 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 17970 if (Res.second) { 17971 // It will be analyzed later. 17972 Vars.push_back(RefExpr); 17973 } 17974 ValueDecl *D = Res.first; 17975 if (!D) 17976 continue; 17977 17978 auto *VD = dyn_cast<VarDecl>(D); 17979 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 17980 // in a Construct] 17981 // Variables with the predetermined data-sharing attributes may not be 17982 // listed in data-sharing attributes clauses, except for the cases 17983 // listed below. For these exceptions only, listing a predetermined 17984 // variable in a data-sharing attribute clause is allowed and overrides 17985 // the variable's predetermined data-sharing attributes. 17986 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false); 17987 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_shared && 17988 DVar.RefExpr) { 17989 Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind) 17990 << getOpenMPClauseName(OMPC_shared); 17991 reportOriginalDsa(*this, DSAStack, D, DVar); 17992 continue; 17993 } 17994 17995 DeclRefExpr *Ref = nullptr; 17996 if (!VD && isOpenMPCapturedDecl(D) && !CurContext->isDependentContext()) 17997 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true); 17998 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_shared, Ref); 17999 Vars.push_back((VD || !Ref || CurContext->isDependentContext()) 18000 ? RefExpr->IgnoreParens() 18001 : Ref); 18002 } 18003 18004 if (Vars.empty()) 18005 return nullptr; 18006 18007 return OMPSharedClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars); 18008 } 18009 18010 namespace { 18011 class DSARefChecker : public StmtVisitor<DSARefChecker, bool> { 18012 DSAStackTy *Stack; 18013 18014 public: 18015 bool VisitDeclRefExpr(DeclRefExpr *E) { 18016 if (auto *VD = dyn_cast<VarDecl>(E->getDecl())) { 18017 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(VD, /*FromParent=*/false); 18018 if (DVar.CKind == OMPC_shared && !DVar.RefExpr) 18019 return false; 18020 if (DVar.CKind != OMPC_unknown) 18021 return true; 18022 DSAStackTy::DSAVarData DVarPrivate = Stack->hasDSA( 18023 VD, 18024 [](OpenMPClauseKind C, bool AppliedToPointee) { 18025 return isOpenMPPrivate(C) && !AppliedToPointee; 18026 }, 18027 [](OpenMPDirectiveKind) { return true; }, 18028 /*FromParent=*/true); 18029 return DVarPrivate.CKind != OMPC_unknown; 18030 } 18031 return false; 18032 } 18033 bool VisitStmt(Stmt *S) { 18034 for (Stmt *Child : S->children()) { 18035 if (Child && Visit(Child)) 18036 return true; 18037 } 18038 return false; 18039 } 18040 explicit DSARefChecker(DSAStackTy *S) : Stack(S) {} 18041 }; 18042 } // namespace 18043 18044 namespace { 18045 // Transform MemberExpression for specified FieldDecl of current class to 18046 // DeclRefExpr to specified OMPCapturedExprDecl. 18047 class TransformExprToCaptures : public TreeTransform<TransformExprToCaptures> { 18048 typedef TreeTransform<TransformExprToCaptures> BaseTransform; 18049 ValueDecl *Field = nullptr; 18050 DeclRefExpr *CapturedExpr = nullptr; 18051 18052 public: 18053 TransformExprToCaptures(Sema &SemaRef, ValueDecl *FieldDecl) 18054 : BaseTransform(SemaRef), Field(FieldDecl), CapturedExpr(nullptr) {} 18055 18056 ExprResult TransformMemberExpr(MemberExpr *E) { 18057 if (isa<CXXThisExpr>(E->getBase()->IgnoreParenImpCasts()) && 18058 E->getMemberDecl() == Field) { 18059 CapturedExpr = buildCapture(SemaRef, Field, E, /*WithInit=*/false); 18060 return CapturedExpr; 18061 } 18062 return BaseTransform::TransformMemberExpr(E); 18063 } 18064 DeclRefExpr *getCapturedExpr() { return CapturedExpr; } 18065 }; 18066 } // namespace 18067 18068 template <typename T, typename U> 18069 static T filterLookupForUDReductionAndMapper( 18070 SmallVectorImpl<U> &Lookups, const llvm::function_ref<T(ValueDecl *)> Gen) { 18071 for (U &Set : Lookups) { 18072 for (auto *D : Set) { 18073 if (T Res = Gen(cast<ValueDecl>(D))) 18074 return Res; 18075 } 18076 } 18077 return T(); 18078 } 18079 18080 static NamedDecl *findAcceptableDecl(Sema &SemaRef, NamedDecl *D) { 18081 assert(!LookupResult::isVisible(SemaRef, D) && "not in slow case"); 18082 18083 for (auto RD : D->redecls()) { 18084 // Don't bother with extra checks if we already know this one isn't visible. 18085 if (RD == D) 18086 continue; 18087 18088 auto ND = cast<NamedDecl>(RD); 18089 if (LookupResult::isVisible(SemaRef, ND)) 18090 return ND; 18091 } 18092 18093 return nullptr; 18094 } 18095 18096 static void 18097 argumentDependentLookup(Sema &SemaRef, const DeclarationNameInfo &Id, 18098 SourceLocation Loc, QualType Ty, 18099 SmallVectorImpl<UnresolvedSet<8>> &Lookups) { 18100 // Find all of the associated namespaces and classes based on the 18101 // arguments we have. 18102 Sema::AssociatedNamespaceSet AssociatedNamespaces; 18103 Sema::AssociatedClassSet AssociatedClasses; 18104 OpaqueValueExpr OVE(Loc, Ty, VK_LValue); 18105 SemaRef.FindAssociatedClassesAndNamespaces(Loc, &OVE, AssociatedNamespaces, 18106 AssociatedClasses); 18107 18108 // C++ [basic.lookup.argdep]p3: 18109 // Let X be the lookup set produced by unqualified lookup (3.4.1) 18110 // and let Y be the lookup set produced by argument dependent 18111 // lookup (defined as follows). If X contains [...] then Y is 18112 // empty. Otherwise Y is the set of declarations found in the 18113 // namespaces associated with the argument types as described 18114 // below. The set of declarations found by the lookup of the name 18115 // is the union of X and Y. 18116 // 18117 // Here, we compute Y and add its members to the overloaded 18118 // candidate set. 18119 for (auto *NS : AssociatedNamespaces) { 18120 // When considering an associated namespace, the lookup is the 18121 // same as the lookup performed when the associated namespace is 18122 // used as a qualifier (3.4.3.2) except that: 18123 // 18124 // -- Any using-directives in the associated namespace are 18125 // ignored. 18126 // 18127 // -- Any namespace-scope friend functions declared in 18128 // associated classes are visible within their respective 18129 // namespaces even if they are not visible during an ordinary 18130 // lookup (11.4). 18131 DeclContext::lookup_result R = NS->lookup(Id.getName()); 18132 for (auto *D : R) { 18133 auto *Underlying = D; 18134 if (auto *USD = dyn_cast<UsingShadowDecl>(D)) 18135 Underlying = USD->getTargetDecl(); 18136 18137 if (!isa<OMPDeclareReductionDecl>(Underlying) && 18138 !isa<OMPDeclareMapperDecl>(Underlying)) 18139 continue; 18140 18141 if (!SemaRef.isVisible(D)) { 18142 D = findAcceptableDecl(SemaRef, D); 18143 if (!D) 18144 continue; 18145 if (auto *USD = dyn_cast<UsingShadowDecl>(D)) 18146 Underlying = USD->getTargetDecl(); 18147 } 18148 Lookups.emplace_back(); 18149 Lookups.back().addDecl(Underlying); 18150 } 18151 } 18152 } 18153 18154 static ExprResult 18155 buildDeclareReductionRef(Sema &SemaRef, SourceLocation Loc, SourceRange Range, 18156 Scope *S, CXXScopeSpec &ReductionIdScopeSpec, 18157 const DeclarationNameInfo &ReductionId, QualType Ty, 18158 CXXCastPath &BasePath, Expr *UnresolvedReduction) { 18159 if (ReductionIdScopeSpec.isInvalid()) 18160 return ExprError(); 18161 SmallVector<UnresolvedSet<8>, 4> Lookups; 18162 if (S) { 18163 LookupResult Lookup(SemaRef, ReductionId, Sema::LookupOMPReductionName); 18164 Lookup.suppressDiagnostics(); 18165 while (S && SemaRef.LookupParsedName(Lookup, S, &ReductionIdScopeSpec)) { 18166 NamedDecl *D = Lookup.getRepresentativeDecl(); 18167 do { 18168 S = S->getParent(); 18169 } while (S && !S->isDeclScope(D)); 18170 if (S) 18171 S = S->getParent(); 18172 Lookups.emplace_back(); 18173 Lookups.back().append(Lookup.begin(), Lookup.end()); 18174 Lookup.clear(); 18175 } 18176 } else if (auto *ULE = 18177 cast_or_null<UnresolvedLookupExpr>(UnresolvedReduction)) { 18178 Lookups.push_back(UnresolvedSet<8>()); 18179 Decl *PrevD = nullptr; 18180 for (NamedDecl *D : ULE->decls()) { 18181 if (D == PrevD) 18182 Lookups.push_back(UnresolvedSet<8>()); 18183 else if (auto *DRD = dyn_cast<OMPDeclareReductionDecl>(D)) 18184 Lookups.back().addDecl(DRD); 18185 PrevD = D; 18186 } 18187 } 18188 if (SemaRef.CurContext->isDependentContext() || Ty->isDependentType() || 18189 Ty->isInstantiationDependentType() || 18190 Ty->containsUnexpandedParameterPack() || 18191 filterLookupForUDReductionAndMapper<bool>(Lookups, [](ValueDecl *D) { 18192 return !D->isInvalidDecl() && 18193 (D->getType()->isDependentType() || 18194 D->getType()->isInstantiationDependentType() || 18195 D->getType()->containsUnexpandedParameterPack()); 18196 })) { 18197 UnresolvedSet<8> ResSet; 18198 for (const UnresolvedSet<8> &Set : Lookups) { 18199 if (Set.empty()) 18200 continue; 18201 ResSet.append(Set.begin(), Set.end()); 18202 // The last item marks the end of all declarations at the specified scope. 18203 ResSet.addDecl(Set[Set.size() - 1]); 18204 } 18205 return UnresolvedLookupExpr::Create( 18206 SemaRef.Context, /*NamingClass=*/nullptr, 18207 ReductionIdScopeSpec.getWithLocInContext(SemaRef.Context), ReductionId, 18208 /*ADL=*/true, /*Overloaded=*/true, ResSet.begin(), ResSet.end()); 18209 } 18210 // Lookup inside the classes. 18211 // C++ [over.match.oper]p3: 18212 // For a unary operator @ with an operand of a type whose 18213 // cv-unqualified version is T1, and for a binary operator @ with 18214 // a left operand of a type whose cv-unqualified version is T1 and 18215 // a right operand of a type whose cv-unqualified version is T2, 18216 // three sets of candidate functions, designated member 18217 // candidates, non-member candidates and built-in candidates, are 18218 // constructed as follows: 18219 // -- If T1 is a complete class type or a class currently being 18220 // defined, the set of member candidates is the result of the 18221 // qualified lookup of T1::operator@ (13.3.1.1.1); otherwise, 18222 // the set of member candidates is empty. 18223 LookupResult Lookup(SemaRef, ReductionId, Sema::LookupOMPReductionName); 18224 Lookup.suppressDiagnostics(); 18225 if (const auto *TyRec = Ty->getAs<RecordType>()) { 18226 // Complete the type if it can be completed. 18227 // If the type is neither complete nor being defined, bail out now. 18228 if (SemaRef.isCompleteType(Loc, Ty) || TyRec->isBeingDefined() || 18229 TyRec->getDecl()->getDefinition()) { 18230 Lookup.clear(); 18231 SemaRef.LookupQualifiedName(Lookup, TyRec->getDecl()); 18232 if (Lookup.empty()) { 18233 Lookups.emplace_back(); 18234 Lookups.back().append(Lookup.begin(), Lookup.end()); 18235 } 18236 } 18237 } 18238 // Perform ADL. 18239 if (SemaRef.getLangOpts().CPlusPlus) 18240 argumentDependentLookup(SemaRef, ReductionId, Loc, Ty, Lookups); 18241 if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>( 18242 Lookups, [&SemaRef, Ty](ValueDecl *D) -> ValueDecl * { 18243 if (!D->isInvalidDecl() && 18244 SemaRef.Context.hasSameType(D->getType(), Ty)) 18245 return D; 18246 return nullptr; 18247 })) 18248 return SemaRef.BuildDeclRefExpr(VD, VD->getType().getNonReferenceType(), 18249 VK_LValue, Loc); 18250 if (SemaRef.getLangOpts().CPlusPlus) { 18251 if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>( 18252 Lookups, [&SemaRef, Ty, Loc](ValueDecl *D) -> ValueDecl * { 18253 if (!D->isInvalidDecl() && 18254 SemaRef.IsDerivedFrom(Loc, Ty, D->getType()) && 18255 !Ty.isMoreQualifiedThan(D->getType())) 18256 return D; 18257 return nullptr; 18258 })) { 18259 CXXBasePaths Paths(/*FindAmbiguities=*/true, /*RecordPaths=*/true, 18260 /*DetectVirtual=*/false); 18261 if (SemaRef.IsDerivedFrom(Loc, Ty, VD->getType(), Paths)) { 18262 if (!Paths.isAmbiguous(SemaRef.Context.getCanonicalType( 18263 VD->getType().getUnqualifiedType()))) { 18264 if (SemaRef.CheckBaseClassAccess( 18265 Loc, VD->getType(), Ty, Paths.front(), 18266 /*DiagID=*/0) != Sema::AR_inaccessible) { 18267 SemaRef.BuildBasePathArray(Paths, BasePath); 18268 return SemaRef.BuildDeclRefExpr( 18269 VD, VD->getType().getNonReferenceType(), VK_LValue, Loc); 18270 } 18271 } 18272 } 18273 } 18274 } 18275 if (ReductionIdScopeSpec.isSet()) { 18276 SemaRef.Diag(Loc, diag::err_omp_not_resolved_reduction_identifier) 18277 << Ty << Range; 18278 return ExprError(); 18279 } 18280 return ExprEmpty(); 18281 } 18282 18283 namespace { 18284 /// Data for the reduction-based clauses. 18285 struct ReductionData { 18286 /// List of original reduction items. 18287 SmallVector<Expr *, 8> Vars; 18288 /// List of private copies of the reduction items. 18289 SmallVector<Expr *, 8> Privates; 18290 /// LHS expressions for the reduction_op expressions. 18291 SmallVector<Expr *, 8> LHSs; 18292 /// RHS expressions for the reduction_op expressions. 18293 SmallVector<Expr *, 8> RHSs; 18294 /// Reduction operation expression. 18295 SmallVector<Expr *, 8> ReductionOps; 18296 /// inscan copy operation expressions. 18297 SmallVector<Expr *, 8> InscanCopyOps; 18298 /// inscan copy temp array expressions for prefix sums. 18299 SmallVector<Expr *, 8> InscanCopyArrayTemps; 18300 /// inscan copy temp array element expressions for prefix sums. 18301 SmallVector<Expr *, 8> InscanCopyArrayElems; 18302 /// Taskgroup descriptors for the corresponding reduction items in 18303 /// in_reduction clauses. 18304 SmallVector<Expr *, 8> TaskgroupDescriptors; 18305 /// List of captures for clause. 18306 SmallVector<Decl *, 4> ExprCaptures; 18307 /// List of postupdate expressions. 18308 SmallVector<Expr *, 4> ExprPostUpdates; 18309 /// Reduction modifier. 18310 unsigned RedModifier = 0; 18311 ReductionData() = delete; 18312 /// Reserves required memory for the reduction data. 18313 ReductionData(unsigned Size, unsigned Modifier = 0) : RedModifier(Modifier) { 18314 Vars.reserve(Size); 18315 Privates.reserve(Size); 18316 LHSs.reserve(Size); 18317 RHSs.reserve(Size); 18318 ReductionOps.reserve(Size); 18319 if (RedModifier == OMPC_REDUCTION_inscan) { 18320 InscanCopyOps.reserve(Size); 18321 InscanCopyArrayTemps.reserve(Size); 18322 InscanCopyArrayElems.reserve(Size); 18323 } 18324 TaskgroupDescriptors.reserve(Size); 18325 ExprCaptures.reserve(Size); 18326 ExprPostUpdates.reserve(Size); 18327 } 18328 /// Stores reduction item and reduction operation only (required for dependent 18329 /// reduction item). 18330 void push(Expr *Item, Expr *ReductionOp) { 18331 Vars.emplace_back(Item); 18332 Privates.emplace_back(nullptr); 18333 LHSs.emplace_back(nullptr); 18334 RHSs.emplace_back(nullptr); 18335 ReductionOps.emplace_back(ReductionOp); 18336 TaskgroupDescriptors.emplace_back(nullptr); 18337 if (RedModifier == OMPC_REDUCTION_inscan) { 18338 InscanCopyOps.push_back(nullptr); 18339 InscanCopyArrayTemps.push_back(nullptr); 18340 InscanCopyArrayElems.push_back(nullptr); 18341 } 18342 } 18343 /// Stores reduction data. 18344 void push(Expr *Item, Expr *Private, Expr *LHS, Expr *RHS, Expr *ReductionOp, 18345 Expr *TaskgroupDescriptor, Expr *CopyOp, Expr *CopyArrayTemp, 18346 Expr *CopyArrayElem) { 18347 Vars.emplace_back(Item); 18348 Privates.emplace_back(Private); 18349 LHSs.emplace_back(LHS); 18350 RHSs.emplace_back(RHS); 18351 ReductionOps.emplace_back(ReductionOp); 18352 TaskgroupDescriptors.emplace_back(TaskgroupDescriptor); 18353 if (RedModifier == OMPC_REDUCTION_inscan) { 18354 InscanCopyOps.push_back(CopyOp); 18355 InscanCopyArrayTemps.push_back(CopyArrayTemp); 18356 InscanCopyArrayElems.push_back(CopyArrayElem); 18357 } else { 18358 assert(CopyOp == nullptr && CopyArrayTemp == nullptr && 18359 CopyArrayElem == nullptr && 18360 "Copy operation must be used for inscan reductions only."); 18361 } 18362 } 18363 }; 18364 } // namespace 18365 18366 static bool checkOMPArraySectionConstantForReduction( 18367 ASTContext &Context, const OMPArraySectionExpr *OASE, bool &SingleElement, 18368 SmallVectorImpl<llvm::APSInt> &ArraySizes) { 18369 const Expr *Length = OASE->getLength(); 18370 if (Length == nullptr) { 18371 // For array sections of the form [1:] or [:], we would need to analyze 18372 // the lower bound... 18373 if (OASE->getColonLocFirst().isValid()) 18374 return false; 18375 18376 // This is an array subscript which has implicit length 1! 18377 SingleElement = true; 18378 ArraySizes.push_back(llvm::APSInt::get(1)); 18379 } else { 18380 Expr::EvalResult Result; 18381 if (!Length->EvaluateAsInt(Result, Context)) 18382 return false; 18383 18384 llvm::APSInt ConstantLengthValue = Result.Val.getInt(); 18385 SingleElement = (ConstantLengthValue.getSExtValue() == 1); 18386 ArraySizes.push_back(ConstantLengthValue); 18387 } 18388 18389 // Get the base of this array section and walk up from there. 18390 const Expr *Base = OASE->getBase()->IgnoreParenImpCasts(); 18391 18392 // We require length = 1 for all array sections except the right-most to 18393 // guarantee that the memory region is contiguous and has no holes in it. 18394 while (const auto *TempOASE = dyn_cast<OMPArraySectionExpr>(Base)) { 18395 Length = TempOASE->getLength(); 18396 if (Length == nullptr) { 18397 // For array sections of the form [1:] or [:], we would need to analyze 18398 // the lower bound... 18399 if (OASE->getColonLocFirst().isValid()) 18400 return false; 18401 18402 // This is an array subscript which has implicit length 1! 18403 ArraySizes.push_back(llvm::APSInt::get(1)); 18404 } else { 18405 Expr::EvalResult Result; 18406 if (!Length->EvaluateAsInt(Result, Context)) 18407 return false; 18408 18409 llvm::APSInt ConstantLengthValue = Result.Val.getInt(); 18410 if (ConstantLengthValue.getSExtValue() != 1) 18411 return false; 18412 18413 ArraySizes.push_back(ConstantLengthValue); 18414 } 18415 Base = TempOASE->getBase()->IgnoreParenImpCasts(); 18416 } 18417 18418 // If we have a single element, we don't need to add the implicit lengths. 18419 if (!SingleElement) { 18420 while (const auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base)) { 18421 // Has implicit length 1! 18422 ArraySizes.push_back(llvm::APSInt::get(1)); 18423 Base = TempASE->getBase()->IgnoreParenImpCasts(); 18424 } 18425 } 18426 18427 // This array section can be privatized as a single value or as a constant 18428 // sized array. 18429 return true; 18430 } 18431 18432 static BinaryOperatorKind 18433 getRelatedCompoundReductionOp(BinaryOperatorKind BOK) { 18434 if (BOK == BO_Add) 18435 return BO_AddAssign; 18436 if (BOK == BO_Mul) 18437 return BO_MulAssign; 18438 if (BOK == BO_And) 18439 return BO_AndAssign; 18440 if (BOK == BO_Or) 18441 return BO_OrAssign; 18442 if (BOK == BO_Xor) 18443 return BO_XorAssign; 18444 return BOK; 18445 } 18446 18447 static bool actOnOMPReductionKindClause( 18448 Sema &S, DSAStackTy *Stack, OpenMPClauseKind ClauseKind, 18449 ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, 18450 SourceLocation ColonLoc, SourceLocation EndLoc, 18451 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, 18452 ArrayRef<Expr *> UnresolvedReductions, ReductionData &RD) { 18453 DeclarationName DN = ReductionId.getName(); 18454 OverloadedOperatorKind OOK = DN.getCXXOverloadedOperator(); 18455 BinaryOperatorKind BOK = BO_Comma; 18456 18457 ASTContext &Context = S.Context; 18458 // OpenMP [2.14.3.6, reduction clause] 18459 // C 18460 // reduction-identifier is either an identifier or one of the following 18461 // operators: +, -, *, &, |, ^, && and || 18462 // C++ 18463 // reduction-identifier is either an id-expression or one of the following 18464 // operators: +, -, *, &, |, ^, && and || 18465 switch (OOK) { 18466 case OO_Plus: 18467 case OO_Minus: 18468 BOK = BO_Add; 18469 break; 18470 case OO_Star: 18471 BOK = BO_Mul; 18472 break; 18473 case OO_Amp: 18474 BOK = BO_And; 18475 break; 18476 case OO_Pipe: 18477 BOK = BO_Or; 18478 break; 18479 case OO_Caret: 18480 BOK = BO_Xor; 18481 break; 18482 case OO_AmpAmp: 18483 BOK = BO_LAnd; 18484 break; 18485 case OO_PipePipe: 18486 BOK = BO_LOr; 18487 break; 18488 case OO_New: 18489 case OO_Delete: 18490 case OO_Array_New: 18491 case OO_Array_Delete: 18492 case OO_Slash: 18493 case OO_Percent: 18494 case OO_Tilde: 18495 case OO_Exclaim: 18496 case OO_Equal: 18497 case OO_Less: 18498 case OO_Greater: 18499 case OO_LessEqual: 18500 case OO_GreaterEqual: 18501 case OO_PlusEqual: 18502 case OO_MinusEqual: 18503 case OO_StarEqual: 18504 case OO_SlashEqual: 18505 case OO_PercentEqual: 18506 case OO_CaretEqual: 18507 case OO_AmpEqual: 18508 case OO_PipeEqual: 18509 case OO_LessLess: 18510 case OO_GreaterGreater: 18511 case OO_LessLessEqual: 18512 case OO_GreaterGreaterEqual: 18513 case OO_EqualEqual: 18514 case OO_ExclaimEqual: 18515 case OO_Spaceship: 18516 case OO_PlusPlus: 18517 case OO_MinusMinus: 18518 case OO_Comma: 18519 case OO_ArrowStar: 18520 case OO_Arrow: 18521 case OO_Call: 18522 case OO_Subscript: 18523 case OO_Conditional: 18524 case OO_Coawait: 18525 case NUM_OVERLOADED_OPERATORS: 18526 llvm_unreachable("Unexpected reduction identifier"); 18527 case OO_None: 18528 if (IdentifierInfo *II = DN.getAsIdentifierInfo()) { 18529 if (II->isStr("max")) 18530 BOK = BO_GT; 18531 else if (II->isStr("min")) 18532 BOK = BO_LT; 18533 } 18534 break; 18535 } 18536 SourceRange ReductionIdRange; 18537 if (ReductionIdScopeSpec.isValid()) 18538 ReductionIdRange.setBegin(ReductionIdScopeSpec.getBeginLoc()); 18539 else 18540 ReductionIdRange.setBegin(ReductionId.getBeginLoc()); 18541 ReductionIdRange.setEnd(ReductionId.getEndLoc()); 18542 18543 auto IR = UnresolvedReductions.begin(), ER = UnresolvedReductions.end(); 18544 bool FirstIter = true; 18545 for (Expr *RefExpr : VarList) { 18546 assert(RefExpr && "nullptr expr in OpenMP reduction clause."); 18547 // OpenMP [2.1, C/C++] 18548 // A list item is a variable or array section, subject to the restrictions 18549 // specified in Section 2.4 on page 42 and in each of the sections 18550 // describing clauses and directives for which a list appears. 18551 // OpenMP [2.14.3.3, Restrictions, p.1] 18552 // A variable that is part of another variable (as an array or 18553 // structure element) cannot appear in a private clause. 18554 if (!FirstIter && IR != ER) 18555 ++IR; 18556 FirstIter = false; 18557 SourceLocation ELoc; 18558 SourceRange ERange; 18559 Expr *SimpleRefExpr = RefExpr; 18560 auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange, 18561 /*AllowArraySection=*/true); 18562 if (Res.second) { 18563 // Try to find 'declare reduction' corresponding construct before using 18564 // builtin/overloaded operators. 18565 QualType Type = Context.DependentTy; 18566 CXXCastPath BasePath; 18567 ExprResult DeclareReductionRef = buildDeclareReductionRef( 18568 S, ELoc, ERange, Stack->getCurScope(), ReductionIdScopeSpec, 18569 ReductionId, Type, BasePath, IR == ER ? nullptr : *IR); 18570 Expr *ReductionOp = nullptr; 18571 if (S.CurContext->isDependentContext() && 18572 (DeclareReductionRef.isUnset() || 18573 isa<UnresolvedLookupExpr>(DeclareReductionRef.get()))) 18574 ReductionOp = DeclareReductionRef.get(); 18575 // It will be analyzed later. 18576 RD.push(RefExpr, ReductionOp); 18577 } 18578 ValueDecl *D = Res.first; 18579 if (!D) 18580 continue; 18581 18582 Expr *TaskgroupDescriptor = nullptr; 18583 QualType Type; 18584 auto *ASE = dyn_cast<ArraySubscriptExpr>(RefExpr->IgnoreParens()); 18585 auto *OASE = dyn_cast<OMPArraySectionExpr>(RefExpr->IgnoreParens()); 18586 if (ASE) { 18587 Type = ASE->getType().getNonReferenceType(); 18588 } else if (OASE) { 18589 QualType BaseType = 18590 OMPArraySectionExpr::getBaseOriginalType(OASE->getBase()); 18591 if (const auto *ATy = BaseType->getAsArrayTypeUnsafe()) 18592 Type = ATy->getElementType(); 18593 else 18594 Type = BaseType->getPointeeType(); 18595 Type = Type.getNonReferenceType(); 18596 } else { 18597 Type = Context.getBaseElementType(D->getType().getNonReferenceType()); 18598 } 18599 auto *VD = dyn_cast<VarDecl>(D); 18600 18601 // OpenMP [2.9.3.3, Restrictions, C/C++, p.3] 18602 // A variable that appears in a private clause must not have an incomplete 18603 // type or a reference type. 18604 if (S.RequireCompleteType(ELoc, D->getType(), 18605 diag::err_omp_reduction_incomplete_type)) 18606 continue; 18607 // OpenMP [2.14.3.6, reduction clause, Restrictions] 18608 // A list item that appears in a reduction clause must not be 18609 // const-qualified. 18610 if (rejectConstNotMutableType(S, D, Type, ClauseKind, ELoc, 18611 /*AcceptIfMutable*/ false, ASE || OASE)) 18612 continue; 18613 18614 OpenMPDirectiveKind CurrDir = Stack->getCurrentDirective(); 18615 // OpenMP [2.9.3.6, Restrictions, C/C++, p.4] 18616 // If a list-item is a reference type then it must bind to the same object 18617 // for all threads of the team. 18618 if (!ASE && !OASE) { 18619 if (VD) { 18620 VarDecl *VDDef = VD->getDefinition(); 18621 if (VD->getType()->isReferenceType() && VDDef && VDDef->hasInit()) { 18622 DSARefChecker Check(Stack); 18623 if (Check.Visit(VDDef->getInit())) { 18624 S.Diag(ELoc, diag::err_omp_reduction_ref_type_arg) 18625 << getOpenMPClauseName(ClauseKind) << ERange; 18626 S.Diag(VDDef->getLocation(), diag::note_defined_here) << VDDef; 18627 continue; 18628 } 18629 } 18630 } 18631 18632 // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables Referenced 18633 // in a Construct] 18634 // Variables with the predetermined data-sharing attributes may not be 18635 // listed in data-sharing attributes clauses, except for the cases 18636 // listed below. For these exceptions only, listing a predetermined 18637 // variable in a data-sharing attribute clause is allowed and overrides 18638 // the variable's predetermined data-sharing attributes. 18639 // OpenMP [2.14.3.6, Restrictions, p.3] 18640 // Any number of reduction clauses can be specified on the directive, 18641 // but a list item can appear only once in the reduction clauses for that 18642 // directive. 18643 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(D, /*FromParent=*/false); 18644 if (DVar.CKind == OMPC_reduction) { 18645 S.Diag(ELoc, diag::err_omp_once_referenced) 18646 << getOpenMPClauseName(ClauseKind); 18647 if (DVar.RefExpr) 18648 S.Diag(DVar.RefExpr->getExprLoc(), diag::note_omp_referenced); 18649 continue; 18650 } 18651 if (DVar.CKind != OMPC_unknown) { 18652 S.Diag(ELoc, diag::err_omp_wrong_dsa) 18653 << getOpenMPClauseName(DVar.CKind) 18654 << getOpenMPClauseName(OMPC_reduction); 18655 reportOriginalDsa(S, Stack, D, DVar); 18656 continue; 18657 } 18658 18659 // OpenMP [2.14.3.6, Restrictions, p.1] 18660 // A list item that appears in a reduction clause of a worksharing 18661 // construct must be shared in the parallel regions to which any of the 18662 // worksharing regions arising from the worksharing construct bind. 18663 if (isOpenMPWorksharingDirective(CurrDir) && 18664 !isOpenMPParallelDirective(CurrDir) && 18665 !isOpenMPTeamsDirective(CurrDir)) { 18666 DVar = Stack->getImplicitDSA(D, true); 18667 if (DVar.CKind != OMPC_shared) { 18668 S.Diag(ELoc, diag::err_omp_required_access) 18669 << getOpenMPClauseName(OMPC_reduction) 18670 << getOpenMPClauseName(OMPC_shared); 18671 reportOriginalDsa(S, Stack, D, DVar); 18672 continue; 18673 } 18674 } 18675 } else { 18676 // Threadprivates cannot be shared between threads, so dignose if the base 18677 // is a threadprivate variable. 18678 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(D, /*FromParent=*/false); 18679 if (DVar.CKind == OMPC_threadprivate) { 18680 S.Diag(ELoc, diag::err_omp_wrong_dsa) 18681 << getOpenMPClauseName(DVar.CKind) 18682 << getOpenMPClauseName(OMPC_reduction); 18683 reportOriginalDsa(S, Stack, D, DVar); 18684 continue; 18685 } 18686 } 18687 18688 // Try to find 'declare reduction' corresponding construct before using 18689 // builtin/overloaded operators. 18690 CXXCastPath BasePath; 18691 ExprResult DeclareReductionRef = buildDeclareReductionRef( 18692 S, ELoc, ERange, Stack->getCurScope(), ReductionIdScopeSpec, 18693 ReductionId, Type, BasePath, IR == ER ? nullptr : *IR); 18694 if (DeclareReductionRef.isInvalid()) 18695 continue; 18696 if (S.CurContext->isDependentContext() && 18697 (DeclareReductionRef.isUnset() || 18698 isa<UnresolvedLookupExpr>(DeclareReductionRef.get()))) { 18699 RD.push(RefExpr, DeclareReductionRef.get()); 18700 continue; 18701 } 18702 if (BOK == BO_Comma && DeclareReductionRef.isUnset()) { 18703 // Not allowed reduction identifier is found. 18704 S.Diag(ReductionId.getBeginLoc(), 18705 diag::err_omp_unknown_reduction_identifier) 18706 << Type << ReductionIdRange; 18707 continue; 18708 } 18709 18710 // OpenMP [2.14.3.6, reduction clause, Restrictions] 18711 // The type of a list item that appears in a reduction clause must be valid 18712 // for the reduction-identifier. For a max or min reduction in C, the type 18713 // of the list item must be an allowed arithmetic data type: char, int, 18714 // float, double, or _Bool, possibly modified with long, short, signed, or 18715 // unsigned. For a max or min reduction in C++, the type of the list item 18716 // must be an allowed arithmetic data type: char, wchar_t, int, float, 18717 // double, or bool, possibly modified with long, short, signed, or unsigned. 18718 if (DeclareReductionRef.isUnset()) { 18719 if ((BOK == BO_GT || BOK == BO_LT) && 18720 !(Type->isScalarType() || 18721 (S.getLangOpts().CPlusPlus && Type->isArithmeticType()))) { 18722 S.Diag(ELoc, diag::err_omp_clause_not_arithmetic_type_arg) 18723 << getOpenMPClauseName(ClauseKind) << S.getLangOpts().CPlusPlus; 18724 if (!ASE && !OASE) { 18725 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) == 18726 VarDecl::DeclarationOnly; 18727 S.Diag(D->getLocation(), 18728 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 18729 << D; 18730 } 18731 continue; 18732 } 18733 if ((BOK == BO_OrAssign || BOK == BO_AndAssign || BOK == BO_XorAssign) && 18734 !S.getLangOpts().CPlusPlus && Type->isFloatingType()) { 18735 S.Diag(ELoc, diag::err_omp_clause_floating_type_arg) 18736 << getOpenMPClauseName(ClauseKind); 18737 if (!ASE && !OASE) { 18738 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) == 18739 VarDecl::DeclarationOnly; 18740 S.Diag(D->getLocation(), 18741 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 18742 << D; 18743 } 18744 continue; 18745 } 18746 } 18747 18748 Type = Type.getNonLValueExprType(Context).getUnqualifiedType(); 18749 VarDecl *LHSVD = buildVarDecl(S, ELoc, Type, ".reduction.lhs", 18750 D->hasAttrs() ? &D->getAttrs() : nullptr); 18751 VarDecl *RHSVD = buildVarDecl(S, ELoc, Type, D->getName(), 18752 D->hasAttrs() ? &D->getAttrs() : nullptr); 18753 QualType PrivateTy = Type; 18754 18755 // Try if we can determine constant lengths for all array sections and avoid 18756 // the VLA. 18757 bool ConstantLengthOASE = false; 18758 if (OASE) { 18759 bool SingleElement; 18760 llvm::SmallVector<llvm::APSInt, 4> ArraySizes; 18761 ConstantLengthOASE = checkOMPArraySectionConstantForReduction( 18762 Context, OASE, SingleElement, ArraySizes); 18763 18764 // If we don't have a single element, we must emit a constant array type. 18765 if (ConstantLengthOASE && !SingleElement) { 18766 for (llvm::APSInt &Size : ArraySizes) 18767 PrivateTy = Context.getConstantArrayType(PrivateTy, Size, nullptr, 18768 ArrayType::Normal, 18769 /*IndexTypeQuals=*/0); 18770 } 18771 } 18772 18773 if ((OASE && !ConstantLengthOASE) || 18774 (!OASE && !ASE && 18775 D->getType().getNonReferenceType()->isVariablyModifiedType())) { 18776 if (!Context.getTargetInfo().isVLASupported()) { 18777 if (isOpenMPTargetExecutionDirective(Stack->getCurrentDirective())) { 18778 S.Diag(ELoc, diag::err_omp_reduction_vla_unsupported) << !!OASE; 18779 S.Diag(ELoc, diag::note_vla_unsupported); 18780 continue; 18781 } else { 18782 S.targetDiag(ELoc, diag::err_omp_reduction_vla_unsupported) << !!OASE; 18783 S.targetDiag(ELoc, diag::note_vla_unsupported); 18784 } 18785 } 18786 // For arrays/array sections only: 18787 // Create pseudo array type for private copy. The size for this array will 18788 // be generated during codegen. 18789 // For array subscripts or single variables Private Ty is the same as Type 18790 // (type of the variable or single array element). 18791 PrivateTy = Context.getVariableArrayType( 18792 Type, 18793 new (Context) 18794 OpaqueValueExpr(ELoc, Context.getSizeType(), VK_PRValue), 18795 ArrayType::Normal, /*IndexTypeQuals=*/0, SourceRange()); 18796 } else if (!ASE && !OASE && 18797 Context.getAsArrayType(D->getType().getNonReferenceType())) { 18798 PrivateTy = D->getType().getNonReferenceType(); 18799 } 18800 // Private copy. 18801 VarDecl *PrivateVD = 18802 buildVarDecl(S, ELoc, PrivateTy, D->getName(), 18803 D->hasAttrs() ? &D->getAttrs() : nullptr, 18804 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr); 18805 // Add initializer for private variable. 18806 Expr *Init = nullptr; 18807 DeclRefExpr *LHSDRE = buildDeclRefExpr(S, LHSVD, Type, ELoc); 18808 DeclRefExpr *RHSDRE = buildDeclRefExpr(S, RHSVD, Type, ELoc); 18809 if (DeclareReductionRef.isUsable()) { 18810 auto *DRDRef = DeclareReductionRef.getAs<DeclRefExpr>(); 18811 auto *DRD = cast<OMPDeclareReductionDecl>(DRDRef->getDecl()); 18812 if (DRD->getInitializer()) { 18813 Init = DRDRef; 18814 RHSVD->setInit(DRDRef); 18815 RHSVD->setInitStyle(VarDecl::CallInit); 18816 } 18817 } else { 18818 switch (BOK) { 18819 case BO_Add: 18820 case BO_Xor: 18821 case BO_Or: 18822 case BO_LOr: 18823 // '+', '-', '^', '|', '||' reduction ops - initializer is '0'. 18824 if (Type->isScalarType() || Type->isAnyComplexType()) 18825 Init = S.ActOnIntegerConstant(ELoc, /*Val=*/0).get(); 18826 break; 18827 case BO_Mul: 18828 case BO_LAnd: 18829 if (Type->isScalarType() || Type->isAnyComplexType()) { 18830 // '*' and '&&' reduction ops - initializer is '1'. 18831 Init = S.ActOnIntegerConstant(ELoc, /*Val=*/1).get(); 18832 } 18833 break; 18834 case BO_And: { 18835 // '&' reduction op - initializer is '~0'. 18836 QualType OrigType = Type; 18837 if (auto *ComplexTy = OrigType->getAs<ComplexType>()) 18838 Type = ComplexTy->getElementType(); 18839 if (Type->isRealFloatingType()) { 18840 llvm::APFloat InitValue = llvm::APFloat::getAllOnesValue( 18841 Context.getFloatTypeSemantics(Type)); 18842 Init = FloatingLiteral::Create(Context, InitValue, /*isexact=*/true, 18843 Type, ELoc); 18844 } else if (Type->isScalarType()) { 18845 uint64_t Size = Context.getTypeSize(Type); 18846 QualType IntTy = Context.getIntTypeForBitwidth(Size, /*Signed=*/0); 18847 llvm::APInt InitValue = llvm::APInt::getAllOnes(Size); 18848 Init = IntegerLiteral::Create(Context, InitValue, IntTy, ELoc); 18849 } 18850 if (Init && OrigType->isAnyComplexType()) { 18851 // Init = 0xFFFF + 0xFFFFi; 18852 auto *Im = new (Context) ImaginaryLiteral(Init, OrigType); 18853 Init = S.CreateBuiltinBinOp(ELoc, BO_Add, Init, Im).get(); 18854 } 18855 Type = OrigType; 18856 break; 18857 } 18858 case BO_LT: 18859 case BO_GT: { 18860 // 'min' reduction op - initializer is 'Largest representable number in 18861 // the reduction list item type'. 18862 // 'max' reduction op - initializer is 'Least representable number in 18863 // the reduction list item type'. 18864 if (Type->isIntegerType() || Type->isPointerType()) { 18865 bool IsSigned = Type->hasSignedIntegerRepresentation(); 18866 uint64_t Size = Context.getTypeSize(Type); 18867 QualType IntTy = 18868 Context.getIntTypeForBitwidth(Size, /*Signed=*/IsSigned); 18869 llvm::APInt InitValue = 18870 (BOK != BO_LT) ? IsSigned ? llvm::APInt::getSignedMinValue(Size) 18871 : llvm::APInt::getMinValue(Size) 18872 : IsSigned ? llvm::APInt::getSignedMaxValue(Size) 18873 : llvm::APInt::getMaxValue(Size); 18874 Init = IntegerLiteral::Create(Context, InitValue, IntTy, ELoc); 18875 if (Type->isPointerType()) { 18876 // Cast to pointer type. 18877 ExprResult CastExpr = S.BuildCStyleCastExpr( 18878 ELoc, Context.getTrivialTypeSourceInfo(Type, ELoc), ELoc, Init); 18879 if (CastExpr.isInvalid()) 18880 continue; 18881 Init = CastExpr.get(); 18882 } 18883 } else if (Type->isRealFloatingType()) { 18884 llvm::APFloat InitValue = llvm::APFloat::getLargest( 18885 Context.getFloatTypeSemantics(Type), BOK != BO_LT); 18886 Init = FloatingLiteral::Create(Context, InitValue, /*isexact=*/true, 18887 Type, ELoc); 18888 } 18889 break; 18890 } 18891 case BO_PtrMemD: 18892 case BO_PtrMemI: 18893 case BO_MulAssign: 18894 case BO_Div: 18895 case BO_Rem: 18896 case BO_Sub: 18897 case BO_Shl: 18898 case BO_Shr: 18899 case BO_LE: 18900 case BO_GE: 18901 case BO_EQ: 18902 case BO_NE: 18903 case BO_Cmp: 18904 case BO_AndAssign: 18905 case BO_XorAssign: 18906 case BO_OrAssign: 18907 case BO_Assign: 18908 case BO_AddAssign: 18909 case BO_SubAssign: 18910 case BO_DivAssign: 18911 case BO_RemAssign: 18912 case BO_ShlAssign: 18913 case BO_ShrAssign: 18914 case BO_Comma: 18915 llvm_unreachable("Unexpected reduction operation"); 18916 } 18917 } 18918 if (Init && DeclareReductionRef.isUnset()) { 18919 S.AddInitializerToDecl(RHSVD, Init, /*DirectInit=*/false); 18920 // Store initializer for single element in private copy. Will be used 18921 // during codegen. 18922 PrivateVD->setInit(RHSVD->getInit()); 18923 PrivateVD->setInitStyle(RHSVD->getInitStyle()); 18924 } else if (!Init) { 18925 S.ActOnUninitializedDecl(RHSVD); 18926 // Store initializer for single element in private copy. Will be used 18927 // during codegen. 18928 PrivateVD->setInit(RHSVD->getInit()); 18929 PrivateVD->setInitStyle(RHSVD->getInitStyle()); 18930 } 18931 if (RHSVD->isInvalidDecl()) 18932 continue; 18933 if (!RHSVD->hasInit() && DeclareReductionRef.isUnset()) { 18934 S.Diag(ELoc, diag::err_omp_reduction_id_not_compatible) 18935 << Type << ReductionIdRange; 18936 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) == 18937 VarDecl::DeclarationOnly; 18938 S.Diag(D->getLocation(), 18939 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 18940 << D; 18941 continue; 18942 } 18943 DeclRefExpr *PrivateDRE = buildDeclRefExpr(S, PrivateVD, PrivateTy, ELoc); 18944 ExprResult ReductionOp; 18945 if (DeclareReductionRef.isUsable()) { 18946 QualType RedTy = DeclareReductionRef.get()->getType(); 18947 QualType PtrRedTy = Context.getPointerType(RedTy); 18948 ExprResult LHS = S.CreateBuiltinUnaryOp(ELoc, UO_AddrOf, LHSDRE); 18949 ExprResult RHS = S.CreateBuiltinUnaryOp(ELoc, UO_AddrOf, RHSDRE); 18950 if (!BasePath.empty()) { 18951 LHS = S.DefaultLvalueConversion(LHS.get()); 18952 RHS = S.DefaultLvalueConversion(RHS.get()); 18953 LHS = ImplicitCastExpr::Create( 18954 Context, PtrRedTy, CK_UncheckedDerivedToBase, LHS.get(), &BasePath, 18955 LHS.get()->getValueKind(), FPOptionsOverride()); 18956 RHS = ImplicitCastExpr::Create( 18957 Context, PtrRedTy, CK_UncheckedDerivedToBase, RHS.get(), &BasePath, 18958 RHS.get()->getValueKind(), FPOptionsOverride()); 18959 } 18960 FunctionProtoType::ExtProtoInfo EPI; 18961 QualType Params[] = {PtrRedTy, PtrRedTy}; 18962 QualType FnTy = Context.getFunctionType(Context.VoidTy, Params, EPI); 18963 auto *OVE = new (Context) OpaqueValueExpr( 18964 ELoc, Context.getPointerType(FnTy), VK_PRValue, OK_Ordinary, 18965 S.DefaultLvalueConversion(DeclareReductionRef.get()).get()); 18966 Expr *Args[] = {LHS.get(), RHS.get()}; 18967 ReductionOp = 18968 CallExpr::Create(Context, OVE, Args, Context.VoidTy, VK_PRValue, ELoc, 18969 S.CurFPFeatureOverrides()); 18970 } else { 18971 BinaryOperatorKind CombBOK = getRelatedCompoundReductionOp(BOK); 18972 if (Type->isRecordType() && CombBOK != BOK) { 18973 Sema::TentativeAnalysisScope Trap(S); 18974 ReductionOp = 18975 S.BuildBinOp(Stack->getCurScope(), ReductionId.getBeginLoc(), 18976 CombBOK, LHSDRE, RHSDRE); 18977 } 18978 if (!ReductionOp.isUsable()) { 18979 ReductionOp = 18980 S.BuildBinOp(Stack->getCurScope(), ReductionId.getBeginLoc(), BOK, 18981 LHSDRE, RHSDRE); 18982 if (ReductionOp.isUsable()) { 18983 if (BOK != BO_LT && BOK != BO_GT) { 18984 ReductionOp = 18985 S.BuildBinOp(Stack->getCurScope(), ReductionId.getBeginLoc(), 18986 BO_Assign, LHSDRE, ReductionOp.get()); 18987 } else { 18988 auto *ConditionalOp = new (Context) 18989 ConditionalOperator(ReductionOp.get(), ELoc, LHSDRE, ELoc, 18990 RHSDRE, Type, VK_LValue, OK_Ordinary); 18991 ReductionOp = 18992 S.BuildBinOp(Stack->getCurScope(), ReductionId.getBeginLoc(), 18993 BO_Assign, LHSDRE, ConditionalOp); 18994 } 18995 } 18996 } 18997 if (ReductionOp.isUsable()) 18998 ReductionOp = S.ActOnFinishFullExpr(ReductionOp.get(), 18999 /*DiscardedValue*/ false); 19000 if (!ReductionOp.isUsable()) 19001 continue; 19002 } 19003 19004 // Add copy operations for inscan reductions. 19005 // LHS = RHS; 19006 ExprResult CopyOpRes, TempArrayRes, TempArrayElem; 19007 if (ClauseKind == OMPC_reduction && 19008 RD.RedModifier == OMPC_REDUCTION_inscan) { 19009 ExprResult RHS = S.DefaultLvalueConversion(RHSDRE); 19010 CopyOpRes = S.BuildBinOp(Stack->getCurScope(), ELoc, BO_Assign, LHSDRE, 19011 RHS.get()); 19012 if (!CopyOpRes.isUsable()) 19013 continue; 19014 CopyOpRes = 19015 S.ActOnFinishFullExpr(CopyOpRes.get(), /*DiscardedValue=*/true); 19016 if (!CopyOpRes.isUsable()) 19017 continue; 19018 // For simd directive and simd-based directives in simd mode no need to 19019 // construct temp array, need just a single temp element. 19020 if (Stack->getCurrentDirective() == OMPD_simd || 19021 (S.getLangOpts().OpenMPSimd && 19022 isOpenMPSimdDirective(Stack->getCurrentDirective()))) { 19023 VarDecl *TempArrayVD = 19024 buildVarDecl(S, ELoc, PrivateTy, D->getName(), 19025 D->hasAttrs() ? &D->getAttrs() : nullptr); 19026 // Add a constructor to the temp decl. 19027 S.ActOnUninitializedDecl(TempArrayVD); 19028 TempArrayRes = buildDeclRefExpr(S, TempArrayVD, PrivateTy, ELoc); 19029 } else { 19030 // Build temp array for prefix sum. 19031 auto *Dim = new (S.Context) 19032 OpaqueValueExpr(ELoc, S.Context.getSizeType(), VK_PRValue); 19033 QualType ArrayTy = 19034 S.Context.getVariableArrayType(PrivateTy, Dim, ArrayType::Normal, 19035 /*IndexTypeQuals=*/0, {ELoc, ELoc}); 19036 VarDecl *TempArrayVD = 19037 buildVarDecl(S, ELoc, ArrayTy, D->getName(), 19038 D->hasAttrs() ? &D->getAttrs() : nullptr); 19039 // Add a constructor to the temp decl. 19040 S.ActOnUninitializedDecl(TempArrayVD); 19041 TempArrayRes = buildDeclRefExpr(S, TempArrayVD, ArrayTy, ELoc); 19042 TempArrayElem = 19043 S.DefaultFunctionArrayLvalueConversion(TempArrayRes.get()); 19044 auto *Idx = new (S.Context) 19045 OpaqueValueExpr(ELoc, S.Context.getSizeType(), VK_PRValue); 19046 TempArrayElem = S.CreateBuiltinArraySubscriptExpr(TempArrayElem.get(), 19047 ELoc, Idx, ELoc); 19048 } 19049 } 19050 19051 // OpenMP [2.15.4.6, Restrictions, p.2] 19052 // A list item that appears in an in_reduction clause of a task construct 19053 // must appear in a task_reduction clause of a construct associated with a 19054 // taskgroup region that includes the participating task in its taskgroup 19055 // set. The construct associated with the innermost region that meets this 19056 // condition must specify the same reduction-identifier as the in_reduction 19057 // clause. 19058 if (ClauseKind == OMPC_in_reduction) { 19059 SourceRange ParentSR; 19060 BinaryOperatorKind ParentBOK; 19061 const Expr *ParentReductionOp = nullptr; 19062 Expr *ParentBOKTD = nullptr, *ParentReductionOpTD = nullptr; 19063 DSAStackTy::DSAVarData ParentBOKDSA = 19064 Stack->getTopMostTaskgroupReductionData(D, ParentSR, ParentBOK, 19065 ParentBOKTD); 19066 DSAStackTy::DSAVarData ParentReductionOpDSA = 19067 Stack->getTopMostTaskgroupReductionData( 19068 D, ParentSR, ParentReductionOp, ParentReductionOpTD); 19069 bool IsParentBOK = ParentBOKDSA.DKind != OMPD_unknown; 19070 bool IsParentReductionOp = ParentReductionOpDSA.DKind != OMPD_unknown; 19071 if ((DeclareReductionRef.isUnset() && IsParentReductionOp) || 19072 (DeclareReductionRef.isUsable() && IsParentBOK) || 19073 (IsParentBOK && BOK != ParentBOK) || IsParentReductionOp) { 19074 bool EmitError = true; 19075 if (IsParentReductionOp && DeclareReductionRef.isUsable()) { 19076 llvm::FoldingSetNodeID RedId, ParentRedId; 19077 ParentReductionOp->Profile(ParentRedId, Context, /*Canonical=*/true); 19078 DeclareReductionRef.get()->Profile(RedId, Context, 19079 /*Canonical=*/true); 19080 EmitError = RedId != ParentRedId; 19081 } 19082 if (EmitError) { 19083 S.Diag(ReductionId.getBeginLoc(), 19084 diag::err_omp_reduction_identifier_mismatch) 19085 << ReductionIdRange << RefExpr->getSourceRange(); 19086 S.Diag(ParentSR.getBegin(), 19087 diag::note_omp_previous_reduction_identifier) 19088 << ParentSR 19089 << (IsParentBOK ? ParentBOKDSA.RefExpr 19090 : ParentReductionOpDSA.RefExpr) 19091 ->getSourceRange(); 19092 continue; 19093 } 19094 } 19095 TaskgroupDescriptor = IsParentBOK ? ParentBOKTD : ParentReductionOpTD; 19096 } 19097 19098 DeclRefExpr *Ref = nullptr; 19099 Expr *VarsExpr = RefExpr->IgnoreParens(); 19100 if (!VD && !S.CurContext->isDependentContext()) { 19101 if (ASE || OASE) { 19102 TransformExprToCaptures RebuildToCapture(S, D); 19103 VarsExpr = 19104 RebuildToCapture.TransformExpr(RefExpr->IgnoreParens()).get(); 19105 Ref = RebuildToCapture.getCapturedExpr(); 19106 } else { 19107 VarsExpr = Ref = buildCapture(S, D, SimpleRefExpr, /*WithInit=*/false); 19108 } 19109 if (!S.isOpenMPCapturedDecl(D)) { 19110 RD.ExprCaptures.emplace_back(Ref->getDecl()); 19111 if (Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>()) { 19112 ExprResult RefRes = S.DefaultLvalueConversion(Ref); 19113 if (!RefRes.isUsable()) 19114 continue; 19115 ExprResult PostUpdateRes = 19116 S.BuildBinOp(Stack->getCurScope(), ELoc, BO_Assign, SimpleRefExpr, 19117 RefRes.get()); 19118 if (!PostUpdateRes.isUsable()) 19119 continue; 19120 if (isOpenMPTaskingDirective(Stack->getCurrentDirective()) || 19121 Stack->getCurrentDirective() == OMPD_taskgroup) { 19122 S.Diag(RefExpr->getExprLoc(), 19123 diag::err_omp_reduction_non_addressable_expression) 19124 << RefExpr->getSourceRange(); 19125 continue; 19126 } 19127 RD.ExprPostUpdates.emplace_back( 19128 S.IgnoredValueConversions(PostUpdateRes.get()).get()); 19129 } 19130 } 19131 } 19132 // All reduction items are still marked as reduction (to do not increase 19133 // code base size). 19134 unsigned Modifier = RD.RedModifier; 19135 // Consider task_reductions as reductions with task modifier. Required for 19136 // correct analysis of in_reduction clauses. 19137 if (CurrDir == OMPD_taskgroup && ClauseKind == OMPC_task_reduction) 19138 Modifier = OMPC_REDUCTION_task; 19139 Stack->addDSA(D, RefExpr->IgnoreParens(), OMPC_reduction, Ref, Modifier, 19140 ASE || OASE); 19141 if (Modifier == OMPC_REDUCTION_task && 19142 (CurrDir == OMPD_taskgroup || 19143 ((isOpenMPParallelDirective(CurrDir) || 19144 isOpenMPWorksharingDirective(CurrDir)) && 19145 !isOpenMPSimdDirective(CurrDir)))) { 19146 if (DeclareReductionRef.isUsable()) 19147 Stack->addTaskgroupReductionData(D, ReductionIdRange, 19148 DeclareReductionRef.get()); 19149 else 19150 Stack->addTaskgroupReductionData(D, ReductionIdRange, BOK); 19151 } 19152 RD.push(VarsExpr, PrivateDRE, LHSDRE, RHSDRE, ReductionOp.get(), 19153 TaskgroupDescriptor, CopyOpRes.get(), TempArrayRes.get(), 19154 TempArrayElem.get()); 19155 } 19156 return RD.Vars.empty(); 19157 } 19158 19159 OMPClause *Sema::ActOnOpenMPReductionClause( 19160 ArrayRef<Expr *> VarList, OpenMPReductionClauseModifier Modifier, 19161 SourceLocation StartLoc, SourceLocation LParenLoc, 19162 SourceLocation ModifierLoc, SourceLocation ColonLoc, SourceLocation EndLoc, 19163 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, 19164 ArrayRef<Expr *> UnresolvedReductions) { 19165 if (ModifierLoc.isValid() && Modifier == OMPC_REDUCTION_unknown) { 19166 Diag(LParenLoc, diag::err_omp_unexpected_clause_value) 19167 << getListOfPossibleValues(OMPC_reduction, /*First=*/0, 19168 /*Last=*/OMPC_REDUCTION_unknown) 19169 << getOpenMPClauseName(OMPC_reduction); 19170 return nullptr; 19171 } 19172 // OpenMP 5.0, 2.19.5.4 reduction Clause, Restrictions 19173 // A reduction clause with the inscan reduction-modifier may only appear on a 19174 // worksharing-loop construct, a worksharing-loop SIMD construct, a simd 19175 // construct, a parallel worksharing-loop construct or a parallel 19176 // worksharing-loop SIMD construct. 19177 if (Modifier == OMPC_REDUCTION_inscan && 19178 (DSAStack->getCurrentDirective() != OMPD_for && 19179 DSAStack->getCurrentDirective() != OMPD_for_simd && 19180 DSAStack->getCurrentDirective() != OMPD_simd && 19181 DSAStack->getCurrentDirective() != OMPD_parallel_for && 19182 DSAStack->getCurrentDirective() != OMPD_parallel_for_simd)) { 19183 Diag(ModifierLoc, diag::err_omp_wrong_inscan_reduction); 19184 return nullptr; 19185 } 19186 19187 ReductionData RD(VarList.size(), Modifier); 19188 if (actOnOMPReductionKindClause(*this, DSAStack, OMPC_reduction, VarList, 19189 StartLoc, LParenLoc, ColonLoc, EndLoc, 19190 ReductionIdScopeSpec, ReductionId, 19191 UnresolvedReductions, RD)) 19192 return nullptr; 19193 19194 return OMPReductionClause::Create( 19195 Context, StartLoc, LParenLoc, ModifierLoc, ColonLoc, EndLoc, Modifier, 19196 RD.Vars, ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId, 19197 RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps, RD.InscanCopyOps, 19198 RD.InscanCopyArrayTemps, RD.InscanCopyArrayElems, 19199 buildPreInits(Context, RD.ExprCaptures), 19200 buildPostUpdate(*this, RD.ExprPostUpdates)); 19201 } 19202 19203 OMPClause *Sema::ActOnOpenMPTaskReductionClause( 19204 ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, 19205 SourceLocation ColonLoc, SourceLocation EndLoc, 19206 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, 19207 ArrayRef<Expr *> UnresolvedReductions) { 19208 ReductionData RD(VarList.size()); 19209 if (actOnOMPReductionKindClause(*this, DSAStack, OMPC_task_reduction, VarList, 19210 StartLoc, LParenLoc, ColonLoc, EndLoc, 19211 ReductionIdScopeSpec, ReductionId, 19212 UnresolvedReductions, RD)) 19213 return nullptr; 19214 19215 return OMPTaskReductionClause::Create( 19216 Context, StartLoc, LParenLoc, ColonLoc, EndLoc, RD.Vars, 19217 ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId, 19218 RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps, 19219 buildPreInits(Context, RD.ExprCaptures), 19220 buildPostUpdate(*this, RD.ExprPostUpdates)); 19221 } 19222 19223 OMPClause *Sema::ActOnOpenMPInReductionClause( 19224 ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, 19225 SourceLocation ColonLoc, SourceLocation EndLoc, 19226 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, 19227 ArrayRef<Expr *> UnresolvedReductions) { 19228 ReductionData RD(VarList.size()); 19229 if (actOnOMPReductionKindClause(*this, DSAStack, OMPC_in_reduction, VarList, 19230 StartLoc, LParenLoc, ColonLoc, EndLoc, 19231 ReductionIdScopeSpec, ReductionId, 19232 UnresolvedReductions, RD)) 19233 return nullptr; 19234 19235 return OMPInReductionClause::Create( 19236 Context, StartLoc, LParenLoc, ColonLoc, EndLoc, RD.Vars, 19237 ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId, 19238 RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps, RD.TaskgroupDescriptors, 19239 buildPreInits(Context, RD.ExprCaptures), 19240 buildPostUpdate(*this, RD.ExprPostUpdates)); 19241 } 19242 19243 bool Sema::CheckOpenMPLinearModifier(OpenMPLinearClauseKind LinKind, 19244 SourceLocation LinLoc) { 19245 if ((!LangOpts.CPlusPlus && LinKind != OMPC_LINEAR_val) || 19246 LinKind == OMPC_LINEAR_unknown) { 19247 Diag(LinLoc, diag::err_omp_wrong_linear_modifier) << LangOpts.CPlusPlus; 19248 return true; 19249 } 19250 return false; 19251 } 19252 19253 bool Sema::CheckOpenMPLinearDecl(const ValueDecl *D, SourceLocation ELoc, 19254 OpenMPLinearClauseKind LinKind, QualType Type, 19255 bool IsDeclareSimd) { 19256 const auto *VD = dyn_cast_or_null<VarDecl>(D); 19257 // A variable must not have an incomplete type or a reference type. 19258 if (RequireCompleteType(ELoc, Type, diag::err_omp_linear_incomplete_type)) 19259 return true; 19260 if ((LinKind == OMPC_LINEAR_uval || LinKind == OMPC_LINEAR_ref) && 19261 !Type->isReferenceType()) { 19262 Diag(ELoc, diag::err_omp_wrong_linear_modifier_non_reference) 19263 << Type << getOpenMPSimpleClauseTypeName(OMPC_linear, LinKind); 19264 return true; 19265 } 19266 Type = Type.getNonReferenceType(); 19267 19268 // OpenMP 5.0 [2.19.3, List Item Privatization, Restrictions] 19269 // A variable that is privatized must not have a const-qualified type 19270 // unless it is of class type with a mutable member. This restriction does 19271 // not apply to the firstprivate clause, nor to the linear clause on 19272 // declarative directives (like declare simd). 19273 if (!IsDeclareSimd && 19274 rejectConstNotMutableType(*this, D, Type, OMPC_linear, ELoc)) 19275 return true; 19276 19277 // A list item must be of integral or pointer type. 19278 Type = Type.getUnqualifiedType().getCanonicalType(); 19279 const auto *Ty = Type.getTypePtrOrNull(); 19280 if (!Ty || (LinKind != OMPC_LINEAR_ref && !Ty->isDependentType() && 19281 !Ty->isIntegralType(Context) && !Ty->isPointerType())) { 19282 Diag(ELoc, diag::err_omp_linear_expected_int_or_ptr) << Type; 19283 if (D) { 19284 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) == 19285 VarDecl::DeclarationOnly; 19286 Diag(D->getLocation(), 19287 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 19288 << D; 19289 } 19290 return true; 19291 } 19292 return false; 19293 } 19294 19295 OMPClause *Sema::ActOnOpenMPLinearClause( 19296 ArrayRef<Expr *> VarList, Expr *Step, SourceLocation StartLoc, 19297 SourceLocation LParenLoc, OpenMPLinearClauseKind LinKind, 19298 SourceLocation LinLoc, SourceLocation ColonLoc, SourceLocation EndLoc) { 19299 SmallVector<Expr *, 8> Vars; 19300 SmallVector<Expr *, 8> Privates; 19301 SmallVector<Expr *, 8> Inits; 19302 SmallVector<Decl *, 4> ExprCaptures; 19303 SmallVector<Expr *, 4> ExprPostUpdates; 19304 if (CheckOpenMPLinearModifier(LinKind, LinLoc)) 19305 LinKind = OMPC_LINEAR_val; 19306 for (Expr *RefExpr : VarList) { 19307 assert(RefExpr && "NULL expr in OpenMP linear clause."); 19308 SourceLocation ELoc; 19309 SourceRange ERange; 19310 Expr *SimpleRefExpr = RefExpr; 19311 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 19312 if (Res.second) { 19313 // It will be analyzed later. 19314 Vars.push_back(RefExpr); 19315 Privates.push_back(nullptr); 19316 Inits.push_back(nullptr); 19317 } 19318 ValueDecl *D = Res.first; 19319 if (!D) 19320 continue; 19321 19322 QualType Type = D->getType(); 19323 auto *VD = dyn_cast<VarDecl>(D); 19324 19325 // OpenMP [2.14.3.7, linear clause] 19326 // A list-item cannot appear in more than one linear clause. 19327 // A list-item that appears in a linear clause cannot appear in any 19328 // other data-sharing attribute clause. 19329 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false); 19330 if (DVar.RefExpr) { 19331 Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind) 19332 << getOpenMPClauseName(OMPC_linear); 19333 reportOriginalDsa(*this, DSAStack, D, DVar); 19334 continue; 19335 } 19336 19337 if (CheckOpenMPLinearDecl(D, ELoc, LinKind, Type)) 19338 continue; 19339 Type = Type.getNonReferenceType().getUnqualifiedType().getCanonicalType(); 19340 19341 // Build private copy of original var. 19342 VarDecl *Private = 19343 buildVarDecl(*this, ELoc, Type, D->getName(), 19344 D->hasAttrs() ? &D->getAttrs() : nullptr, 19345 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr); 19346 DeclRefExpr *PrivateRef = buildDeclRefExpr(*this, Private, Type, ELoc); 19347 // Build var to save initial value. 19348 VarDecl *Init = buildVarDecl(*this, ELoc, Type, ".linear.start"); 19349 Expr *InitExpr; 19350 DeclRefExpr *Ref = nullptr; 19351 if (!VD && !CurContext->isDependentContext()) { 19352 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false); 19353 if (!isOpenMPCapturedDecl(D)) { 19354 ExprCaptures.push_back(Ref->getDecl()); 19355 if (Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>()) { 19356 ExprResult RefRes = DefaultLvalueConversion(Ref); 19357 if (!RefRes.isUsable()) 19358 continue; 19359 ExprResult PostUpdateRes = 19360 BuildBinOp(DSAStack->getCurScope(), ELoc, BO_Assign, 19361 SimpleRefExpr, RefRes.get()); 19362 if (!PostUpdateRes.isUsable()) 19363 continue; 19364 ExprPostUpdates.push_back( 19365 IgnoredValueConversions(PostUpdateRes.get()).get()); 19366 } 19367 } 19368 } 19369 if (LinKind == OMPC_LINEAR_uval) 19370 InitExpr = VD ? VD->getInit() : SimpleRefExpr; 19371 else 19372 InitExpr = VD ? SimpleRefExpr : Ref; 19373 AddInitializerToDecl(Init, DefaultLvalueConversion(InitExpr).get(), 19374 /*DirectInit=*/false); 19375 DeclRefExpr *InitRef = buildDeclRefExpr(*this, Init, Type, ELoc); 19376 19377 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_linear, Ref); 19378 Vars.push_back((VD || CurContext->isDependentContext()) 19379 ? RefExpr->IgnoreParens() 19380 : Ref); 19381 Privates.push_back(PrivateRef); 19382 Inits.push_back(InitRef); 19383 } 19384 19385 if (Vars.empty()) 19386 return nullptr; 19387 19388 Expr *StepExpr = Step; 19389 Expr *CalcStepExpr = nullptr; 19390 if (Step && !Step->isValueDependent() && !Step->isTypeDependent() && 19391 !Step->isInstantiationDependent() && 19392 !Step->containsUnexpandedParameterPack()) { 19393 SourceLocation StepLoc = Step->getBeginLoc(); 19394 ExprResult Val = PerformOpenMPImplicitIntegerConversion(StepLoc, Step); 19395 if (Val.isInvalid()) 19396 return nullptr; 19397 StepExpr = Val.get(); 19398 19399 // Build var to save the step value. 19400 VarDecl *SaveVar = 19401 buildVarDecl(*this, StepLoc, StepExpr->getType(), ".linear.step"); 19402 ExprResult SaveRef = 19403 buildDeclRefExpr(*this, SaveVar, StepExpr->getType(), StepLoc); 19404 ExprResult CalcStep = 19405 BuildBinOp(CurScope, StepLoc, BO_Assign, SaveRef.get(), StepExpr); 19406 CalcStep = ActOnFinishFullExpr(CalcStep.get(), /*DiscardedValue*/ false); 19407 19408 // Warn about zero linear step (it would be probably better specified as 19409 // making corresponding variables 'const'). 19410 if (Optional<llvm::APSInt> Result = 19411 StepExpr->getIntegerConstantExpr(Context)) { 19412 if (!Result->isNegative() && !Result->isStrictlyPositive()) 19413 Diag(StepLoc, diag::warn_omp_linear_step_zero) 19414 << Vars[0] << (Vars.size() > 1); 19415 } else if (CalcStep.isUsable()) { 19416 // Calculate the step beforehand instead of doing this on each iteration. 19417 // (This is not used if the number of iterations may be kfold-ed). 19418 CalcStepExpr = CalcStep.get(); 19419 } 19420 } 19421 19422 return OMPLinearClause::Create(Context, StartLoc, LParenLoc, LinKind, LinLoc, 19423 ColonLoc, EndLoc, Vars, Privates, Inits, 19424 StepExpr, CalcStepExpr, 19425 buildPreInits(Context, ExprCaptures), 19426 buildPostUpdate(*this, ExprPostUpdates)); 19427 } 19428 19429 static bool FinishOpenMPLinearClause(OMPLinearClause &Clause, DeclRefExpr *IV, 19430 Expr *NumIterations, Sema &SemaRef, 19431 Scope *S, DSAStackTy *Stack) { 19432 // Walk the vars and build update/final expressions for the CodeGen. 19433 SmallVector<Expr *, 8> Updates; 19434 SmallVector<Expr *, 8> Finals; 19435 SmallVector<Expr *, 8> UsedExprs; 19436 Expr *Step = Clause.getStep(); 19437 Expr *CalcStep = Clause.getCalcStep(); 19438 // OpenMP [2.14.3.7, linear clause] 19439 // If linear-step is not specified it is assumed to be 1. 19440 if (!Step) 19441 Step = SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get(); 19442 else if (CalcStep) 19443 Step = cast<BinaryOperator>(CalcStep)->getLHS(); 19444 bool HasErrors = false; 19445 auto CurInit = Clause.inits().begin(); 19446 auto CurPrivate = Clause.privates().begin(); 19447 OpenMPLinearClauseKind LinKind = Clause.getModifier(); 19448 for (Expr *RefExpr : Clause.varlists()) { 19449 SourceLocation ELoc; 19450 SourceRange ERange; 19451 Expr *SimpleRefExpr = RefExpr; 19452 auto Res = getPrivateItem(SemaRef, SimpleRefExpr, ELoc, ERange); 19453 ValueDecl *D = Res.first; 19454 if (Res.second || !D) { 19455 Updates.push_back(nullptr); 19456 Finals.push_back(nullptr); 19457 HasErrors = true; 19458 continue; 19459 } 19460 auto &&Info = Stack->isLoopControlVariable(D); 19461 // OpenMP [2.15.11, distribute simd Construct] 19462 // A list item may not appear in a linear clause, unless it is the loop 19463 // iteration variable. 19464 if (isOpenMPDistributeDirective(Stack->getCurrentDirective()) && 19465 isOpenMPSimdDirective(Stack->getCurrentDirective()) && !Info.first) { 19466 SemaRef.Diag(ELoc, 19467 diag::err_omp_linear_distribute_var_non_loop_iteration); 19468 Updates.push_back(nullptr); 19469 Finals.push_back(nullptr); 19470 HasErrors = true; 19471 continue; 19472 } 19473 Expr *InitExpr = *CurInit; 19474 19475 // Build privatized reference to the current linear var. 19476 auto *DE = cast<DeclRefExpr>(SimpleRefExpr); 19477 Expr *CapturedRef; 19478 if (LinKind == OMPC_LINEAR_uval) 19479 CapturedRef = cast<VarDecl>(DE->getDecl())->getInit(); 19480 else 19481 CapturedRef = 19482 buildDeclRefExpr(SemaRef, cast<VarDecl>(DE->getDecl()), 19483 DE->getType().getUnqualifiedType(), DE->getExprLoc(), 19484 /*RefersToCapture=*/true); 19485 19486 // Build update: Var = InitExpr + IV * Step 19487 ExprResult Update; 19488 if (!Info.first) 19489 Update = buildCounterUpdate( 19490 SemaRef, S, RefExpr->getExprLoc(), *CurPrivate, InitExpr, IV, Step, 19491 /*Subtract=*/false, /*IsNonRectangularLB=*/false); 19492 else 19493 Update = *CurPrivate; 19494 Update = SemaRef.ActOnFinishFullExpr(Update.get(), DE->getBeginLoc(), 19495 /*DiscardedValue*/ false); 19496 19497 // Build final: Var = PrivCopy; 19498 ExprResult Final; 19499 if (!Info.first) 19500 Final = SemaRef.BuildBinOp( 19501 S, RefExpr->getExprLoc(), BO_Assign, CapturedRef, 19502 SemaRef.DefaultLvalueConversion(*CurPrivate).get()); 19503 else 19504 Final = *CurPrivate; 19505 Final = SemaRef.ActOnFinishFullExpr(Final.get(), DE->getBeginLoc(), 19506 /*DiscardedValue*/ false); 19507 19508 if (!Update.isUsable() || !Final.isUsable()) { 19509 Updates.push_back(nullptr); 19510 Finals.push_back(nullptr); 19511 UsedExprs.push_back(nullptr); 19512 HasErrors = true; 19513 } else { 19514 Updates.push_back(Update.get()); 19515 Finals.push_back(Final.get()); 19516 if (!Info.first) 19517 UsedExprs.push_back(SimpleRefExpr); 19518 } 19519 ++CurInit; 19520 ++CurPrivate; 19521 } 19522 if (Expr *S = Clause.getStep()) 19523 UsedExprs.push_back(S); 19524 // Fill the remaining part with the nullptr. 19525 UsedExprs.append(Clause.varlist_size() + 1 - UsedExprs.size(), nullptr); 19526 Clause.setUpdates(Updates); 19527 Clause.setFinals(Finals); 19528 Clause.setUsedExprs(UsedExprs); 19529 return HasErrors; 19530 } 19531 19532 OMPClause *Sema::ActOnOpenMPAlignedClause( 19533 ArrayRef<Expr *> VarList, Expr *Alignment, SourceLocation StartLoc, 19534 SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc) { 19535 SmallVector<Expr *, 8> Vars; 19536 for (Expr *RefExpr : VarList) { 19537 assert(RefExpr && "NULL expr in OpenMP linear clause."); 19538 SourceLocation ELoc; 19539 SourceRange ERange; 19540 Expr *SimpleRefExpr = RefExpr; 19541 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 19542 if (Res.second) { 19543 // It will be analyzed later. 19544 Vars.push_back(RefExpr); 19545 } 19546 ValueDecl *D = Res.first; 19547 if (!D) 19548 continue; 19549 19550 QualType QType = D->getType(); 19551 auto *VD = dyn_cast<VarDecl>(D); 19552 19553 // OpenMP [2.8.1, simd construct, Restrictions] 19554 // The type of list items appearing in the aligned clause must be 19555 // array, pointer, reference to array, or reference to pointer. 19556 QType = QType.getNonReferenceType().getUnqualifiedType().getCanonicalType(); 19557 const Type *Ty = QType.getTypePtrOrNull(); 19558 if (!Ty || (!Ty->isArrayType() && !Ty->isPointerType())) { 19559 Diag(ELoc, diag::err_omp_aligned_expected_array_or_ptr) 19560 << QType << getLangOpts().CPlusPlus << ERange; 19561 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) == 19562 VarDecl::DeclarationOnly; 19563 Diag(D->getLocation(), 19564 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 19565 << D; 19566 continue; 19567 } 19568 19569 // OpenMP [2.8.1, simd construct, Restrictions] 19570 // A list-item cannot appear in more than one aligned clause. 19571 if (const Expr *PrevRef = DSAStack->addUniqueAligned(D, SimpleRefExpr)) { 19572 Diag(ELoc, diag::err_omp_used_in_clause_twice) 19573 << 0 << getOpenMPClauseName(OMPC_aligned) << ERange; 19574 Diag(PrevRef->getExprLoc(), diag::note_omp_explicit_dsa) 19575 << getOpenMPClauseName(OMPC_aligned); 19576 continue; 19577 } 19578 19579 DeclRefExpr *Ref = nullptr; 19580 if (!VD && isOpenMPCapturedDecl(D)) 19581 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true); 19582 Vars.push_back(DefaultFunctionArrayConversion( 19583 (VD || !Ref) ? RefExpr->IgnoreParens() : Ref) 19584 .get()); 19585 } 19586 19587 // OpenMP [2.8.1, simd construct, Description] 19588 // The parameter of the aligned clause, alignment, must be a constant 19589 // positive integer expression. 19590 // If no optional parameter is specified, implementation-defined default 19591 // alignments for SIMD instructions on the target platforms are assumed. 19592 if (Alignment != nullptr) { 19593 ExprResult AlignResult = 19594 VerifyPositiveIntegerConstantInClause(Alignment, OMPC_aligned); 19595 if (AlignResult.isInvalid()) 19596 return nullptr; 19597 Alignment = AlignResult.get(); 19598 } 19599 if (Vars.empty()) 19600 return nullptr; 19601 19602 return OMPAlignedClause::Create(Context, StartLoc, LParenLoc, ColonLoc, 19603 EndLoc, Vars, Alignment); 19604 } 19605 19606 OMPClause *Sema::ActOnOpenMPCopyinClause(ArrayRef<Expr *> VarList, 19607 SourceLocation StartLoc, 19608 SourceLocation LParenLoc, 19609 SourceLocation EndLoc) { 19610 SmallVector<Expr *, 8> Vars; 19611 SmallVector<Expr *, 8> SrcExprs; 19612 SmallVector<Expr *, 8> DstExprs; 19613 SmallVector<Expr *, 8> AssignmentOps; 19614 for (Expr *RefExpr : VarList) { 19615 assert(RefExpr && "NULL expr in OpenMP copyin clause."); 19616 if (isa<DependentScopeDeclRefExpr>(RefExpr)) { 19617 // It will be analyzed later. 19618 Vars.push_back(RefExpr); 19619 SrcExprs.push_back(nullptr); 19620 DstExprs.push_back(nullptr); 19621 AssignmentOps.push_back(nullptr); 19622 continue; 19623 } 19624 19625 SourceLocation ELoc = RefExpr->getExprLoc(); 19626 // OpenMP [2.1, C/C++] 19627 // A list item is a variable name. 19628 // OpenMP [2.14.4.1, Restrictions, p.1] 19629 // A list item that appears in a copyin clause must be threadprivate. 19630 auto *DE = dyn_cast<DeclRefExpr>(RefExpr); 19631 if (!DE || !isa<VarDecl>(DE->getDecl())) { 19632 Diag(ELoc, diag::err_omp_expected_var_name_member_expr) 19633 << 0 << RefExpr->getSourceRange(); 19634 continue; 19635 } 19636 19637 Decl *D = DE->getDecl(); 19638 auto *VD = cast<VarDecl>(D); 19639 19640 QualType Type = VD->getType(); 19641 if (Type->isDependentType() || Type->isInstantiationDependentType()) { 19642 // It will be analyzed later. 19643 Vars.push_back(DE); 19644 SrcExprs.push_back(nullptr); 19645 DstExprs.push_back(nullptr); 19646 AssignmentOps.push_back(nullptr); 19647 continue; 19648 } 19649 19650 // OpenMP [2.14.4.1, Restrictions, C/C++, p.1] 19651 // A list item that appears in a copyin clause must be threadprivate. 19652 if (!DSAStack->isThreadPrivate(VD)) { 19653 Diag(ELoc, diag::err_omp_required_access) 19654 << getOpenMPClauseName(OMPC_copyin) 19655 << getOpenMPDirectiveName(OMPD_threadprivate); 19656 continue; 19657 } 19658 19659 // OpenMP [2.14.4.1, Restrictions, C/C++, p.2] 19660 // A variable of class type (or array thereof) that appears in a 19661 // copyin clause requires an accessible, unambiguous copy assignment 19662 // operator for the class type. 19663 QualType ElemType = Context.getBaseElementType(Type).getNonReferenceType(); 19664 VarDecl *SrcVD = 19665 buildVarDecl(*this, DE->getBeginLoc(), ElemType.getUnqualifiedType(), 19666 ".copyin.src", VD->hasAttrs() ? &VD->getAttrs() : nullptr); 19667 DeclRefExpr *PseudoSrcExpr = buildDeclRefExpr( 19668 *this, SrcVD, ElemType.getUnqualifiedType(), DE->getExprLoc()); 19669 VarDecl *DstVD = 19670 buildVarDecl(*this, DE->getBeginLoc(), ElemType, ".copyin.dst", 19671 VD->hasAttrs() ? &VD->getAttrs() : nullptr); 19672 DeclRefExpr *PseudoDstExpr = 19673 buildDeclRefExpr(*this, DstVD, ElemType, DE->getExprLoc()); 19674 // For arrays generate assignment operation for single element and replace 19675 // it by the original array element in CodeGen. 19676 ExprResult AssignmentOp = 19677 BuildBinOp(/*S=*/nullptr, DE->getExprLoc(), BO_Assign, PseudoDstExpr, 19678 PseudoSrcExpr); 19679 if (AssignmentOp.isInvalid()) 19680 continue; 19681 AssignmentOp = ActOnFinishFullExpr(AssignmentOp.get(), DE->getExprLoc(), 19682 /*DiscardedValue*/ false); 19683 if (AssignmentOp.isInvalid()) 19684 continue; 19685 19686 DSAStack->addDSA(VD, DE, OMPC_copyin); 19687 Vars.push_back(DE); 19688 SrcExprs.push_back(PseudoSrcExpr); 19689 DstExprs.push_back(PseudoDstExpr); 19690 AssignmentOps.push_back(AssignmentOp.get()); 19691 } 19692 19693 if (Vars.empty()) 19694 return nullptr; 19695 19696 return OMPCopyinClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars, 19697 SrcExprs, DstExprs, AssignmentOps); 19698 } 19699 19700 OMPClause *Sema::ActOnOpenMPCopyprivateClause(ArrayRef<Expr *> VarList, 19701 SourceLocation StartLoc, 19702 SourceLocation LParenLoc, 19703 SourceLocation EndLoc) { 19704 SmallVector<Expr *, 8> Vars; 19705 SmallVector<Expr *, 8> SrcExprs; 19706 SmallVector<Expr *, 8> DstExprs; 19707 SmallVector<Expr *, 8> AssignmentOps; 19708 for (Expr *RefExpr : VarList) { 19709 assert(RefExpr && "NULL expr in OpenMP linear clause."); 19710 SourceLocation ELoc; 19711 SourceRange ERange; 19712 Expr *SimpleRefExpr = RefExpr; 19713 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 19714 if (Res.second) { 19715 // It will be analyzed later. 19716 Vars.push_back(RefExpr); 19717 SrcExprs.push_back(nullptr); 19718 DstExprs.push_back(nullptr); 19719 AssignmentOps.push_back(nullptr); 19720 } 19721 ValueDecl *D = Res.first; 19722 if (!D) 19723 continue; 19724 19725 QualType Type = D->getType(); 19726 auto *VD = dyn_cast<VarDecl>(D); 19727 19728 // OpenMP [2.14.4.2, Restrictions, p.2] 19729 // A list item that appears in a copyprivate clause may not appear in a 19730 // private or firstprivate clause on the single construct. 19731 if (!VD || !DSAStack->isThreadPrivate(VD)) { 19732 DSAStackTy::DSAVarData DVar = 19733 DSAStack->getTopDSA(D, /*FromParent=*/false); 19734 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_copyprivate && 19735 DVar.RefExpr) { 19736 Diag(ELoc, diag::err_omp_wrong_dsa) 19737 << getOpenMPClauseName(DVar.CKind) 19738 << getOpenMPClauseName(OMPC_copyprivate); 19739 reportOriginalDsa(*this, DSAStack, D, DVar); 19740 continue; 19741 } 19742 19743 // OpenMP [2.11.4.2, Restrictions, p.1] 19744 // All list items that appear in a copyprivate clause must be either 19745 // threadprivate or private in the enclosing context. 19746 if (DVar.CKind == OMPC_unknown) { 19747 DVar = DSAStack->getImplicitDSA(D, false); 19748 if (DVar.CKind == OMPC_shared) { 19749 Diag(ELoc, diag::err_omp_required_access) 19750 << getOpenMPClauseName(OMPC_copyprivate) 19751 << "threadprivate or private in the enclosing context"; 19752 reportOriginalDsa(*this, DSAStack, D, DVar); 19753 continue; 19754 } 19755 } 19756 } 19757 19758 // Variably modified types are not supported. 19759 if (!Type->isAnyPointerType() && Type->isVariablyModifiedType()) { 19760 Diag(ELoc, diag::err_omp_variably_modified_type_not_supported) 19761 << getOpenMPClauseName(OMPC_copyprivate) << Type 19762 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 19763 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) == 19764 VarDecl::DeclarationOnly; 19765 Diag(D->getLocation(), 19766 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 19767 << D; 19768 continue; 19769 } 19770 19771 // OpenMP [2.14.4.1, Restrictions, C/C++, p.2] 19772 // A variable of class type (or array thereof) that appears in a 19773 // copyin clause requires an accessible, unambiguous copy assignment 19774 // operator for the class type. 19775 Type = Context.getBaseElementType(Type.getNonReferenceType()) 19776 .getUnqualifiedType(); 19777 VarDecl *SrcVD = 19778 buildVarDecl(*this, RefExpr->getBeginLoc(), Type, ".copyprivate.src", 19779 D->hasAttrs() ? &D->getAttrs() : nullptr); 19780 DeclRefExpr *PseudoSrcExpr = buildDeclRefExpr(*this, SrcVD, Type, ELoc); 19781 VarDecl *DstVD = 19782 buildVarDecl(*this, RefExpr->getBeginLoc(), Type, ".copyprivate.dst", 19783 D->hasAttrs() ? &D->getAttrs() : nullptr); 19784 DeclRefExpr *PseudoDstExpr = buildDeclRefExpr(*this, DstVD, Type, ELoc); 19785 ExprResult AssignmentOp = BuildBinOp( 19786 DSAStack->getCurScope(), ELoc, BO_Assign, PseudoDstExpr, PseudoSrcExpr); 19787 if (AssignmentOp.isInvalid()) 19788 continue; 19789 AssignmentOp = 19790 ActOnFinishFullExpr(AssignmentOp.get(), ELoc, /*DiscardedValue*/ false); 19791 if (AssignmentOp.isInvalid()) 19792 continue; 19793 19794 // No need to mark vars as copyprivate, they are already threadprivate or 19795 // implicitly private. 19796 assert(VD || isOpenMPCapturedDecl(D)); 19797 Vars.push_back( 19798 VD ? RefExpr->IgnoreParens() 19799 : buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false)); 19800 SrcExprs.push_back(PseudoSrcExpr); 19801 DstExprs.push_back(PseudoDstExpr); 19802 AssignmentOps.push_back(AssignmentOp.get()); 19803 } 19804 19805 if (Vars.empty()) 19806 return nullptr; 19807 19808 return OMPCopyprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, 19809 Vars, SrcExprs, DstExprs, AssignmentOps); 19810 } 19811 19812 OMPClause *Sema::ActOnOpenMPFlushClause(ArrayRef<Expr *> VarList, 19813 SourceLocation StartLoc, 19814 SourceLocation LParenLoc, 19815 SourceLocation EndLoc) { 19816 if (VarList.empty()) 19817 return nullptr; 19818 19819 return OMPFlushClause::Create(Context, StartLoc, LParenLoc, EndLoc, VarList); 19820 } 19821 19822 /// Tries to find omp_depend_t. type. 19823 static bool findOMPDependT(Sema &S, SourceLocation Loc, DSAStackTy *Stack, 19824 bool Diagnose = true) { 19825 QualType OMPDependT = Stack->getOMPDependT(); 19826 if (!OMPDependT.isNull()) 19827 return true; 19828 IdentifierInfo *II = &S.PP.getIdentifierTable().get("omp_depend_t"); 19829 ParsedType PT = S.getTypeName(*II, Loc, S.getCurScope()); 19830 if (!PT.getAsOpaquePtr() || PT.get().isNull()) { 19831 if (Diagnose) 19832 S.Diag(Loc, diag::err_omp_implied_type_not_found) << "omp_depend_t"; 19833 return false; 19834 } 19835 Stack->setOMPDependT(PT.get()); 19836 return true; 19837 } 19838 19839 OMPClause *Sema::ActOnOpenMPDepobjClause(Expr *Depobj, SourceLocation StartLoc, 19840 SourceLocation LParenLoc, 19841 SourceLocation EndLoc) { 19842 if (!Depobj) 19843 return nullptr; 19844 19845 bool OMPDependTFound = findOMPDependT(*this, StartLoc, DSAStack); 19846 19847 // OpenMP 5.0, 2.17.10.1 depobj Construct 19848 // depobj is an lvalue expression of type omp_depend_t. 19849 if (!Depobj->isTypeDependent() && !Depobj->isValueDependent() && 19850 !Depobj->isInstantiationDependent() && 19851 !Depobj->containsUnexpandedParameterPack() && 19852 (OMPDependTFound && 19853 !Context.typesAreCompatible(DSAStack->getOMPDependT(), Depobj->getType(), 19854 /*CompareUnqualified=*/true))) { 19855 Diag(Depobj->getExprLoc(), diag::err_omp_expected_omp_depend_t_lvalue) 19856 << 0 << Depobj->getType() << Depobj->getSourceRange(); 19857 } 19858 19859 if (!Depobj->isLValue()) { 19860 Diag(Depobj->getExprLoc(), diag::err_omp_expected_omp_depend_t_lvalue) 19861 << 1 << Depobj->getSourceRange(); 19862 } 19863 19864 return OMPDepobjClause::Create(Context, StartLoc, LParenLoc, EndLoc, Depobj); 19865 } 19866 19867 OMPClause * 19868 Sema::ActOnOpenMPDependClause(const OMPDependClause::DependDataTy &Data, 19869 Expr *DepModifier, ArrayRef<Expr *> VarList, 19870 SourceLocation StartLoc, SourceLocation LParenLoc, 19871 SourceLocation EndLoc) { 19872 OpenMPDependClauseKind DepKind = Data.DepKind; 19873 SourceLocation DepLoc = Data.DepLoc; 19874 if (DSAStack->getCurrentDirective() == OMPD_ordered && 19875 DepKind != OMPC_DEPEND_source && DepKind != OMPC_DEPEND_sink) { 19876 Diag(DepLoc, diag::err_omp_unexpected_clause_value) 19877 << "'source' or 'sink'" << getOpenMPClauseName(OMPC_depend); 19878 return nullptr; 19879 } 19880 if (DSAStack->getCurrentDirective() == OMPD_taskwait && 19881 DepKind == OMPC_DEPEND_mutexinoutset) { 19882 Diag(DepLoc, diag::err_omp_taskwait_depend_mutexinoutset_not_allowed); 19883 return nullptr; 19884 } 19885 if ((DSAStack->getCurrentDirective() != OMPD_ordered || 19886 DSAStack->getCurrentDirective() == OMPD_depobj) && 19887 (DepKind == OMPC_DEPEND_unknown || DepKind == OMPC_DEPEND_source || 19888 DepKind == OMPC_DEPEND_sink || 19889 ((LangOpts.OpenMP < 50 || 19890 DSAStack->getCurrentDirective() == OMPD_depobj) && 19891 DepKind == OMPC_DEPEND_depobj))) { 19892 SmallVector<unsigned, 6> Except = {OMPC_DEPEND_source, OMPC_DEPEND_sink, 19893 OMPC_DEPEND_outallmemory, 19894 OMPC_DEPEND_inoutallmemory}; 19895 if (LangOpts.OpenMP < 50 || DSAStack->getCurrentDirective() == OMPD_depobj) 19896 Except.push_back(OMPC_DEPEND_depobj); 19897 if (LangOpts.OpenMP < 51) 19898 Except.push_back(OMPC_DEPEND_inoutset); 19899 std::string Expected = (LangOpts.OpenMP >= 50 && !DepModifier) 19900 ? "depend modifier(iterator) or " 19901 : ""; 19902 Diag(DepLoc, diag::err_omp_unexpected_clause_value) 19903 << Expected + getListOfPossibleValues(OMPC_depend, /*First=*/0, 19904 /*Last=*/OMPC_DEPEND_unknown, 19905 Except) 19906 << getOpenMPClauseName(OMPC_depend); 19907 return nullptr; 19908 } 19909 if (DepModifier && 19910 (DepKind == OMPC_DEPEND_source || DepKind == OMPC_DEPEND_sink)) { 19911 Diag(DepModifier->getExprLoc(), 19912 diag::err_omp_depend_sink_source_with_modifier); 19913 return nullptr; 19914 } 19915 if (DepModifier && 19916 !DepModifier->getType()->isSpecificBuiltinType(BuiltinType::OMPIterator)) 19917 Diag(DepModifier->getExprLoc(), diag::err_omp_depend_modifier_not_iterator); 19918 19919 SmallVector<Expr *, 8> Vars; 19920 DSAStackTy::OperatorOffsetTy OpsOffs; 19921 llvm::APSInt DepCounter(/*BitWidth=*/32); 19922 llvm::APSInt TotalDepCount(/*BitWidth=*/32); 19923 if (DepKind == OMPC_DEPEND_sink || DepKind == OMPC_DEPEND_source) { 19924 if (const Expr *OrderedCountExpr = 19925 DSAStack->getParentOrderedRegionParam().first) { 19926 TotalDepCount = OrderedCountExpr->EvaluateKnownConstInt(Context); 19927 TotalDepCount.setIsUnsigned(/*Val=*/true); 19928 } 19929 } 19930 for (Expr *RefExpr : VarList) { 19931 assert(RefExpr && "NULL expr in OpenMP shared clause."); 19932 if (isa<DependentScopeDeclRefExpr>(RefExpr)) { 19933 // It will be analyzed later. 19934 Vars.push_back(RefExpr); 19935 continue; 19936 } 19937 19938 SourceLocation ELoc = RefExpr->getExprLoc(); 19939 Expr *SimpleExpr = RefExpr->IgnoreParenCasts(); 19940 if (DepKind == OMPC_DEPEND_sink) { 19941 if (DSAStack->getParentOrderedRegionParam().first && 19942 DepCounter >= TotalDepCount) { 19943 Diag(ELoc, diag::err_omp_depend_sink_unexpected_expr); 19944 continue; 19945 } 19946 ++DepCounter; 19947 // OpenMP [2.13.9, Summary] 19948 // depend(dependence-type : vec), where dependence-type is: 19949 // 'sink' and where vec is the iteration vector, which has the form: 19950 // x1 [+- d1], x2 [+- d2 ], . . . , xn [+- dn] 19951 // where n is the value specified by the ordered clause in the loop 19952 // directive, xi denotes the loop iteration variable of the i-th nested 19953 // loop associated with the loop directive, and di is a constant 19954 // non-negative integer. 19955 if (CurContext->isDependentContext()) { 19956 // It will be analyzed later. 19957 Vars.push_back(RefExpr); 19958 continue; 19959 } 19960 SimpleExpr = SimpleExpr->IgnoreImplicit(); 19961 OverloadedOperatorKind OOK = OO_None; 19962 SourceLocation OOLoc; 19963 Expr *LHS = SimpleExpr; 19964 Expr *RHS = nullptr; 19965 if (auto *BO = dyn_cast<BinaryOperator>(SimpleExpr)) { 19966 OOK = BinaryOperator::getOverloadedOperator(BO->getOpcode()); 19967 OOLoc = BO->getOperatorLoc(); 19968 LHS = BO->getLHS()->IgnoreParenImpCasts(); 19969 RHS = BO->getRHS()->IgnoreParenImpCasts(); 19970 } else if (auto *OCE = dyn_cast<CXXOperatorCallExpr>(SimpleExpr)) { 19971 OOK = OCE->getOperator(); 19972 OOLoc = OCE->getOperatorLoc(); 19973 LHS = OCE->getArg(/*Arg=*/0)->IgnoreParenImpCasts(); 19974 RHS = OCE->getArg(/*Arg=*/1)->IgnoreParenImpCasts(); 19975 } else if (auto *MCE = dyn_cast<CXXMemberCallExpr>(SimpleExpr)) { 19976 OOK = MCE->getMethodDecl() 19977 ->getNameInfo() 19978 .getName() 19979 .getCXXOverloadedOperator(); 19980 OOLoc = MCE->getCallee()->getExprLoc(); 19981 LHS = MCE->getImplicitObjectArgument()->IgnoreParenImpCasts(); 19982 RHS = MCE->getArg(/*Arg=*/0)->IgnoreParenImpCasts(); 19983 } 19984 SourceLocation ELoc; 19985 SourceRange ERange; 19986 auto Res = getPrivateItem(*this, LHS, ELoc, ERange); 19987 if (Res.second) { 19988 // It will be analyzed later. 19989 Vars.push_back(RefExpr); 19990 } 19991 ValueDecl *D = Res.first; 19992 if (!D) 19993 continue; 19994 19995 if (OOK != OO_Plus && OOK != OO_Minus && (RHS || OOK != OO_None)) { 19996 Diag(OOLoc, diag::err_omp_depend_sink_expected_plus_minus); 19997 continue; 19998 } 19999 if (RHS) { 20000 ExprResult RHSRes = VerifyPositiveIntegerConstantInClause( 20001 RHS, OMPC_depend, /*StrictlyPositive=*/false); 20002 if (RHSRes.isInvalid()) 20003 continue; 20004 } 20005 if (!CurContext->isDependentContext() && 20006 DSAStack->getParentOrderedRegionParam().first && 20007 DepCounter != DSAStack->isParentLoopControlVariable(D).first) { 20008 const ValueDecl *VD = 20009 DSAStack->getParentLoopControlVariable(DepCounter.getZExtValue()); 20010 if (VD) 20011 Diag(ELoc, diag::err_omp_depend_sink_expected_loop_iteration) 20012 << 1 << VD; 20013 else 20014 Diag(ELoc, diag::err_omp_depend_sink_expected_loop_iteration) << 0; 20015 continue; 20016 } 20017 OpsOffs.emplace_back(RHS, OOK); 20018 } else { 20019 bool OMPDependTFound = LangOpts.OpenMP >= 50; 20020 if (OMPDependTFound) 20021 OMPDependTFound = findOMPDependT(*this, StartLoc, DSAStack, 20022 DepKind == OMPC_DEPEND_depobj); 20023 if (DepKind == OMPC_DEPEND_depobj) { 20024 // OpenMP 5.0, 2.17.11 depend Clause, Restrictions, C/C++ 20025 // List items used in depend clauses with the depobj dependence type 20026 // must be expressions of the omp_depend_t type. 20027 if (!RefExpr->isValueDependent() && !RefExpr->isTypeDependent() && 20028 !RefExpr->isInstantiationDependent() && 20029 !RefExpr->containsUnexpandedParameterPack() && 20030 (OMPDependTFound && 20031 !Context.hasSameUnqualifiedType(DSAStack->getOMPDependT(), 20032 RefExpr->getType()))) { 20033 Diag(ELoc, diag::err_omp_expected_omp_depend_t_lvalue) 20034 << 0 << RefExpr->getType() << RefExpr->getSourceRange(); 20035 continue; 20036 } 20037 if (!RefExpr->isLValue()) { 20038 Diag(ELoc, diag::err_omp_expected_omp_depend_t_lvalue) 20039 << 1 << RefExpr->getType() << RefExpr->getSourceRange(); 20040 continue; 20041 } 20042 } else { 20043 // OpenMP 5.0 [2.17.11, Restrictions] 20044 // List items used in depend clauses cannot be zero-length array 20045 // sections. 20046 QualType ExprTy = RefExpr->getType().getNonReferenceType(); 20047 const auto *OASE = dyn_cast<OMPArraySectionExpr>(SimpleExpr); 20048 if (OASE) { 20049 QualType BaseType = 20050 OMPArraySectionExpr::getBaseOriginalType(OASE->getBase()); 20051 if (const auto *ATy = BaseType->getAsArrayTypeUnsafe()) 20052 ExprTy = ATy->getElementType(); 20053 else 20054 ExprTy = BaseType->getPointeeType(); 20055 ExprTy = ExprTy.getNonReferenceType(); 20056 const Expr *Length = OASE->getLength(); 20057 Expr::EvalResult Result; 20058 if (Length && !Length->isValueDependent() && 20059 Length->EvaluateAsInt(Result, Context) && 20060 Result.Val.getInt().isZero()) { 20061 Diag(ELoc, 20062 diag::err_omp_depend_zero_length_array_section_not_allowed) 20063 << SimpleExpr->getSourceRange(); 20064 continue; 20065 } 20066 } 20067 20068 // OpenMP 5.0, 2.17.11 depend Clause, Restrictions, C/C++ 20069 // List items used in depend clauses with the in, out, inout, 20070 // inoutset, or mutexinoutset dependence types cannot be 20071 // expressions of the omp_depend_t type. 20072 if (!RefExpr->isValueDependent() && !RefExpr->isTypeDependent() && 20073 !RefExpr->isInstantiationDependent() && 20074 !RefExpr->containsUnexpandedParameterPack() && 20075 (!RefExpr->IgnoreParenImpCasts()->isLValue() || 20076 (OMPDependTFound && 20077 DSAStack->getOMPDependT().getTypePtr() == ExprTy.getTypePtr()))) { 20078 Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item) 20079 << (LangOpts.OpenMP >= 50 ? 1 : 0) 20080 << (LangOpts.OpenMP >= 50 ? 1 : 0) << RefExpr->getSourceRange(); 20081 continue; 20082 } 20083 20084 auto *ASE = dyn_cast<ArraySubscriptExpr>(SimpleExpr); 20085 if (ASE && !ASE->getBase()->isTypeDependent() && 20086 !ASE->getBase()->getType().getNonReferenceType()->isPointerType() && 20087 !ASE->getBase()->getType().getNonReferenceType()->isArrayType()) { 20088 Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item) 20089 << (LangOpts.OpenMP >= 50 ? 1 : 0) 20090 << (LangOpts.OpenMP >= 50 ? 1 : 0) << RefExpr->getSourceRange(); 20091 continue; 20092 } 20093 20094 ExprResult Res; 20095 { 20096 Sema::TentativeAnalysisScope Trap(*this); 20097 Res = CreateBuiltinUnaryOp(ELoc, UO_AddrOf, 20098 RefExpr->IgnoreParenImpCasts()); 20099 } 20100 if (!Res.isUsable() && !isa<OMPArraySectionExpr>(SimpleExpr) && 20101 !isa<OMPArrayShapingExpr>(SimpleExpr)) { 20102 Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item) 20103 << (LangOpts.OpenMP >= 50 ? 1 : 0) 20104 << (LangOpts.OpenMP >= 50 ? 1 : 0) << RefExpr->getSourceRange(); 20105 continue; 20106 } 20107 } 20108 } 20109 Vars.push_back(RefExpr->IgnoreParenImpCasts()); 20110 } 20111 20112 if (!CurContext->isDependentContext() && DepKind == OMPC_DEPEND_sink && 20113 TotalDepCount > VarList.size() && 20114 DSAStack->getParentOrderedRegionParam().first && 20115 DSAStack->getParentLoopControlVariable(VarList.size() + 1)) { 20116 Diag(EndLoc, diag::err_omp_depend_sink_expected_loop_iteration) 20117 << 1 << DSAStack->getParentLoopControlVariable(VarList.size() + 1); 20118 } 20119 if (DepKind != OMPC_DEPEND_source && DepKind != OMPC_DEPEND_sink && 20120 DepKind != OMPC_DEPEND_outallmemory && 20121 DepKind != OMPC_DEPEND_inoutallmemory && Vars.empty()) 20122 return nullptr; 20123 20124 auto *C = OMPDependClause::Create( 20125 Context, StartLoc, LParenLoc, EndLoc, 20126 {DepKind, DepLoc, Data.ColonLoc, Data.OmpAllMemoryLoc}, DepModifier, Vars, 20127 TotalDepCount.getZExtValue()); 20128 if ((DepKind == OMPC_DEPEND_sink || DepKind == OMPC_DEPEND_source) && 20129 DSAStack->isParentOrderedRegion()) 20130 DSAStack->addDoacrossDependClause(C, OpsOffs); 20131 return C; 20132 } 20133 20134 OMPClause *Sema::ActOnOpenMPDeviceClause(OpenMPDeviceClauseModifier Modifier, 20135 Expr *Device, SourceLocation StartLoc, 20136 SourceLocation LParenLoc, 20137 SourceLocation ModifierLoc, 20138 SourceLocation EndLoc) { 20139 assert((ModifierLoc.isInvalid() || LangOpts.OpenMP >= 50) && 20140 "Unexpected device modifier in OpenMP < 50."); 20141 20142 bool ErrorFound = false; 20143 if (ModifierLoc.isValid() && Modifier == OMPC_DEVICE_unknown) { 20144 std::string Values = 20145 getListOfPossibleValues(OMPC_device, /*First=*/0, OMPC_DEVICE_unknown); 20146 Diag(ModifierLoc, diag::err_omp_unexpected_clause_value) 20147 << Values << getOpenMPClauseName(OMPC_device); 20148 ErrorFound = true; 20149 } 20150 20151 Expr *ValExpr = Device; 20152 Stmt *HelperValStmt = nullptr; 20153 20154 // OpenMP [2.9.1, Restrictions] 20155 // The device expression must evaluate to a non-negative integer value. 20156 ErrorFound = !isNonNegativeIntegerValue(ValExpr, *this, OMPC_device, 20157 /*StrictlyPositive=*/false) || 20158 ErrorFound; 20159 if (ErrorFound) 20160 return nullptr; 20161 20162 // OpenMP 5.0 [2.12.5, Restrictions] 20163 // In case of ancestor device-modifier, a requires directive with 20164 // the reverse_offload clause must be specified. 20165 if (Modifier == OMPC_DEVICE_ancestor) { 20166 if (!DSAStack->hasRequiresDeclWithClause<OMPReverseOffloadClause>()) { 20167 targetDiag( 20168 StartLoc, 20169 diag::err_omp_device_ancestor_without_requires_reverse_offload); 20170 ErrorFound = true; 20171 } 20172 } 20173 20174 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 20175 OpenMPDirectiveKind CaptureRegion = 20176 getOpenMPCaptureRegionForClause(DKind, OMPC_device, LangOpts.OpenMP); 20177 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 20178 ValExpr = MakeFullExpr(ValExpr).get(); 20179 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 20180 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 20181 HelperValStmt = buildPreInits(Context, Captures); 20182 } 20183 20184 return new (Context) 20185 OMPDeviceClause(Modifier, ValExpr, HelperValStmt, CaptureRegion, StartLoc, 20186 LParenLoc, ModifierLoc, EndLoc); 20187 } 20188 20189 static bool checkTypeMappable(SourceLocation SL, SourceRange SR, Sema &SemaRef, 20190 DSAStackTy *Stack, QualType QTy, 20191 bool FullCheck = true) { 20192 if (SemaRef.RequireCompleteType(SL, QTy, diag::err_incomplete_type)) 20193 return false; 20194 if (FullCheck && !SemaRef.CurContext->isDependentContext() && 20195 !QTy.isTriviallyCopyableType(SemaRef.Context)) 20196 SemaRef.Diag(SL, diag::warn_omp_non_trivial_type_mapped) << QTy << SR; 20197 return true; 20198 } 20199 20200 /// Return true if it can be proven that the provided array expression 20201 /// (array section or array subscript) does NOT specify the whole size of the 20202 /// array whose base type is \a BaseQTy. 20203 static bool checkArrayExpressionDoesNotReferToWholeSize(Sema &SemaRef, 20204 const Expr *E, 20205 QualType BaseQTy) { 20206 const auto *OASE = dyn_cast<OMPArraySectionExpr>(E); 20207 20208 // If this is an array subscript, it refers to the whole size if the size of 20209 // the dimension is constant and equals 1. Also, an array section assumes the 20210 // format of an array subscript if no colon is used. 20211 if (isa<ArraySubscriptExpr>(E) || 20212 (OASE && OASE->getColonLocFirst().isInvalid())) { 20213 if (const auto *ATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr())) 20214 return ATy->getSize().getSExtValue() != 1; 20215 // Size can't be evaluated statically. 20216 return false; 20217 } 20218 20219 assert(OASE && "Expecting array section if not an array subscript."); 20220 const Expr *LowerBound = OASE->getLowerBound(); 20221 const Expr *Length = OASE->getLength(); 20222 20223 // If there is a lower bound that does not evaluates to zero, we are not 20224 // covering the whole dimension. 20225 if (LowerBound) { 20226 Expr::EvalResult Result; 20227 if (!LowerBound->EvaluateAsInt(Result, SemaRef.getASTContext())) 20228 return false; // Can't get the integer value as a constant. 20229 20230 llvm::APSInt ConstLowerBound = Result.Val.getInt(); 20231 if (ConstLowerBound.getSExtValue()) 20232 return true; 20233 } 20234 20235 // If we don't have a length we covering the whole dimension. 20236 if (!Length) 20237 return false; 20238 20239 // If the base is a pointer, we don't have a way to get the size of the 20240 // pointee. 20241 if (BaseQTy->isPointerType()) 20242 return false; 20243 20244 // We can only check if the length is the same as the size of the dimension 20245 // if we have a constant array. 20246 const auto *CATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr()); 20247 if (!CATy) 20248 return false; 20249 20250 Expr::EvalResult Result; 20251 if (!Length->EvaluateAsInt(Result, SemaRef.getASTContext())) 20252 return false; // Can't get the integer value as a constant. 20253 20254 llvm::APSInt ConstLength = Result.Val.getInt(); 20255 return CATy->getSize().getSExtValue() != ConstLength.getSExtValue(); 20256 } 20257 20258 // Return true if it can be proven that the provided array expression (array 20259 // section or array subscript) does NOT specify a single element of the array 20260 // whose base type is \a BaseQTy. 20261 static bool checkArrayExpressionDoesNotReferToUnitySize(Sema &SemaRef, 20262 const Expr *E, 20263 QualType BaseQTy) { 20264 const auto *OASE = dyn_cast<OMPArraySectionExpr>(E); 20265 20266 // An array subscript always refer to a single element. Also, an array section 20267 // assumes the format of an array subscript if no colon is used. 20268 if (isa<ArraySubscriptExpr>(E) || 20269 (OASE && OASE->getColonLocFirst().isInvalid())) 20270 return false; 20271 20272 assert(OASE && "Expecting array section if not an array subscript."); 20273 const Expr *Length = OASE->getLength(); 20274 20275 // If we don't have a length we have to check if the array has unitary size 20276 // for this dimension. Also, we should always expect a length if the base type 20277 // is pointer. 20278 if (!Length) { 20279 if (const auto *ATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr())) 20280 return ATy->getSize().getSExtValue() != 1; 20281 // We cannot assume anything. 20282 return false; 20283 } 20284 20285 // Check if the length evaluates to 1. 20286 Expr::EvalResult Result; 20287 if (!Length->EvaluateAsInt(Result, SemaRef.getASTContext())) 20288 return false; // Can't get the integer value as a constant. 20289 20290 llvm::APSInt ConstLength = Result.Val.getInt(); 20291 return ConstLength.getSExtValue() != 1; 20292 } 20293 20294 // The base of elements of list in a map clause have to be either: 20295 // - a reference to variable or field. 20296 // - a member expression. 20297 // - an array expression. 20298 // 20299 // E.g. if we have the expression 'r.S.Arr[:12]', we want to retrieve the 20300 // reference to 'r'. 20301 // 20302 // If we have: 20303 // 20304 // struct SS { 20305 // Bla S; 20306 // foo() { 20307 // #pragma omp target map (S.Arr[:12]); 20308 // } 20309 // } 20310 // 20311 // We want to retrieve the member expression 'this->S'; 20312 20313 // OpenMP 5.0 [2.19.7.1, map Clause, Restrictions, p.2] 20314 // If a list item is an array section, it must specify contiguous storage. 20315 // 20316 // For this restriction it is sufficient that we make sure only references 20317 // to variables or fields and array expressions, and that no array sections 20318 // exist except in the rightmost expression (unless they cover the whole 20319 // dimension of the array). E.g. these would be invalid: 20320 // 20321 // r.ArrS[3:5].Arr[6:7] 20322 // 20323 // r.ArrS[3:5].x 20324 // 20325 // but these would be valid: 20326 // r.ArrS[3].Arr[6:7] 20327 // 20328 // r.ArrS[3].x 20329 namespace { 20330 class MapBaseChecker final : public StmtVisitor<MapBaseChecker, bool> { 20331 Sema &SemaRef; 20332 OpenMPClauseKind CKind = OMPC_unknown; 20333 OpenMPDirectiveKind DKind = OMPD_unknown; 20334 OMPClauseMappableExprCommon::MappableExprComponentList &Components; 20335 bool IsNonContiguous = false; 20336 bool NoDiagnose = false; 20337 const Expr *RelevantExpr = nullptr; 20338 bool AllowUnitySizeArraySection = true; 20339 bool AllowWholeSizeArraySection = true; 20340 bool AllowAnotherPtr = true; 20341 SourceLocation ELoc; 20342 SourceRange ERange; 20343 20344 void emitErrorMsg() { 20345 // If nothing else worked, this is not a valid map clause expression. 20346 if (SemaRef.getLangOpts().OpenMP < 50) { 20347 SemaRef.Diag(ELoc, 20348 diag::err_omp_expected_named_var_member_or_array_expression) 20349 << ERange; 20350 } else { 20351 SemaRef.Diag(ELoc, diag::err_omp_non_lvalue_in_map_or_motion_clauses) 20352 << getOpenMPClauseName(CKind) << ERange; 20353 } 20354 } 20355 20356 public: 20357 bool VisitDeclRefExpr(DeclRefExpr *DRE) { 20358 if (!isa<VarDecl>(DRE->getDecl())) { 20359 emitErrorMsg(); 20360 return false; 20361 } 20362 assert(!RelevantExpr && "RelevantExpr is expected to be nullptr"); 20363 RelevantExpr = DRE; 20364 // Record the component. 20365 Components.emplace_back(DRE, DRE->getDecl(), IsNonContiguous); 20366 return true; 20367 } 20368 20369 bool VisitMemberExpr(MemberExpr *ME) { 20370 Expr *E = ME; 20371 Expr *BaseE = ME->getBase()->IgnoreParenCasts(); 20372 20373 if (isa<CXXThisExpr>(BaseE)) { 20374 assert(!RelevantExpr && "RelevantExpr is expected to be nullptr"); 20375 // We found a base expression: this->Val. 20376 RelevantExpr = ME; 20377 } else { 20378 E = BaseE; 20379 } 20380 20381 if (!isa<FieldDecl>(ME->getMemberDecl())) { 20382 if (!NoDiagnose) { 20383 SemaRef.Diag(ELoc, diag::err_omp_expected_access_to_data_field) 20384 << ME->getSourceRange(); 20385 return false; 20386 } 20387 if (RelevantExpr) 20388 return false; 20389 return Visit(E); 20390 } 20391 20392 auto *FD = cast<FieldDecl>(ME->getMemberDecl()); 20393 20394 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.3] 20395 // A bit-field cannot appear in a map clause. 20396 // 20397 if (FD->isBitField()) { 20398 if (!NoDiagnose) { 20399 SemaRef.Diag(ELoc, diag::err_omp_bit_fields_forbidden_in_clause) 20400 << ME->getSourceRange() << getOpenMPClauseName(CKind); 20401 return false; 20402 } 20403 if (RelevantExpr) 20404 return false; 20405 return Visit(E); 20406 } 20407 20408 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1] 20409 // If the type of a list item is a reference to a type T then the type 20410 // will be considered to be T for all purposes of this clause. 20411 QualType CurType = BaseE->getType().getNonReferenceType(); 20412 20413 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.2] 20414 // A list item cannot be a variable that is a member of a structure with 20415 // a union type. 20416 // 20417 if (CurType->isUnionType()) { 20418 if (!NoDiagnose) { 20419 SemaRef.Diag(ELoc, diag::err_omp_union_type_not_allowed) 20420 << ME->getSourceRange(); 20421 return false; 20422 } 20423 return RelevantExpr || Visit(E); 20424 } 20425 20426 // If we got a member expression, we should not expect any array section 20427 // before that: 20428 // 20429 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.7] 20430 // If a list item is an element of a structure, only the rightmost symbol 20431 // of the variable reference can be an array section. 20432 // 20433 AllowUnitySizeArraySection = false; 20434 AllowWholeSizeArraySection = false; 20435 20436 // Record the component. 20437 Components.emplace_back(ME, FD, IsNonContiguous); 20438 return RelevantExpr || Visit(E); 20439 } 20440 20441 bool VisitArraySubscriptExpr(ArraySubscriptExpr *AE) { 20442 Expr *E = AE->getBase()->IgnoreParenImpCasts(); 20443 20444 if (!E->getType()->isAnyPointerType() && !E->getType()->isArrayType()) { 20445 if (!NoDiagnose) { 20446 SemaRef.Diag(ELoc, diag::err_omp_expected_base_var_name) 20447 << 0 << AE->getSourceRange(); 20448 return false; 20449 } 20450 return RelevantExpr || Visit(E); 20451 } 20452 20453 // If we got an array subscript that express the whole dimension we 20454 // can have any array expressions before. If it only expressing part of 20455 // the dimension, we can only have unitary-size array expressions. 20456 if (checkArrayExpressionDoesNotReferToWholeSize(SemaRef, AE, E->getType())) 20457 AllowWholeSizeArraySection = false; 20458 20459 if (const auto *TE = dyn_cast<CXXThisExpr>(E->IgnoreParenCasts())) { 20460 Expr::EvalResult Result; 20461 if (!AE->getIdx()->isValueDependent() && 20462 AE->getIdx()->EvaluateAsInt(Result, SemaRef.getASTContext()) && 20463 !Result.Val.getInt().isZero()) { 20464 SemaRef.Diag(AE->getIdx()->getExprLoc(), 20465 diag::err_omp_invalid_map_this_expr); 20466 SemaRef.Diag(AE->getIdx()->getExprLoc(), 20467 diag::note_omp_invalid_subscript_on_this_ptr_map); 20468 } 20469 assert(!RelevantExpr && "RelevantExpr is expected to be nullptr"); 20470 RelevantExpr = TE; 20471 } 20472 20473 // Record the component - we don't have any declaration associated. 20474 Components.emplace_back(AE, nullptr, IsNonContiguous); 20475 20476 return RelevantExpr || Visit(E); 20477 } 20478 20479 bool VisitOMPArraySectionExpr(OMPArraySectionExpr *OASE) { 20480 // After OMP 5.0 Array section in reduction clause will be implicitly 20481 // mapped 20482 assert(!(SemaRef.getLangOpts().OpenMP < 50 && NoDiagnose) && 20483 "Array sections cannot be implicitly mapped."); 20484 Expr *E = OASE->getBase()->IgnoreParenImpCasts(); 20485 QualType CurType = 20486 OMPArraySectionExpr::getBaseOriginalType(E).getCanonicalType(); 20487 20488 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1] 20489 // If the type of a list item is a reference to a type T then the type 20490 // will be considered to be T for all purposes of this clause. 20491 if (CurType->isReferenceType()) 20492 CurType = CurType->getPointeeType(); 20493 20494 bool IsPointer = CurType->isAnyPointerType(); 20495 20496 if (!IsPointer && !CurType->isArrayType()) { 20497 SemaRef.Diag(ELoc, diag::err_omp_expected_base_var_name) 20498 << 0 << OASE->getSourceRange(); 20499 return false; 20500 } 20501 20502 bool NotWhole = 20503 checkArrayExpressionDoesNotReferToWholeSize(SemaRef, OASE, CurType); 20504 bool NotUnity = 20505 checkArrayExpressionDoesNotReferToUnitySize(SemaRef, OASE, CurType); 20506 20507 if (AllowWholeSizeArraySection) { 20508 // Any array section is currently allowed. Allowing a whole size array 20509 // section implies allowing a unity array section as well. 20510 // 20511 // If this array section refers to the whole dimension we can still 20512 // accept other array sections before this one, except if the base is a 20513 // pointer. Otherwise, only unitary sections are accepted. 20514 if (NotWhole || IsPointer) 20515 AllowWholeSizeArraySection = false; 20516 } else if (DKind == OMPD_target_update && 20517 SemaRef.getLangOpts().OpenMP >= 50) { 20518 if (IsPointer && !AllowAnotherPtr) 20519 SemaRef.Diag(ELoc, diag::err_omp_section_length_undefined) 20520 << /*array of unknown bound */ 1; 20521 else 20522 IsNonContiguous = true; 20523 } else if (AllowUnitySizeArraySection && NotUnity) { 20524 // A unity or whole array section is not allowed and that is not 20525 // compatible with the properties of the current array section. 20526 if (NoDiagnose) 20527 return false; 20528 SemaRef.Diag(ELoc, 20529 diag::err_array_section_does_not_specify_contiguous_storage) 20530 << OASE->getSourceRange(); 20531 return false; 20532 } 20533 20534 if (IsPointer) 20535 AllowAnotherPtr = false; 20536 20537 if (const auto *TE = dyn_cast<CXXThisExpr>(E)) { 20538 Expr::EvalResult ResultR; 20539 Expr::EvalResult ResultL; 20540 if (!OASE->getLength()->isValueDependent() && 20541 OASE->getLength()->EvaluateAsInt(ResultR, SemaRef.getASTContext()) && 20542 !ResultR.Val.getInt().isOne()) { 20543 SemaRef.Diag(OASE->getLength()->getExprLoc(), 20544 diag::err_omp_invalid_map_this_expr); 20545 SemaRef.Diag(OASE->getLength()->getExprLoc(), 20546 diag::note_omp_invalid_length_on_this_ptr_mapping); 20547 } 20548 if (OASE->getLowerBound() && !OASE->getLowerBound()->isValueDependent() && 20549 OASE->getLowerBound()->EvaluateAsInt(ResultL, 20550 SemaRef.getASTContext()) && 20551 !ResultL.Val.getInt().isZero()) { 20552 SemaRef.Diag(OASE->getLowerBound()->getExprLoc(), 20553 diag::err_omp_invalid_map_this_expr); 20554 SemaRef.Diag(OASE->getLowerBound()->getExprLoc(), 20555 diag::note_omp_invalid_lower_bound_on_this_ptr_mapping); 20556 } 20557 assert(!RelevantExpr && "RelevantExpr is expected to be nullptr"); 20558 RelevantExpr = TE; 20559 } 20560 20561 // Record the component - we don't have any declaration associated. 20562 Components.emplace_back(OASE, nullptr, /*IsNonContiguous=*/false); 20563 return RelevantExpr || Visit(E); 20564 } 20565 bool VisitOMPArrayShapingExpr(OMPArrayShapingExpr *E) { 20566 Expr *Base = E->getBase(); 20567 20568 // Record the component - we don't have any declaration associated. 20569 Components.emplace_back(E, nullptr, IsNonContiguous); 20570 20571 return Visit(Base->IgnoreParenImpCasts()); 20572 } 20573 20574 bool VisitUnaryOperator(UnaryOperator *UO) { 20575 if (SemaRef.getLangOpts().OpenMP < 50 || !UO->isLValue() || 20576 UO->getOpcode() != UO_Deref) { 20577 emitErrorMsg(); 20578 return false; 20579 } 20580 if (!RelevantExpr) { 20581 // Record the component if haven't found base decl. 20582 Components.emplace_back(UO, nullptr, /*IsNonContiguous=*/false); 20583 } 20584 return RelevantExpr || Visit(UO->getSubExpr()->IgnoreParenImpCasts()); 20585 } 20586 bool VisitBinaryOperator(BinaryOperator *BO) { 20587 if (SemaRef.getLangOpts().OpenMP < 50 || !BO->getType()->isPointerType()) { 20588 emitErrorMsg(); 20589 return false; 20590 } 20591 20592 // Pointer arithmetic is the only thing we expect to happen here so after we 20593 // make sure the binary operator is a pointer type, the we only thing need 20594 // to to is to visit the subtree that has the same type as root (so that we 20595 // know the other subtree is just an offset) 20596 Expr *LE = BO->getLHS()->IgnoreParenImpCasts(); 20597 Expr *RE = BO->getRHS()->IgnoreParenImpCasts(); 20598 Components.emplace_back(BO, nullptr, false); 20599 assert((LE->getType().getTypePtr() == BO->getType().getTypePtr() || 20600 RE->getType().getTypePtr() == BO->getType().getTypePtr()) && 20601 "Either LHS or RHS have base decl inside"); 20602 if (BO->getType().getTypePtr() == LE->getType().getTypePtr()) 20603 return RelevantExpr || Visit(LE); 20604 return RelevantExpr || Visit(RE); 20605 } 20606 bool VisitCXXThisExpr(CXXThisExpr *CTE) { 20607 assert(!RelevantExpr && "RelevantExpr is expected to be nullptr"); 20608 RelevantExpr = CTE; 20609 Components.emplace_back(CTE, nullptr, IsNonContiguous); 20610 return true; 20611 } 20612 bool VisitCXXOperatorCallExpr(CXXOperatorCallExpr *COCE) { 20613 assert(!RelevantExpr && "RelevantExpr is expected to be nullptr"); 20614 Components.emplace_back(COCE, nullptr, IsNonContiguous); 20615 return true; 20616 } 20617 bool VisitOpaqueValueExpr(OpaqueValueExpr *E) { 20618 Expr *Source = E->getSourceExpr(); 20619 if (!Source) { 20620 emitErrorMsg(); 20621 return false; 20622 } 20623 return Visit(Source); 20624 } 20625 bool VisitStmt(Stmt *) { 20626 emitErrorMsg(); 20627 return false; 20628 } 20629 const Expr *getFoundBase() const { return RelevantExpr; } 20630 explicit MapBaseChecker( 20631 Sema &SemaRef, OpenMPClauseKind CKind, OpenMPDirectiveKind DKind, 20632 OMPClauseMappableExprCommon::MappableExprComponentList &Components, 20633 bool NoDiagnose, SourceLocation &ELoc, SourceRange &ERange) 20634 : SemaRef(SemaRef), CKind(CKind), DKind(DKind), Components(Components), 20635 NoDiagnose(NoDiagnose), ELoc(ELoc), ERange(ERange) {} 20636 }; 20637 } // namespace 20638 20639 /// Return the expression of the base of the mappable expression or null if it 20640 /// cannot be determined and do all the necessary checks to see if the 20641 /// expression is valid as a standalone mappable expression. In the process, 20642 /// record all the components of the expression. 20643 static const Expr *checkMapClauseExpressionBase( 20644 Sema &SemaRef, Expr *E, 20645 OMPClauseMappableExprCommon::MappableExprComponentList &CurComponents, 20646 OpenMPClauseKind CKind, OpenMPDirectiveKind DKind, bool NoDiagnose) { 20647 SourceLocation ELoc = E->getExprLoc(); 20648 SourceRange ERange = E->getSourceRange(); 20649 MapBaseChecker Checker(SemaRef, CKind, DKind, CurComponents, NoDiagnose, ELoc, 20650 ERange); 20651 if (Checker.Visit(E->IgnoreParens())) { 20652 // Check if the highest dimension array section has length specified 20653 if (SemaRef.getLangOpts().OpenMP >= 50 && !CurComponents.empty() && 20654 (CKind == OMPC_to || CKind == OMPC_from)) { 20655 auto CI = CurComponents.rbegin(); 20656 auto CE = CurComponents.rend(); 20657 for (; CI != CE; ++CI) { 20658 const auto *OASE = 20659 dyn_cast<OMPArraySectionExpr>(CI->getAssociatedExpression()); 20660 if (!OASE) 20661 continue; 20662 if (OASE && OASE->getLength()) 20663 break; 20664 SemaRef.Diag(ELoc, diag::err_array_section_does_not_specify_length) 20665 << ERange; 20666 } 20667 } 20668 return Checker.getFoundBase(); 20669 } 20670 return nullptr; 20671 } 20672 20673 // Return true if expression E associated with value VD has conflicts with other 20674 // map information. 20675 static bool checkMapConflicts( 20676 Sema &SemaRef, DSAStackTy *DSAS, const ValueDecl *VD, const Expr *E, 20677 bool CurrentRegionOnly, 20678 OMPClauseMappableExprCommon::MappableExprComponentListRef CurComponents, 20679 OpenMPClauseKind CKind) { 20680 assert(VD && E); 20681 SourceLocation ELoc = E->getExprLoc(); 20682 SourceRange ERange = E->getSourceRange(); 20683 20684 // In order to easily check the conflicts we need to match each component of 20685 // the expression under test with the components of the expressions that are 20686 // already in the stack. 20687 20688 assert(!CurComponents.empty() && "Map clause expression with no components!"); 20689 assert(CurComponents.back().getAssociatedDeclaration() == VD && 20690 "Map clause expression with unexpected base!"); 20691 20692 // Variables to help detecting enclosing problems in data environment nests. 20693 bool IsEnclosedByDataEnvironmentExpr = false; 20694 const Expr *EnclosingExpr = nullptr; 20695 20696 bool FoundError = DSAS->checkMappableExprComponentListsForDecl( 20697 VD, CurrentRegionOnly, 20698 [&IsEnclosedByDataEnvironmentExpr, &SemaRef, VD, CurrentRegionOnly, ELoc, 20699 ERange, CKind, &EnclosingExpr, 20700 CurComponents](OMPClauseMappableExprCommon::MappableExprComponentListRef 20701 StackComponents, 20702 OpenMPClauseKind Kind) { 20703 if (CKind == Kind && SemaRef.LangOpts.OpenMP >= 50) 20704 return false; 20705 assert(!StackComponents.empty() && 20706 "Map clause expression with no components!"); 20707 assert(StackComponents.back().getAssociatedDeclaration() == VD && 20708 "Map clause expression with unexpected base!"); 20709 (void)VD; 20710 20711 // The whole expression in the stack. 20712 const Expr *RE = StackComponents.front().getAssociatedExpression(); 20713 20714 // Expressions must start from the same base. Here we detect at which 20715 // point both expressions diverge from each other and see if we can 20716 // detect if the memory referred to both expressions is contiguous and 20717 // do not overlap. 20718 auto CI = CurComponents.rbegin(); 20719 auto CE = CurComponents.rend(); 20720 auto SI = StackComponents.rbegin(); 20721 auto SE = StackComponents.rend(); 20722 for (; CI != CE && SI != SE; ++CI, ++SI) { 20723 20724 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.3] 20725 // At most one list item can be an array item derived from a given 20726 // variable in map clauses of the same construct. 20727 if (CurrentRegionOnly && 20728 (isa<ArraySubscriptExpr>(CI->getAssociatedExpression()) || 20729 isa<OMPArraySectionExpr>(CI->getAssociatedExpression()) || 20730 isa<OMPArrayShapingExpr>(CI->getAssociatedExpression())) && 20731 (isa<ArraySubscriptExpr>(SI->getAssociatedExpression()) || 20732 isa<OMPArraySectionExpr>(SI->getAssociatedExpression()) || 20733 isa<OMPArrayShapingExpr>(SI->getAssociatedExpression()))) { 20734 SemaRef.Diag(CI->getAssociatedExpression()->getExprLoc(), 20735 diag::err_omp_multiple_array_items_in_map_clause) 20736 << CI->getAssociatedExpression()->getSourceRange(); 20737 SemaRef.Diag(SI->getAssociatedExpression()->getExprLoc(), 20738 diag::note_used_here) 20739 << SI->getAssociatedExpression()->getSourceRange(); 20740 return true; 20741 } 20742 20743 // Do both expressions have the same kind? 20744 if (CI->getAssociatedExpression()->getStmtClass() != 20745 SI->getAssociatedExpression()->getStmtClass()) 20746 break; 20747 20748 // Are we dealing with different variables/fields? 20749 if (CI->getAssociatedDeclaration() != SI->getAssociatedDeclaration()) 20750 break; 20751 } 20752 // Check if the extra components of the expressions in the enclosing 20753 // data environment are redundant for the current base declaration. 20754 // If they are, the maps completely overlap, which is legal. 20755 for (; SI != SE; ++SI) { 20756 QualType Type; 20757 if (const auto *ASE = 20758 dyn_cast<ArraySubscriptExpr>(SI->getAssociatedExpression())) { 20759 Type = ASE->getBase()->IgnoreParenImpCasts()->getType(); 20760 } else if (const auto *OASE = dyn_cast<OMPArraySectionExpr>( 20761 SI->getAssociatedExpression())) { 20762 const Expr *E = OASE->getBase()->IgnoreParenImpCasts(); 20763 Type = 20764 OMPArraySectionExpr::getBaseOriginalType(E).getCanonicalType(); 20765 } else if (const auto *OASE = dyn_cast<OMPArrayShapingExpr>( 20766 SI->getAssociatedExpression())) { 20767 Type = OASE->getBase()->getType()->getPointeeType(); 20768 } 20769 if (Type.isNull() || Type->isAnyPointerType() || 20770 checkArrayExpressionDoesNotReferToWholeSize( 20771 SemaRef, SI->getAssociatedExpression(), Type)) 20772 break; 20773 } 20774 20775 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.4] 20776 // List items of map clauses in the same construct must not share 20777 // original storage. 20778 // 20779 // If the expressions are exactly the same or one is a subset of the 20780 // other, it means they are sharing storage. 20781 if (CI == CE && SI == SE) { 20782 if (CurrentRegionOnly) { 20783 if (CKind == OMPC_map) { 20784 SemaRef.Diag(ELoc, diag::err_omp_map_shared_storage) << ERange; 20785 } else { 20786 assert(CKind == OMPC_to || CKind == OMPC_from); 20787 SemaRef.Diag(ELoc, diag::err_omp_once_referenced_in_target_update) 20788 << ERange; 20789 } 20790 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here) 20791 << RE->getSourceRange(); 20792 return true; 20793 } 20794 // If we find the same expression in the enclosing data environment, 20795 // that is legal. 20796 IsEnclosedByDataEnvironmentExpr = true; 20797 return false; 20798 } 20799 20800 QualType DerivedType = 20801 std::prev(CI)->getAssociatedDeclaration()->getType(); 20802 SourceLocation DerivedLoc = 20803 std::prev(CI)->getAssociatedExpression()->getExprLoc(); 20804 20805 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1] 20806 // If the type of a list item is a reference to a type T then the type 20807 // will be considered to be T for all purposes of this clause. 20808 DerivedType = DerivedType.getNonReferenceType(); 20809 20810 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.1] 20811 // A variable for which the type is pointer and an array section 20812 // derived from that variable must not appear as list items of map 20813 // clauses of the same construct. 20814 // 20815 // Also, cover one of the cases in: 20816 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.5] 20817 // If any part of the original storage of a list item has corresponding 20818 // storage in the device data environment, all of the original storage 20819 // must have corresponding storage in the device data environment. 20820 // 20821 if (DerivedType->isAnyPointerType()) { 20822 if (CI == CE || SI == SE) { 20823 SemaRef.Diag( 20824 DerivedLoc, 20825 diag::err_omp_pointer_mapped_along_with_derived_section) 20826 << DerivedLoc; 20827 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here) 20828 << RE->getSourceRange(); 20829 return true; 20830 } 20831 if (CI->getAssociatedExpression()->getStmtClass() != 20832 SI->getAssociatedExpression()->getStmtClass() || 20833 CI->getAssociatedDeclaration()->getCanonicalDecl() == 20834 SI->getAssociatedDeclaration()->getCanonicalDecl()) { 20835 assert(CI != CE && SI != SE); 20836 SemaRef.Diag(DerivedLoc, diag::err_omp_same_pointer_dereferenced) 20837 << DerivedLoc; 20838 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here) 20839 << RE->getSourceRange(); 20840 return true; 20841 } 20842 } 20843 20844 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.4] 20845 // List items of map clauses in the same construct must not share 20846 // original storage. 20847 // 20848 // An expression is a subset of the other. 20849 if (CurrentRegionOnly && (CI == CE || SI == SE)) { 20850 if (CKind == OMPC_map) { 20851 if (CI != CE || SI != SE) { 20852 // Allow constructs like this: map(s, s.ptr[0:1]), where s.ptr is 20853 // a pointer. 20854 auto Begin = 20855 CI != CE ? CurComponents.begin() : StackComponents.begin(); 20856 auto End = CI != CE ? CurComponents.end() : StackComponents.end(); 20857 auto It = Begin; 20858 while (It != End && !It->getAssociatedDeclaration()) 20859 std::advance(It, 1); 20860 assert(It != End && 20861 "Expected at least one component with the declaration."); 20862 if (It != Begin && It->getAssociatedDeclaration() 20863 ->getType() 20864 .getCanonicalType() 20865 ->isAnyPointerType()) { 20866 IsEnclosedByDataEnvironmentExpr = false; 20867 EnclosingExpr = nullptr; 20868 return false; 20869 } 20870 } 20871 SemaRef.Diag(ELoc, diag::err_omp_map_shared_storage) << ERange; 20872 } else { 20873 assert(CKind == OMPC_to || CKind == OMPC_from); 20874 SemaRef.Diag(ELoc, diag::err_omp_once_referenced_in_target_update) 20875 << ERange; 20876 } 20877 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here) 20878 << RE->getSourceRange(); 20879 return true; 20880 } 20881 20882 // The current expression uses the same base as other expression in the 20883 // data environment but does not contain it completely. 20884 if (!CurrentRegionOnly && SI != SE) 20885 EnclosingExpr = RE; 20886 20887 // The current expression is a subset of the expression in the data 20888 // environment. 20889 IsEnclosedByDataEnvironmentExpr |= 20890 (!CurrentRegionOnly && CI != CE && SI == SE); 20891 20892 return false; 20893 }); 20894 20895 if (CurrentRegionOnly) 20896 return FoundError; 20897 20898 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.5] 20899 // If any part of the original storage of a list item has corresponding 20900 // storage in the device data environment, all of the original storage must 20901 // have corresponding storage in the device data environment. 20902 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.6] 20903 // If a list item is an element of a structure, and a different element of 20904 // the structure has a corresponding list item in the device data environment 20905 // prior to a task encountering the construct associated with the map clause, 20906 // then the list item must also have a corresponding list item in the device 20907 // data environment prior to the task encountering the construct. 20908 // 20909 if (EnclosingExpr && !IsEnclosedByDataEnvironmentExpr) { 20910 SemaRef.Diag(ELoc, 20911 diag::err_omp_original_storage_is_shared_and_does_not_contain) 20912 << ERange; 20913 SemaRef.Diag(EnclosingExpr->getExprLoc(), diag::note_used_here) 20914 << EnclosingExpr->getSourceRange(); 20915 return true; 20916 } 20917 20918 return FoundError; 20919 } 20920 20921 // Look up the user-defined mapper given the mapper name and mapped type, and 20922 // build a reference to it. 20923 static ExprResult buildUserDefinedMapperRef(Sema &SemaRef, Scope *S, 20924 CXXScopeSpec &MapperIdScopeSpec, 20925 const DeclarationNameInfo &MapperId, 20926 QualType Type, 20927 Expr *UnresolvedMapper) { 20928 if (MapperIdScopeSpec.isInvalid()) 20929 return ExprError(); 20930 // Get the actual type for the array type. 20931 if (Type->isArrayType()) { 20932 assert(Type->getAsArrayTypeUnsafe() && "Expect to get a valid array type"); 20933 Type = Type->getAsArrayTypeUnsafe()->getElementType().getCanonicalType(); 20934 } 20935 // Find all user-defined mappers with the given MapperId. 20936 SmallVector<UnresolvedSet<8>, 4> Lookups; 20937 LookupResult Lookup(SemaRef, MapperId, Sema::LookupOMPMapperName); 20938 Lookup.suppressDiagnostics(); 20939 if (S) { 20940 while (S && SemaRef.LookupParsedName(Lookup, S, &MapperIdScopeSpec)) { 20941 NamedDecl *D = Lookup.getRepresentativeDecl(); 20942 while (S && !S->isDeclScope(D)) 20943 S = S->getParent(); 20944 if (S) 20945 S = S->getParent(); 20946 Lookups.emplace_back(); 20947 Lookups.back().append(Lookup.begin(), Lookup.end()); 20948 Lookup.clear(); 20949 } 20950 } else if (auto *ULE = cast_or_null<UnresolvedLookupExpr>(UnresolvedMapper)) { 20951 // Extract the user-defined mappers with the given MapperId. 20952 Lookups.push_back(UnresolvedSet<8>()); 20953 for (NamedDecl *D : ULE->decls()) { 20954 auto *DMD = cast<OMPDeclareMapperDecl>(D); 20955 assert(DMD && "Expect valid OMPDeclareMapperDecl during instantiation."); 20956 Lookups.back().addDecl(DMD); 20957 } 20958 } 20959 // Defer the lookup for dependent types. The results will be passed through 20960 // UnresolvedMapper on instantiation. 20961 if (SemaRef.CurContext->isDependentContext() || Type->isDependentType() || 20962 Type->isInstantiationDependentType() || 20963 Type->containsUnexpandedParameterPack() || 20964 filterLookupForUDReductionAndMapper<bool>(Lookups, [](ValueDecl *D) { 20965 return !D->isInvalidDecl() && 20966 (D->getType()->isDependentType() || 20967 D->getType()->isInstantiationDependentType() || 20968 D->getType()->containsUnexpandedParameterPack()); 20969 })) { 20970 UnresolvedSet<8> URS; 20971 for (const UnresolvedSet<8> &Set : Lookups) { 20972 if (Set.empty()) 20973 continue; 20974 URS.append(Set.begin(), Set.end()); 20975 } 20976 return UnresolvedLookupExpr::Create( 20977 SemaRef.Context, /*NamingClass=*/nullptr, 20978 MapperIdScopeSpec.getWithLocInContext(SemaRef.Context), MapperId, 20979 /*ADL=*/false, /*Overloaded=*/true, URS.begin(), URS.end()); 20980 } 20981 SourceLocation Loc = MapperId.getLoc(); 20982 // [OpenMP 5.0], 2.19.7.3 declare mapper Directive, Restrictions 20983 // The type must be of struct, union or class type in C and C++ 20984 if (!Type->isStructureOrClassType() && !Type->isUnionType() && 20985 (MapperIdScopeSpec.isSet() || MapperId.getAsString() != "default")) { 20986 SemaRef.Diag(Loc, diag::err_omp_mapper_wrong_type); 20987 return ExprError(); 20988 } 20989 // Perform argument dependent lookup. 20990 if (SemaRef.getLangOpts().CPlusPlus && !MapperIdScopeSpec.isSet()) 20991 argumentDependentLookup(SemaRef, MapperId, Loc, Type, Lookups); 20992 // Return the first user-defined mapper with the desired type. 20993 if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>( 20994 Lookups, [&SemaRef, Type](ValueDecl *D) -> ValueDecl * { 20995 if (!D->isInvalidDecl() && 20996 SemaRef.Context.hasSameType(D->getType(), Type)) 20997 return D; 20998 return nullptr; 20999 })) 21000 return SemaRef.BuildDeclRefExpr(VD, Type, VK_LValue, Loc); 21001 // Find the first user-defined mapper with a type derived from the desired 21002 // type. 21003 if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>( 21004 Lookups, [&SemaRef, Type, Loc](ValueDecl *D) -> ValueDecl * { 21005 if (!D->isInvalidDecl() && 21006 SemaRef.IsDerivedFrom(Loc, Type, D->getType()) && 21007 !Type.isMoreQualifiedThan(D->getType())) 21008 return D; 21009 return nullptr; 21010 })) { 21011 CXXBasePaths Paths(/*FindAmbiguities=*/true, /*RecordPaths=*/true, 21012 /*DetectVirtual=*/false); 21013 if (SemaRef.IsDerivedFrom(Loc, Type, VD->getType(), Paths)) { 21014 if (!Paths.isAmbiguous(SemaRef.Context.getCanonicalType( 21015 VD->getType().getUnqualifiedType()))) { 21016 if (SemaRef.CheckBaseClassAccess( 21017 Loc, VD->getType(), Type, Paths.front(), 21018 /*DiagID=*/0) != Sema::AR_inaccessible) { 21019 return SemaRef.BuildDeclRefExpr(VD, Type, VK_LValue, Loc); 21020 } 21021 } 21022 } 21023 } 21024 // Report error if a mapper is specified, but cannot be found. 21025 if (MapperIdScopeSpec.isSet() || MapperId.getAsString() != "default") { 21026 SemaRef.Diag(Loc, diag::err_omp_invalid_mapper) 21027 << Type << MapperId.getName(); 21028 return ExprError(); 21029 } 21030 return ExprEmpty(); 21031 } 21032 21033 namespace { 21034 // Utility struct that gathers all the related lists associated with a mappable 21035 // expression. 21036 struct MappableVarListInfo { 21037 // The list of expressions. 21038 ArrayRef<Expr *> VarList; 21039 // The list of processed expressions. 21040 SmallVector<Expr *, 16> ProcessedVarList; 21041 // The mappble components for each expression. 21042 OMPClauseMappableExprCommon::MappableExprComponentLists VarComponents; 21043 // The base declaration of the variable. 21044 SmallVector<ValueDecl *, 16> VarBaseDeclarations; 21045 // The reference to the user-defined mapper associated with every expression. 21046 SmallVector<Expr *, 16> UDMapperList; 21047 21048 MappableVarListInfo(ArrayRef<Expr *> VarList) : VarList(VarList) { 21049 // We have a list of components and base declarations for each entry in the 21050 // variable list. 21051 VarComponents.reserve(VarList.size()); 21052 VarBaseDeclarations.reserve(VarList.size()); 21053 } 21054 }; 21055 } // namespace 21056 21057 // Check the validity of the provided variable list for the provided clause kind 21058 // \a CKind. In the check process the valid expressions, mappable expression 21059 // components, variables, and user-defined mappers are extracted and used to 21060 // fill \a ProcessedVarList, \a VarComponents, \a VarBaseDeclarations, and \a 21061 // UDMapperList in MVLI. \a MapType, \a IsMapTypeImplicit, \a MapperIdScopeSpec, 21062 // and \a MapperId are expected to be valid if the clause kind is 'map'. 21063 static void checkMappableExpressionList( 21064 Sema &SemaRef, DSAStackTy *DSAS, OpenMPClauseKind CKind, 21065 MappableVarListInfo &MVLI, SourceLocation StartLoc, 21066 CXXScopeSpec &MapperIdScopeSpec, DeclarationNameInfo MapperId, 21067 ArrayRef<Expr *> UnresolvedMappers, 21068 OpenMPMapClauseKind MapType = OMPC_MAP_unknown, 21069 ArrayRef<OpenMPMapModifierKind> Modifiers = None, 21070 bool IsMapTypeImplicit = false, bool NoDiagnose = false) { 21071 // We only expect mappable expressions in 'to', 'from', and 'map' clauses. 21072 assert((CKind == OMPC_map || CKind == OMPC_to || CKind == OMPC_from) && 21073 "Unexpected clause kind with mappable expressions!"); 21074 21075 // If the identifier of user-defined mapper is not specified, it is "default". 21076 // We do not change the actual name in this clause to distinguish whether a 21077 // mapper is specified explicitly, i.e., it is not explicitly specified when 21078 // MapperId.getName() is empty. 21079 if (!MapperId.getName() || MapperId.getName().isEmpty()) { 21080 auto &DeclNames = SemaRef.getASTContext().DeclarationNames; 21081 MapperId.setName(DeclNames.getIdentifier( 21082 &SemaRef.getASTContext().Idents.get("default"))); 21083 MapperId.setLoc(StartLoc); 21084 } 21085 21086 // Iterators to find the current unresolved mapper expression. 21087 auto UMIt = UnresolvedMappers.begin(), UMEnd = UnresolvedMappers.end(); 21088 bool UpdateUMIt = false; 21089 Expr *UnresolvedMapper = nullptr; 21090 21091 bool HasHoldModifier = 21092 llvm::is_contained(Modifiers, OMPC_MAP_MODIFIER_ompx_hold); 21093 21094 // Keep track of the mappable components and base declarations in this clause. 21095 // Each entry in the list is going to have a list of components associated. We 21096 // record each set of the components so that we can build the clause later on. 21097 // In the end we should have the same amount of declarations and component 21098 // lists. 21099 21100 for (Expr *RE : MVLI.VarList) { 21101 assert(RE && "Null expr in omp to/from/map clause"); 21102 SourceLocation ELoc = RE->getExprLoc(); 21103 21104 // Find the current unresolved mapper expression. 21105 if (UpdateUMIt && UMIt != UMEnd) { 21106 UMIt++; 21107 assert( 21108 UMIt != UMEnd && 21109 "Expect the size of UnresolvedMappers to match with that of VarList"); 21110 } 21111 UpdateUMIt = true; 21112 if (UMIt != UMEnd) 21113 UnresolvedMapper = *UMIt; 21114 21115 const Expr *VE = RE->IgnoreParenLValueCasts(); 21116 21117 if (VE->isValueDependent() || VE->isTypeDependent() || 21118 VE->isInstantiationDependent() || 21119 VE->containsUnexpandedParameterPack()) { 21120 // Try to find the associated user-defined mapper. 21121 ExprResult ER = buildUserDefinedMapperRef( 21122 SemaRef, DSAS->getCurScope(), MapperIdScopeSpec, MapperId, 21123 VE->getType().getCanonicalType(), UnresolvedMapper); 21124 if (ER.isInvalid()) 21125 continue; 21126 MVLI.UDMapperList.push_back(ER.get()); 21127 // We can only analyze this information once the missing information is 21128 // resolved. 21129 MVLI.ProcessedVarList.push_back(RE); 21130 continue; 21131 } 21132 21133 Expr *SimpleExpr = RE->IgnoreParenCasts(); 21134 21135 if (!RE->isLValue()) { 21136 if (SemaRef.getLangOpts().OpenMP < 50) { 21137 SemaRef.Diag( 21138 ELoc, diag::err_omp_expected_named_var_member_or_array_expression) 21139 << RE->getSourceRange(); 21140 } else { 21141 SemaRef.Diag(ELoc, diag::err_omp_non_lvalue_in_map_or_motion_clauses) 21142 << getOpenMPClauseName(CKind) << RE->getSourceRange(); 21143 } 21144 continue; 21145 } 21146 21147 OMPClauseMappableExprCommon::MappableExprComponentList CurComponents; 21148 ValueDecl *CurDeclaration = nullptr; 21149 21150 // Obtain the array or member expression bases if required. Also, fill the 21151 // components array with all the components identified in the process. 21152 const Expr *BE = 21153 checkMapClauseExpressionBase(SemaRef, SimpleExpr, CurComponents, CKind, 21154 DSAS->getCurrentDirective(), NoDiagnose); 21155 if (!BE) 21156 continue; 21157 21158 assert(!CurComponents.empty() && 21159 "Invalid mappable expression information."); 21160 21161 if (const auto *TE = dyn_cast<CXXThisExpr>(BE)) { 21162 // Add store "this" pointer to class in DSAStackTy for future checking 21163 DSAS->addMappedClassesQualTypes(TE->getType()); 21164 // Try to find the associated user-defined mapper. 21165 ExprResult ER = buildUserDefinedMapperRef( 21166 SemaRef, DSAS->getCurScope(), MapperIdScopeSpec, MapperId, 21167 VE->getType().getCanonicalType(), UnresolvedMapper); 21168 if (ER.isInvalid()) 21169 continue; 21170 MVLI.UDMapperList.push_back(ER.get()); 21171 // Skip restriction checking for variable or field declarations 21172 MVLI.ProcessedVarList.push_back(RE); 21173 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1); 21174 MVLI.VarComponents.back().append(CurComponents.begin(), 21175 CurComponents.end()); 21176 MVLI.VarBaseDeclarations.push_back(nullptr); 21177 continue; 21178 } 21179 21180 // For the following checks, we rely on the base declaration which is 21181 // expected to be associated with the last component. The declaration is 21182 // expected to be a variable or a field (if 'this' is being mapped). 21183 CurDeclaration = CurComponents.back().getAssociatedDeclaration(); 21184 assert(CurDeclaration && "Null decl on map clause."); 21185 assert( 21186 CurDeclaration->isCanonicalDecl() && 21187 "Expecting components to have associated only canonical declarations."); 21188 21189 auto *VD = dyn_cast<VarDecl>(CurDeclaration); 21190 const auto *FD = dyn_cast<FieldDecl>(CurDeclaration); 21191 21192 assert((VD || FD) && "Only variables or fields are expected here!"); 21193 (void)FD; 21194 21195 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.10] 21196 // threadprivate variables cannot appear in a map clause. 21197 // OpenMP 4.5 [2.10.5, target update Construct] 21198 // threadprivate variables cannot appear in a from clause. 21199 if (VD && DSAS->isThreadPrivate(VD)) { 21200 if (NoDiagnose) 21201 continue; 21202 DSAStackTy::DSAVarData DVar = DSAS->getTopDSA(VD, /*FromParent=*/false); 21203 SemaRef.Diag(ELoc, diag::err_omp_threadprivate_in_clause) 21204 << getOpenMPClauseName(CKind); 21205 reportOriginalDsa(SemaRef, DSAS, VD, DVar); 21206 continue; 21207 } 21208 21209 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.9] 21210 // A list item cannot appear in both a map clause and a data-sharing 21211 // attribute clause on the same construct. 21212 21213 // Check conflicts with other map clause expressions. We check the conflicts 21214 // with the current construct separately from the enclosing data 21215 // environment, because the restrictions are different. We only have to 21216 // check conflicts across regions for the map clauses. 21217 if (checkMapConflicts(SemaRef, DSAS, CurDeclaration, SimpleExpr, 21218 /*CurrentRegionOnly=*/true, CurComponents, CKind)) 21219 break; 21220 if (CKind == OMPC_map && 21221 (SemaRef.getLangOpts().OpenMP <= 45 || StartLoc.isValid()) && 21222 checkMapConflicts(SemaRef, DSAS, CurDeclaration, SimpleExpr, 21223 /*CurrentRegionOnly=*/false, CurComponents, CKind)) 21224 break; 21225 21226 // OpenMP 4.5 [2.10.5, target update Construct] 21227 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1] 21228 // If the type of a list item is a reference to a type T then the type will 21229 // be considered to be T for all purposes of this clause. 21230 auto I = llvm::find_if( 21231 CurComponents, 21232 [](const OMPClauseMappableExprCommon::MappableComponent &MC) { 21233 return MC.getAssociatedDeclaration(); 21234 }); 21235 assert(I != CurComponents.end() && "Null decl on map clause."); 21236 (void)I; 21237 QualType Type; 21238 auto *ASE = dyn_cast<ArraySubscriptExpr>(VE->IgnoreParens()); 21239 auto *OASE = dyn_cast<OMPArraySectionExpr>(VE->IgnoreParens()); 21240 auto *OAShE = dyn_cast<OMPArrayShapingExpr>(VE->IgnoreParens()); 21241 if (ASE) { 21242 Type = ASE->getType().getNonReferenceType(); 21243 } else if (OASE) { 21244 QualType BaseType = 21245 OMPArraySectionExpr::getBaseOriginalType(OASE->getBase()); 21246 if (const auto *ATy = BaseType->getAsArrayTypeUnsafe()) 21247 Type = ATy->getElementType(); 21248 else 21249 Type = BaseType->getPointeeType(); 21250 Type = Type.getNonReferenceType(); 21251 } else if (OAShE) { 21252 Type = OAShE->getBase()->getType()->getPointeeType(); 21253 } else { 21254 Type = VE->getType(); 21255 } 21256 21257 // OpenMP 4.5 [2.10.5, target update Construct, Restrictions, p.4] 21258 // A list item in a to or from clause must have a mappable type. 21259 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.9] 21260 // A list item must have a mappable type. 21261 if (!checkTypeMappable(VE->getExprLoc(), VE->getSourceRange(), SemaRef, 21262 DSAS, Type, /*FullCheck=*/true)) 21263 continue; 21264 21265 if (CKind == OMPC_map) { 21266 // target enter data 21267 // OpenMP [2.10.2, Restrictions, p. 99] 21268 // A map-type must be specified in all map clauses and must be either 21269 // to or alloc. 21270 OpenMPDirectiveKind DKind = DSAS->getCurrentDirective(); 21271 if (DKind == OMPD_target_enter_data && 21272 !(MapType == OMPC_MAP_to || MapType == OMPC_MAP_alloc)) { 21273 SemaRef.Diag(StartLoc, diag::err_omp_invalid_map_type_for_directive) 21274 << (IsMapTypeImplicit ? 1 : 0) 21275 << getOpenMPSimpleClauseTypeName(OMPC_map, MapType) 21276 << getOpenMPDirectiveName(DKind); 21277 continue; 21278 } 21279 21280 // target exit_data 21281 // OpenMP [2.10.3, Restrictions, p. 102] 21282 // A map-type must be specified in all map clauses and must be either 21283 // from, release, or delete. 21284 if (DKind == OMPD_target_exit_data && 21285 !(MapType == OMPC_MAP_from || MapType == OMPC_MAP_release || 21286 MapType == OMPC_MAP_delete)) { 21287 SemaRef.Diag(StartLoc, diag::err_omp_invalid_map_type_for_directive) 21288 << (IsMapTypeImplicit ? 1 : 0) 21289 << getOpenMPSimpleClauseTypeName(OMPC_map, MapType) 21290 << getOpenMPDirectiveName(DKind); 21291 continue; 21292 } 21293 21294 // The 'ompx_hold' modifier is specifically intended to be used on a 21295 // 'target' or 'target data' directive to prevent data from being unmapped 21296 // during the associated statement. It is not permitted on a 'target 21297 // enter data' or 'target exit data' directive, which have no associated 21298 // statement. 21299 if ((DKind == OMPD_target_enter_data || DKind == OMPD_target_exit_data) && 21300 HasHoldModifier) { 21301 SemaRef.Diag(StartLoc, 21302 diag::err_omp_invalid_map_type_modifier_for_directive) 21303 << getOpenMPSimpleClauseTypeName(OMPC_map, 21304 OMPC_MAP_MODIFIER_ompx_hold) 21305 << getOpenMPDirectiveName(DKind); 21306 continue; 21307 } 21308 21309 // target, target data 21310 // OpenMP 5.0 [2.12.2, Restrictions, p. 163] 21311 // OpenMP 5.0 [2.12.5, Restrictions, p. 174] 21312 // A map-type in a map clause must be to, from, tofrom or alloc 21313 if ((DKind == OMPD_target_data || 21314 isOpenMPTargetExecutionDirective(DKind)) && 21315 !(MapType == OMPC_MAP_to || MapType == OMPC_MAP_from || 21316 MapType == OMPC_MAP_tofrom || MapType == OMPC_MAP_alloc)) { 21317 SemaRef.Diag(StartLoc, diag::err_omp_invalid_map_type_for_directive) 21318 << (IsMapTypeImplicit ? 1 : 0) 21319 << getOpenMPSimpleClauseTypeName(OMPC_map, MapType) 21320 << getOpenMPDirectiveName(DKind); 21321 continue; 21322 } 21323 21324 // OpenMP 4.5 [2.15.5.1, Restrictions, p.3] 21325 // A list item cannot appear in both a map clause and a data-sharing 21326 // attribute clause on the same construct 21327 // 21328 // OpenMP 5.0 [2.19.7.1, Restrictions, p.7] 21329 // A list item cannot appear in both a map clause and a data-sharing 21330 // attribute clause on the same construct unless the construct is a 21331 // combined construct. 21332 if (VD && ((SemaRef.LangOpts.OpenMP <= 45 && 21333 isOpenMPTargetExecutionDirective(DKind)) || 21334 DKind == OMPD_target)) { 21335 DSAStackTy::DSAVarData DVar = DSAS->getTopDSA(VD, /*FromParent=*/false); 21336 if (isOpenMPPrivate(DVar.CKind)) { 21337 SemaRef.Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa) 21338 << getOpenMPClauseName(DVar.CKind) 21339 << getOpenMPClauseName(OMPC_map) 21340 << getOpenMPDirectiveName(DSAS->getCurrentDirective()); 21341 reportOriginalDsa(SemaRef, DSAS, CurDeclaration, DVar); 21342 continue; 21343 } 21344 } 21345 } 21346 21347 // Try to find the associated user-defined mapper. 21348 ExprResult ER = buildUserDefinedMapperRef( 21349 SemaRef, DSAS->getCurScope(), MapperIdScopeSpec, MapperId, 21350 Type.getCanonicalType(), UnresolvedMapper); 21351 if (ER.isInvalid()) 21352 continue; 21353 MVLI.UDMapperList.push_back(ER.get()); 21354 21355 // Save the current expression. 21356 MVLI.ProcessedVarList.push_back(RE); 21357 21358 // Store the components in the stack so that they can be used to check 21359 // against other clauses later on. 21360 DSAS->addMappableExpressionComponents(CurDeclaration, CurComponents, 21361 /*WhereFoundClauseKind=*/OMPC_map); 21362 21363 // Save the components and declaration to create the clause. For purposes of 21364 // the clause creation, any component list that has has base 'this' uses 21365 // null as base declaration. 21366 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1); 21367 MVLI.VarComponents.back().append(CurComponents.begin(), 21368 CurComponents.end()); 21369 MVLI.VarBaseDeclarations.push_back(isa<MemberExpr>(BE) ? nullptr 21370 : CurDeclaration); 21371 } 21372 } 21373 21374 OMPClause *Sema::ActOnOpenMPMapClause( 21375 ArrayRef<OpenMPMapModifierKind> MapTypeModifiers, 21376 ArrayRef<SourceLocation> MapTypeModifiersLoc, 21377 CXXScopeSpec &MapperIdScopeSpec, DeclarationNameInfo &MapperId, 21378 OpenMPMapClauseKind MapType, bool IsMapTypeImplicit, SourceLocation MapLoc, 21379 SourceLocation ColonLoc, ArrayRef<Expr *> VarList, 21380 const OMPVarListLocTy &Locs, bool NoDiagnose, 21381 ArrayRef<Expr *> UnresolvedMappers) { 21382 OpenMPMapModifierKind Modifiers[] = { 21383 OMPC_MAP_MODIFIER_unknown, OMPC_MAP_MODIFIER_unknown, 21384 OMPC_MAP_MODIFIER_unknown, OMPC_MAP_MODIFIER_unknown, 21385 OMPC_MAP_MODIFIER_unknown}; 21386 SourceLocation ModifiersLoc[NumberOfOMPMapClauseModifiers]; 21387 21388 // Process map-type-modifiers, flag errors for duplicate modifiers. 21389 unsigned Count = 0; 21390 for (unsigned I = 0, E = MapTypeModifiers.size(); I < E; ++I) { 21391 if (MapTypeModifiers[I] != OMPC_MAP_MODIFIER_unknown && 21392 llvm::is_contained(Modifiers, MapTypeModifiers[I])) { 21393 Diag(MapTypeModifiersLoc[I], diag::err_omp_duplicate_map_type_modifier); 21394 continue; 21395 } 21396 assert(Count < NumberOfOMPMapClauseModifiers && 21397 "Modifiers exceed the allowed number of map type modifiers"); 21398 Modifiers[Count] = MapTypeModifiers[I]; 21399 ModifiersLoc[Count] = MapTypeModifiersLoc[I]; 21400 ++Count; 21401 } 21402 21403 MappableVarListInfo MVLI(VarList); 21404 checkMappableExpressionList(*this, DSAStack, OMPC_map, MVLI, Locs.StartLoc, 21405 MapperIdScopeSpec, MapperId, UnresolvedMappers, 21406 MapType, Modifiers, IsMapTypeImplicit, 21407 NoDiagnose); 21408 21409 // We need to produce a map clause even if we don't have variables so that 21410 // other diagnostics related with non-existing map clauses are accurate. 21411 return OMPMapClause::Create(Context, Locs, MVLI.ProcessedVarList, 21412 MVLI.VarBaseDeclarations, MVLI.VarComponents, 21413 MVLI.UDMapperList, Modifiers, ModifiersLoc, 21414 MapperIdScopeSpec.getWithLocInContext(Context), 21415 MapperId, MapType, IsMapTypeImplicit, MapLoc); 21416 } 21417 21418 QualType Sema::ActOnOpenMPDeclareReductionType(SourceLocation TyLoc, 21419 TypeResult ParsedType) { 21420 assert(ParsedType.isUsable()); 21421 21422 QualType ReductionType = GetTypeFromParser(ParsedType.get()); 21423 if (ReductionType.isNull()) 21424 return QualType(); 21425 21426 // [OpenMP 4.0], 2.15 declare reduction Directive, Restrictions, C\C++ 21427 // A type name in a declare reduction directive cannot be a function type, an 21428 // array type, a reference type, or a type qualified with const, volatile or 21429 // restrict. 21430 if (ReductionType.hasQualifiers()) { 21431 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 0; 21432 return QualType(); 21433 } 21434 21435 if (ReductionType->isFunctionType()) { 21436 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 1; 21437 return QualType(); 21438 } 21439 if (ReductionType->isReferenceType()) { 21440 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 2; 21441 return QualType(); 21442 } 21443 if (ReductionType->isArrayType()) { 21444 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 3; 21445 return QualType(); 21446 } 21447 return ReductionType; 21448 } 21449 21450 Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareReductionDirectiveStart( 21451 Scope *S, DeclContext *DC, DeclarationName Name, 21452 ArrayRef<std::pair<QualType, SourceLocation>> ReductionTypes, 21453 AccessSpecifier AS, Decl *PrevDeclInScope) { 21454 SmallVector<Decl *, 8> Decls; 21455 Decls.reserve(ReductionTypes.size()); 21456 21457 LookupResult Lookup(*this, Name, SourceLocation(), LookupOMPReductionName, 21458 forRedeclarationInCurContext()); 21459 // [OpenMP 4.0], 2.15 declare reduction Directive, Restrictions 21460 // A reduction-identifier may not be re-declared in the current scope for the 21461 // same type or for a type that is compatible according to the base language 21462 // rules. 21463 llvm::DenseMap<QualType, SourceLocation> PreviousRedeclTypes; 21464 OMPDeclareReductionDecl *PrevDRD = nullptr; 21465 bool InCompoundScope = true; 21466 if (S != nullptr) { 21467 // Find previous declaration with the same name not referenced in other 21468 // declarations. 21469 FunctionScopeInfo *ParentFn = getEnclosingFunction(); 21470 InCompoundScope = 21471 (ParentFn != nullptr) && !ParentFn->CompoundScopes.empty(); 21472 LookupName(Lookup, S); 21473 FilterLookupForScope(Lookup, DC, S, /*ConsiderLinkage=*/false, 21474 /*AllowInlineNamespace=*/false); 21475 llvm::DenseMap<OMPDeclareReductionDecl *, bool> UsedAsPrevious; 21476 LookupResult::Filter Filter = Lookup.makeFilter(); 21477 while (Filter.hasNext()) { 21478 auto *PrevDecl = cast<OMPDeclareReductionDecl>(Filter.next()); 21479 if (InCompoundScope) { 21480 auto I = UsedAsPrevious.find(PrevDecl); 21481 if (I == UsedAsPrevious.end()) 21482 UsedAsPrevious[PrevDecl] = false; 21483 if (OMPDeclareReductionDecl *D = PrevDecl->getPrevDeclInScope()) 21484 UsedAsPrevious[D] = true; 21485 } 21486 PreviousRedeclTypes[PrevDecl->getType().getCanonicalType()] = 21487 PrevDecl->getLocation(); 21488 } 21489 Filter.done(); 21490 if (InCompoundScope) { 21491 for (const auto &PrevData : UsedAsPrevious) { 21492 if (!PrevData.second) { 21493 PrevDRD = PrevData.first; 21494 break; 21495 } 21496 } 21497 } 21498 } else if (PrevDeclInScope != nullptr) { 21499 auto *PrevDRDInScope = PrevDRD = 21500 cast<OMPDeclareReductionDecl>(PrevDeclInScope); 21501 do { 21502 PreviousRedeclTypes[PrevDRDInScope->getType().getCanonicalType()] = 21503 PrevDRDInScope->getLocation(); 21504 PrevDRDInScope = PrevDRDInScope->getPrevDeclInScope(); 21505 } while (PrevDRDInScope != nullptr); 21506 } 21507 for (const auto &TyData : ReductionTypes) { 21508 const auto I = PreviousRedeclTypes.find(TyData.first.getCanonicalType()); 21509 bool Invalid = false; 21510 if (I != PreviousRedeclTypes.end()) { 21511 Diag(TyData.second, diag::err_omp_declare_reduction_redefinition) 21512 << TyData.first; 21513 Diag(I->second, diag::note_previous_definition); 21514 Invalid = true; 21515 } 21516 PreviousRedeclTypes[TyData.first.getCanonicalType()] = TyData.second; 21517 auto *DRD = OMPDeclareReductionDecl::Create(Context, DC, TyData.second, 21518 Name, TyData.first, PrevDRD); 21519 DC->addDecl(DRD); 21520 DRD->setAccess(AS); 21521 Decls.push_back(DRD); 21522 if (Invalid) 21523 DRD->setInvalidDecl(); 21524 else 21525 PrevDRD = DRD; 21526 } 21527 21528 return DeclGroupPtrTy::make( 21529 DeclGroupRef::Create(Context, Decls.begin(), Decls.size())); 21530 } 21531 21532 void Sema::ActOnOpenMPDeclareReductionCombinerStart(Scope *S, Decl *D) { 21533 auto *DRD = cast<OMPDeclareReductionDecl>(D); 21534 21535 // Enter new function scope. 21536 PushFunctionScope(); 21537 setFunctionHasBranchProtectedScope(); 21538 getCurFunction()->setHasOMPDeclareReductionCombiner(); 21539 21540 if (S != nullptr) 21541 PushDeclContext(S, DRD); 21542 else 21543 CurContext = DRD; 21544 21545 PushExpressionEvaluationContext( 21546 ExpressionEvaluationContext::PotentiallyEvaluated); 21547 21548 QualType ReductionType = DRD->getType(); 21549 // Create 'T* omp_parm;T omp_in;'. All references to 'omp_in' will 21550 // be replaced by '*omp_parm' during codegen. This required because 'omp_in' 21551 // uses semantics of argument handles by value, but it should be passed by 21552 // reference. C lang does not support references, so pass all parameters as 21553 // pointers. 21554 // Create 'T omp_in;' variable. 21555 VarDecl *OmpInParm = 21556 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_in"); 21557 // Create 'T* omp_parm;T omp_out;'. All references to 'omp_out' will 21558 // be replaced by '*omp_parm' during codegen. This required because 'omp_out' 21559 // uses semantics of argument handles by value, but it should be passed by 21560 // reference. C lang does not support references, so pass all parameters as 21561 // pointers. 21562 // Create 'T omp_out;' variable. 21563 VarDecl *OmpOutParm = 21564 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_out"); 21565 if (S != nullptr) { 21566 PushOnScopeChains(OmpInParm, S); 21567 PushOnScopeChains(OmpOutParm, S); 21568 } else { 21569 DRD->addDecl(OmpInParm); 21570 DRD->addDecl(OmpOutParm); 21571 } 21572 Expr *InE = 21573 ::buildDeclRefExpr(*this, OmpInParm, ReductionType, D->getLocation()); 21574 Expr *OutE = 21575 ::buildDeclRefExpr(*this, OmpOutParm, ReductionType, D->getLocation()); 21576 DRD->setCombinerData(InE, OutE); 21577 } 21578 21579 void Sema::ActOnOpenMPDeclareReductionCombinerEnd(Decl *D, Expr *Combiner) { 21580 auto *DRD = cast<OMPDeclareReductionDecl>(D); 21581 DiscardCleanupsInEvaluationContext(); 21582 PopExpressionEvaluationContext(); 21583 21584 PopDeclContext(); 21585 PopFunctionScopeInfo(); 21586 21587 if (Combiner != nullptr) 21588 DRD->setCombiner(Combiner); 21589 else 21590 DRD->setInvalidDecl(); 21591 } 21592 21593 VarDecl *Sema::ActOnOpenMPDeclareReductionInitializerStart(Scope *S, Decl *D) { 21594 auto *DRD = cast<OMPDeclareReductionDecl>(D); 21595 21596 // Enter new function scope. 21597 PushFunctionScope(); 21598 setFunctionHasBranchProtectedScope(); 21599 21600 if (S != nullptr) 21601 PushDeclContext(S, DRD); 21602 else 21603 CurContext = DRD; 21604 21605 PushExpressionEvaluationContext( 21606 ExpressionEvaluationContext::PotentiallyEvaluated); 21607 21608 QualType ReductionType = DRD->getType(); 21609 // Create 'T* omp_parm;T omp_priv;'. All references to 'omp_priv' will 21610 // be replaced by '*omp_parm' during codegen. This required because 'omp_priv' 21611 // uses semantics of argument handles by value, but it should be passed by 21612 // reference. C lang does not support references, so pass all parameters as 21613 // pointers. 21614 // Create 'T omp_priv;' variable. 21615 VarDecl *OmpPrivParm = 21616 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_priv"); 21617 // Create 'T* omp_parm;T omp_orig;'. All references to 'omp_orig' will 21618 // be replaced by '*omp_parm' during codegen. This required because 'omp_orig' 21619 // uses semantics of argument handles by value, but it should be passed by 21620 // reference. C lang does not support references, so pass all parameters as 21621 // pointers. 21622 // Create 'T omp_orig;' variable. 21623 VarDecl *OmpOrigParm = 21624 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_orig"); 21625 if (S != nullptr) { 21626 PushOnScopeChains(OmpPrivParm, S); 21627 PushOnScopeChains(OmpOrigParm, S); 21628 } else { 21629 DRD->addDecl(OmpPrivParm); 21630 DRD->addDecl(OmpOrigParm); 21631 } 21632 Expr *OrigE = 21633 ::buildDeclRefExpr(*this, OmpOrigParm, ReductionType, D->getLocation()); 21634 Expr *PrivE = 21635 ::buildDeclRefExpr(*this, OmpPrivParm, ReductionType, D->getLocation()); 21636 DRD->setInitializerData(OrigE, PrivE); 21637 return OmpPrivParm; 21638 } 21639 21640 void Sema::ActOnOpenMPDeclareReductionInitializerEnd(Decl *D, Expr *Initializer, 21641 VarDecl *OmpPrivParm) { 21642 auto *DRD = cast<OMPDeclareReductionDecl>(D); 21643 DiscardCleanupsInEvaluationContext(); 21644 PopExpressionEvaluationContext(); 21645 21646 PopDeclContext(); 21647 PopFunctionScopeInfo(); 21648 21649 if (Initializer != nullptr) { 21650 DRD->setInitializer(Initializer, OMPDeclareReductionDecl::CallInit); 21651 } else if (OmpPrivParm->hasInit()) { 21652 DRD->setInitializer(OmpPrivParm->getInit(), 21653 OmpPrivParm->isDirectInit() 21654 ? OMPDeclareReductionDecl::DirectInit 21655 : OMPDeclareReductionDecl::CopyInit); 21656 } else { 21657 DRD->setInvalidDecl(); 21658 } 21659 } 21660 21661 Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareReductionDirectiveEnd( 21662 Scope *S, DeclGroupPtrTy DeclReductions, bool IsValid) { 21663 for (Decl *D : DeclReductions.get()) { 21664 if (IsValid) { 21665 if (S) 21666 PushOnScopeChains(cast<OMPDeclareReductionDecl>(D), S, 21667 /*AddToContext=*/false); 21668 } else { 21669 D->setInvalidDecl(); 21670 } 21671 } 21672 return DeclReductions; 21673 } 21674 21675 TypeResult Sema::ActOnOpenMPDeclareMapperVarDecl(Scope *S, Declarator &D) { 21676 TypeSourceInfo *TInfo = GetTypeForDeclarator(D, S); 21677 QualType T = TInfo->getType(); 21678 if (D.isInvalidType()) 21679 return true; 21680 21681 if (getLangOpts().CPlusPlus) { 21682 // Check that there are no default arguments (C++ only). 21683 CheckExtraCXXDefaultArguments(D); 21684 } 21685 21686 return CreateParsedType(T, TInfo); 21687 } 21688 21689 QualType Sema::ActOnOpenMPDeclareMapperType(SourceLocation TyLoc, 21690 TypeResult ParsedType) { 21691 assert(ParsedType.isUsable() && "Expect usable parsed mapper type"); 21692 21693 QualType MapperType = GetTypeFromParser(ParsedType.get()); 21694 assert(!MapperType.isNull() && "Expect valid mapper type"); 21695 21696 // [OpenMP 5.0], 2.19.7.3 declare mapper Directive, Restrictions 21697 // The type must be of struct, union or class type in C and C++ 21698 if (!MapperType->isStructureOrClassType() && !MapperType->isUnionType()) { 21699 Diag(TyLoc, diag::err_omp_mapper_wrong_type); 21700 return QualType(); 21701 } 21702 return MapperType; 21703 } 21704 21705 Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareMapperDirective( 21706 Scope *S, DeclContext *DC, DeclarationName Name, QualType MapperType, 21707 SourceLocation StartLoc, DeclarationName VN, AccessSpecifier AS, 21708 Expr *MapperVarRef, ArrayRef<OMPClause *> Clauses, Decl *PrevDeclInScope) { 21709 LookupResult Lookup(*this, Name, SourceLocation(), LookupOMPMapperName, 21710 forRedeclarationInCurContext()); 21711 // [OpenMP 5.0], 2.19.7.3 declare mapper Directive, Restrictions 21712 // A mapper-identifier may not be redeclared in the current scope for the 21713 // same type or for a type that is compatible according to the base language 21714 // rules. 21715 llvm::DenseMap<QualType, SourceLocation> PreviousRedeclTypes; 21716 OMPDeclareMapperDecl *PrevDMD = nullptr; 21717 bool InCompoundScope = true; 21718 if (S != nullptr) { 21719 // Find previous declaration with the same name not referenced in other 21720 // declarations. 21721 FunctionScopeInfo *ParentFn = getEnclosingFunction(); 21722 InCompoundScope = 21723 (ParentFn != nullptr) && !ParentFn->CompoundScopes.empty(); 21724 LookupName(Lookup, S); 21725 FilterLookupForScope(Lookup, DC, S, /*ConsiderLinkage=*/false, 21726 /*AllowInlineNamespace=*/false); 21727 llvm::DenseMap<OMPDeclareMapperDecl *, bool> UsedAsPrevious; 21728 LookupResult::Filter Filter = Lookup.makeFilter(); 21729 while (Filter.hasNext()) { 21730 auto *PrevDecl = cast<OMPDeclareMapperDecl>(Filter.next()); 21731 if (InCompoundScope) { 21732 auto I = UsedAsPrevious.find(PrevDecl); 21733 if (I == UsedAsPrevious.end()) 21734 UsedAsPrevious[PrevDecl] = false; 21735 if (OMPDeclareMapperDecl *D = PrevDecl->getPrevDeclInScope()) 21736 UsedAsPrevious[D] = true; 21737 } 21738 PreviousRedeclTypes[PrevDecl->getType().getCanonicalType()] = 21739 PrevDecl->getLocation(); 21740 } 21741 Filter.done(); 21742 if (InCompoundScope) { 21743 for (const auto &PrevData : UsedAsPrevious) { 21744 if (!PrevData.second) { 21745 PrevDMD = PrevData.first; 21746 break; 21747 } 21748 } 21749 } 21750 } else if (PrevDeclInScope) { 21751 auto *PrevDMDInScope = PrevDMD = 21752 cast<OMPDeclareMapperDecl>(PrevDeclInScope); 21753 do { 21754 PreviousRedeclTypes[PrevDMDInScope->getType().getCanonicalType()] = 21755 PrevDMDInScope->getLocation(); 21756 PrevDMDInScope = PrevDMDInScope->getPrevDeclInScope(); 21757 } while (PrevDMDInScope != nullptr); 21758 } 21759 const auto I = PreviousRedeclTypes.find(MapperType.getCanonicalType()); 21760 bool Invalid = false; 21761 if (I != PreviousRedeclTypes.end()) { 21762 Diag(StartLoc, diag::err_omp_declare_mapper_redefinition) 21763 << MapperType << Name; 21764 Diag(I->second, diag::note_previous_definition); 21765 Invalid = true; 21766 } 21767 // Build expressions for implicit maps of data members with 'default' 21768 // mappers. 21769 SmallVector<OMPClause *, 4> ClausesWithImplicit(Clauses.begin(), 21770 Clauses.end()); 21771 if (LangOpts.OpenMP >= 50) 21772 processImplicitMapsWithDefaultMappers(*this, DSAStack, ClausesWithImplicit); 21773 auto *DMD = 21774 OMPDeclareMapperDecl::Create(Context, DC, StartLoc, Name, MapperType, VN, 21775 ClausesWithImplicit, PrevDMD); 21776 if (S) 21777 PushOnScopeChains(DMD, S); 21778 else 21779 DC->addDecl(DMD); 21780 DMD->setAccess(AS); 21781 if (Invalid) 21782 DMD->setInvalidDecl(); 21783 21784 auto *VD = cast<DeclRefExpr>(MapperVarRef)->getDecl(); 21785 VD->setDeclContext(DMD); 21786 VD->setLexicalDeclContext(DMD); 21787 DMD->addDecl(VD); 21788 DMD->setMapperVarRef(MapperVarRef); 21789 21790 return DeclGroupPtrTy::make(DeclGroupRef(DMD)); 21791 } 21792 21793 ExprResult 21794 Sema::ActOnOpenMPDeclareMapperDirectiveVarDecl(Scope *S, QualType MapperType, 21795 SourceLocation StartLoc, 21796 DeclarationName VN) { 21797 TypeSourceInfo *TInfo = 21798 Context.getTrivialTypeSourceInfo(MapperType, StartLoc); 21799 auto *VD = VarDecl::Create(Context, Context.getTranslationUnitDecl(), 21800 StartLoc, StartLoc, VN.getAsIdentifierInfo(), 21801 MapperType, TInfo, SC_None); 21802 if (S) 21803 PushOnScopeChains(VD, S, /*AddToContext=*/false); 21804 Expr *E = buildDeclRefExpr(*this, VD, MapperType, StartLoc); 21805 DSAStack->addDeclareMapperVarRef(E); 21806 return E; 21807 } 21808 21809 bool Sema::isOpenMPDeclareMapperVarDeclAllowed(const VarDecl *VD) const { 21810 assert(LangOpts.OpenMP && "Expected OpenMP mode."); 21811 const Expr *Ref = DSAStack->getDeclareMapperVarRef(); 21812 if (const auto *DRE = cast_or_null<DeclRefExpr>(Ref)) { 21813 if (VD->getCanonicalDecl() == DRE->getDecl()->getCanonicalDecl()) 21814 return true; 21815 if (VD->isUsableInConstantExpressions(Context)) 21816 return true; 21817 return false; 21818 } 21819 return true; 21820 } 21821 21822 const ValueDecl *Sema::getOpenMPDeclareMapperVarName() const { 21823 assert(LangOpts.OpenMP && "Expected OpenMP mode."); 21824 return cast<DeclRefExpr>(DSAStack->getDeclareMapperVarRef())->getDecl(); 21825 } 21826 21827 OMPClause *Sema::ActOnOpenMPNumTeamsClause(Expr *NumTeams, 21828 SourceLocation StartLoc, 21829 SourceLocation LParenLoc, 21830 SourceLocation EndLoc) { 21831 Expr *ValExpr = NumTeams; 21832 Stmt *HelperValStmt = nullptr; 21833 21834 // OpenMP [teams Constrcut, Restrictions] 21835 // The num_teams expression must evaluate to a positive integer value. 21836 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_num_teams, 21837 /*StrictlyPositive=*/true)) 21838 return nullptr; 21839 21840 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 21841 OpenMPDirectiveKind CaptureRegion = 21842 getOpenMPCaptureRegionForClause(DKind, OMPC_num_teams, LangOpts.OpenMP); 21843 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 21844 ValExpr = MakeFullExpr(ValExpr).get(); 21845 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 21846 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 21847 HelperValStmt = buildPreInits(Context, Captures); 21848 } 21849 21850 return new (Context) OMPNumTeamsClause(ValExpr, HelperValStmt, CaptureRegion, 21851 StartLoc, LParenLoc, EndLoc); 21852 } 21853 21854 OMPClause *Sema::ActOnOpenMPThreadLimitClause(Expr *ThreadLimit, 21855 SourceLocation StartLoc, 21856 SourceLocation LParenLoc, 21857 SourceLocation EndLoc) { 21858 Expr *ValExpr = ThreadLimit; 21859 Stmt *HelperValStmt = nullptr; 21860 21861 // OpenMP [teams Constrcut, Restrictions] 21862 // The thread_limit expression must evaluate to a positive integer value. 21863 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_thread_limit, 21864 /*StrictlyPositive=*/true)) 21865 return nullptr; 21866 21867 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 21868 OpenMPDirectiveKind CaptureRegion = getOpenMPCaptureRegionForClause( 21869 DKind, OMPC_thread_limit, LangOpts.OpenMP); 21870 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 21871 ValExpr = MakeFullExpr(ValExpr).get(); 21872 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 21873 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 21874 HelperValStmt = buildPreInits(Context, Captures); 21875 } 21876 21877 return new (Context) OMPThreadLimitClause( 21878 ValExpr, HelperValStmt, CaptureRegion, StartLoc, LParenLoc, EndLoc); 21879 } 21880 21881 OMPClause *Sema::ActOnOpenMPPriorityClause(Expr *Priority, 21882 SourceLocation StartLoc, 21883 SourceLocation LParenLoc, 21884 SourceLocation EndLoc) { 21885 Expr *ValExpr = Priority; 21886 Stmt *HelperValStmt = nullptr; 21887 OpenMPDirectiveKind CaptureRegion = OMPD_unknown; 21888 21889 // OpenMP [2.9.1, task Constrcut] 21890 // The priority-value is a non-negative numerical scalar expression. 21891 if (!isNonNegativeIntegerValue( 21892 ValExpr, *this, OMPC_priority, 21893 /*StrictlyPositive=*/false, /*BuildCapture=*/true, 21894 DSAStack->getCurrentDirective(), &CaptureRegion, &HelperValStmt)) 21895 return nullptr; 21896 21897 return new (Context) OMPPriorityClause(ValExpr, HelperValStmt, CaptureRegion, 21898 StartLoc, LParenLoc, EndLoc); 21899 } 21900 21901 OMPClause *Sema::ActOnOpenMPGrainsizeClause(Expr *Grainsize, 21902 SourceLocation StartLoc, 21903 SourceLocation LParenLoc, 21904 SourceLocation EndLoc) { 21905 Expr *ValExpr = Grainsize; 21906 Stmt *HelperValStmt = nullptr; 21907 OpenMPDirectiveKind CaptureRegion = OMPD_unknown; 21908 21909 // OpenMP [2.9.2, taskloop Constrcut] 21910 // The parameter of the grainsize clause must be a positive integer 21911 // expression. 21912 if (!isNonNegativeIntegerValue( 21913 ValExpr, *this, OMPC_grainsize, 21914 /*StrictlyPositive=*/true, /*BuildCapture=*/true, 21915 DSAStack->getCurrentDirective(), &CaptureRegion, &HelperValStmt)) 21916 return nullptr; 21917 21918 return new (Context) OMPGrainsizeClause(ValExpr, HelperValStmt, CaptureRegion, 21919 StartLoc, LParenLoc, EndLoc); 21920 } 21921 21922 OMPClause *Sema::ActOnOpenMPNumTasksClause(Expr *NumTasks, 21923 SourceLocation StartLoc, 21924 SourceLocation LParenLoc, 21925 SourceLocation EndLoc) { 21926 Expr *ValExpr = NumTasks; 21927 Stmt *HelperValStmt = nullptr; 21928 OpenMPDirectiveKind CaptureRegion = OMPD_unknown; 21929 21930 // OpenMP [2.9.2, taskloop Constrcut] 21931 // The parameter of the num_tasks clause must be a positive integer 21932 // expression. 21933 if (!isNonNegativeIntegerValue( 21934 ValExpr, *this, OMPC_num_tasks, 21935 /*StrictlyPositive=*/true, /*BuildCapture=*/true, 21936 DSAStack->getCurrentDirective(), &CaptureRegion, &HelperValStmt)) 21937 return nullptr; 21938 21939 return new (Context) OMPNumTasksClause(ValExpr, HelperValStmt, CaptureRegion, 21940 StartLoc, LParenLoc, EndLoc); 21941 } 21942 21943 OMPClause *Sema::ActOnOpenMPHintClause(Expr *Hint, SourceLocation StartLoc, 21944 SourceLocation LParenLoc, 21945 SourceLocation EndLoc) { 21946 // OpenMP [2.13.2, critical construct, Description] 21947 // ... where hint-expression is an integer constant expression that evaluates 21948 // to a valid lock hint. 21949 ExprResult HintExpr = 21950 VerifyPositiveIntegerConstantInClause(Hint, OMPC_hint, false); 21951 if (HintExpr.isInvalid()) 21952 return nullptr; 21953 return new (Context) 21954 OMPHintClause(HintExpr.get(), StartLoc, LParenLoc, EndLoc); 21955 } 21956 21957 /// Tries to find omp_event_handle_t type. 21958 static bool findOMPEventHandleT(Sema &S, SourceLocation Loc, 21959 DSAStackTy *Stack) { 21960 QualType OMPEventHandleT = Stack->getOMPEventHandleT(); 21961 if (!OMPEventHandleT.isNull()) 21962 return true; 21963 IdentifierInfo *II = &S.PP.getIdentifierTable().get("omp_event_handle_t"); 21964 ParsedType PT = S.getTypeName(*II, Loc, S.getCurScope()); 21965 if (!PT.getAsOpaquePtr() || PT.get().isNull()) { 21966 S.Diag(Loc, diag::err_omp_implied_type_not_found) << "omp_event_handle_t"; 21967 return false; 21968 } 21969 Stack->setOMPEventHandleT(PT.get()); 21970 return true; 21971 } 21972 21973 OMPClause *Sema::ActOnOpenMPDetachClause(Expr *Evt, SourceLocation StartLoc, 21974 SourceLocation LParenLoc, 21975 SourceLocation EndLoc) { 21976 if (!Evt->isValueDependent() && !Evt->isTypeDependent() && 21977 !Evt->isInstantiationDependent() && 21978 !Evt->containsUnexpandedParameterPack()) { 21979 if (!findOMPEventHandleT(*this, Evt->getExprLoc(), DSAStack)) 21980 return nullptr; 21981 // OpenMP 5.0, 2.10.1 task Construct. 21982 // event-handle is a variable of the omp_event_handle_t type. 21983 auto *Ref = dyn_cast<DeclRefExpr>(Evt->IgnoreParenImpCasts()); 21984 if (!Ref) { 21985 Diag(Evt->getExprLoc(), diag::err_omp_var_expected) 21986 << "omp_event_handle_t" << 0 << Evt->getSourceRange(); 21987 return nullptr; 21988 } 21989 auto *VD = dyn_cast_or_null<VarDecl>(Ref->getDecl()); 21990 if (!VD) { 21991 Diag(Evt->getExprLoc(), diag::err_omp_var_expected) 21992 << "omp_event_handle_t" << 0 << Evt->getSourceRange(); 21993 return nullptr; 21994 } 21995 if (!Context.hasSameUnqualifiedType(DSAStack->getOMPEventHandleT(), 21996 VD->getType()) || 21997 VD->getType().isConstant(Context)) { 21998 Diag(Evt->getExprLoc(), diag::err_omp_var_expected) 21999 << "omp_event_handle_t" << 1 << VD->getType() 22000 << Evt->getSourceRange(); 22001 return nullptr; 22002 } 22003 // OpenMP 5.0, 2.10.1 task Construct 22004 // [detach clause]... The event-handle will be considered as if it was 22005 // specified on a firstprivate clause. 22006 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(VD, /*FromParent=*/false); 22007 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_firstprivate && 22008 DVar.RefExpr) { 22009 Diag(Evt->getExprLoc(), diag::err_omp_wrong_dsa) 22010 << getOpenMPClauseName(DVar.CKind) 22011 << getOpenMPClauseName(OMPC_firstprivate); 22012 reportOriginalDsa(*this, DSAStack, VD, DVar); 22013 return nullptr; 22014 } 22015 } 22016 22017 return new (Context) OMPDetachClause(Evt, StartLoc, LParenLoc, EndLoc); 22018 } 22019 22020 OMPClause *Sema::ActOnOpenMPDistScheduleClause( 22021 OpenMPDistScheduleClauseKind Kind, Expr *ChunkSize, SourceLocation StartLoc, 22022 SourceLocation LParenLoc, SourceLocation KindLoc, SourceLocation CommaLoc, 22023 SourceLocation EndLoc) { 22024 if (Kind == OMPC_DIST_SCHEDULE_unknown) { 22025 std::string Values; 22026 Values += "'"; 22027 Values += getOpenMPSimpleClauseTypeName(OMPC_dist_schedule, 0); 22028 Values += "'"; 22029 Diag(KindLoc, diag::err_omp_unexpected_clause_value) 22030 << Values << getOpenMPClauseName(OMPC_dist_schedule); 22031 return nullptr; 22032 } 22033 Expr *ValExpr = ChunkSize; 22034 Stmt *HelperValStmt = nullptr; 22035 if (ChunkSize) { 22036 if (!ChunkSize->isValueDependent() && !ChunkSize->isTypeDependent() && 22037 !ChunkSize->isInstantiationDependent() && 22038 !ChunkSize->containsUnexpandedParameterPack()) { 22039 SourceLocation ChunkSizeLoc = ChunkSize->getBeginLoc(); 22040 ExprResult Val = 22041 PerformOpenMPImplicitIntegerConversion(ChunkSizeLoc, ChunkSize); 22042 if (Val.isInvalid()) 22043 return nullptr; 22044 22045 ValExpr = Val.get(); 22046 22047 // OpenMP [2.7.1, Restrictions] 22048 // chunk_size must be a loop invariant integer expression with a positive 22049 // value. 22050 if (Optional<llvm::APSInt> Result = 22051 ValExpr->getIntegerConstantExpr(Context)) { 22052 if (Result->isSigned() && !Result->isStrictlyPositive()) { 22053 Diag(ChunkSizeLoc, diag::err_omp_negative_expression_in_clause) 22054 << "dist_schedule" << ChunkSize->getSourceRange(); 22055 return nullptr; 22056 } 22057 } else if (getOpenMPCaptureRegionForClause( 22058 DSAStack->getCurrentDirective(), OMPC_dist_schedule, 22059 LangOpts.OpenMP) != OMPD_unknown && 22060 !CurContext->isDependentContext()) { 22061 ValExpr = MakeFullExpr(ValExpr).get(); 22062 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 22063 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 22064 HelperValStmt = buildPreInits(Context, Captures); 22065 } 22066 } 22067 } 22068 22069 return new (Context) 22070 OMPDistScheduleClause(StartLoc, LParenLoc, KindLoc, CommaLoc, EndLoc, 22071 Kind, ValExpr, HelperValStmt); 22072 } 22073 22074 OMPClause *Sema::ActOnOpenMPDefaultmapClause( 22075 OpenMPDefaultmapClauseModifier M, OpenMPDefaultmapClauseKind Kind, 22076 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation MLoc, 22077 SourceLocation KindLoc, SourceLocation EndLoc) { 22078 if (getLangOpts().OpenMP < 50) { 22079 if (M != OMPC_DEFAULTMAP_MODIFIER_tofrom || 22080 Kind != OMPC_DEFAULTMAP_scalar) { 22081 std::string Value; 22082 SourceLocation Loc; 22083 Value += "'"; 22084 if (M != OMPC_DEFAULTMAP_MODIFIER_tofrom) { 22085 Value += getOpenMPSimpleClauseTypeName(OMPC_defaultmap, 22086 OMPC_DEFAULTMAP_MODIFIER_tofrom); 22087 Loc = MLoc; 22088 } else { 22089 Value += getOpenMPSimpleClauseTypeName(OMPC_defaultmap, 22090 OMPC_DEFAULTMAP_scalar); 22091 Loc = KindLoc; 22092 } 22093 Value += "'"; 22094 Diag(Loc, diag::err_omp_unexpected_clause_value) 22095 << Value << getOpenMPClauseName(OMPC_defaultmap); 22096 return nullptr; 22097 } 22098 } else { 22099 bool isDefaultmapModifier = (M != OMPC_DEFAULTMAP_MODIFIER_unknown); 22100 bool isDefaultmapKind = (Kind != OMPC_DEFAULTMAP_unknown) || 22101 (LangOpts.OpenMP >= 50 && KindLoc.isInvalid()); 22102 if (!isDefaultmapKind || !isDefaultmapModifier) { 22103 StringRef KindValue = "'scalar', 'aggregate', 'pointer'"; 22104 if (LangOpts.OpenMP == 50) { 22105 StringRef ModifierValue = "'alloc', 'from', 'to', 'tofrom', " 22106 "'firstprivate', 'none', 'default'"; 22107 if (!isDefaultmapKind && isDefaultmapModifier) { 22108 Diag(KindLoc, diag::err_omp_unexpected_clause_value) 22109 << KindValue << getOpenMPClauseName(OMPC_defaultmap); 22110 } else if (isDefaultmapKind && !isDefaultmapModifier) { 22111 Diag(MLoc, diag::err_omp_unexpected_clause_value) 22112 << ModifierValue << getOpenMPClauseName(OMPC_defaultmap); 22113 } else { 22114 Diag(MLoc, diag::err_omp_unexpected_clause_value) 22115 << ModifierValue << getOpenMPClauseName(OMPC_defaultmap); 22116 Diag(KindLoc, diag::err_omp_unexpected_clause_value) 22117 << KindValue << getOpenMPClauseName(OMPC_defaultmap); 22118 } 22119 } else { 22120 StringRef ModifierValue = 22121 "'alloc', 'from', 'to', 'tofrom', " 22122 "'firstprivate', 'none', 'default', 'present'"; 22123 if (!isDefaultmapKind && isDefaultmapModifier) { 22124 Diag(KindLoc, diag::err_omp_unexpected_clause_value) 22125 << KindValue << getOpenMPClauseName(OMPC_defaultmap); 22126 } else if (isDefaultmapKind && !isDefaultmapModifier) { 22127 Diag(MLoc, diag::err_omp_unexpected_clause_value) 22128 << ModifierValue << getOpenMPClauseName(OMPC_defaultmap); 22129 } else { 22130 Diag(MLoc, diag::err_omp_unexpected_clause_value) 22131 << ModifierValue << getOpenMPClauseName(OMPC_defaultmap); 22132 Diag(KindLoc, diag::err_omp_unexpected_clause_value) 22133 << KindValue << getOpenMPClauseName(OMPC_defaultmap); 22134 } 22135 } 22136 return nullptr; 22137 } 22138 22139 // OpenMP [5.0, 2.12.5, Restrictions, p. 174] 22140 // At most one defaultmap clause for each category can appear on the 22141 // directive. 22142 if (DSAStack->checkDefaultmapCategory(Kind)) { 22143 Diag(StartLoc, diag::err_omp_one_defaultmap_each_category); 22144 return nullptr; 22145 } 22146 } 22147 if (Kind == OMPC_DEFAULTMAP_unknown) { 22148 // Variable category is not specified - mark all categories. 22149 DSAStack->setDefaultDMAAttr(M, OMPC_DEFAULTMAP_aggregate, StartLoc); 22150 DSAStack->setDefaultDMAAttr(M, OMPC_DEFAULTMAP_scalar, StartLoc); 22151 DSAStack->setDefaultDMAAttr(M, OMPC_DEFAULTMAP_pointer, StartLoc); 22152 } else { 22153 DSAStack->setDefaultDMAAttr(M, Kind, StartLoc); 22154 } 22155 22156 return new (Context) 22157 OMPDefaultmapClause(StartLoc, LParenLoc, MLoc, KindLoc, EndLoc, Kind, M); 22158 } 22159 22160 bool Sema::ActOnStartOpenMPDeclareTargetContext( 22161 DeclareTargetContextInfo &DTCI) { 22162 DeclContext *CurLexicalContext = getCurLexicalContext(); 22163 if (!CurLexicalContext->isFileContext() && 22164 !CurLexicalContext->isExternCContext() && 22165 !CurLexicalContext->isExternCXXContext() && 22166 !isa<CXXRecordDecl>(CurLexicalContext) && 22167 !isa<ClassTemplateDecl>(CurLexicalContext) && 22168 !isa<ClassTemplatePartialSpecializationDecl>(CurLexicalContext) && 22169 !isa<ClassTemplateSpecializationDecl>(CurLexicalContext)) { 22170 Diag(DTCI.Loc, diag::err_omp_region_not_file_context); 22171 return false; 22172 } 22173 DeclareTargetNesting.push_back(DTCI); 22174 return true; 22175 } 22176 22177 const Sema::DeclareTargetContextInfo 22178 Sema::ActOnOpenMPEndDeclareTargetDirective() { 22179 assert(!DeclareTargetNesting.empty() && 22180 "check isInOpenMPDeclareTargetContext() first!"); 22181 return DeclareTargetNesting.pop_back_val(); 22182 } 22183 22184 void Sema::ActOnFinishedOpenMPDeclareTargetContext( 22185 DeclareTargetContextInfo &DTCI) { 22186 for (auto &It : DTCI.ExplicitlyMapped) 22187 ActOnOpenMPDeclareTargetName(It.first, It.second.Loc, It.second.MT, DTCI); 22188 } 22189 22190 void Sema::DiagnoseUnterminatedOpenMPDeclareTarget() { 22191 if (DeclareTargetNesting.empty()) 22192 return; 22193 DeclareTargetContextInfo &DTCI = DeclareTargetNesting.back(); 22194 Diag(DTCI.Loc, diag::warn_omp_unterminated_declare_target) 22195 << getOpenMPDirectiveName(DTCI.Kind); 22196 } 22197 22198 NamedDecl *Sema::lookupOpenMPDeclareTargetName(Scope *CurScope, 22199 CXXScopeSpec &ScopeSpec, 22200 const DeclarationNameInfo &Id) { 22201 LookupResult Lookup(*this, Id, LookupOrdinaryName); 22202 LookupParsedName(Lookup, CurScope, &ScopeSpec, true); 22203 22204 if (Lookup.isAmbiguous()) 22205 return nullptr; 22206 Lookup.suppressDiagnostics(); 22207 22208 if (!Lookup.isSingleResult()) { 22209 VarOrFuncDeclFilterCCC CCC(*this); 22210 if (TypoCorrection Corrected = 22211 CorrectTypo(Id, LookupOrdinaryName, CurScope, nullptr, CCC, 22212 CTK_ErrorRecovery)) { 22213 diagnoseTypo(Corrected, PDiag(diag::err_undeclared_var_use_suggest) 22214 << Id.getName()); 22215 checkDeclIsAllowedInOpenMPTarget(nullptr, Corrected.getCorrectionDecl()); 22216 return nullptr; 22217 } 22218 22219 Diag(Id.getLoc(), diag::err_undeclared_var_use) << Id.getName(); 22220 return nullptr; 22221 } 22222 22223 NamedDecl *ND = Lookup.getAsSingle<NamedDecl>(); 22224 if (!isa<VarDecl>(ND) && !isa<FunctionDecl>(ND) && 22225 !isa<FunctionTemplateDecl>(ND)) { 22226 Diag(Id.getLoc(), diag::err_omp_invalid_target_decl) << Id.getName(); 22227 return nullptr; 22228 } 22229 return ND; 22230 } 22231 22232 void Sema::ActOnOpenMPDeclareTargetName(NamedDecl *ND, SourceLocation Loc, 22233 OMPDeclareTargetDeclAttr::MapTypeTy MT, 22234 DeclareTargetContextInfo &DTCI) { 22235 assert((isa<VarDecl>(ND) || isa<FunctionDecl>(ND) || 22236 isa<FunctionTemplateDecl>(ND)) && 22237 "Expected variable, function or function template."); 22238 22239 // Diagnose marking after use as it may lead to incorrect diagnosis and 22240 // codegen. 22241 if (LangOpts.OpenMP >= 50 && 22242 (ND->isUsed(/*CheckUsedAttr=*/false) || ND->isReferenced())) 22243 Diag(Loc, diag::warn_omp_declare_target_after_first_use); 22244 22245 // Explicit declare target lists have precedence. 22246 const unsigned Level = -1; 22247 22248 auto *VD = cast<ValueDecl>(ND); 22249 llvm::Optional<OMPDeclareTargetDeclAttr *> ActiveAttr = 22250 OMPDeclareTargetDeclAttr::getActiveAttr(VD); 22251 if (ActiveAttr && ActiveAttr.getValue()->getDevType() != DTCI.DT && 22252 ActiveAttr.getValue()->getLevel() == Level) { 22253 Diag(Loc, diag::err_omp_device_type_mismatch) 22254 << OMPDeclareTargetDeclAttr::ConvertDevTypeTyToStr(DTCI.DT) 22255 << OMPDeclareTargetDeclAttr::ConvertDevTypeTyToStr( 22256 ActiveAttr.getValue()->getDevType()); 22257 return; 22258 } 22259 if (ActiveAttr && ActiveAttr.getValue()->getMapType() != MT && 22260 ActiveAttr.getValue()->getLevel() == Level) { 22261 Diag(Loc, diag::err_omp_declare_target_to_and_link) << ND; 22262 return; 22263 } 22264 22265 if (ActiveAttr && ActiveAttr.getValue()->getLevel() == Level) 22266 return; 22267 22268 Expr *IndirectE = nullptr; 22269 bool IsIndirect = false; 22270 if (DTCI.Indirect) { 22271 IndirectE = DTCI.Indirect.getValue(); 22272 if (!IndirectE) 22273 IsIndirect = true; 22274 } 22275 auto *A = OMPDeclareTargetDeclAttr::CreateImplicit( 22276 Context, MT, DTCI.DT, IndirectE, IsIndirect, Level, 22277 SourceRange(Loc, Loc)); 22278 ND->addAttr(A); 22279 if (ASTMutationListener *ML = Context.getASTMutationListener()) 22280 ML->DeclarationMarkedOpenMPDeclareTarget(ND, A); 22281 checkDeclIsAllowedInOpenMPTarget(nullptr, ND, Loc); 22282 } 22283 22284 static void checkDeclInTargetContext(SourceLocation SL, SourceRange SR, 22285 Sema &SemaRef, Decl *D) { 22286 if (!D || !isa<VarDecl>(D)) 22287 return; 22288 auto *VD = cast<VarDecl>(D); 22289 Optional<OMPDeclareTargetDeclAttr::MapTypeTy> MapTy = 22290 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD); 22291 if (SemaRef.LangOpts.OpenMP >= 50 && 22292 (SemaRef.getCurLambda(/*IgnoreNonLambdaCapturingScope=*/true) || 22293 SemaRef.getCurBlock() || SemaRef.getCurCapturedRegion()) && 22294 VD->hasGlobalStorage()) { 22295 if (!MapTy || *MapTy != OMPDeclareTargetDeclAttr::MT_To) { 22296 // OpenMP 5.0, 2.12.7 declare target Directive, Restrictions 22297 // If a lambda declaration and definition appears between a 22298 // declare target directive and the matching end declare target 22299 // directive, all variables that are captured by the lambda 22300 // expression must also appear in a to clause. 22301 SemaRef.Diag(VD->getLocation(), 22302 diag::err_omp_lambda_capture_in_declare_target_not_to); 22303 SemaRef.Diag(SL, diag::note_var_explicitly_captured_here) 22304 << VD << 0 << SR; 22305 return; 22306 } 22307 } 22308 if (MapTy) 22309 return; 22310 SemaRef.Diag(VD->getLocation(), diag::warn_omp_not_in_target_context); 22311 SemaRef.Diag(SL, diag::note_used_here) << SR; 22312 } 22313 22314 static bool checkValueDeclInTarget(SourceLocation SL, SourceRange SR, 22315 Sema &SemaRef, DSAStackTy *Stack, 22316 ValueDecl *VD) { 22317 return OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD) || 22318 checkTypeMappable(SL, SR, SemaRef, Stack, VD->getType(), 22319 /*FullCheck=*/false); 22320 } 22321 22322 void Sema::checkDeclIsAllowedInOpenMPTarget(Expr *E, Decl *D, 22323 SourceLocation IdLoc) { 22324 if (!D || D->isInvalidDecl()) 22325 return; 22326 SourceRange SR = E ? E->getSourceRange() : D->getSourceRange(); 22327 SourceLocation SL = E ? E->getBeginLoc() : D->getLocation(); 22328 if (auto *VD = dyn_cast<VarDecl>(D)) { 22329 // Only global variables can be marked as declare target. 22330 if (!VD->isFileVarDecl() && !VD->isStaticLocal() && 22331 !VD->isStaticDataMember()) 22332 return; 22333 // 2.10.6: threadprivate variable cannot appear in a declare target 22334 // directive. 22335 if (DSAStack->isThreadPrivate(VD)) { 22336 Diag(SL, diag::err_omp_threadprivate_in_target); 22337 reportOriginalDsa(*this, DSAStack, VD, DSAStack->getTopDSA(VD, false)); 22338 return; 22339 } 22340 } 22341 if (const auto *FTD = dyn_cast<FunctionTemplateDecl>(D)) 22342 D = FTD->getTemplatedDecl(); 22343 if (auto *FD = dyn_cast<FunctionDecl>(D)) { 22344 llvm::Optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res = 22345 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(FD); 22346 if (IdLoc.isValid() && Res && *Res == OMPDeclareTargetDeclAttr::MT_Link) { 22347 Diag(IdLoc, diag::err_omp_function_in_link_clause); 22348 Diag(FD->getLocation(), diag::note_defined_here) << FD; 22349 return; 22350 } 22351 } 22352 if (auto *VD = dyn_cast<ValueDecl>(D)) { 22353 // Problem if any with var declared with incomplete type will be reported 22354 // as normal, so no need to check it here. 22355 if ((E || !VD->getType()->isIncompleteType()) && 22356 !checkValueDeclInTarget(SL, SR, *this, DSAStack, VD)) 22357 return; 22358 if (!E && isInOpenMPDeclareTargetContext()) { 22359 // Checking declaration inside declare target region. 22360 if (isa<VarDecl>(D) || isa<FunctionDecl>(D) || 22361 isa<FunctionTemplateDecl>(D)) { 22362 llvm::Optional<OMPDeclareTargetDeclAttr *> ActiveAttr = 22363 OMPDeclareTargetDeclAttr::getActiveAttr(VD); 22364 unsigned Level = DeclareTargetNesting.size(); 22365 if (ActiveAttr && ActiveAttr.getValue()->getLevel() >= Level) 22366 return; 22367 DeclareTargetContextInfo &DTCI = DeclareTargetNesting.back(); 22368 Expr *IndirectE = nullptr; 22369 bool IsIndirect = false; 22370 if (DTCI.Indirect) { 22371 IndirectE = DTCI.Indirect.getValue(); 22372 if (!IndirectE) 22373 IsIndirect = true; 22374 } 22375 auto *A = OMPDeclareTargetDeclAttr::CreateImplicit( 22376 Context, OMPDeclareTargetDeclAttr::MT_To, DTCI.DT, IndirectE, 22377 IsIndirect, Level, SourceRange(DTCI.Loc, DTCI.Loc)); 22378 D->addAttr(A); 22379 if (ASTMutationListener *ML = Context.getASTMutationListener()) 22380 ML->DeclarationMarkedOpenMPDeclareTarget(D, A); 22381 } 22382 return; 22383 } 22384 } 22385 if (!E) 22386 return; 22387 checkDeclInTargetContext(E->getExprLoc(), E->getSourceRange(), *this, D); 22388 } 22389 22390 OMPClause *Sema::ActOnOpenMPToClause( 22391 ArrayRef<OpenMPMotionModifierKind> MotionModifiers, 22392 ArrayRef<SourceLocation> MotionModifiersLoc, 22393 CXXScopeSpec &MapperIdScopeSpec, DeclarationNameInfo &MapperId, 22394 SourceLocation ColonLoc, ArrayRef<Expr *> VarList, 22395 const OMPVarListLocTy &Locs, ArrayRef<Expr *> UnresolvedMappers) { 22396 OpenMPMotionModifierKind Modifiers[] = {OMPC_MOTION_MODIFIER_unknown, 22397 OMPC_MOTION_MODIFIER_unknown}; 22398 SourceLocation ModifiersLoc[NumberOfOMPMotionModifiers]; 22399 22400 // Process motion-modifiers, flag errors for duplicate modifiers. 22401 unsigned Count = 0; 22402 for (unsigned I = 0, E = MotionModifiers.size(); I < E; ++I) { 22403 if (MotionModifiers[I] != OMPC_MOTION_MODIFIER_unknown && 22404 llvm::is_contained(Modifiers, MotionModifiers[I])) { 22405 Diag(MotionModifiersLoc[I], diag::err_omp_duplicate_motion_modifier); 22406 continue; 22407 } 22408 assert(Count < NumberOfOMPMotionModifiers && 22409 "Modifiers exceed the allowed number of motion modifiers"); 22410 Modifiers[Count] = MotionModifiers[I]; 22411 ModifiersLoc[Count] = MotionModifiersLoc[I]; 22412 ++Count; 22413 } 22414 22415 MappableVarListInfo MVLI(VarList); 22416 checkMappableExpressionList(*this, DSAStack, OMPC_to, MVLI, Locs.StartLoc, 22417 MapperIdScopeSpec, MapperId, UnresolvedMappers); 22418 if (MVLI.ProcessedVarList.empty()) 22419 return nullptr; 22420 22421 return OMPToClause::Create( 22422 Context, Locs, MVLI.ProcessedVarList, MVLI.VarBaseDeclarations, 22423 MVLI.VarComponents, MVLI.UDMapperList, Modifiers, ModifiersLoc, 22424 MapperIdScopeSpec.getWithLocInContext(Context), MapperId); 22425 } 22426 22427 OMPClause *Sema::ActOnOpenMPFromClause( 22428 ArrayRef<OpenMPMotionModifierKind> MotionModifiers, 22429 ArrayRef<SourceLocation> MotionModifiersLoc, 22430 CXXScopeSpec &MapperIdScopeSpec, DeclarationNameInfo &MapperId, 22431 SourceLocation ColonLoc, ArrayRef<Expr *> VarList, 22432 const OMPVarListLocTy &Locs, ArrayRef<Expr *> UnresolvedMappers) { 22433 OpenMPMotionModifierKind Modifiers[] = {OMPC_MOTION_MODIFIER_unknown, 22434 OMPC_MOTION_MODIFIER_unknown}; 22435 SourceLocation ModifiersLoc[NumberOfOMPMotionModifiers]; 22436 22437 // Process motion-modifiers, flag errors for duplicate modifiers. 22438 unsigned Count = 0; 22439 for (unsigned I = 0, E = MotionModifiers.size(); I < E; ++I) { 22440 if (MotionModifiers[I] != OMPC_MOTION_MODIFIER_unknown && 22441 llvm::is_contained(Modifiers, MotionModifiers[I])) { 22442 Diag(MotionModifiersLoc[I], diag::err_omp_duplicate_motion_modifier); 22443 continue; 22444 } 22445 assert(Count < NumberOfOMPMotionModifiers && 22446 "Modifiers exceed the allowed number of motion modifiers"); 22447 Modifiers[Count] = MotionModifiers[I]; 22448 ModifiersLoc[Count] = MotionModifiersLoc[I]; 22449 ++Count; 22450 } 22451 22452 MappableVarListInfo MVLI(VarList); 22453 checkMappableExpressionList(*this, DSAStack, OMPC_from, MVLI, Locs.StartLoc, 22454 MapperIdScopeSpec, MapperId, UnresolvedMappers); 22455 if (MVLI.ProcessedVarList.empty()) 22456 return nullptr; 22457 22458 return OMPFromClause::Create( 22459 Context, Locs, MVLI.ProcessedVarList, MVLI.VarBaseDeclarations, 22460 MVLI.VarComponents, MVLI.UDMapperList, Modifiers, ModifiersLoc, 22461 MapperIdScopeSpec.getWithLocInContext(Context), MapperId); 22462 } 22463 22464 OMPClause *Sema::ActOnOpenMPUseDevicePtrClause(ArrayRef<Expr *> VarList, 22465 const OMPVarListLocTy &Locs) { 22466 MappableVarListInfo MVLI(VarList); 22467 SmallVector<Expr *, 8> PrivateCopies; 22468 SmallVector<Expr *, 8> Inits; 22469 22470 for (Expr *RefExpr : VarList) { 22471 assert(RefExpr && "NULL expr in OpenMP use_device_ptr clause."); 22472 SourceLocation ELoc; 22473 SourceRange ERange; 22474 Expr *SimpleRefExpr = RefExpr; 22475 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 22476 if (Res.second) { 22477 // It will be analyzed later. 22478 MVLI.ProcessedVarList.push_back(RefExpr); 22479 PrivateCopies.push_back(nullptr); 22480 Inits.push_back(nullptr); 22481 } 22482 ValueDecl *D = Res.first; 22483 if (!D) 22484 continue; 22485 22486 QualType Type = D->getType(); 22487 Type = Type.getNonReferenceType().getUnqualifiedType(); 22488 22489 auto *VD = dyn_cast<VarDecl>(D); 22490 22491 // Item should be a pointer or reference to pointer. 22492 if (!Type->isPointerType()) { 22493 Diag(ELoc, diag::err_omp_usedeviceptr_not_a_pointer) 22494 << 0 << RefExpr->getSourceRange(); 22495 continue; 22496 } 22497 22498 // Build the private variable and the expression that refers to it. 22499 auto VDPrivate = 22500 buildVarDecl(*this, ELoc, Type, D->getName(), 22501 D->hasAttrs() ? &D->getAttrs() : nullptr, 22502 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr); 22503 if (VDPrivate->isInvalidDecl()) 22504 continue; 22505 22506 CurContext->addDecl(VDPrivate); 22507 DeclRefExpr *VDPrivateRefExpr = buildDeclRefExpr( 22508 *this, VDPrivate, RefExpr->getType().getUnqualifiedType(), ELoc); 22509 22510 // Add temporary variable to initialize the private copy of the pointer. 22511 VarDecl *VDInit = 22512 buildVarDecl(*this, RefExpr->getExprLoc(), Type, ".devptr.temp"); 22513 DeclRefExpr *VDInitRefExpr = buildDeclRefExpr( 22514 *this, VDInit, RefExpr->getType(), RefExpr->getExprLoc()); 22515 AddInitializerToDecl(VDPrivate, 22516 DefaultLvalueConversion(VDInitRefExpr).get(), 22517 /*DirectInit=*/false); 22518 22519 // If required, build a capture to implement the privatization initialized 22520 // with the current list item value. 22521 DeclRefExpr *Ref = nullptr; 22522 if (!VD) 22523 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true); 22524 MVLI.ProcessedVarList.push_back(VD ? RefExpr->IgnoreParens() : Ref); 22525 PrivateCopies.push_back(VDPrivateRefExpr); 22526 Inits.push_back(VDInitRefExpr); 22527 22528 // We need to add a data sharing attribute for this variable to make sure it 22529 // is correctly captured. A variable that shows up in a use_device_ptr has 22530 // similar properties of a first private variable. 22531 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_firstprivate, Ref); 22532 22533 // Create a mappable component for the list item. List items in this clause 22534 // only need a component. 22535 MVLI.VarBaseDeclarations.push_back(D); 22536 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1); 22537 MVLI.VarComponents.back().emplace_back(SimpleRefExpr, D, 22538 /*IsNonContiguous=*/false); 22539 } 22540 22541 if (MVLI.ProcessedVarList.empty()) 22542 return nullptr; 22543 22544 return OMPUseDevicePtrClause::Create( 22545 Context, Locs, MVLI.ProcessedVarList, PrivateCopies, Inits, 22546 MVLI.VarBaseDeclarations, MVLI.VarComponents); 22547 } 22548 22549 OMPClause *Sema::ActOnOpenMPUseDeviceAddrClause(ArrayRef<Expr *> VarList, 22550 const OMPVarListLocTy &Locs) { 22551 MappableVarListInfo MVLI(VarList); 22552 22553 for (Expr *RefExpr : VarList) { 22554 assert(RefExpr && "NULL expr in OpenMP use_device_addr clause."); 22555 SourceLocation ELoc; 22556 SourceRange ERange; 22557 Expr *SimpleRefExpr = RefExpr; 22558 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange, 22559 /*AllowArraySection=*/true); 22560 if (Res.second) { 22561 // It will be analyzed later. 22562 MVLI.ProcessedVarList.push_back(RefExpr); 22563 } 22564 ValueDecl *D = Res.first; 22565 if (!D) 22566 continue; 22567 auto *VD = dyn_cast<VarDecl>(D); 22568 22569 // If required, build a capture to implement the privatization initialized 22570 // with the current list item value. 22571 DeclRefExpr *Ref = nullptr; 22572 if (!VD) 22573 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true); 22574 MVLI.ProcessedVarList.push_back(VD ? RefExpr->IgnoreParens() : Ref); 22575 22576 // We need to add a data sharing attribute for this variable to make sure it 22577 // is correctly captured. A variable that shows up in a use_device_addr has 22578 // similar properties of a first private variable. 22579 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_firstprivate, Ref); 22580 22581 // Create a mappable component for the list item. List items in this clause 22582 // only need a component. 22583 MVLI.VarBaseDeclarations.push_back(D); 22584 MVLI.VarComponents.emplace_back(); 22585 Expr *Component = SimpleRefExpr; 22586 if (VD && (isa<OMPArraySectionExpr>(RefExpr->IgnoreParenImpCasts()) || 22587 isa<ArraySubscriptExpr>(RefExpr->IgnoreParenImpCasts()))) 22588 Component = DefaultFunctionArrayLvalueConversion(SimpleRefExpr).get(); 22589 MVLI.VarComponents.back().emplace_back(Component, D, 22590 /*IsNonContiguous=*/false); 22591 } 22592 22593 if (MVLI.ProcessedVarList.empty()) 22594 return nullptr; 22595 22596 return OMPUseDeviceAddrClause::Create(Context, Locs, MVLI.ProcessedVarList, 22597 MVLI.VarBaseDeclarations, 22598 MVLI.VarComponents); 22599 } 22600 22601 OMPClause *Sema::ActOnOpenMPIsDevicePtrClause(ArrayRef<Expr *> VarList, 22602 const OMPVarListLocTy &Locs) { 22603 MappableVarListInfo MVLI(VarList); 22604 for (Expr *RefExpr : VarList) { 22605 assert(RefExpr && "NULL expr in OpenMP is_device_ptr clause."); 22606 SourceLocation ELoc; 22607 SourceRange ERange; 22608 Expr *SimpleRefExpr = RefExpr; 22609 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 22610 if (Res.second) { 22611 // It will be analyzed later. 22612 MVLI.ProcessedVarList.push_back(RefExpr); 22613 } 22614 ValueDecl *D = Res.first; 22615 if (!D) 22616 continue; 22617 22618 QualType Type = D->getType(); 22619 // item should be a pointer or array or reference to pointer or array 22620 if (!Type.getNonReferenceType()->isPointerType() && 22621 !Type.getNonReferenceType()->isArrayType()) { 22622 Diag(ELoc, diag::err_omp_argument_type_isdeviceptr) 22623 << 0 << RefExpr->getSourceRange(); 22624 continue; 22625 } 22626 22627 // Check if the declaration in the clause does not show up in any data 22628 // sharing attribute. 22629 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false); 22630 if (isOpenMPPrivate(DVar.CKind)) { 22631 Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa) 22632 << getOpenMPClauseName(DVar.CKind) 22633 << getOpenMPClauseName(OMPC_is_device_ptr) 22634 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 22635 reportOriginalDsa(*this, DSAStack, D, DVar); 22636 continue; 22637 } 22638 22639 const Expr *ConflictExpr; 22640 if (DSAStack->checkMappableExprComponentListsForDecl( 22641 D, /*CurrentRegionOnly=*/true, 22642 [&ConflictExpr]( 22643 OMPClauseMappableExprCommon::MappableExprComponentListRef R, 22644 OpenMPClauseKind) -> bool { 22645 ConflictExpr = R.front().getAssociatedExpression(); 22646 return true; 22647 })) { 22648 Diag(ELoc, diag::err_omp_map_shared_storage) << RefExpr->getSourceRange(); 22649 Diag(ConflictExpr->getExprLoc(), diag::note_used_here) 22650 << ConflictExpr->getSourceRange(); 22651 continue; 22652 } 22653 22654 // Store the components in the stack so that they can be used to check 22655 // against other clauses later on. 22656 OMPClauseMappableExprCommon::MappableComponent MC( 22657 SimpleRefExpr, D, /*IsNonContiguous=*/false); 22658 DSAStack->addMappableExpressionComponents( 22659 D, MC, /*WhereFoundClauseKind=*/OMPC_is_device_ptr); 22660 22661 // Record the expression we've just processed. 22662 MVLI.ProcessedVarList.push_back(SimpleRefExpr); 22663 22664 // Create a mappable component for the list item. List items in this clause 22665 // only need a component. We use a null declaration to signal fields in 22666 // 'this'. 22667 assert((isa<DeclRefExpr>(SimpleRefExpr) || 22668 isa<CXXThisExpr>(cast<MemberExpr>(SimpleRefExpr)->getBase())) && 22669 "Unexpected device pointer expression!"); 22670 MVLI.VarBaseDeclarations.push_back( 22671 isa<DeclRefExpr>(SimpleRefExpr) ? D : nullptr); 22672 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1); 22673 MVLI.VarComponents.back().push_back(MC); 22674 } 22675 22676 if (MVLI.ProcessedVarList.empty()) 22677 return nullptr; 22678 22679 return OMPIsDevicePtrClause::Create(Context, Locs, MVLI.ProcessedVarList, 22680 MVLI.VarBaseDeclarations, 22681 MVLI.VarComponents); 22682 } 22683 22684 OMPClause *Sema::ActOnOpenMPHasDeviceAddrClause(ArrayRef<Expr *> VarList, 22685 const OMPVarListLocTy &Locs) { 22686 MappableVarListInfo MVLI(VarList); 22687 for (Expr *RefExpr : VarList) { 22688 assert(RefExpr && "NULL expr in OpenMP has_device_addr clause."); 22689 SourceLocation ELoc; 22690 SourceRange ERange; 22691 Expr *SimpleRefExpr = RefExpr; 22692 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange, 22693 /*AllowArraySection=*/true); 22694 if (Res.second) { 22695 // It will be analyzed later. 22696 MVLI.ProcessedVarList.push_back(RefExpr); 22697 } 22698 ValueDecl *D = Res.first; 22699 if (!D) 22700 continue; 22701 22702 // Check if the declaration in the clause does not show up in any data 22703 // sharing attribute. 22704 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false); 22705 if (isOpenMPPrivate(DVar.CKind)) { 22706 Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa) 22707 << getOpenMPClauseName(DVar.CKind) 22708 << getOpenMPClauseName(OMPC_has_device_addr) 22709 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 22710 reportOriginalDsa(*this, DSAStack, D, DVar); 22711 continue; 22712 } 22713 22714 const Expr *ConflictExpr; 22715 if (DSAStack->checkMappableExprComponentListsForDecl( 22716 D, /*CurrentRegionOnly=*/true, 22717 [&ConflictExpr]( 22718 OMPClauseMappableExprCommon::MappableExprComponentListRef R, 22719 OpenMPClauseKind) -> bool { 22720 ConflictExpr = R.front().getAssociatedExpression(); 22721 return true; 22722 })) { 22723 Diag(ELoc, diag::err_omp_map_shared_storage) << RefExpr->getSourceRange(); 22724 Diag(ConflictExpr->getExprLoc(), diag::note_used_here) 22725 << ConflictExpr->getSourceRange(); 22726 continue; 22727 } 22728 22729 // Store the components in the stack so that they can be used to check 22730 // against other clauses later on. 22731 OMPClauseMappableExprCommon::MappableComponent MC( 22732 SimpleRefExpr, D, /*IsNonContiguous=*/false); 22733 DSAStack->addMappableExpressionComponents( 22734 D, MC, /*WhereFoundClauseKind=*/OMPC_has_device_addr); 22735 22736 // Record the expression we've just processed. 22737 auto *VD = dyn_cast<VarDecl>(D); 22738 if (!VD && !CurContext->isDependentContext()) { 22739 DeclRefExpr *Ref = 22740 buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true); 22741 assert(Ref && "has_device_addr capture failed"); 22742 MVLI.ProcessedVarList.push_back(Ref); 22743 } else 22744 MVLI.ProcessedVarList.push_back(RefExpr->IgnoreParens()); 22745 22746 // Create a mappable component for the list item. List items in this clause 22747 // only need a component. We use a null declaration to signal fields in 22748 // 'this'. 22749 assert((isa<DeclRefExpr>(SimpleRefExpr) || 22750 isa<CXXThisExpr>(cast<MemberExpr>(SimpleRefExpr)->getBase())) && 22751 "Unexpected device pointer expression!"); 22752 MVLI.VarBaseDeclarations.push_back( 22753 isa<DeclRefExpr>(SimpleRefExpr) ? D : nullptr); 22754 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1); 22755 MVLI.VarComponents.back().push_back(MC); 22756 } 22757 22758 if (MVLI.ProcessedVarList.empty()) 22759 return nullptr; 22760 22761 return OMPHasDeviceAddrClause::Create(Context, Locs, MVLI.ProcessedVarList, 22762 MVLI.VarBaseDeclarations, 22763 MVLI.VarComponents); 22764 } 22765 22766 OMPClause *Sema::ActOnOpenMPAllocateClause( 22767 Expr *Allocator, ArrayRef<Expr *> VarList, SourceLocation StartLoc, 22768 SourceLocation ColonLoc, SourceLocation LParenLoc, SourceLocation EndLoc) { 22769 if (Allocator) { 22770 // OpenMP [2.11.4 allocate Clause, Description] 22771 // allocator is an expression of omp_allocator_handle_t type. 22772 if (!findOMPAllocatorHandleT(*this, Allocator->getExprLoc(), DSAStack)) 22773 return nullptr; 22774 22775 ExprResult AllocatorRes = DefaultLvalueConversion(Allocator); 22776 if (AllocatorRes.isInvalid()) 22777 return nullptr; 22778 AllocatorRes = PerformImplicitConversion(AllocatorRes.get(), 22779 DSAStack->getOMPAllocatorHandleT(), 22780 Sema::AA_Initializing, 22781 /*AllowExplicit=*/true); 22782 if (AllocatorRes.isInvalid()) 22783 return nullptr; 22784 Allocator = AllocatorRes.get(); 22785 } else { 22786 // OpenMP 5.0, 2.11.4 allocate Clause, Restrictions. 22787 // allocate clauses that appear on a target construct or on constructs in a 22788 // target region must specify an allocator expression unless a requires 22789 // directive with the dynamic_allocators clause is present in the same 22790 // compilation unit. 22791 if (LangOpts.OpenMPIsDevice && 22792 !DSAStack->hasRequiresDeclWithClause<OMPDynamicAllocatorsClause>()) 22793 targetDiag(StartLoc, diag::err_expected_allocator_expression); 22794 } 22795 // Analyze and build list of variables. 22796 SmallVector<Expr *, 8> Vars; 22797 for (Expr *RefExpr : VarList) { 22798 assert(RefExpr && "NULL expr in OpenMP private clause."); 22799 SourceLocation ELoc; 22800 SourceRange ERange; 22801 Expr *SimpleRefExpr = RefExpr; 22802 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 22803 if (Res.second) { 22804 // It will be analyzed later. 22805 Vars.push_back(RefExpr); 22806 } 22807 ValueDecl *D = Res.first; 22808 if (!D) 22809 continue; 22810 22811 auto *VD = dyn_cast<VarDecl>(D); 22812 DeclRefExpr *Ref = nullptr; 22813 if (!VD && !CurContext->isDependentContext()) 22814 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false); 22815 Vars.push_back((VD || CurContext->isDependentContext()) 22816 ? RefExpr->IgnoreParens() 22817 : Ref); 22818 } 22819 22820 if (Vars.empty()) 22821 return nullptr; 22822 22823 if (Allocator) 22824 DSAStack->addInnerAllocatorExpr(Allocator); 22825 return OMPAllocateClause::Create(Context, StartLoc, LParenLoc, Allocator, 22826 ColonLoc, EndLoc, Vars); 22827 } 22828 22829 OMPClause *Sema::ActOnOpenMPNontemporalClause(ArrayRef<Expr *> VarList, 22830 SourceLocation StartLoc, 22831 SourceLocation LParenLoc, 22832 SourceLocation EndLoc) { 22833 SmallVector<Expr *, 8> Vars; 22834 for (Expr *RefExpr : VarList) { 22835 assert(RefExpr && "NULL expr in OpenMP nontemporal clause."); 22836 SourceLocation ELoc; 22837 SourceRange ERange; 22838 Expr *SimpleRefExpr = RefExpr; 22839 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 22840 if (Res.second) 22841 // It will be analyzed later. 22842 Vars.push_back(RefExpr); 22843 ValueDecl *D = Res.first; 22844 if (!D) 22845 continue; 22846 22847 // OpenMP 5.0, 2.9.3.1 simd Construct, Restrictions. 22848 // A list-item cannot appear in more than one nontemporal clause. 22849 if (const Expr *PrevRef = 22850 DSAStack->addUniqueNontemporal(D, SimpleRefExpr)) { 22851 Diag(ELoc, diag::err_omp_used_in_clause_twice) 22852 << 0 << getOpenMPClauseName(OMPC_nontemporal) << ERange; 22853 Diag(PrevRef->getExprLoc(), diag::note_omp_explicit_dsa) 22854 << getOpenMPClauseName(OMPC_nontemporal); 22855 continue; 22856 } 22857 22858 Vars.push_back(RefExpr); 22859 } 22860 22861 if (Vars.empty()) 22862 return nullptr; 22863 22864 return OMPNontemporalClause::Create(Context, StartLoc, LParenLoc, EndLoc, 22865 Vars); 22866 } 22867 22868 OMPClause *Sema::ActOnOpenMPInclusiveClause(ArrayRef<Expr *> VarList, 22869 SourceLocation StartLoc, 22870 SourceLocation LParenLoc, 22871 SourceLocation EndLoc) { 22872 SmallVector<Expr *, 8> Vars; 22873 for (Expr *RefExpr : VarList) { 22874 assert(RefExpr && "NULL expr in OpenMP nontemporal clause."); 22875 SourceLocation ELoc; 22876 SourceRange ERange; 22877 Expr *SimpleRefExpr = RefExpr; 22878 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange, 22879 /*AllowArraySection=*/true); 22880 if (Res.second) 22881 // It will be analyzed later. 22882 Vars.push_back(RefExpr); 22883 ValueDecl *D = Res.first; 22884 if (!D) 22885 continue; 22886 22887 const DSAStackTy::DSAVarData DVar = 22888 DSAStack->getTopDSA(D, /*FromParent=*/true); 22889 // OpenMP 5.0, 2.9.6, scan Directive, Restrictions. 22890 // A list item that appears in the inclusive or exclusive clause must appear 22891 // in a reduction clause with the inscan modifier on the enclosing 22892 // worksharing-loop, worksharing-loop SIMD, or simd construct. 22893 if (DVar.CKind != OMPC_reduction || DVar.Modifier != OMPC_REDUCTION_inscan) 22894 Diag(ELoc, diag::err_omp_inclusive_exclusive_not_reduction) 22895 << RefExpr->getSourceRange(); 22896 22897 if (DSAStack->getParentDirective() != OMPD_unknown) 22898 DSAStack->markDeclAsUsedInScanDirective(D); 22899 Vars.push_back(RefExpr); 22900 } 22901 22902 if (Vars.empty()) 22903 return nullptr; 22904 22905 return OMPInclusiveClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars); 22906 } 22907 22908 OMPClause *Sema::ActOnOpenMPExclusiveClause(ArrayRef<Expr *> VarList, 22909 SourceLocation StartLoc, 22910 SourceLocation LParenLoc, 22911 SourceLocation EndLoc) { 22912 SmallVector<Expr *, 8> Vars; 22913 for (Expr *RefExpr : VarList) { 22914 assert(RefExpr && "NULL expr in OpenMP nontemporal clause."); 22915 SourceLocation ELoc; 22916 SourceRange ERange; 22917 Expr *SimpleRefExpr = RefExpr; 22918 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange, 22919 /*AllowArraySection=*/true); 22920 if (Res.second) 22921 // It will be analyzed later. 22922 Vars.push_back(RefExpr); 22923 ValueDecl *D = Res.first; 22924 if (!D) 22925 continue; 22926 22927 OpenMPDirectiveKind ParentDirective = DSAStack->getParentDirective(); 22928 DSAStackTy::DSAVarData DVar; 22929 if (ParentDirective != OMPD_unknown) 22930 DVar = DSAStack->getTopDSA(D, /*FromParent=*/true); 22931 // OpenMP 5.0, 2.9.6, scan Directive, Restrictions. 22932 // A list item that appears in the inclusive or exclusive clause must appear 22933 // in a reduction clause with the inscan modifier on the enclosing 22934 // worksharing-loop, worksharing-loop SIMD, or simd construct. 22935 if (ParentDirective == OMPD_unknown || DVar.CKind != OMPC_reduction || 22936 DVar.Modifier != OMPC_REDUCTION_inscan) { 22937 Diag(ELoc, diag::err_omp_inclusive_exclusive_not_reduction) 22938 << RefExpr->getSourceRange(); 22939 } else { 22940 DSAStack->markDeclAsUsedInScanDirective(D); 22941 } 22942 Vars.push_back(RefExpr); 22943 } 22944 22945 if (Vars.empty()) 22946 return nullptr; 22947 22948 return OMPExclusiveClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars); 22949 } 22950 22951 /// Tries to find omp_alloctrait_t type. 22952 static bool findOMPAlloctraitT(Sema &S, SourceLocation Loc, DSAStackTy *Stack) { 22953 QualType OMPAlloctraitT = Stack->getOMPAlloctraitT(); 22954 if (!OMPAlloctraitT.isNull()) 22955 return true; 22956 IdentifierInfo &II = S.PP.getIdentifierTable().get("omp_alloctrait_t"); 22957 ParsedType PT = S.getTypeName(II, Loc, S.getCurScope()); 22958 if (!PT.getAsOpaquePtr() || PT.get().isNull()) { 22959 S.Diag(Loc, diag::err_omp_implied_type_not_found) << "omp_alloctrait_t"; 22960 return false; 22961 } 22962 Stack->setOMPAlloctraitT(PT.get()); 22963 return true; 22964 } 22965 22966 OMPClause *Sema::ActOnOpenMPUsesAllocatorClause( 22967 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc, 22968 ArrayRef<UsesAllocatorsData> Data) { 22969 // OpenMP [2.12.5, target Construct] 22970 // allocator is an identifier of omp_allocator_handle_t type. 22971 if (!findOMPAllocatorHandleT(*this, StartLoc, DSAStack)) 22972 return nullptr; 22973 // OpenMP [2.12.5, target Construct] 22974 // allocator-traits-array is an identifier of const omp_alloctrait_t * type. 22975 if (llvm::any_of( 22976 Data, 22977 [](const UsesAllocatorsData &D) { return D.AllocatorTraits; }) && 22978 !findOMPAlloctraitT(*this, StartLoc, DSAStack)) 22979 return nullptr; 22980 llvm::SmallPtrSet<CanonicalDeclPtr<Decl>, 4> PredefinedAllocators; 22981 for (int I = 0; I < OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; ++I) { 22982 auto AllocatorKind = static_cast<OMPAllocateDeclAttr::AllocatorTypeTy>(I); 22983 StringRef Allocator = 22984 OMPAllocateDeclAttr::ConvertAllocatorTypeTyToStr(AllocatorKind); 22985 DeclarationName AllocatorName = &Context.Idents.get(Allocator); 22986 PredefinedAllocators.insert(LookupSingleName( 22987 TUScope, AllocatorName, StartLoc, Sema::LookupAnyName)); 22988 } 22989 22990 SmallVector<OMPUsesAllocatorsClause::Data, 4> NewData; 22991 for (const UsesAllocatorsData &D : Data) { 22992 Expr *AllocatorExpr = nullptr; 22993 // Check allocator expression. 22994 if (D.Allocator->isTypeDependent()) { 22995 AllocatorExpr = D.Allocator; 22996 } else { 22997 // Traits were specified - need to assign new allocator to the specified 22998 // allocator, so it must be an lvalue. 22999 AllocatorExpr = D.Allocator->IgnoreParenImpCasts(); 23000 auto *DRE = dyn_cast<DeclRefExpr>(AllocatorExpr); 23001 bool IsPredefinedAllocator = false; 23002 if (DRE) 23003 IsPredefinedAllocator = PredefinedAllocators.count(DRE->getDecl()); 23004 if (!DRE || 23005 !(Context.hasSameUnqualifiedType( 23006 AllocatorExpr->getType(), DSAStack->getOMPAllocatorHandleT()) || 23007 Context.typesAreCompatible(AllocatorExpr->getType(), 23008 DSAStack->getOMPAllocatorHandleT(), 23009 /*CompareUnqualified=*/true)) || 23010 (!IsPredefinedAllocator && 23011 (AllocatorExpr->getType().isConstant(Context) || 23012 !AllocatorExpr->isLValue()))) { 23013 Diag(D.Allocator->getExprLoc(), diag::err_omp_var_expected) 23014 << "omp_allocator_handle_t" << (DRE ? 1 : 0) 23015 << AllocatorExpr->getType() << D.Allocator->getSourceRange(); 23016 continue; 23017 } 23018 // OpenMP [2.12.5, target Construct] 23019 // Predefined allocators appearing in a uses_allocators clause cannot have 23020 // traits specified. 23021 if (IsPredefinedAllocator && D.AllocatorTraits) { 23022 Diag(D.AllocatorTraits->getExprLoc(), 23023 diag::err_omp_predefined_allocator_with_traits) 23024 << D.AllocatorTraits->getSourceRange(); 23025 Diag(D.Allocator->getExprLoc(), diag::note_omp_predefined_allocator) 23026 << cast<NamedDecl>(DRE->getDecl())->getName() 23027 << D.Allocator->getSourceRange(); 23028 continue; 23029 } 23030 // OpenMP [2.12.5, target Construct] 23031 // Non-predefined allocators appearing in a uses_allocators clause must 23032 // have traits specified. 23033 if (!IsPredefinedAllocator && !D.AllocatorTraits) { 23034 Diag(D.Allocator->getExprLoc(), 23035 diag::err_omp_nonpredefined_allocator_without_traits); 23036 continue; 23037 } 23038 // No allocator traits - just convert it to rvalue. 23039 if (!D.AllocatorTraits) 23040 AllocatorExpr = DefaultLvalueConversion(AllocatorExpr).get(); 23041 DSAStack->addUsesAllocatorsDecl( 23042 DRE->getDecl(), 23043 IsPredefinedAllocator 23044 ? DSAStackTy::UsesAllocatorsDeclKind::PredefinedAllocator 23045 : DSAStackTy::UsesAllocatorsDeclKind::UserDefinedAllocator); 23046 } 23047 Expr *AllocatorTraitsExpr = nullptr; 23048 if (D.AllocatorTraits) { 23049 if (D.AllocatorTraits->isTypeDependent()) { 23050 AllocatorTraitsExpr = D.AllocatorTraits; 23051 } else { 23052 // OpenMP [2.12.5, target Construct] 23053 // Arrays that contain allocator traits that appear in a uses_allocators 23054 // clause must be constant arrays, have constant values and be defined 23055 // in the same scope as the construct in which the clause appears. 23056 AllocatorTraitsExpr = D.AllocatorTraits->IgnoreParenImpCasts(); 23057 // Check that traits expr is a constant array. 23058 QualType TraitTy; 23059 if (const ArrayType *Ty = 23060 AllocatorTraitsExpr->getType()->getAsArrayTypeUnsafe()) 23061 if (const auto *ConstArrayTy = dyn_cast<ConstantArrayType>(Ty)) 23062 TraitTy = ConstArrayTy->getElementType(); 23063 if (TraitTy.isNull() || 23064 !(Context.hasSameUnqualifiedType(TraitTy, 23065 DSAStack->getOMPAlloctraitT()) || 23066 Context.typesAreCompatible(TraitTy, DSAStack->getOMPAlloctraitT(), 23067 /*CompareUnqualified=*/true))) { 23068 Diag(D.AllocatorTraits->getExprLoc(), 23069 diag::err_omp_expected_array_alloctraits) 23070 << AllocatorTraitsExpr->getType(); 23071 continue; 23072 } 23073 // Do not map by default allocator traits if it is a standalone 23074 // variable. 23075 if (auto *DRE = dyn_cast<DeclRefExpr>(AllocatorTraitsExpr)) 23076 DSAStack->addUsesAllocatorsDecl( 23077 DRE->getDecl(), 23078 DSAStackTy::UsesAllocatorsDeclKind::AllocatorTrait); 23079 } 23080 } 23081 OMPUsesAllocatorsClause::Data &NewD = NewData.emplace_back(); 23082 NewD.Allocator = AllocatorExpr; 23083 NewD.AllocatorTraits = AllocatorTraitsExpr; 23084 NewD.LParenLoc = D.LParenLoc; 23085 NewD.RParenLoc = D.RParenLoc; 23086 } 23087 return OMPUsesAllocatorsClause::Create(Context, StartLoc, LParenLoc, EndLoc, 23088 NewData); 23089 } 23090 23091 OMPClause *Sema::ActOnOpenMPAffinityClause( 23092 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation ColonLoc, 23093 SourceLocation EndLoc, Expr *Modifier, ArrayRef<Expr *> Locators) { 23094 SmallVector<Expr *, 8> Vars; 23095 for (Expr *RefExpr : Locators) { 23096 assert(RefExpr && "NULL expr in OpenMP shared clause."); 23097 if (isa<DependentScopeDeclRefExpr>(RefExpr) || RefExpr->isTypeDependent()) { 23098 // It will be analyzed later. 23099 Vars.push_back(RefExpr); 23100 continue; 23101 } 23102 23103 SourceLocation ELoc = RefExpr->getExprLoc(); 23104 Expr *SimpleExpr = RefExpr->IgnoreParenImpCasts(); 23105 23106 if (!SimpleExpr->isLValue()) { 23107 Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item) 23108 << 1 << 0 << RefExpr->getSourceRange(); 23109 continue; 23110 } 23111 23112 ExprResult Res; 23113 { 23114 Sema::TentativeAnalysisScope Trap(*this); 23115 Res = CreateBuiltinUnaryOp(ELoc, UO_AddrOf, SimpleExpr); 23116 } 23117 if (!Res.isUsable() && !isa<OMPArraySectionExpr>(SimpleExpr) && 23118 !isa<OMPArrayShapingExpr>(SimpleExpr)) { 23119 Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item) 23120 << 1 << 0 << RefExpr->getSourceRange(); 23121 continue; 23122 } 23123 Vars.push_back(SimpleExpr); 23124 } 23125 23126 return OMPAffinityClause::Create(Context, StartLoc, LParenLoc, ColonLoc, 23127 EndLoc, Modifier, Vars); 23128 } 23129 23130 OMPClause *Sema::ActOnOpenMPBindClause(OpenMPBindClauseKind Kind, 23131 SourceLocation KindLoc, 23132 SourceLocation StartLoc, 23133 SourceLocation LParenLoc, 23134 SourceLocation EndLoc) { 23135 if (Kind == OMPC_BIND_unknown) { 23136 Diag(KindLoc, diag::err_omp_unexpected_clause_value) 23137 << getListOfPossibleValues(OMPC_bind, /*First=*/0, 23138 /*Last=*/unsigned(OMPC_BIND_unknown)) 23139 << getOpenMPClauseName(OMPC_bind); 23140 return nullptr; 23141 } 23142 23143 return OMPBindClause::Create(Context, Kind, KindLoc, StartLoc, LParenLoc, 23144 EndLoc); 23145 } 23146