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.hasValue()) 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.hasValue()) 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).getValueOr( 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).hasValue()) 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_loop: 3975 case OMPD_teams: 3976 case OMPD_teams_distribute: 3977 case OMPD_teams_distribute_simd: { 3978 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 3979 QualType KmpInt32PtrTy = 3980 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3981 Sema::CapturedParamNameType Params[] = { 3982 std::make_pair(".global_tid.", KmpInt32PtrTy), 3983 std::make_pair(".bound_tid.", KmpInt32PtrTy), 3984 std::make_pair(StringRef(), QualType()) // __context with shared vars 3985 }; 3986 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3987 Params); 3988 break; 3989 } 3990 case OMPD_target_teams: 3991 case OMPD_target_parallel: 3992 case OMPD_target_parallel_for: 3993 case OMPD_target_parallel_for_simd: 3994 case OMPD_target_teams_loop: 3995 case OMPD_target_parallel_loop: 3996 case OMPD_target_teams_distribute: 3997 case OMPD_target_teams_distribute_simd: { 3998 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 3999 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 4000 QualType KmpInt32PtrTy = 4001 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 4002 QualType Args[] = {VoidPtrTy}; 4003 FunctionProtoType::ExtProtoInfo EPI; 4004 EPI.Variadic = true; 4005 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 4006 Sema::CapturedParamNameType Params[] = { 4007 std::make_pair(".global_tid.", KmpInt32Ty), 4008 std::make_pair(".part_id.", KmpInt32PtrTy), 4009 std::make_pair(".privates.", VoidPtrTy), 4010 std::make_pair( 4011 ".copy_fn.", 4012 Context.getPointerType(CopyFnType).withConst().withRestrict()), 4013 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 4014 std::make_pair(StringRef(), QualType()) // __context with shared vars 4015 }; 4016 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 4017 Params, /*OpenMPCaptureLevel=*/0); 4018 // Mark this captured region as inlined, because we don't use outlined 4019 // function directly. 4020 getCurCapturedRegion()->TheCapturedDecl->addAttr( 4021 AlwaysInlineAttr::CreateImplicit( 4022 Context, {}, AttributeCommonInfo::AS_Keyword, 4023 AlwaysInlineAttr::Keyword_forceinline)); 4024 Sema::CapturedParamNameType ParamsTarget[] = { 4025 std::make_pair(StringRef(), QualType()) // __context with shared vars 4026 }; 4027 // Start a captured region for 'target' with no implicit parameters. 4028 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 4029 ParamsTarget, /*OpenMPCaptureLevel=*/1); 4030 Sema::CapturedParamNameType ParamsTeamsOrParallel[] = { 4031 std::make_pair(".global_tid.", KmpInt32PtrTy), 4032 std::make_pair(".bound_tid.", KmpInt32PtrTy), 4033 std::make_pair(StringRef(), QualType()) // __context with shared vars 4034 }; 4035 // Start a captured region for 'teams' or 'parallel'. Both regions have 4036 // the same implicit parameters. 4037 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 4038 ParamsTeamsOrParallel, /*OpenMPCaptureLevel=*/2); 4039 break; 4040 } 4041 case OMPD_target: 4042 case OMPD_target_simd: { 4043 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 4044 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 4045 QualType KmpInt32PtrTy = 4046 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 4047 QualType Args[] = {VoidPtrTy}; 4048 FunctionProtoType::ExtProtoInfo EPI; 4049 EPI.Variadic = true; 4050 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 4051 Sema::CapturedParamNameType Params[] = { 4052 std::make_pair(".global_tid.", KmpInt32Ty), 4053 std::make_pair(".part_id.", KmpInt32PtrTy), 4054 std::make_pair(".privates.", VoidPtrTy), 4055 std::make_pair( 4056 ".copy_fn.", 4057 Context.getPointerType(CopyFnType).withConst().withRestrict()), 4058 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 4059 std::make_pair(StringRef(), QualType()) // __context with shared vars 4060 }; 4061 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 4062 Params, /*OpenMPCaptureLevel=*/0); 4063 // Mark this captured region as inlined, because we don't use outlined 4064 // function directly. 4065 getCurCapturedRegion()->TheCapturedDecl->addAttr( 4066 AlwaysInlineAttr::CreateImplicit( 4067 Context, {}, AttributeCommonInfo::AS_Keyword, 4068 AlwaysInlineAttr::Keyword_forceinline)); 4069 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 4070 std::make_pair(StringRef(), QualType()), 4071 /*OpenMPCaptureLevel=*/1); 4072 break; 4073 } 4074 case OMPD_atomic: 4075 case OMPD_critical: 4076 case OMPD_section: 4077 case OMPD_master: 4078 case OMPD_masked: 4079 case OMPD_tile: 4080 case OMPD_unroll: 4081 break; 4082 case OMPD_loop: 4083 // TODO: 'loop' may require additional parameters depending on the binding. 4084 // Treat similar to OMPD_simd/OMPD_for for now. 4085 case OMPD_simd: 4086 case OMPD_for: 4087 case OMPD_for_simd: 4088 case OMPD_sections: 4089 case OMPD_single: 4090 case OMPD_taskgroup: 4091 case OMPD_distribute: 4092 case OMPD_distribute_simd: 4093 case OMPD_ordered: 4094 case OMPD_target_data: 4095 case OMPD_dispatch: { 4096 Sema::CapturedParamNameType Params[] = { 4097 std::make_pair(StringRef(), QualType()) // __context with shared vars 4098 }; 4099 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 4100 Params); 4101 break; 4102 } 4103 case OMPD_task: { 4104 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 4105 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 4106 QualType KmpInt32PtrTy = 4107 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 4108 QualType Args[] = {VoidPtrTy}; 4109 FunctionProtoType::ExtProtoInfo EPI; 4110 EPI.Variadic = true; 4111 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 4112 Sema::CapturedParamNameType Params[] = { 4113 std::make_pair(".global_tid.", KmpInt32Ty), 4114 std::make_pair(".part_id.", KmpInt32PtrTy), 4115 std::make_pair(".privates.", VoidPtrTy), 4116 std::make_pair( 4117 ".copy_fn.", 4118 Context.getPointerType(CopyFnType).withConst().withRestrict()), 4119 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 4120 std::make_pair(StringRef(), QualType()) // __context with shared vars 4121 }; 4122 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 4123 Params); 4124 // Mark this captured region as inlined, because we don't use outlined 4125 // function directly. 4126 getCurCapturedRegion()->TheCapturedDecl->addAttr( 4127 AlwaysInlineAttr::CreateImplicit( 4128 Context, {}, AttributeCommonInfo::AS_Keyword, 4129 AlwaysInlineAttr::Keyword_forceinline)); 4130 break; 4131 } 4132 case OMPD_taskloop: 4133 case OMPD_taskloop_simd: 4134 case OMPD_master_taskloop: 4135 case OMPD_master_taskloop_simd: { 4136 QualType KmpInt32Ty = 4137 Context.getIntTypeForBitwidth(/*DestWidth=*/32, /*Signed=*/1) 4138 .withConst(); 4139 QualType KmpUInt64Ty = 4140 Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/0) 4141 .withConst(); 4142 QualType KmpInt64Ty = 4143 Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/1) 4144 .withConst(); 4145 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 4146 QualType KmpInt32PtrTy = 4147 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 4148 QualType Args[] = {VoidPtrTy}; 4149 FunctionProtoType::ExtProtoInfo EPI; 4150 EPI.Variadic = true; 4151 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 4152 Sema::CapturedParamNameType Params[] = { 4153 std::make_pair(".global_tid.", KmpInt32Ty), 4154 std::make_pair(".part_id.", KmpInt32PtrTy), 4155 std::make_pair(".privates.", VoidPtrTy), 4156 std::make_pair( 4157 ".copy_fn.", 4158 Context.getPointerType(CopyFnType).withConst().withRestrict()), 4159 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 4160 std::make_pair(".lb.", KmpUInt64Ty), 4161 std::make_pair(".ub.", KmpUInt64Ty), 4162 std::make_pair(".st.", KmpInt64Ty), 4163 std::make_pair(".liter.", KmpInt32Ty), 4164 std::make_pair(".reductions.", VoidPtrTy), 4165 std::make_pair(StringRef(), QualType()) // __context with shared vars 4166 }; 4167 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 4168 Params); 4169 // Mark this captured region as inlined, because we don't use outlined 4170 // function directly. 4171 getCurCapturedRegion()->TheCapturedDecl->addAttr( 4172 AlwaysInlineAttr::CreateImplicit( 4173 Context, {}, AttributeCommonInfo::AS_Keyword, 4174 AlwaysInlineAttr::Keyword_forceinline)); 4175 break; 4176 } 4177 case OMPD_parallel_master_taskloop: 4178 case OMPD_parallel_master_taskloop_simd: { 4179 QualType KmpInt32Ty = 4180 Context.getIntTypeForBitwidth(/*DestWidth=*/32, /*Signed=*/1) 4181 .withConst(); 4182 QualType KmpUInt64Ty = 4183 Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/0) 4184 .withConst(); 4185 QualType KmpInt64Ty = 4186 Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/1) 4187 .withConst(); 4188 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 4189 QualType KmpInt32PtrTy = 4190 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 4191 Sema::CapturedParamNameType ParamsParallel[] = { 4192 std::make_pair(".global_tid.", KmpInt32PtrTy), 4193 std::make_pair(".bound_tid.", KmpInt32PtrTy), 4194 std::make_pair(StringRef(), QualType()) // __context with shared vars 4195 }; 4196 // Start a captured region for 'parallel'. 4197 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 4198 ParamsParallel, /*OpenMPCaptureLevel=*/0); 4199 QualType Args[] = {VoidPtrTy}; 4200 FunctionProtoType::ExtProtoInfo EPI; 4201 EPI.Variadic = true; 4202 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 4203 Sema::CapturedParamNameType Params[] = { 4204 std::make_pair(".global_tid.", KmpInt32Ty), 4205 std::make_pair(".part_id.", KmpInt32PtrTy), 4206 std::make_pair(".privates.", VoidPtrTy), 4207 std::make_pair( 4208 ".copy_fn.", 4209 Context.getPointerType(CopyFnType).withConst().withRestrict()), 4210 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 4211 std::make_pair(".lb.", KmpUInt64Ty), 4212 std::make_pair(".ub.", KmpUInt64Ty), 4213 std::make_pair(".st.", KmpInt64Ty), 4214 std::make_pair(".liter.", KmpInt32Ty), 4215 std::make_pair(".reductions.", VoidPtrTy), 4216 std::make_pair(StringRef(), QualType()) // __context with shared vars 4217 }; 4218 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 4219 Params, /*OpenMPCaptureLevel=*/1); 4220 // Mark this captured region as inlined, because we don't use outlined 4221 // function directly. 4222 getCurCapturedRegion()->TheCapturedDecl->addAttr( 4223 AlwaysInlineAttr::CreateImplicit( 4224 Context, {}, AttributeCommonInfo::AS_Keyword, 4225 AlwaysInlineAttr::Keyword_forceinline)); 4226 break; 4227 } 4228 case OMPD_distribute_parallel_for_simd: 4229 case OMPD_distribute_parallel_for: { 4230 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 4231 QualType KmpInt32PtrTy = 4232 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 4233 Sema::CapturedParamNameType Params[] = { 4234 std::make_pair(".global_tid.", KmpInt32PtrTy), 4235 std::make_pair(".bound_tid.", KmpInt32PtrTy), 4236 std::make_pair(".previous.lb.", Context.getSizeType().withConst()), 4237 std::make_pair(".previous.ub.", Context.getSizeType().withConst()), 4238 std::make_pair(StringRef(), QualType()) // __context with shared vars 4239 }; 4240 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 4241 Params); 4242 break; 4243 } 4244 case OMPD_target_teams_distribute_parallel_for: 4245 case OMPD_target_teams_distribute_parallel_for_simd: { 4246 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 4247 QualType KmpInt32PtrTy = 4248 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 4249 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 4250 4251 QualType Args[] = {VoidPtrTy}; 4252 FunctionProtoType::ExtProtoInfo EPI; 4253 EPI.Variadic = true; 4254 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 4255 Sema::CapturedParamNameType Params[] = { 4256 std::make_pair(".global_tid.", KmpInt32Ty), 4257 std::make_pair(".part_id.", KmpInt32PtrTy), 4258 std::make_pair(".privates.", VoidPtrTy), 4259 std::make_pair( 4260 ".copy_fn.", 4261 Context.getPointerType(CopyFnType).withConst().withRestrict()), 4262 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 4263 std::make_pair(StringRef(), QualType()) // __context with shared vars 4264 }; 4265 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 4266 Params, /*OpenMPCaptureLevel=*/0); 4267 // Mark this captured region as inlined, because we don't use outlined 4268 // function directly. 4269 getCurCapturedRegion()->TheCapturedDecl->addAttr( 4270 AlwaysInlineAttr::CreateImplicit( 4271 Context, {}, AttributeCommonInfo::AS_Keyword, 4272 AlwaysInlineAttr::Keyword_forceinline)); 4273 Sema::CapturedParamNameType ParamsTarget[] = { 4274 std::make_pair(StringRef(), QualType()) // __context with shared vars 4275 }; 4276 // Start a captured region for 'target' with no implicit parameters. 4277 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 4278 ParamsTarget, /*OpenMPCaptureLevel=*/1); 4279 4280 Sema::CapturedParamNameType ParamsTeams[] = { 4281 std::make_pair(".global_tid.", KmpInt32PtrTy), 4282 std::make_pair(".bound_tid.", KmpInt32PtrTy), 4283 std::make_pair(StringRef(), QualType()) // __context with shared vars 4284 }; 4285 // Start a captured region for 'target' with no implicit parameters. 4286 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 4287 ParamsTeams, /*OpenMPCaptureLevel=*/2); 4288 4289 Sema::CapturedParamNameType ParamsParallel[] = { 4290 std::make_pair(".global_tid.", KmpInt32PtrTy), 4291 std::make_pair(".bound_tid.", KmpInt32PtrTy), 4292 std::make_pair(".previous.lb.", Context.getSizeType().withConst()), 4293 std::make_pair(".previous.ub.", Context.getSizeType().withConst()), 4294 std::make_pair(StringRef(), QualType()) // __context with shared vars 4295 }; 4296 // Start a captured region for 'teams' or 'parallel'. Both regions have 4297 // the same implicit parameters. 4298 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 4299 ParamsParallel, /*OpenMPCaptureLevel=*/3); 4300 break; 4301 } 4302 4303 case OMPD_teams_loop: { 4304 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 4305 QualType KmpInt32PtrTy = 4306 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 4307 4308 Sema::CapturedParamNameType ParamsTeams[] = { 4309 std::make_pair(".global_tid.", KmpInt32PtrTy), 4310 std::make_pair(".bound_tid.", KmpInt32PtrTy), 4311 std::make_pair(StringRef(), QualType()) // __context with shared vars 4312 }; 4313 // Start a captured region for 'teams'. 4314 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 4315 ParamsTeams, /*OpenMPCaptureLevel=*/0); 4316 break; 4317 } 4318 4319 case OMPD_teams_distribute_parallel_for: 4320 case OMPD_teams_distribute_parallel_for_simd: { 4321 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 4322 QualType KmpInt32PtrTy = 4323 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 4324 4325 Sema::CapturedParamNameType ParamsTeams[] = { 4326 std::make_pair(".global_tid.", KmpInt32PtrTy), 4327 std::make_pair(".bound_tid.", KmpInt32PtrTy), 4328 std::make_pair(StringRef(), QualType()) // __context with shared vars 4329 }; 4330 // Start a captured region for 'target' with no implicit parameters. 4331 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 4332 ParamsTeams, /*OpenMPCaptureLevel=*/0); 4333 4334 Sema::CapturedParamNameType ParamsParallel[] = { 4335 std::make_pair(".global_tid.", KmpInt32PtrTy), 4336 std::make_pair(".bound_tid.", KmpInt32PtrTy), 4337 std::make_pair(".previous.lb.", Context.getSizeType().withConst()), 4338 std::make_pair(".previous.ub.", Context.getSizeType().withConst()), 4339 std::make_pair(StringRef(), QualType()) // __context with shared vars 4340 }; 4341 // Start a captured region for 'teams' or 'parallel'. Both regions have 4342 // the same implicit parameters. 4343 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 4344 ParamsParallel, /*OpenMPCaptureLevel=*/1); 4345 break; 4346 } 4347 case OMPD_target_update: 4348 case OMPD_target_enter_data: 4349 case OMPD_target_exit_data: { 4350 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 4351 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 4352 QualType KmpInt32PtrTy = 4353 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 4354 QualType Args[] = {VoidPtrTy}; 4355 FunctionProtoType::ExtProtoInfo EPI; 4356 EPI.Variadic = true; 4357 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 4358 Sema::CapturedParamNameType Params[] = { 4359 std::make_pair(".global_tid.", KmpInt32Ty), 4360 std::make_pair(".part_id.", KmpInt32PtrTy), 4361 std::make_pair(".privates.", VoidPtrTy), 4362 std::make_pair( 4363 ".copy_fn.", 4364 Context.getPointerType(CopyFnType).withConst().withRestrict()), 4365 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 4366 std::make_pair(StringRef(), QualType()) // __context with shared vars 4367 }; 4368 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 4369 Params); 4370 // Mark this captured region as inlined, because we don't use outlined 4371 // function directly. 4372 getCurCapturedRegion()->TheCapturedDecl->addAttr( 4373 AlwaysInlineAttr::CreateImplicit( 4374 Context, {}, AttributeCommonInfo::AS_Keyword, 4375 AlwaysInlineAttr::Keyword_forceinline)); 4376 break; 4377 } 4378 case OMPD_threadprivate: 4379 case OMPD_allocate: 4380 case OMPD_taskyield: 4381 case OMPD_barrier: 4382 case OMPD_taskwait: 4383 case OMPD_cancellation_point: 4384 case OMPD_cancel: 4385 case OMPD_flush: 4386 case OMPD_depobj: 4387 case OMPD_scan: 4388 case OMPD_declare_reduction: 4389 case OMPD_declare_mapper: 4390 case OMPD_declare_simd: 4391 case OMPD_declare_target: 4392 case OMPD_end_declare_target: 4393 case OMPD_requires: 4394 case OMPD_declare_variant: 4395 case OMPD_begin_declare_variant: 4396 case OMPD_end_declare_variant: 4397 case OMPD_metadirective: 4398 llvm_unreachable("OpenMP Directive is not allowed"); 4399 case OMPD_unknown: 4400 default: 4401 llvm_unreachable("Unknown OpenMP directive"); 4402 } 4403 DSAStack->setContext(CurContext); 4404 handleDeclareVariantConstructTrait(DSAStack, DKind, /* ScopeEntry */ true); 4405 } 4406 4407 int Sema::getNumberOfConstructScopes(unsigned Level) const { 4408 return getOpenMPCaptureLevels(DSAStack->getDirective(Level)); 4409 } 4410 4411 int Sema::getOpenMPCaptureLevels(OpenMPDirectiveKind DKind) { 4412 SmallVector<OpenMPDirectiveKind, 4> CaptureRegions; 4413 getOpenMPCaptureRegions(CaptureRegions, DKind); 4414 return CaptureRegions.size(); 4415 } 4416 4417 static OMPCapturedExprDecl *buildCaptureDecl(Sema &S, IdentifierInfo *Id, 4418 Expr *CaptureExpr, bool WithInit, 4419 bool AsExpression) { 4420 assert(CaptureExpr); 4421 ASTContext &C = S.getASTContext(); 4422 Expr *Init = AsExpression ? CaptureExpr : CaptureExpr->IgnoreImpCasts(); 4423 QualType Ty = Init->getType(); 4424 if (CaptureExpr->getObjectKind() == OK_Ordinary && CaptureExpr->isGLValue()) { 4425 if (S.getLangOpts().CPlusPlus) { 4426 Ty = C.getLValueReferenceType(Ty); 4427 } else { 4428 Ty = C.getPointerType(Ty); 4429 ExprResult Res = 4430 S.CreateBuiltinUnaryOp(CaptureExpr->getExprLoc(), UO_AddrOf, Init); 4431 if (!Res.isUsable()) 4432 return nullptr; 4433 Init = Res.get(); 4434 } 4435 WithInit = true; 4436 } 4437 auto *CED = OMPCapturedExprDecl::Create(C, S.CurContext, Id, Ty, 4438 CaptureExpr->getBeginLoc()); 4439 if (!WithInit) 4440 CED->addAttr(OMPCaptureNoInitAttr::CreateImplicit(C)); 4441 S.CurContext->addHiddenDecl(CED); 4442 Sema::TentativeAnalysisScope Trap(S); 4443 S.AddInitializerToDecl(CED, Init, /*DirectInit=*/false); 4444 return CED; 4445 } 4446 4447 static DeclRefExpr *buildCapture(Sema &S, ValueDecl *D, Expr *CaptureExpr, 4448 bool WithInit) { 4449 OMPCapturedExprDecl *CD; 4450 if (VarDecl *VD = S.isOpenMPCapturedDecl(D)) 4451 CD = cast<OMPCapturedExprDecl>(VD); 4452 else 4453 CD = buildCaptureDecl(S, D->getIdentifier(), CaptureExpr, WithInit, 4454 /*AsExpression=*/false); 4455 return buildDeclRefExpr(S, CD, CD->getType().getNonReferenceType(), 4456 CaptureExpr->getExprLoc()); 4457 } 4458 4459 static ExprResult buildCapture(Sema &S, Expr *CaptureExpr, DeclRefExpr *&Ref) { 4460 CaptureExpr = S.DefaultLvalueConversion(CaptureExpr).get(); 4461 if (!Ref) { 4462 OMPCapturedExprDecl *CD = buildCaptureDecl( 4463 S, &S.getASTContext().Idents.get(".capture_expr."), CaptureExpr, 4464 /*WithInit=*/true, /*AsExpression=*/true); 4465 Ref = buildDeclRefExpr(S, CD, CD->getType().getNonReferenceType(), 4466 CaptureExpr->getExprLoc()); 4467 } 4468 ExprResult Res = Ref; 4469 if (!S.getLangOpts().CPlusPlus && 4470 CaptureExpr->getObjectKind() == OK_Ordinary && CaptureExpr->isGLValue() && 4471 Ref->getType()->isPointerType()) { 4472 Res = S.CreateBuiltinUnaryOp(CaptureExpr->getExprLoc(), UO_Deref, Ref); 4473 if (!Res.isUsable()) 4474 return ExprError(); 4475 } 4476 return S.DefaultLvalueConversion(Res.get()); 4477 } 4478 4479 namespace { 4480 // OpenMP directives parsed in this section are represented as a 4481 // CapturedStatement with an associated statement. If a syntax error 4482 // is detected during the parsing of the associated statement, the 4483 // compiler must abort processing and close the CapturedStatement. 4484 // 4485 // Combined directives such as 'target parallel' have more than one 4486 // nested CapturedStatements. This RAII ensures that we unwind out 4487 // of all the nested CapturedStatements when an error is found. 4488 class CaptureRegionUnwinderRAII { 4489 private: 4490 Sema &S; 4491 bool &ErrorFound; 4492 OpenMPDirectiveKind DKind = OMPD_unknown; 4493 4494 public: 4495 CaptureRegionUnwinderRAII(Sema &S, bool &ErrorFound, 4496 OpenMPDirectiveKind DKind) 4497 : S(S), ErrorFound(ErrorFound), DKind(DKind) {} 4498 ~CaptureRegionUnwinderRAII() { 4499 if (ErrorFound) { 4500 int ThisCaptureLevel = S.getOpenMPCaptureLevels(DKind); 4501 while (--ThisCaptureLevel >= 0) 4502 S.ActOnCapturedRegionError(); 4503 } 4504 } 4505 }; 4506 } // namespace 4507 4508 void Sema::tryCaptureOpenMPLambdas(ValueDecl *V) { 4509 // Capture variables captured by reference in lambdas for target-based 4510 // directives. 4511 if (!CurContext->isDependentContext() && 4512 (isOpenMPTargetExecutionDirective(DSAStack->getCurrentDirective()) || 4513 isOpenMPTargetDataManagementDirective( 4514 DSAStack->getCurrentDirective()))) { 4515 QualType Type = V->getType(); 4516 if (const auto *RD = Type.getCanonicalType() 4517 .getNonReferenceType() 4518 ->getAsCXXRecordDecl()) { 4519 bool SavedForceCaptureByReferenceInTargetExecutable = 4520 DSAStack->isForceCaptureByReferenceInTargetExecutable(); 4521 DSAStack->setForceCaptureByReferenceInTargetExecutable( 4522 /*V=*/true); 4523 if (RD->isLambda()) { 4524 llvm::DenseMap<const VarDecl *, FieldDecl *> Captures; 4525 FieldDecl *ThisCapture; 4526 RD->getCaptureFields(Captures, ThisCapture); 4527 for (const LambdaCapture &LC : RD->captures()) { 4528 if (LC.getCaptureKind() == LCK_ByRef) { 4529 VarDecl *VD = LC.getCapturedVar(); 4530 DeclContext *VDC = VD->getDeclContext(); 4531 if (!VDC->Encloses(CurContext)) 4532 continue; 4533 MarkVariableReferenced(LC.getLocation(), VD); 4534 } else if (LC.getCaptureKind() == LCK_This) { 4535 QualType ThisTy = getCurrentThisType(); 4536 if (!ThisTy.isNull() && 4537 Context.typesAreCompatible(ThisTy, ThisCapture->getType())) 4538 CheckCXXThisCapture(LC.getLocation()); 4539 } 4540 } 4541 } 4542 DSAStack->setForceCaptureByReferenceInTargetExecutable( 4543 SavedForceCaptureByReferenceInTargetExecutable); 4544 } 4545 } 4546 } 4547 4548 static bool checkOrderedOrderSpecified(Sema &S, 4549 const ArrayRef<OMPClause *> Clauses) { 4550 const OMPOrderedClause *Ordered = nullptr; 4551 const OMPOrderClause *Order = nullptr; 4552 4553 for (const OMPClause *Clause : Clauses) { 4554 if (Clause->getClauseKind() == OMPC_ordered) 4555 Ordered = cast<OMPOrderedClause>(Clause); 4556 else if (Clause->getClauseKind() == OMPC_order) { 4557 Order = cast<OMPOrderClause>(Clause); 4558 if (Order->getKind() != OMPC_ORDER_concurrent) 4559 Order = nullptr; 4560 } 4561 if (Ordered && Order) 4562 break; 4563 } 4564 4565 if (Ordered && Order) { 4566 S.Diag(Order->getKindKwLoc(), 4567 diag::err_omp_simple_clause_incompatible_with_ordered) 4568 << getOpenMPClauseName(OMPC_order) 4569 << getOpenMPSimpleClauseTypeName(OMPC_order, OMPC_ORDER_concurrent) 4570 << SourceRange(Order->getBeginLoc(), Order->getEndLoc()); 4571 S.Diag(Ordered->getBeginLoc(), diag::note_omp_ordered_param) 4572 << 0 << SourceRange(Ordered->getBeginLoc(), Ordered->getEndLoc()); 4573 return true; 4574 } 4575 return false; 4576 } 4577 4578 StmtResult Sema::ActOnOpenMPRegionEnd(StmtResult S, 4579 ArrayRef<OMPClause *> Clauses) { 4580 handleDeclareVariantConstructTrait(DSAStack, DSAStack->getCurrentDirective(), 4581 /* ScopeEntry */ false); 4582 if (DSAStack->getCurrentDirective() == OMPD_atomic || 4583 DSAStack->getCurrentDirective() == OMPD_critical || 4584 DSAStack->getCurrentDirective() == OMPD_section || 4585 DSAStack->getCurrentDirective() == OMPD_master || 4586 DSAStack->getCurrentDirective() == OMPD_masked) 4587 return S; 4588 4589 bool ErrorFound = false; 4590 CaptureRegionUnwinderRAII CaptureRegionUnwinder( 4591 *this, ErrorFound, DSAStack->getCurrentDirective()); 4592 if (!S.isUsable()) { 4593 ErrorFound = true; 4594 return StmtError(); 4595 } 4596 4597 SmallVector<OpenMPDirectiveKind, 4> CaptureRegions; 4598 getOpenMPCaptureRegions(CaptureRegions, DSAStack->getCurrentDirective()); 4599 OMPOrderedClause *OC = nullptr; 4600 OMPScheduleClause *SC = nullptr; 4601 SmallVector<const OMPLinearClause *, 4> LCs; 4602 SmallVector<const OMPClauseWithPreInit *, 4> PICs; 4603 // This is required for proper codegen. 4604 for (OMPClause *Clause : Clauses) { 4605 if (!LangOpts.OpenMPSimd && 4606 isOpenMPTaskingDirective(DSAStack->getCurrentDirective()) && 4607 Clause->getClauseKind() == OMPC_in_reduction) { 4608 // Capture taskgroup task_reduction descriptors inside the tasking regions 4609 // with the corresponding in_reduction items. 4610 auto *IRC = cast<OMPInReductionClause>(Clause); 4611 for (Expr *E : IRC->taskgroup_descriptors()) 4612 if (E) 4613 MarkDeclarationsReferencedInExpr(E); 4614 } 4615 if (isOpenMPPrivate(Clause->getClauseKind()) || 4616 Clause->getClauseKind() == OMPC_copyprivate || 4617 (getLangOpts().OpenMPUseTLS && 4618 getASTContext().getTargetInfo().isTLSSupported() && 4619 Clause->getClauseKind() == OMPC_copyin)) { 4620 DSAStack->setForceVarCapturing(Clause->getClauseKind() == OMPC_copyin); 4621 // Mark all variables in private list clauses as used in inner region. 4622 for (Stmt *VarRef : Clause->children()) { 4623 if (auto *E = cast_or_null<Expr>(VarRef)) { 4624 MarkDeclarationsReferencedInExpr(E); 4625 } 4626 } 4627 DSAStack->setForceVarCapturing(/*V=*/false); 4628 } else if (isOpenMPLoopTransformationDirective( 4629 DSAStack->getCurrentDirective())) { 4630 assert(CaptureRegions.empty() && 4631 "No captured regions in loop transformation directives."); 4632 } else if (CaptureRegions.size() > 1 || 4633 CaptureRegions.back() != OMPD_unknown) { 4634 if (auto *C = OMPClauseWithPreInit::get(Clause)) 4635 PICs.push_back(C); 4636 if (auto *C = OMPClauseWithPostUpdate::get(Clause)) { 4637 if (Expr *E = C->getPostUpdateExpr()) 4638 MarkDeclarationsReferencedInExpr(E); 4639 } 4640 } 4641 if (Clause->getClauseKind() == OMPC_schedule) 4642 SC = cast<OMPScheduleClause>(Clause); 4643 else if (Clause->getClauseKind() == OMPC_ordered) 4644 OC = cast<OMPOrderedClause>(Clause); 4645 else if (Clause->getClauseKind() == OMPC_linear) 4646 LCs.push_back(cast<OMPLinearClause>(Clause)); 4647 } 4648 // Capture allocator expressions if used. 4649 for (Expr *E : DSAStack->getInnerAllocators()) 4650 MarkDeclarationsReferencedInExpr(E); 4651 // OpenMP, 2.7.1 Loop Construct, Restrictions 4652 // The nonmonotonic modifier cannot be specified if an ordered clause is 4653 // specified. 4654 if (SC && 4655 (SC->getFirstScheduleModifier() == OMPC_SCHEDULE_MODIFIER_nonmonotonic || 4656 SC->getSecondScheduleModifier() == 4657 OMPC_SCHEDULE_MODIFIER_nonmonotonic) && 4658 OC) { 4659 Diag(SC->getFirstScheduleModifier() == OMPC_SCHEDULE_MODIFIER_nonmonotonic 4660 ? SC->getFirstScheduleModifierLoc() 4661 : SC->getSecondScheduleModifierLoc(), 4662 diag::err_omp_simple_clause_incompatible_with_ordered) 4663 << getOpenMPClauseName(OMPC_schedule) 4664 << getOpenMPSimpleClauseTypeName(OMPC_schedule, 4665 OMPC_SCHEDULE_MODIFIER_nonmonotonic) 4666 << SourceRange(OC->getBeginLoc(), OC->getEndLoc()); 4667 ErrorFound = true; 4668 } 4669 // OpenMP 5.0, 2.9.2 Worksharing-Loop Construct, Restrictions. 4670 // If an order(concurrent) clause is present, an ordered clause may not appear 4671 // on the same directive. 4672 if (checkOrderedOrderSpecified(*this, Clauses)) 4673 ErrorFound = true; 4674 if (!LCs.empty() && OC && OC->getNumForLoops()) { 4675 for (const OMPLinearClause *C : LCs) { 4676 Diag(C->getBeginLoc(), diag::err_omp_linear_ordered) 4677 << SourceRange(OC->getBeginLoc(), OC->getEndLoc()); 4678 } 4679 ErrorFound = true; 4680 } 4681 if (isOpenMPWorksharingDirective(DSAStack->getCurrentDirective()) && 4682 isOpenMPSimdDirective(DSAStack->getCurrentDirective()) && OC && 4683 OC->getNumForLoops()) { 4684 Diag(OC->getBeginLoc(), diag::err_omp_ordered_simd) 4685 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 4686 ErrorFound = true; 4687 } 4688 if (ErrorFound) { 4689 return StmtError(); 4690 } 4691 StmtResult SR = S; 4692 unsigned CompletedRegions = 0; 4693 for (OpenMPDirectiveKind ThisCaptureRegion : llvm::reverse(CaptureRegions)) { 4694 // Mark all variables in private list clauses as used in inner region. 4695 // Required for proper codegen of combined directives. 4696 // TODO: add processing for other clauses. 4697 if (ThisCaptureRegion != OMPD_unknown) { 4698 for (const clang::OMPClauseWithPreInit *C : PICs) { 4699 OpenMPDirectiveKind CaptureRegion = C->getCaptureRegion(); 4700 // Find the particular capture region for the clause if the 4701 // directive is a combined one with multiple capture regions. 4702 // If the directive is not a combined one, the capture region 4703 // associated with the clause is OMPD_unknown and is generated 4704 // only once. 4705 if (CaptureRegion == ThisCaptureRegion || 4706 CaptureRegion == OMPD_unknown) { 4707 if (auto *DS = cast_or_null<DeclStmt>(C->getPreInitStmt())) { 4708 for (Decl *D : DS->decls()) 4709 MarkVariableReferenced(D->getLocation(), cast<VarDecl>(D)); 4710 } 4711 } 4712 } 4713 } 4714 if (ThisCaptureRegion == OMPD_target) { 4715 // Capture allocator traits in the target region. They are used implicitly 4716 // and, thus, are not captured by default. 4717 for (OMPClause *C : Clauses) { 4718 if (const auto *UAC = dyn_cast<OMPUsesAllocatorsClause>(C)) { 4719 for (unsigned I = 0, End = UAC->getNumberOfAllocators(); I < End; 4720 ++I) { 4721 OMPUsesAllocatorsClause::Data D = UAC->getAllocatorData(I); 4722 if (Expr *E = D.AllocatorTraits) 4723 MarkDeclarationsReferencedInExpr(E); 4724 } 4725 continue; 4726 } 4727 } 4728 } 4729 if (ThisCaptureRegion == OMPD_parallel) { 4730 // Capture temp arrays for inscan reductions and locals in aligned 4731 // clauses. 4732 for (OMPClause *C : Clauses) { 4733 if (auto *RC = dyn_cast<OMPReductionClause>(C)) { 4734 if (RC->getModifier() != OMPC_REDUCTION_inscan) 4735 continue; 4736 for (Expr *E : RC->copy_array_temps()) 4737 MarkDeclarationsReferencedInExpr(E); 4738 } 4739 if (auto *AC = dyn_cast<OMPAlignedClause>(C)) { 4740 for (Expr *E : AC->varlists()) 4741 MarkDeclarationsReferencedInExpr(E); 4742 } 4743 } 4744 } 4745 if (++CompletedRegions == CaptureRegions.size()) 4746 DSAStack->setBodyComplete(); 4747 SR = ActOnCapturedRegionEnd(SR.get()); 4748 } 4749 return SR; 4750 } 4751 4752 static bool checkCancelRegion(Sema &SemaRef, OpenMPDirectiveKind CurrentRegion, 4753 OpenMPDirectiveKind CancelRegion, 4754 SourceLocation StartLoc) { 4755 // CancelRegion is only needed for cancel and cancellation_point. 4756 if (CurrentRegion != OMPD_cancel && CurrentRegion != OMPD_cancellation_point) 4757 return false; 4758 4759 if (CancelRegion == OMPD_parallel || CancelRegion == OMPD_for || 4760 CancelRegion == OMPD_sections || CancelRegion == OMPD_taskgroup) 4761 return false; 4762 4763 SemaRef.Diag(StartLoc, diag::err_omp_wrong_cancel_region) 4764 << getOpenMPDirectiveName(CancelRegion); 4765 return true; 4766 } 4767 4768 static bool checkNestingOfRegions(Sema &SemaRef, const DSAStackTy *Stack, 4769 OpenMPDirectiveKind CurrentRegion, 4770 const DeclarationNameInfo &CurrentName, 4771 OpenMPDirectiveKind CancelRegion, 4772 OpenMPBindClauseKind BindKind, 4773 SourceLocation StartLoc) { 4774 if (Stack->getCurScope()) { 4775 OpenMPDirectiveKind ParentRegion = Stack->getParentDirective(); 4776 OpenMPDirectiveKind OffendingRegion = ParentRegion; 4777 bool NestingProhibited = false; 4778 bool CloseNesting = true; 4779 bool OrphanSeen = false; 4780 enum { 4781 NoRecommend, 4782 ShouldBeInParallelRegion, 4783 ShouldBeInOrderedRegion, 4784 ShouldBeInTargetRegion, 4785 ShouldBeInTeamsRegion, 4786 ShouldBeInLoopSimdRegion, 4787 } Recommend = NoRecommend; 4788 if (isOpenMPSimdDirective(ParentRegion) && 4789 ((SemaRef.LangOpts.OpenMP <= 45 && CurrentRegion != OMPD_ordered) || 4790 (SemaRef.LangOpts.OpenMP >= 50 && CurrentRegion != OMPD_ordered && 4791 CurrentRegion != OMPD_simd && CurrentRegion != OMPD_atomic && 4792 CurrentRegion != OMPD_scan))) { 4793 // OpenMP [2.16, Nesting of Regions] 4794 // OpenMP constructs may not be nested inside a simd region. 4795 // OpenMP [2.8.1,simd Construct, Restrictions] 4796 // An ordered construct with the simd clause is the only OpenMP 4797 // construct that can appear in the simd region. 4798 // Allowing a SIMD construct nested in another SIMD construct is an 4799 // extension. The OpenMP 4.5 spec does not allow it. Issue a warning 4800 // message. 4801 // OpenMP 5.0 [2.9.3.1, simd Construct, Restrictions] 4802 // The only OpenMP constructs that can be encountered during execution of 4803 // a simd region are the atomic construct, the loop construct, the simd 4804 // construct and the ordered construct with the simd clause. 4805 SemaRef.Diag(StartLoc, (CurrentRegion != OMPD_simd) 4806 ? diag::err_omp_prohibited_region_simd 4807 : diag::warn_omp_nesting_simd) 4808 << (SemaRef.LangOpts.OpenMP >= 50 ? 1 : 0); 4809 return CurrentRegion != OMPD_simd; 4810 } 4811 if (ParentRegion == OMPD_atomic) { 4812 // OpenMP [2.16, Nesting of Regions] 4813 // OpenMP constructs may not be nested inside an atomic region. 4814 SemaRef.Diag(StartLoc, diag::err_omp_prohibited_region_atomic); 4815 return true; 4816 } 4817 if (CurrentRegion == OMPD_section) { 4818 // OpenMP [2.7.2, sections Construct, Restrictions] 4819 // Orphaned section directives are prohibited. That is, the section 4820 // directives must appear within the sections construct and must not be 4821 // encountered elsewhere in the sections region. 4822 if (ParentRegion != OMPD_sections && 4823 ParentRegion != OMPD_parallel_sections) { 4824 SemaRef.Diag(StartLoc, diag::err_omp_orphaned_section_directive) 4825 << (ParentRegion != OMPD_unknown) 4826 << getOpenMPDirectiveName(ParentRegion); 4827 return true; 4828 } 4829 return false; 4830 } 4831 // Allow some constructs (except teams and cancellation constructs) to be 4832 // orphaned (they could be used in functions, called from OpenMP regions 4833 // with the required preconditions). 4834 if (ParentRegion == OMPD_unknown && 4835 !isOpenMPNestingTeamsDirective(CurrentRegion) && 4836 CurrentRegion != OMPD_cancellation_point && 4837 CurrentRegion != OMPD_cancel && CurrentRegion != OMPD_scan) 4838 return false; 4839 if (CurrentRegion == OMPD_cancellation_point || 4840 CurrentRegion == OMPD_cancel) { 4841 // OpenMP [2.16, Nesting of Regions] 4842 // A cancellation point construct for which construct-type-clause is 4843 // taskgroup must be nested inside a task construct. A cancellation 4844 // point construct for which construct-type-clause is not taskgroup must 4845 // be closely nested inside an OpenMP construct that matches the type 4846 // specified in construct-type-clause. 4847 // A cancel construct for which construct-type-clause is taskgroup must be 4848 // nested inside a task construct. A cancel construct for which 4849 // construct-type-clause is not taskgroup must be closely nested inside an 4850 // OpenMP construct that matches the type specified in 4851 // construct-type-clause. 4852 NestingProhibited = 4853 !((CancelRegion == OMPD_parallel && 4854 (ParentRegion == OMPD_parallel || 4855 ParentRegion == OMPD_target_parallel)) || 4856 (CancelRegion == OMPD_for && 4857 (ParentRegion == OMPD_for || ParentRegion == OMPD_parallel_for || 4858 ParentRegion == OMPD_target_parallel_for || 4859 ParentRegion == OMPD_distribute_parallel_for || 4860 ParentRegion == OMPD_teams_distribute_parallel_for || 4861 ParentRegion == OMPD_target_teams_distribute_parallel_for)) || 4862 (CancelRegion == OMPD_taskgroup && 4863 (ParentRegion == OMPD_task || 4864 (SemaRef.getLangOpts().OpenMP >= 50 && 4865 (ParentRegion == OMPD_taskloop || 4866 ParentRegion == OMPD_master_taskloop || 4867 ParentRegion == OMPD_parallel_master_taskloop)))) || 4868 (CancelRegion == OMPD_sections && 4869 (ParentRegion == OMPD_section || ParentRegion == OMPD_sections || 4870 ParentRegion == OMPD_parallel_sections))); 4871 OrphanSeen = ParentRegion == OMPD_unknown; 4872 } else if (CurrentRegion == OMPD_master || CurrentRegion == OMPD_masked) { 4873 // OpenMP 5.1 [2.22, Nesting of Regions] 4874 // A masked region may not be closely nested inside a worksharing, loop, 4875 // atomic, task, or taskloop region. 4876 NestingProhibited = isOpenMPWorksharingDirective(ParentRegion) || 4877 isOpenMPGenericLoopDirective(ParentRegion) || 4878 isOpenMPTaskingDirective(ParentRegion); 4879 } else if (CurrentRegion == OMPD_critical && CurrentName.getName()) { 4880 // OpenMP [2.16, Nesting of Regions] 4881 // A critical region may not be nested (closely or otherwise) inside a 4882 // critical region with the same name. Note that this restriction is not 4883 // sufficient to prevent deadlock. 4884 SourceLocation PreviousCriticalLoc; 4885 bool DeadLock = Stack->hasDirective( 4886 [CurrentName, &PreviousCriticalLoc](OpenMPDirectiveKind K, 4887 const DeclarationNameInfo &DNI, 4888 SourceLocation Loc) { 4889 if (K == OMPD_critical && DNI.getName() == CurrentName.getName()) { 4890 PreviousCriticalLoc = Loc; 4891 return true; 4892 } 4893 return false; 4894 }, 4895 false /* skip top directive */); 4896 if (DeadLock) { 4897 SemaRef.Diag(StartLoc, 4898 diag::err_omp_prohibited_region_critical_same_name) 4899 << CurrentName.getName(); 4900 if (PreviousCriticalLoc.isValid()) 4901 SemaRef.Diag(PreviousCriticalLoc, 4902 diag::note_omp_previous_critical_region); 4903 return true; 4904 } 4905 } else if (CurrentRegion == OMPD_barrier) { 4906 // OpenMP 5.1 [2.22, Nesting of Regions] 4907 // A barrier region may not be closely nested inside a worksharing, loop, 4908 // task, taskloop, critical, ordered, atomic, or masked region. 4909 NestingProhibited = 4910 isOpenMPWorksharingDirective(ParentRegion) || 4911 isOpenMPGenericLoopDirective(ParentRegion) || 4912 isOpenMPTaskingDirective(ParentRegion) || 4913 ParentRegion == OMPD_master || ParentRegion == OMPD_masked || 4914 ParentRegion == OMPD_parallel_master || 4915 ParentRegion == OMPD_critical || ParentRegion == OMPD_ordered; 4916 } else if (isOpenMPWorksharingDirective(CurrentRegion) && 4917 !isOpenMPParallelDirective(CurrentRegion) && 4918 !isOpenMPTeamsDirective(CurrentRegion)) { 4919 // OpenMP 5.1 [2.22, Nesting of Regions] 4920 // A loop region that binds to a parallel region or a worksharing region 4921 // may not be closely nested inside a worksharing, loop, task, taskloop, 4922 // critical, ordered, atomic, or masked region. 4923 NestingProhibited = 4924 isOpenMPWorksharingDirective(ParentRegion) || 4925 isOpenMPGenericLoopDirective(ParentRegion) || 4926 isOpenMPTaskingDirective(ParentRegion) || 4927 ParentRegion == OMPD_master || ParentRegion == OMPD_masked || 4928 ParentRegion == OMPD_parallel_master || 4929 ParentRegion == OMPD_critical || ParentRegion == OMPD_ordered; 4930 Recommend = ShouldBeInParallelRegion; 4931 } else if (CurrentRegion == OMPD_ordered) { 4932 // OpenMP [2.16, Nesting of Regions] 4933 // An ordered region may not be closely nested inside a critical, 4934 // atomic, or explicit task region. 4935 // An ordered region must be closely nested inside a loop region (or 4936 // parallel loop region) with an ordered clause. 4937 // OpenMP [2.8.1,simd Construct, Restrictions] 4938 // An ordered construct with the simd clause is the only OpenMP construct 4939 // that can appear in the simd region. 4940 NestingProhibited = ParentRegion == OMPD_critical || 4941 isOpenMPTaskingDirective(ParentRegion) || 4942 !(isOpenMPSimdDirective(ParentRegion) || 4943 Stack->isParentOrderedRegion()); 4944 Recommend = ShouldBeInOrderedRegion; 4945 } else if (isOpenMPNestingTeamsDirective(CurrentRegion)) { 4946 // OpenMP [2.16, Nesting of Regions] 4947 // If specified, a teams construct must be contained within a target 4948 // construct. 4949 NestingProhibited = 4950 (SemaRef.LangOpts.OpenMP <= 45 && ParentRegion != OMPD_target) || 4951 (SemaRef.LangOpts.OpenMP >= 50 && ParentRegion != OMPD_unknown && 4952 ParentRegion != OMPD_target); 4953 OrphanSeen = ParentRegion == OMPD_unknown; 4954 Recommend = ShouldBeInTargetRegion; 4955 } else if (CurrentRegion == OMPD_scan) { 4956 // OpenMP [2.16, Nesting of Regions] 4957 // If specified, a teams construct must be contained within a target 4958 // construct. 4959 NestingProhibited = 4960 SemaRef.LangOpts.OpenMP < 50 || 4961 (ParentRegion != OMPD_simd && ParentRegion != OMPD_for && 4962 ParentRegion != OMPD_for_simd && ParentRegion != OMPD_parallel_for && 4963 ParentRegion != OMPD_parallel_for_simd); 4964 OrphanSeen = ParentRegion == OMPD_unknown; 4965 Recommend = ShouldBeInLoopSimdRegion; 4966 } 4967 if (!NestingProhibited && 4968 !isOpenMPTargetExecutionDirective(CurrentRegion) && 4969 !isOpenMPTargetDataManagementDirective(CurrentRegion) && 4970 (ParentRegion == OMPD_teams || ParentRegion == OMPD_target_teams)) { 4971 // OpenMP [5.1, 2.22, Nesting of Regions] 4972 // distribute, distribute simd, distribute parallel worksharing-loop, 4973 // distribute parallel worksharing-loop SIMD, loop, parallel regions, 4974 // including any parallel regions arising from combined constructs, 4975 // omp_get_num_teams() regions, and omp_get_team_num() regions are the 4976 // only OpenMP regions that may be strictly nested inside the teams 4977 // region. 4978 // 4979 // As an extension, we permit atomic within teams as well. 4980 NestingProhibited = !isOpenMPParallelDirective(CurrentRegion) && 4981 !isOpenMPDistributeDirective(CurrentRegion) && 4982 CurrentRegion != OMPD_loop && 4983 !(SemaRef.getLangOpts().OpenMPExtensions && 4984 CurrentRegion == OMPD_atomic); 4985 Recommend = ShouldBeInParallelRegion; 4986 } 4987 if (!NestingProhibited && CurrentRegion == OMPD_loop) { 4988 // OpenMP [5.1, 2.11.7, loop Construct, Restrictions] 4989 // If the bind clause is present on the loop construct and binding is 4990 // teams then the corresponding loop region must be strictly nested inside 4991 // a teams region. 4992 NestingProhibited = BindKind == OMPC_BIND_teams && 4993 ParentRegion != OMPD_teams && 4994 ParentRegion != OMPD_target_teams; 4995 Recommend = ShouldBeInTeamsRegion; 4996 } 4997 if (!NestingProhibited && 4998 isOpenMPNestingDistributeDirective(CurrentRegion)) { 4999 // OpenMP 4.5 [2.17 Nesting of Regions] 5000 // The region associated with the distribute construct must be strictly 5001 // nested inside a teams region 5002 NestingProhibited = 5003 (ParentRegion != OMPD_teams && ParentRegion != OMPD_target_teams); 5004 Recommend = ShouldBeInTeamsRegion; 5005 } 5006 if (!NestingProhibited && 5007 (isOpenMPTargetExecutionDirective(CurrentRegion) || 5008 isOpenMPTargetDataManagementDirective(CurrentRegion))) { 5009 // OpenMP 4.5 [2.17 Nesting of Regions] 5010 // If a target, target update, target data, target enter data, or 5011 // target exit data construct is encountered during execution of a 5012 // target region, the behavior is unspecified. 5013 NestingProhibited = Stack->hasDirective( 5014 [&OffendingRegion](OpenMPDirectiveKind K, const DeclarationNameInfo &, 5015 SourceLocation) { 5016 if (isOpenMPTargetExecutionDirective(K)) { 5017 OffendingRegion = K; 5018 return true; 5019 } 5020 return false; 5021 }, 5022 false /* don't skip top directive */); 5023 CloseNesting = false; 5024 } 5025 if (NestingProhibited) { 5026 if (OrphanSeen) { 5027 SemaRef.Diag(StartLoc, diag::err_omp_orphaned_device_directive) 5028 << getOpenMPDirectiveName(CurrentRegion) << Recommend; 5029 } else { 5030 SemaRef.Diag(StartLoc, diag::err_omp_prohibited_region) 5031 << CloseNesting << getOpenMPDirectiveName(OffendingRegion) 5032 << Recommend << getOpenMPDirectiveName(CurrentRegion); 5033 } 5034 return true; 5035 } 5036 } 5037 return false; 5038 } 5039 5040 struct Kind2Unsigned { 5041 using argument_type = OpenMPDirectiveKind; 5042 unsigned operator()(argument_type DK) { return unsigned(DK); } 5043 }; 5044 static bool checkIfClauses(Sema &S, OpenMPDirectiveKind Kind, 5045 ArrayRef<OMPClause *> Clauses, 5046 ArrayRef<OpenMPDirectiveKind> AllowedNameModifiers) { 5047 bool ErrorFound = false; 5048 unsigned NamedModifiersNumber = 0; 5049 llvm::IndexedMap<const OMPIfClause *, Kind2Unsigned> FoundNameModifiers; 5050 FoundNameModifiers.resize(llvm::omp::Directive_enumSize + 1); 5051 SmallVector<SourceLocation, 4> NameModifierLoc; 5052 for (const OMPClause *C : Clauses) { 5053 if (const auto *IC = dyn_cast_or_null<OMPIfClause>(C)) { 5054 // At most one if clause without a directive-name-modifier can appear on 5055 // the directive. 5056 OpenMPDirectiveKind CurNM = IC->getNameModifier(); 5057 if (FoundNameModifiers[CurNM]) { 5058 S.Diag(C->getBeginLoc(), diag::err_omp_more_one_clause) 5059 << getOpenMPDirectiveName(Kind) << getOpenMPClauseName(OMPC_if) 5060 << (CurNM != OMPD_unknown) << getOpenMPDirectiveName(CurNM); 5061 ErrorFound = true; 5062 } else if (CurNM != OMPD_unknown) { 5063 NameModifierLoc.push_back(IC->getNameModifierLoc()); 5064 ++NamedModifiersNumber; 5065 } 5066 FoundNameModifiers[CurNM] = IC; 5067 if (CurNM == OMPD_unknown) 5068 continue; 5069 // Check if the specified name modifier is allowed for the current 5070 // directive. 5071 // At most one if clause with the particular directive-name-modifier can 5072 // appear on the directive. 5073 if (!llvm::is_contained(AllowedNameModifiers, CurNM)) { 5074 S.Diag(IC->getNameModifierLoc(), 5075 diag::err_omp_wrong_if_directive_name_modifier) 5076 << getOpenMPDirectiveName(CurNM) << getOpenMPDirectiveName(Kind); 5077 ErrorFound = true; 5078 } 5079 } 5080 } 5081 // If any if clause on the directive includes a directive-name-modifier then 5082 // all if clauses on the directive must include a directive-name-modifier. 5083 if (FoundNameModifiers[OMPD_unknown] && NamedModifiersNumber > 0) { 5084 if (NamedModifiersNumber == AllowedNameModifiers.size()) { 5085 S.Diag(FoundNameModifiers[OMPD_unknown]->getBeginLoc(), 5086 diag::err_omp_no_more_if_clause); 5087 } else { 5088 std::string Values; 5089 std::string Sep(", "); 5090 unsigned AllowedCnt = 0; 5091 unsigned TotalAllowedNum = 5092 AllowedNameModifiers.size() - NamedModifiersNumber; 5093 for (unsigned Cnt = 0, End = AllowedNameModifiers.size(); Cnt < End; 5094 ++Cnt) { 5095 OpenMPDirectiveKind NM = AllowedNameModifiers[Cnt]; 5096 if (!FoundNameModifiers[NM]) { 5097 Values += "'"; 5098 Values += getOpenMPDirectiveName(NM); 5099 Values += "'"; 5100 if (AllowedCnt + 2 == TotalAllowedNum) 5101 Values += " or "; 5102 else if (AllowedCnt + 1 != TotalAllowedNum) 5103 Values += Sep; 5104 ++AllowedCnt; 5105 } 5106 } 5107 S.Diag(FoundNameModifiers[OMPD_unknown]->getCondition()->getBeginLoc(), 5108 diag::err_omp_unnamed_if_clause) 5109 << (TotalAllowedNum > 1) << Values; 5110 } 5111 for (SourceLocation Loc : NameModifierLoc) { 5112 S.Diag(Loc, diag::note_omp_previous_named_if_clause); 5113 } 5114 ErrorFound = true; 5115 } 5116 return ErrorFound; 5117 } 5118 5119 static std::pair<ValueDecl *, bool> getPrivateItem(Sema &S, Expr *&RefExpr, 5120 SourceLocation &ELoc, 5121 SourceRange &ERange, 5122 bool AllowArraySection) { 5123 if (RefExpr->isTypeDependent() || RefExpr->isValueDependent() || 5124 RefExpr->containsUnexpandedParameterPack()) 5125 return std::make_pair(nullptr, true); 5126 5127 // OpenMP [3.1, C/C++] 5128 // A list item is a variable name. 5129 // OpenMP [2.9.3.3, Restrictions, p.1] 5130 // A variable that is part of another variable (as an array or 5131 // structure element) cannot appear in a private clause. 5132 RefExpr = RefExpr->IgnoreParens(); 5133 enum { 5134 NoArrayExpr = -1, 5135 ArraySubscript = 0, 5136 OMPArraySection = 1 5137 } IsArrayExpr = NoArrayExpr; 5138 if (AllowArraySection) { 5139 if (auto *ASE = dyn_cast_or_null<ArraySubscriptExpr>(RefExpr)) { 5140 Expr *Base = ASE->getBase()->IgnoreParenImpCasts(); 5141 while (auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base)) 5142 Base = TempASE->getBase()->IgnoreParenImpCasts(); 5143 RefExpr = Base; 5144 IsArrayExpr = ArraySubscript; 5145 } else if (auto *OASE = dyn_cast_or_null<OMPArraySectionExpr>(RefExpr)) { 5146 Expr *Base = OASE->getBase()->IgnoreParenImpCasts(); 5147 while (auto *TempOASE = dyn_cast<OMPArraySectionExpr>(Base)) 5148 Base = TempOASE->getBase()->IgnoreParenImpCasts(); 5149 while (auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base)) 5150 Base = TempASE->getBase()->IgnoreParenImpCasts(); 5151 RefExpr = Base; 5152 IsArrayExpr = OMPArraySection; 5153 } 5154 } 5155 ELoc = RefExpr->getExprLoc(); 5156 ERange = RefExpr->getSourceRange(); 5157 RefExpr = RefExpr->IgnoreParenImpCasts(); 5158 auto *DE = dyn_cast_or_null<DeclRefExpr>(RefExpr); 5159 auto *ME = dyn_cast_or_null<MemberExpr>(RefExpr); 5160 if ((!DE || !isa<VarDecl>(DE->getDecl())) && 5161 (S.getCurrentThisType().isNull() || !ME || 5162 !isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts()) || 5163 !isa<FieldDecl>(ME->getMemberDecl()))) { 5164 if (IsArrayExpr != NoArrayExpr) { 5165 S.Diag(ELoc, diag::err_omp_expected_base_var_name) 5166 << IsArrayExpr << ERange; 5167 } else { 5168 S.Diag(ELoc, 5169 AllowArraySection 5170 ? diag::err_omp_expected_var_name_member_expr_or_array_item 5171 : diag::err_omp_expected_var_name_member_expr) 5172 << (S.getCurrentThisType().isNull() ? 0 : 1) << ERange; 5173 } 5174 return std::make_pair(nullptr, false); 5175 } 5176 return std::make_pair( 5177 getCanonicalDecl(DE ? DE->getDecl() : ME->getMemberDecl()), false); 5178 } 5179 5180 namespace { 5181 /// Checks if the allocator is used in uses_allocators clause to be allowed in 5182 /// target regions. 5183 class AllocatorChecker final : public ConstStmtVisitor<AllocatorChecker, bool> { 5184 DSAStackTy *S = nullptr; 5185 5186 public: 5187 bool VisitDeclRefExpr(const DeclRefExpr *E) { 5188 return S->isUsesAllocatorsDecl(E->getDecl()) 5189 .getValueOr( 5190 DSAStackTy::UsesAllocatorsDeclKind::AllocatorTrait) == 5191 DSAStackTy::UsesAllocatorsDeclKind::AllocatorTrait; 5192 } 5193 bool VisitStmt(const Stmt *S) { 5194 for (const Stmt *Child : S->children()) { 5195 if (Child && Visit(Child)) 5196 return true; 5197 } 5198 return false; 5199 } 5200 explicit AllocatorChecker(DSAStackTy *S) : S(S) {} 5201 }; 5202 } // namespace 5203 5204 static void checkAllocateClauses(Sema &S, DSAStackTy *Stack, 5205 ArrayRef<OMPClause *> Clauses) { 5206 assert(!S.CurContext->isDependentContext() && 5207 "Expected non-dependent context."); 5208 auto AllocateRange = 5209 llvm::make_filter_range(Clauses, OMPAllocateClause::classof); 5210 llvm::DenseMap<CanonicalDeclPtr<Decl>, CanonicalDeclPtr<VarDecl>> DeclToCopy; 5211 auto PrivateRange = llvm::make_filter_range(Clauses, [](const OMPClause *C) { 5212 return isOpenMPPrivate(C->getClauseKind()); 5213 }); 5214 for (OMPClause *Cl : PrivateRange) { 5215 MutableArrayRef<Expr *>::iterator I, It, Et; 5216 if (Cl->getClauseKind() == OMPC_private) { 5217 auto *PC = cast<OMPPrivateClause>(Cl); 5218 I = PC->private_copies().begin(); 5219 It = PC->varlist_begin(); 5220 Et = PC->varlist_end(); 5221 } else if (Cl->getClauseKind() == OMPC_firstprivate) { 5222 auto *PC = cast<OMPFirstprivateClause>(Cl); 5223 I = PC->private_copies().begin(); 5224 It = PC->varlist_begin(); 5225 Et = PC->varlist_end(); 5226 } else if (Cl->getClauseKind() == OMPC_lastprivate) { 5227 auto *PC = cast<OMPLastprivateClause>(Cl); 5228 I = PC->private_copies().begin(); 5229 It = PC->varlist_begin(); 5230 Et = PC->varlist_end(); 5231 } else if (Cl->getClauseKind() == OMPC_linear) { 5232 auto *PC = cast<OMPLinearClause>(Cl); 5233 I = PC->privates().begin(); 5234 It = PC->varlist_begin(); 5235 Et = PC->varlist_end(); 5236 } else if (Cl->getClauseKind() == OMPC_reduction) { 5237 auto *PC = cast<OMPReductionClause>(Cl); 5238 I = PC->privates().begin(); 5239 It = PC->varlist_begin(); 5240 Et = PC->varlist_end(); 5241 } else if (Cl->getClauseKind() == OMPC_task_reduction) { 5242 auto *PC = cast<OMPTaskReductionClause>(Cl); 5243 I = PC->privates().begin(); 5244 It = PC->varlist_begin(); 5245 Et = PC->varlist_end(); 5246 } else if (Cl->getClauseKind() == OMPC_in_reduction) { 5247 auto *PC = cast<OMPInReductionClause>(Cl); 5248 I = PC->privates().begin(); 5249 It = PC->varlist_begin(); 5250 Et = PC->varlist_end(); 5251 } else { 5252 llvm_unreachable("Expected private clause."); 5253 } 5254 for (Expr *E : llvm::make_range(It, Et)) { 5255 if (!*I) { 5256 ++I; 5257 continue; 5258 } 5259 SourceLocation ELoc; 5260 SourceRange ERange; 5261 Expr *SimpleRefExpr = E; 5262 auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange, 5263 /*AllowArraySection=*/true); 5264 DeclToCopy.try_emplace(Res.first, 5265 cast<VarDecl>(cast<DeclRefExpr>(*I)->getDecl())); 5266 ++I; 5267 } 5268 } 5269 for (OMPClause *C : AllocateRange) { 5270 auto *AC = cast<OMPAllocateClause>(C); 5271 if (S.getLangOpts().OpenMP >= 50 && 5272 !Stack->hasRequiresDeclWithClause<OMPDynamicAllocatorsClause>() && 5273 isOpenMPTargetExecutionDirective(Stack->getCurrentDirective()) && 5274 AC->getAllocator()) { 5275 Expr *Allocator = AC->getAllocator(); 5276 // OpenMP, 2.12.5 target Construct 5277 // Memory allocators that do not appear in a uses_allocators clause cannot 5278 // appear as an allocator in an allocate clause or be used in the target 5279 // region unless a requires directive with the dynamic_allocators clause 5280 // is present in the same compilation unit. 5281 AllocatorChecker Checker(Stack); 5282 if (Checker.Visit(Allocator)) 5283 S.Diag(Allocator->getExprLoc(), 5284 diag::err_omp_allocator_not_in_uses_allocators) 5285 << Allocator->getSourceRange(); 5286 } 5287 OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind = 5288 getAllocatorKind(S, Stack, AC->getAllocator()); 5289 // OpenMP, 2.11.4 allocate Clause, Restrictions. 5290 // For task, taskloop or target directives, allocation requests to memory 5291 // allocators with the trait access set to thread result in unspecified 5292 // behavior. 5293 if (AllocatorKind == OMPAllocateDeclAttr::OMPThreadMemAlloc && 5294 (isOpenMPTaskingDirective(Stack->getCurrentDirective()) || 5295 isOpenMPTargetExecutionDirective(Stack->getCurrentDirective()))) { 5296 S.Diag(AC->getAllocator()->getExprLoc(), 5297 diag::warn_omp_allocate_thread_on_task_target_directive) 5298 << getOpenMPDirectiveName(Stack->getCurrentDirective()); 5299 } 5300 for (Expr *E : AC->varlists()) { 5301 SourceLocation ELoc; 5302 SourceRange ERange; 5303 Expr *SimpleRefExpr = E; 5304 auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange); 5305 ValueDecl *VD = Res.first; 5306 DSAStackTy::DSAVarData Data = Stack->getTopDSA(VD, /*FromParent=*/false); 5307 if (!isOpenMPPrivate(Data.CKind)) { 5308 S.Diag(E->getExprLoc(), 5309 diag::err_omp_expected_private_copy_for_allocate); 5310 continue; 5311 } 5312 VarDecl *PrivateVD = DeclToCopy[VD]; 5313 if (checkPreviousOMPAllocateAttribute(S, Stack, E, PrivateVD, 5314 AllocatorKind, AC->getAllocator())) 5315 continue; 5316 // Placeholder until allocate clause supports align modifier. 5317 Expr *Alignment = nullptr; 5318 applyOMPAllocateAttribute(S, PrivateVD, AllocatorKind, AC->getAllocator(), 5319 Alignment, E->getSourceRange()); 5320 } 5321 } 5322 } 5323 5324 namespace { 5325 /// Rewrite statements and expressions for Sema \p Actions CurContext. 5326 /// 5327 /// Used to wrap already parsed statements/expressions into a new CapturedStmt 5328 /// context. DeclRefExpr used inside the new context are changed to refer to the 5329 /// captured variable instead. 5330 class CaptureVars : public TreeTransform<CaptureVars> { 5331 using BaseTransform = TreeTransform<CaptureVars>; 5332 5333 public: 5334 CaptureVars(Sema &Actions) : BaseTransform(Actions) {} 5335 5336 bool AlwaysRebuild() { return true; } 5337 }; 5338 } // namespace 5339 5340 static VarDecl *precomputeExpr(Sema &Actions, 5341 SmallVectorImpl<Stmt *> &BodyStmts, Expr *E, 5342 StringRef Name) { 5343 Expr *NewE = AssertSuccess(CaptureVars(Actions).TransformExpr(E)); 5344 VarDecl *NewVar = buildVarDecl(Actions, {}, NewE->getType(), Name, nullptr, 5345 dyn_cast<DeclRefExpr>(E->IgnoreImplicit())); 5346 auto *NewDeclStmt = cast<DeclStmt>(AssertSuccess( 5347 Actions.ActOnDeclStmt(Actions.ConvertDeclToDeclGroup(NewVar), {}, {}))); 5348 Actions.AddInitializerToDecl(NewDeclStmt->getSingleDecl(), NewE, false); 5349 BodyStmts.push_back(NewDeclStmt); 5350 return NewVar; 5351 } 5352 5353 /// Create a closure that computes the number of iterations of a loop. 5354 /// 5355 /// \param Actions The Sema object. 5356 /// \param LogicalTy Type for the logical iteration number. 5357 /// \param Rel Comparison operator of the loop condition. 5358 /// \param StartExpr Value of the loop counter at the first iteration. 5359 /// \param StopExpr Expression the loop counter is compared against in the loop 5360 /// condition. \param StepExpr Amount of increment after each iteration. 5361 /// 5362 /// \return Closure (CapturedStmt) of the distance calculation. 5363 static CapturedStmt *buildDistanceFunc(Sema &Actions, QualType LogicalTy, 5364 BinaryOperator::Opcode Rel, 5365 Expr *StartExpr, Expr *StopExpr, 5366 Expr *StepExpr) { 5367 ASTContext &Ctx = Actions.getASTContext(); 5368 TypeSourceInfo *LogicalTSI = Ctx.getTrivialTypeSourceInfo(LogicalTy); 5369 5370 // Captured regions currently don't support return values, we use an 5371 // out-parameter instead. All inputs are implicit captures. 5372 // TODO: Instead of capturing each DeclRefExpr occurring in 5373 // StartExpr/StopExpr/Step, these could also be passed as a value capture. 5374 QualType ResultTy = Ctx.getLValueReferenceType(LogicalTy); 5375 Sema::CapturedParamNameType Params[] = {{"Distance", ResultTy}, 5376 {StringRef(), QualType()}}; 5377 Actions.ActOnCapturedRegionStart({}, nullptr, CR_Default, Params); 5378 5379 Stmt *Body; 5380 { 5381 Sema::CompoundScopeRAII CompoundScope(Actions); 5382 CapturedDecl *CS = cast<CapturedDecl>(Actions.CurContext); 5383 5384 // Get the LValue expression for the result. 5385 ImplicitParamDecl *DistParam = CS->getParam(0); 5386 DeclRefExpr *DistRef = Actions.BuildDeclRefExpr( 5387 DistParam, LogicalTy, VK_LValue, {}, nullptr, nullptr, {}, nullptr); 5388 5389 SmallVector<Stmt *, 4> BodyStmts; 5390 5391 // Capture all referenced variable references. 5392 // TODO: Instead of computing NewStart/NewStop/NewStep inside the 5393 // CapturedStmt, we could compute them before and capture the result, to be 5394 // used jointly with the LoopVar function. 5395 VarDecl *NewStart = precomputeExpr(Actions, BodyStmts, StartExpr, ".start"); 5396 VarDecl *NewStop = precomputeExpr(Actions, BodyStmts, StopExpr, ".stop"); 5397 VarDecl *NewStep = precomputeExpr(Actions, BodyStmts, StepExpr, ".step"); 5398 auto BuildVarRef = [&](VarDecl *VD) { 5399 return buildDeclRefExpr(Actions, VD, VD->getType(), {}); 5400 }; 5401 5402 IntegerLiteral *Zero = IntegerLiteral::Create( 5403 Ctx, llvm::APInt(Ctx.getIntWidth(LogicalTy), 0), LogicalTy, {}); 5404 IntegerLiteral *One = IntegerLiteral::Create( 5405 Ctx, llvm::APInt(Ctx.getIntWidth(LogicalTy), 1), LogicalTy, {}); 5406 Expr *Dist; 5407 if (Rel == BO_NE) { 5408 // When using a != comparison, the increment can be +1 or -1. This can be 5409 // dynamic at runtime, so we need to check for the direction. 5410 Expr *IsNegStep = AssertSuccess( 5411 Actions.BuildBinOp(nullptr, {}, BO_LT, BuildVarRef(NewStep), Zero)); 5412 5413 // Positive increment. 5414 Expr *ForwardRange = AssertSuccess(Actions.BuildBinOp( 5415 nullptr, {}, BO_Sub, BuildVarRef(NewStop), BuildVarRef(NewStart))); 5416 ForwardRange = AssertSuccess( 5417 Actions.BuildCStyleCastExpr({}, LogicalTSI, {}, ForwardRange)); 5418 Expr *ForwardDist = AssertSuccess(Actions.BuildBinOp( 5419 nullptr, {}, BO_Div, ForwardRange, BuildVarRef(NewStep))); 5420 5421 // Negative increment. 5422 Expr *BackwardRange = AssertSuccess(Actions.BuildBinOp( 5423 nullptr, {}, BO_Sub, BuildVarRef(NewStart), BuildVarRef(NewStop))); 5424 BackwardRange = AssertSuccess( 5425 Actions.BuildCStyleCastExpr({}, LogicalTSI, {}, BackwardRange)); 5426 Expr *NegIncAmount = AssertSuccess( 5427 Actions.BuildUnaryOp(nullptr, {}, UO_Minus, BuildVarRef(NewStep))); 5428 Expr *BackwardDist = AssertSuccess( 5429 Actions.BuildBinOp(nullptr, {}, BO_Div, BackwardRange, NegIncAmount)); 5430 5431 // Use the appropriate case. 5432 Dist = AssertSuccess(Actions.ActOnConditionalOp( 5433 {}, {}, IsNegStep, BackwardDist, ForwardDist)); 5434 } else { 5435 assert((Rel == BO_LT || Rel == BO_LE || Rel == BO_GE || Rel == BO_GT) && 5436 "Expected one of these relational operators"); 5437 5438 // We can derive the direction from any other comparison operator. It is 5439 // non well-formed OpenMP if Step increments/decrements in the other 5440 // directions. Whether at least the first iteration passes the loop 5441 // condition. 5442 Expr *HasAnyIteration = AssertSuccess(Actions.BuildBinOp( 5443 nullptr, {}, Rel, BuildVarRef(NewStart), BuildVarRef(NewStop))); 5444 5445 // Compute the range between first and last counter value. 5446 Expr *Range; 5447 if (Rel == BO_GE || Rel == BO_GT) 5448 Range = AssertSuccess(Actions.BuildBinOp( 5449 nullptr, {}, BO_Sub, BuildVarRef(NewStart), BuildVarRef(NewStop))); 5450 else 5451 Range = AssertSuccess(Actions.BuildBinOp( 5452 nullptr, {}, BO_Sub, BuildVarRef(NewStop), BuildVarRef(NewStart))); 5453 5454 // Ensure unsigned range space. 5455 Range = 5456 AssertSuccess(Actions.BuildCStyleCastExpr({}, LogicalTSI, {}, Range)); 5457 5458 if (Rel == BO_LE || Rel == BO_GE) { 5459 // Add one to the range if the relational operator is inclusive. 5460 Range = 5461 AssertSuccess(Actions.BuildBinOp(nullptr, {}, BO_Add, Range, One)); 5462 } 5463 5464 // Divide by the absolute step amount. If the range is not a multiple of 5465 // the step size, rounding-up the effective upper bound ensures that the 5466 // last iteration is included. 5467 // Note that the rounding-up may cause an overflow in a temporry that 5468 // could be avoided, but would have occurred in a C-style for-loop as well. 5469 Expr *Divisor = BuildVarRef(NewStep); 5470 if (Rel == BO_GE || Rel == BO_GT) 5471 Divisor = 5472 AssertSuccess(Actions.BuildUnaryOp(nullptr, {}, UO_Minus, Divisor)); 5473 Expr *DivisorMinusOne = 5474 AssertSuccess(Actions.BuildBinOp(nullptr, {}, BO_Sub, Divisor, One)); 5475 Expr *RangeRoundUp = AssertSuccess( 5476 Actions.BuildBinOp(nullptr, {}, BO_Add, Range, DivisorMinusOne)); 5477 Dist = AssertSuccess( 5478 Actions.BuildBinOp(nullptr, {}, BO_Div, RangeRoundUp, Divisor)); 5479 5480 // If there is not at least one iteration, the range contains garbage. Fix 5481 // to zero in this case. 5482 Dist = AssertSuccess( 5483 Actions.ActOnConditionalOp({}, {}, HasAnyIteration, Dist, Zero)); 5484 } 5485 5486 // Assign the result to the out-parameter. 5487 Stmt *ResultAssign = AssertSuccess(Actions.BuildBinOp( 5488 Actions.getCurScope(), {}, BO_Assign, DistRef, Dist)); 5489 BodyStmts.push_back(ResultAssign); 5490 5491 Body = AssertSuccess(Actions.ActOnCompoundStmt({}, {}, BodyStmts, false)); 5492 } 5493 5494 return cast<CapturedStmt>( 5495 AssertSuccess(Actions.ActOnCapturedRegionEnd(Body))); 5496 } 5497 5498 /// Create a closure that computes the loop variable from the logical iteration 5499 /// number. 5500 /// 5501 /// \param Actions The Sema object. 5502 /// \param LoopVarTy Type for the loop variable used for result value. 5503 /// \param LogicalTy Type for the logical iteration number. 5504 /// \param StartExpr Value of the loop counter at the first iteration. 5505 /// \param Step Amount of increment after each iteration. 5506 /// \param Deref Whether the loop variable is a dereference of the loop 5507 /// counter variable. 5508 /// 5509 /// \return Closure (CapturedStmt) of the loop value calculation. 5510 static CapturedStmt *buildLoopVarFunc(Sema &Actions, QualType LoopVarTy, 5511 QualType LogicalTy, 5512 DeclRefExpr *StartExpr, Expr *Step, 5513 bool Deref) { 5514 ASTContext &Ctx = Actions.getASTContext(); 5515 5516 // Pass the result as an out-parameter. Passing as return value would require 5517 // the OpenMPIRBuilder to know additional C/C++ semantics, such as how to 5518 // invoke a copy constructor. 5519 QualType TargetParamTy = Ctx.getLValueReferenceType(LoopVarTy); 5520 Sema::CapturedParamNameType Params[] = {{"LoopVar", TargetParamTy}, 5521 {"Logical", LogicalTy}, 5522 {StringRef(), QualType()}}; 5523 Actions.ActOnCapturedRegionStart({}, nullptr, CR_Default, Params); 5524 5525 // Capture the initial iterator which represents the LoopVar value at the 5526 // zero's logical iteration. Since the original ForStmt/CXXForRangeStmt update 5527 // it in every iteration, capture it by value before it is modified. 5528 VarDecl *StartVar = cast<VarDecl>(StartExpr->getDecl()); 5529 bool Invalid = Actions.tryCaptureVariable(StartVar, {}, 5530 Sema::TryCapture_ExplicitByVal, {}); 5531 (void)Invalid; 5532 assert(!Invalid && "Expecting capture-by-value to work."); 5533 5534 Expr *Body; 5535 { 5536 Sema::CompoundScopeRAII CompoundScope(Actions); 5537 auto *CS = cast<CapturedDecl>(Actions.CurContext); 5538 5539 ImplicitParamDecl *TargetParam = CS->getParam(0); 5540 DeclRefExpr *TargetRef = Actions.BuildDeclRefExpr( 5541 TargetParam, LoopVarTy, VK_LValue, {}, nullptr, nullptr, {}, nullptr); 5542 ImplicitParamDecl *IndvarParam = CS->getParam(1); 5543 DeclRefExpr *LogicalRef = Actions.BuildDeclRefExpr( 5544 IndvarParam, LogicalTy, VK_LValue, {}, nullptr, nullptr, {}, nullptr); 5545 5546 // Capture the Start expression. 5547 CaptureVars Recap(Actions); 5548 Expr *NewStart = AssertSuccess(Recap.TransformExpr(StartExpr)); 5549 Expr *NewStep = AssertSuccess(Recap.TransformExpr(Step)); 5550 5551 Expr *Skip = AssertSuccess( 5552 Actions.BuildBinOp(nullptr, {}, BO_Mul, NewStep, LogicalRef)); 5553 // TODO: Explicitly cast to the iterator's difference_type instead of 5554 // relying on implicit conversion. 5555 Expr *Advanced = 5556 AssertSuccess(Actions.BuildBinOp(nullptr, {}, BO_Add, NewStart, Skip)); 5557 5558 if (Deref) { 5559 // For range-based for-loops convert the loop counter value to a concrete 5560 // loop variable value by dereferencing the iterator. 5561 Advanced = 5562 AssertSuccess(Actions.BuildUnaryOp(nullptr, {}, UO_Deref, Advanced)); 5563 } 5564 5565 // Assign the result to the output parameter. 5566 Body = AssertSuccess(Actions.BuildBinOp(Actions.getCurScope(), {}, 5567 BO_Assign, TargetRef, Advanced)); 5568 } 5569 return cast<CapturedStmt>( 5570 AssertSuccess(Actions.ActOnCapturedRegionEnd(Body))); 5571 } 5572 5573 StmtResult Sema::ActOnOpenMPCanonicalLoop(Stmt *AStmt) { 5574 ASTContext &Ctx = getASTContext(); 5575 5576 // Extract the common elements of ForStmt and CXXForRangeStmt: 5577 // Loop variable, repeat condition, increment 5578 Expr *Cond, *Inc; 5579 VarDecl *LIVDecl, *LUVDecl; 5580 if (auto *For = dyn_cast<ForStmt>(AStmt)) { 5581 Stmt *Init = For->getInit(); 5582 if (auto *LCVarDeclStmt = dyn_cast<DeclStmt>(Init)) { 5583 // For statement declares loop variable. 5584 LIVDecl = cast<VarDecl>(LCVarDeclStmt->getSingleDecl()); 5585 } else if (auto *LCAssign = dyn_cast<BinaryOperator>(Init)) { 5586 // For statement reuses variable. 5587 assert(LCAssign->getOpcode() == BO_Assign && 5588 "init part must be a loop variable assignment"); 5589 auto *CounterRef = cast<DeclRefExpr>(LCAssign->getLHS()); 5590 LIVDecl = cast<VarDecl>(CounterRef->getDecl()); 5591 } else 5592 llvm_unreachable("Cannot determine loop variable"); 5593 LUVDecl = LIVDecl; 5594 5595 Cond = For->getCond(); 5596 Inc = For->getInc(); 5597 } else if (auto *RangeFor = dyn_cast<CXXForRangeStmt>(AStmt)) { 5598 DeclStmt *BeginStmt = RangeFor->getBeginStmt(); 5599 LIVDecl = cast<VarDecl>(BeginStmt->getSingleDecl()); 5600 LUVDecl = RangeFor->getLoopVariable(); 5601 5602 Cond = RangeFor->getCond(); 5603 Inc = RangeFor->getInc(); 5604 } else 5605 llvm_unreachable("unhandled kind of loop"); 5606 5607 QualType CounterTy = LIVDecl->getType(); 5608 QualType LVTy = LUVDecl->getType(); 5609 5610 // Analyze the loop condition. 5611 Expr *LHS, *RHS; 5612 BinaryOperator::Opcode CondRel; 5613 Cond = Cond->IgnoreImplicit(); 5614 if (auto *CondBinExpr = dyn_cast<BinaryOperator>(Cond)) { 5615 LHS = CondBinExpr->getLHS(); 5616 RHS = CondBinExpr->getRHS(); 5617 CondRel = CondBinExpr->getOpcode(); 5618 } else if (auto *CondCXXOp = dyn_cast<CXXOperatorCallExpr>(Cond)) { 5619 assert(CondCXXOp->getNumArgs() == 2 && "Comparison should have 2 operands"); 5620 LHS = CondCXXOp->getArg(0); 5621 RHS = CondCXXOp->getArg(1); 5622 switch (CondCXXOp->getOperator()) { 5623 case OO_ExclaimEqual: 5624 CondRel = BO_NE; 5625 break; 5626 case OO_Less: 5627 CondRel = BO_LT; 5628 break; 5629 case OO_LessEqual: 5630 CondRel = BO_LE; 5631 break; 5632 case OO_Greater: 5633 CondRel = BO_GT; 5634 break; 5635 case OO_GreaterEqual: 5636 CondRel = BO_GE; 5637 break; 5638 default: 5639 llvm_unreachable("unexpected iterator operator"); 5640 } 5641 } else 5642 llvm_unreachable("unexpected loop condition"); 5643 5644 // Normalize such that the loop counter is on the LHS. 5645 if (!isa<DeclRefExpr>(LHS->IgnoreImplicit()) || 5646 cast<DeclRefExpr>(LHS->IgnoreImplicit())->getDecl() != LIVDecl) { 5647 std::swap(LHS, RHS); 5648 CondRel = BinaryOperator::reverseComparisonOp(CondRel); 5649 } 5650 auto *CounterRef = cast<DeclRefExpr>(LHS->IgnoreImplicit()); 5651 5652 // Decide the bit width for the logical iteration counter. By default use the 5653 // unsigned ptrdiff_t integer size (for iterators and pointers). 5654 // TODO: For iterators, use iterator::difference_type, 5655 // std::iterator_traits<>::difference_type or decltype(it - end). 5656 QualType LogicalTy = Ctx.getUnsignedPointerDiffType(); 5657 if (CounterTy->isIntegerType()) { 5658 unsigned BitWidth = Ctx.getIntWidth(CounterTy); 5659 LogicalTy = Ctx.getIntTypeForBitwidth(BitWidth, false); 5660 } 5661 5662 // Analyze the loop increment. 5663 Expr *Step; 5664 if (auto *IncUn = dyn_cast<UnaryOperator>(Inc)) { 5665 int Direction; 5666 switch (IncUn->getOpcode()) { 5667 case UO_PreInc: 5668 case UO_PostInc: 5669 Direction = 1; 5670 break; 5671 case UO_PreDec: 5672 case UO_PostDec: 5673 Direction = -1; 5674 break; 5675 default: 5676 llvm_unreachable("unhandled unary increment operator"); 5677 } 5678 Step = IntegerLiteral::Create( 5679 Ctx, llvm::APInt(Ctx.getIntWidth(LogicalTy), Direction), LogicalTy, {}); 5680 } else if (auto *IncBin = dyn_cast<BinaryOperator>(Inc)) { 5681 if (IncBin->getOpcode() == BO_AddAssign) { 5682 Step = IncBin->getRHS(); 5683 } else if (IncBin->getOpcode() == BO_SubAssign) { 5684 Step = 5685 AssertSuccess(BuildUnaryOp(nullptr, {}, UO_Minus, IncBin->getRHS())); 5686 } else 5687 llvm_unreachable("unhandled binary increment operator"); 5688 } else if (auto *CondCXXOp = dyn_cast<CXXOperatorCallExpr>(Inc)) { 5689 switch (CondCXXOp->getOperator()) { 5690 case OO_PlusPlus: 5691 Step = IntegerLiteral::Create( 5692 Ctx, llvm::APInt(Ctx.getIntWidth(LogicalTy), 1), LogicalTy, {}); 5693 break; 5694 case OO_MinusMinus: 5695 Step = IntegerLiteral::Create( 5696 Ctx, llvm::APInt(Ctx.getIntWidth(LogicalTy), -1), LogicalTy, {}); 5697 break; 5698 case OO_PlusEqual: 5699 Step = CondCXXOp->getArg(1); 5700 break; 5701 case OO_MinusEqual: 5702 Step = AssertSuccess( 5703 BuildUnaryOp(nullptr, {}, UO_Minus, CondCXXOp->getArg(1))); 5704 break; 5705 default: 5706 llvm_unreachable("unhandled overloaded increment operator"); 5707 } 5708 } else 5709 llvm_unreachable("unknown increment expression"); 5710 5711 CapturedStmt *DistanceFunc = 5712 buildDistanceFunc(*this, LogicalTy, CondRel, LHS, RHS, Step); 5713 CapturedStmt *LoopVarFunc = buildLoopVarFunc( 5714 *this, LVTy, LogicalTy, CounterRef, Step, isa<CXXForRangeStmt>(AStmt)); 5715 DeclRefExpr *LVRef = BuildDeclRefExpr(LUVDecl, LUVDecl->getType(), VK_LValue, 5716 {}, nullptr, nullptr, {}, nullptr); 5717 return OMPCanonicalLoop::create(getASTContext(), AStmt, DistanceFunc, 5718 LoopVarFunc, LVRef); 5719 } 5720 5721 StmtResult Sema::ActOnOpenMPLoopnest(Stmt *AStmt) { 5722 // Handle a literal loop. 5723 if (isa<ForStmt>(AStmt) || isa<CXXForRangeStmt>(AStmt)) 5724 return ActOnOpenMPCanonicalLoop(AStmt); 5725 5726 // If not a literal loop, it must be the result of a loop transformation. 5727 OMPExecutableDirective *LoopTransform = cast<OMPExecutableDirective>(AStmt); 5728 assert( 5729 isOpenMPLoopTransformationDirective(LoopTransform->getDirectiveKind()) && 5730 "Loop transformation directive expected"); 5731 return LoopTransform; 5732 } 5733 5734 static ExprResult buildUserDefinedMapperRef(Sema &SemaRef, Scope *S, 5735 CXXScopeSpec &MapperIdScopeSpec, 5736 const DeclarationNameInfo &MapperId, 5737 QualType Type, 5738 Expr *UnresolvedMapper); 5739 5740 /// Perform DFS through the structure/class data members trying to find 5741 /// member(s) with user-defined 'default' mapper and generate implicit map 5742 /// clauses for such members with the found 'default' mapper. 5743 static void 5744 processImplicitMapsWithDefaultMappers(Sema &S, DSAStackTy *Stack, 5745 SmallVectorImpl<OMPClause *> &Clauses) { 5746 // Check for the deault mapper for data members. 5747 if (S.getLangOpts().OpenMP < 50) 5748 return; 5749 SmallVector<OMPClause *, 4> ImplicitMaps; 5750 for (int Cnt = 0, EndCnt = Clauses.size(); Cnt < EndCnt; ++Cnt) { 5751 auto *C = dyn_cast<OMPMapClause>(Clauses[Cnt]); 5752 if (!C) 5753 continue; 5754 SmallVector<Expr *, 4> SubExprs; 5755 auto *MI = C->mapperlist_begin(); 5756 for (auto I = C->varlist_begin(), End = C->varlist_end(); I != End; 5757 ++I, ++MI) { 5758 // Expression is mapped using mapper - skip it. 5759 if (*MI) 5760 continue; 5761 Expr *E = *I; 5762 // Expression is dependent - skip it, build the mapper when it gets 5763 // instantiated. 5764 if (E->isTypeDependent() || E->isValueDependent() || 5765 E->containsUnexpandedParameterPack()) 5766 continue; 5767 // Array section - need to check for the mapping of the array section 5768 // element. 5769 QualType CanonType = E->getType().getCanonicalType(); 5770 if (CanonType->isSpecificBuiltinType(BuiltinType::OMPArraySection)) { 5771 const auto *OASE = cast<OMPArraySectionExpr>(E->IgnoreParenImpCasts()); 5772 QualType BaseType = 5773 OMPArraySectionExpr::getBaseOriginalType(OASE->getBase()); 5774 QualType ElemType; 5775 if (const auto *ATy = BaseType->getAsArrayTypeUnsafe()) 5776 ElemType = ATy->getElementType(); 5777 else 5778 ElemType = BaseType->getPointeeType(); 5779 CanonType = ElemType; 5780 } 5781 5782 // DFS over data members in structures/classes. 5783 SmallVector<std::pair<QualType, FieldDecl *>, 4> Types( 5784 1, {CanonType, nullptr}); 5785 llvm::DenseMap<const Type *, Expr *> Visited; 5786 SmallVector<std::pair<FieldDecl *, unsigned>, 4> ParentChain( 5787 1, {nullptr, 1}); 5788 while (!Types.empty()) { 5789 QualType BaseType; 5790 FieldDecl *CurFD; 5791 std::tie(BaseType, CurFD) = Types.pop_back_val(); 5792 while (ParentChain.back().second == 0) 5793 ParentChain.pop_back(); 5794 --ParentChain.back().second; 5795 if (BaseType.isNull()) 5796 continue; 5797 // Only structs/classes are allowed to have mappers. 5798 const RecordDecl *RD = BaseType.getCanonicalType()->getAsRecordDecl(); 5799 if (!RD) 5800 continue; 5801 auto It = Visited.find(BaseType.getTypePtr()); 5802 if (It == Visited.end()) { 5803 // Try to find the associated user-defined mapper. 5804 CXXScopeSpec MapperIdScopeSpec; 5805 DeclarationNameInfo DefaultMapperId; 5806 DefaultMapperId.setName(S.Context.DeclarationNames.getIdentifier( 5807 &S.Context.Idents.get("default"))); 5808 DefaultMapperId.setLoc(E->getExprLoc()); 5809 ExprResult ER = buildUserDefinedMapperRef( 5810 S, Stack->getCurScope(), MapperIdScopeSpec, DefaultMapperId, 5811 BaseType, /*UnresolvedMapper=*/nullptr); 5812 if (ER.isInvalid()) 5813 continue; 5814 It = Visited.try_emplace(BaseType.getTypePtr(), ER.get()).first; 5815 } 5816 // Found default mapper. 5817 if (It->second) { 5818 auto *OE = new (S.Context) OpaqueValueExpr(E->getExprLoc(), CanonType, 5819 VK_LValue, OK_Ordinary, E); 5820 OE->setIsUnique(/*V=*/true); 5821 Expr *BaseExpr = OE; 5822 for (const auto &P : ParentChain) { 5823 if (P.first) { 5824 BaseExpr = S.BuildMemberExpr( 5825 BaseExpr, /*IsArrow=*/false, E->getExprLoc(), 5826 NestedNameSpecifierLoc(), SourceLocation(), P.first, 5827 DeclAccessPair::make(P.first, P.first->getAccess()), 5828 /*HadMultipleCandidates=*/false, DeclarationNameInfo(), 5829 P.first->getType(), VK_LValue, OK_Ordinary); 5830 BaseExpr = S.DefaultLvalueConversion(BaseExpr).get(); 5831 } 5832 } 5833 if (CurFD) 5834 BaseExpr = S.BuildMemberExpr( 5835 BaseExpr, /*IsArrow=*/false, E->getExprLoc(), 5836 NestedNameSpecifierLoc(), SourceLocation(), CurFD, 5837 DeclAccessPair::make(CurFD, CurFD->getAccess()), 5838 /*HadMultipleCandidates=*/false, DeclarationNameInfo(), 5839 CurFD->getType(), VK_LValue, OK_Ordinary); 5840 SubExprs.push_back(BaseExpr); 5841 continue; 5842 } 5843 // Check for the "default" mapper for data members. 5844 bool FirstIter = true; 5845 for (FieldDecl *FD : RD->fields()) { 5846 if (!FD) 5847 continue; 5848 QualType FieldTy = FD->getType(); 5849 if (FieldTy.isNull() || 5850 !(FieldTy->isStructureOrClassType() || FieldTy->isUnionType())) 5851 continue; 5852 if (FirstIter) { 5853 FirstIter = false; 5854 ParentChain.emplace_back(CurFD, 1); 5855 } else { 5856 ++ParentChain.back().second; 5857 } 5858 Types.emplace_back(FieldTy, FD); 5859 } 5860 } 5861 } 5862 if (SubExprs.empty()) 5863 continue; 5864 CXXScopeSpec MapperIdScopeSpec; 5865 DeclarationNameInfo MapperId; 5866 if (OMPClause *NewClause = S.ActOnOpenMPMapClause( 5867 C->getMapTypeModifiers(), C->getMapTypeModifiersLoc(), 5868 MapperIdScopeSpec, MapperId, C->getMapType(), 5869 /*IsMapTypeImplicit=*/true, SourceLocation(), SourceLocation(), 5870 SubExprs, OMPVarListLocTy())) 5871 Clauses.push_back(NewClause); 5872 } 5873 } 5874 5875 StmtResult Sema::ActOnOpenMPExecutableDirective( 5876 OpenMPDirectiveKind Kind, const DeclarationNameInfo &DirName, 5877 OpenMPDirectiveKind CancelRegion, ArrayRef<OMPClause *> Clauses, 5878 Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc) { 5879 StmtResult Res = StmtError(); 5880 OpenMPBindClauseKind BindKind = OMPC_BIND_unknown; 5881 if (const OMPBindClause *BC = 5882 OMPExecutableDirective::getSingleClause<OMPBindClause>(Clauses)) 5883 BindKind = BC->getBindKind(); 5884 // First check CancelRegion which is then used in checkNestingOfRegions. 5885 if (checkCancelRegion(*this, Kind, CancelRegion, StartLoc) || 5886 checkNestingOfRegions(*this, DSAStack, Kind, DirName, CancelRegion, 5887 BindKind, StartLoc)) 5888 return StmtError(); 5889 5890 llvm::SmallVector<OMPClause *, 8> ClausesWithImplicit; 5891 VarsWithInheritedDSAType VarsWithInheritedDSA; 5892 bool ErrorFound = false; 5893 ClausesWithImplicit.append(Clauses.begin(), Clauses.end()); 5894 if (AStmt && !CurContext->isDependentContext() && Kind != OMPD_atomic && 5895 Kind != OMPD_critical && Kind != OMPD_section && Kind != OMPD_master && 5896 Kind != OMPD_masked && !isOpenMPLoopTransformationDirective(Kind)) { 5897 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 5898 5899 // Check default data sharing attributes for referenced variables. 5900 DSAAttrChecker DSAChecker(DSAStack, *this, cast<CapturedStmt>(AStmt)); 5901 int ThisCaptureLevel = getOpenMPCaptureLevels(Kind); 5902 Stmt *S = AStmt; 5903 while (--ThisCaptureLevel >= 0) 5904 S = cast<CapturedStmt>(S)->getCapturedStmt(); 5905 DSAChecker.Visit(S); 5906 if (!isOpenMPTargetDataManagementDirective(Kind) && 5907 !isOpenMPTaskingDirective(Kind)) { 5908 // Visit subcaptures to generate implicit clauses for captured vars. 5909 auto *CS = cast<CapturedStmt>(AStmt); 5910 SmallVector<OpenMPDirectiveKind, 4> CaptureRegions; 5911 getOpenMPCaptureRegions(CaptureRegions, Kind); 5912 // Ignore outer tasking regions for target directives. 5913 if (CaptureRegions.size() > 1 && CaptureRegions.front() == OMPD_task) 5914 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 5915 DSAChecker.visitSubCaptures(CS); 5916 } 5917 if (DSAChecker.isErrorFound()) 5918 return StmtError(); 5919 // Generate list of implicitly defined firstprivate variables. 5920 VarsWithInheritedDSA = DSAChecker.getVarsWithInheritedDSA(); 5921 5922 SmallVector<Expr *, 4> ImplicitFirstprivates( 5923 DSAChecker.getImplicitFirstprivate().begin(), 5924 DSAChecker.getImplicitFirstprivate().end()); 5925 SmallVector<Expr *, 4> ImplicitPrivates( 5926 DSAChecker.getImplicitPrivate().begin(), 5927 DSAChecker.getImplicitPrivate().end()); 5928 const unsigned DefaultmapKindNum = OMPC_DEFAULTMAP_pointer + 1; 5929 SmallVector<Expr *, 4> ImplicitMaps[DefaultmapKindNum][OMPC_MAP_delete]; 5930 SmallVector<OpenMPMapModifierKind, NumberOfOMPMapClauseModifiers> 5931 ImplicitMapModifiers[DefaultmapKindNum]; 5932 SmallVector<SourceLocation, NumberOfOMPMapClauseModifiers> 5933 ImplicitMapModifiersLoc[DefaultmapKindNum]; 5934 // Get the original location of present modifier from Defaultmap clause. 5935 SourceLocation PresentModifierLocs[DefaultmapKindNum]; 5936 for (OMPClause *C : Clauses) { 5937 if (auto *DMC = dyn_cast<OMPDefaultmapClause>(C)) 5938 if (DMC->getDefaultmapModifier() == OMPC_DEFAULTMAP_MODIFIER_present) 5939 PresentModifierLocs[DMC->getDefaultmapKind()] = 5940 DMC->getDefaultmapModifierLoc(); 5941 } 5942 for (unsigned VC = 0; VC < DefaultmapKindNum; ++VC) { 5943 auto Kind = static_cast<OpenMPDefaultmapClauseKind>(VC); 5944 for (unsigned I = 0; I < OMPC_MAP_delete; ++I) { 5945 ArrayRef<Expr *> ImplicitMap = DSAChecker.getImplicitMap( 5946 Kind, static_cast<OpenMPMapClauseKind>(I)); 5947 ImplicitMaps[VC][I].append(ImplicitMap.begin(), ImplicitMap.end()); 5948 } 5949 ArrayRef<OpenMPMapModifierKind> ImplicitModifier = 5950 DSAChecker.getImplicitMapModifier(Kind); 5951 ImplicitMapModifiers[VC].append(ImplicitModifier.begin(), 5952 ImplicitModifier.end()); 5953 std::fill_n(std::back_inserter(ImplicitMapModifiersLoc[VC]), 5954 ImplicitModifier.size(), PresentModifierLocs[VC]); 5955 } 5956 // Mark taskgroup task_reduction descriptors as implicitly firstprivate. 5957 for (OMPClause *C : Clauses) { 5958 if (auto *IRC = dyn_cast<OMPInReductionClause>(C)) { 5959 for (Expr *E : IRC->taskgroup_descriptors()) 5960 if (E) 5961 ImplicitFirstprivates.emplace_back(E); 5962 } 5963 // OpenMP 5.0, 2.10.1 task Construct 5964 // [detach clause]... The event-handle will be considered as if it was 5965 // specified on a firstprivate clause. 5966 if (auto *DC = dyn_cast<OMPDetachClause>(C)) 5967 ImplicitFirstprivates.push_back(DC->getEventHandler()); 5968 } 5969 if (!ImplicitFirstprivates.empty()) { 5970 if (OMPClause *Implicit = ActOnOpenMPFirstprivateClause( 5971 ImplicitFirstprivates, SourceLocation(), SourceLocation(), 5972 SourceLocation())) { 5973 ClausesWithImplicit.push_back(Implicit); 5974 ErrorFound = cast<OMPFirstprivateClause>(Implicit)->varlist_size() != 5975 ImplicitFirstprivates.size(); 5976 } else { 5977 ErrorFound = true; 5978 } 5979 } 5980 if (!ImplicitPrivates.empty()) { 5981 if (OMPClause *Implicit = 5982 ActOnOpenMPPrivateClause(ImplicitPrivates, SourceLocation(), 5983 SourceLocation(), SourceLocation())) { 5984 ClausesWithImplicit.push_back(Implicit); 5985 ErrorFound = cast<OMPPrivateClause>(Implicit)->varlist_size() != 5986 ImplicitPrivates.size(); 5987 } else { 5988 ErrorFound = true; 5989 } 5990 } 5991 // OpenMP 5.0 [2.19.7] 5992 // If a list item appears in a reduction, lastprivate or linear 5993 // clause on a combined target construct then it is treated as 5994 // if it also appears in a map clause with a map-type of tofrom 5995 if (getLangOpts().OpenMP >= 50 && Kind != OMPD_target && 5996 isOpenMPTargetExecutionDirective(Kind)) { 5997 SmallVector<Expr *, 4> ImplicitExprs; 5998 for (OMPClause *C : Clauses) { 5999 if (auto *RC = dyn_cast<OMPReductionClause>(C)) 6000 for (Expr *E : RC->varlists()) 6001 if (!isa<DeclRefExpr>(E->IgnoreParenImpCasts())) 6002 ImplicitExprs.emplace_back(E); 6003 } 6004 if (!ImplicitExprs.empty()) { 6005 ArrayRef<Expr *> Exprs = ImplicitExprs; 6006 CXXScopeSpec MapperIdScopeSpec; 6007 DeclarationNameInfo MapperId; 6008 if (OMPClause *Implicit = ActOnOpenMPMapClause( 6009 OMPC_MAP_MODIFIER_unknown, SourceLocation(), MapperIdScopeSpec, 6010 MapperId, OMPC_MAP_tofrom, 6011 /*IsMapTypeImplicit=*/true, SourceLocation(), SourceLocation(), 6012 Exprs, OMPVarListLocTy(), /*NoDiagnose=*/true)) 6013 ClausesWithImplicit.emplace_back(Implicit); 6014 } 6015 } 6016 for (unsigned I = 0, E = DefaultmapKindNum; I < E; ++I) { 6017 int ClauseKindCnt = -1; 6018 for (ArrayRef<Expr *> ImplicitMap : ImplicitMaps[I]) { 6019 ++ClauseKindCnt; 6020 if (ImplicitMap.empty()) 6021 continue; 6022 CXXScopeSpec MapperIdScopeSpec; 6023 DeclarationNameInfo MapperId; 6024 auto Kind = static_cast<OpenMPMapClauseKind>(ClauseKindCnt); 6025 if (OMPClause *Implicit = ActOnOpenMPMapClause( 6026 ImplicitMapModifiers[I], ImplicitMapModifiersLoc[I], 6027 MapperIdScopeSpec, MapperId, Kind, /*IsMapTypeImplicit=*/true, 6028 SourceLocation(), SourceLocation(), ImplicitMap, 6029 OMPVarListLocTy())) { 6030 ClausesWithImplicit.emplace_back(Implicit); 6031 ErrorFound |= cast<OMPMapClause>(Implicit)->varlist_size() != 6032 ImplicitMap.size(); 6033 } else { 6034 ErrorFound = true; 6035 } 6036 } 6037 } 6038 // Build expressions for implicit maps of data members with 'default' 6039 // mappers. 6040 if (LangOpts.OpenMP >= 50) 6041 processImplicitMapsWithDefaultMappers(*this, DSAStack, 6042 ClausesWithImplicit); 6043 } 6044 6045 llvm::SmallVector<OpenMPDirectiveKind, 4> AllowedNameModifiers; 6046 switch (Kind) { 6047 case OMPD_parallel: 6048 Res = ActOnOpenMPParallelDirective(ClausesWithImplicit, AStmt, StartLoc, 6049 EndLoc); 6050 AllowedNameModifiers.push_back(OMPD_parallel); 6051 break; 6052 case OMPD_simd: 6053 Res = ActOnOpenMPSimdDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc, 6054 VarsWithInheritedDSA); 6055 if (LangOpts.OpenMP >= 50) 6056 AllowedNameModifiers.push_back(OMPD_simd); 6057 break; 6058 case OMPD_tile: 6059 Res = 6060 ActOnOpenMPTileDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc); 6061 break; 6062 case OMPD_unroll: 6063 Res = ActOnOpenMPUnrollDirective(ClausesWithImplicit, AStmt, StartLoc, 6064 EndLoc); 6065 break; 6066 case OMPD_for: 6067 Res = ActOnOpenMPForDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc, 6068 VarsWithInheritedDSA); 6069 break; 6070 case OMPD_for_simd: 6071 Res = ActOnOpenMPForSimdDirective(ClausesWithImplicit, AStmt, StartLoc, 6072 EndLoc, VarsWithInheritedDSA); 6073 if (LangOpts.OpenMP >= 50) 6074 AllowedNameModifiers.push_back(OMPD_simd); 6075 break; 6076 case OMPD_sections: 6077 Res = ActOnOpenMPSectionsDirective(ClausesWithImplicit, AStmt, StartLoc, 6078 EndLoc); 6079 break; 6080 case OMPD_section: 6081 assert(ClausesWithImplicit.empty() && 6082 "No clauses are allowed for 'omp section' directive"); 6083 Res = ActOnOpenMPSectionDirective(AStmt, StartLoc, EndLoc); 6084 break; 6085 case OMPD_single: 6086 Res = ActOnOpenMPSingleDirective(ClausesWithImplicit, AStmt, StartLoc, 6087 EndLoc); 6088 break; 6089 case OMPD_master: 6090 assert(ClausesWithImplicit.empty() && 6091 "No clauses are allowed for 'omp master' directive"); 6092 Res = ActOnOpenMPMasterDirective(AStmt, StartLoc, EndLoc); 6093 break; 6094 case OMPD_masked: 6095 Res = ActOnOpenMPMaskedDirective(ClausesWithImplicit, AStmt, StartLoc, 6096 EndLoc); 6097 break; 6098 case OMPD_critical: 6099 Res = ActOnOpenMPCriticalDirective(DirName, ClausesWithImplicit, AStmt, 6100 StartLoc, EndLoc); 6101 break; 6102 case OMPD_parallel_for: 6103 Res = ActOnOpenMPParallelForDirective(ClausesWithImplicit, AStmt, StartLoc, 6104 EndLoc, VarsWithInheritedDSA); 6105 AllowedNameModifiers.push_back(OMPD_parallel); 6106 break; 6107 case OMPD_parallel_for_simd: 6108 Res = ActOnOpenMPParallelForSimdDirective( 6109 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 6110 AllowedNameModifiers.push_back(OMPD_parallel); 6111 if (LangOpts.OpenMP >= 50) 6112 AllowedNameModifiers.push_back(OMPD_simd); 6113 break; 6114 case OMPD_parallel_master: 6115 Res = ActOnOpenMPParallelMasterDirective(ClausesWithImplicit, AStmt, 6116 StartLoc, EndLoc); 6117 AllowedNameModifiers.push_back(OMPD_parallel); 6118 break; 6119 case OMPD_parallel_sections: 6120 Res = ActOnOpenMPParallelSectionsDirective(ClausesWithImplicit, AStmt, 6121 StartLoc, EndLoc); 6122 AllowedNameModifiers.push_back(OMPD_parallel); 6123 break; 6124 case OMPD_task: 6125 Res = 6126 ActOnOpenMPTaskDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc); 6127 AllowedNameModifiers.push_back(OMPD_task); 6128 break; 6129 case OMPD_taskyield: 6130 assert(ClausesWithImplicit.empty() && 6131 "No clauses are allowed for 'omp taskyield' directive"); 6132 assert(AStmt == nullptr && 6133 "No associated statement allowed for 'omp taskyield' directive"); 6134 Res = ActOnOpenMPTaskyieldDirective(StartLoc, EndLoc); 6135 break; 6136 case OMPD_barrier: 6137 assert(ClausesWithImplicit.empty() && 6138 "No clauses are allowed for 'omp barrier' directive"); 6139 assert(AStmt == nullptr && 6140 "No associated statement allowed for 'omp barrier' directive"); 6141 Res = ActOnOpenMPBarrierDirective(StartLoc, EndLoc); 6142 break; 6143 case OMPD_taskwait: 6144 assert(AStmt == nullptr && 6145 "No associated statement allowed for 'omp taskwait' directive"); 6146 Res = ActOnOpenMPTaskwaitDirective(ClausesWithImplicit, StartLoc, EndLoc); 6147 break; 6148 case OMPD_taskgroup: 6149 Res = ActOnOpenMPTaskgroupDirective(ClausesWithImplicit, AStmt, StartLoc, 6150 EndLoc); 6151 break; 6152 case OMPD_flush: 6153 assert(AStmt == nullptr && 6154 "No associated statement allowed for 'omp flush' directive"); 6155 Res = ActOnOpenMPFlushDirective(ClausesWithImplicit, StartLoc, EndLoc); 6156 break; 6157 case OMPD_depobj: 6158 assert(AStmt == nullptr && 6159 "No associated statement allowed for 'omp depobj' directive"); 6160 Res = ActOnOpenMPDepobjDirective(ClausesWithImplicit, StartLoc, EndLoc); 6161 break; 6162 case OMPD_scan: 6163 assert(AStmt == nullptr && 6164 "No associated statement allowed for 'omp scan' directive"); 6165 Res = ActOnOpenMPScanDirective(ClausesWithImplicit, StartLoc, EndLoc); 6166 break; 6167 case OMPD_ordered: 6168 Res = ActOnOpenMPOrderedDirective(ClausesWithImplicit, AStmt, StartLoc, 6169 EndLoc); 6170 break; 6171 case OMPD_atomic: 6172 Res = ActOnOpenMPAtomicDirective(ClausesWithImplicit, AStmt, StartLoc, 6173 EndLoc); 6174 break; 6175 case OMPD_teams: 6176 Res = 6177 ActOnOpenMPTeamsDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc); 6178 break; 6179 case OMPD_target: 6180 Res = ActOnOpenMPTargetDirective(ClausesWithImplicit, AStmt, StartLoc, 6181 EndLoc); 6182 AllowedNameModifiers.push_back(OMPD_target); 6183 break; 6184 case OMPD_target_parallel: 6185 Res = ActOnOpenMPTargetParallelDirective(ClausesWithImplicit, AStmt, 6186 StartLoc, EndLoc); 6187 AllowedNameModifiers.push_back(OMPD_target); 6188 AllowedNameModifiers.push_back(OMPD_parallel); 6189 break; 6190 case OMPD_target_parallel_for: 6191 Res = ActOnOpenMPTargetParallelForDirective( 6192 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 6193 AllowedNameModifiers.push_back(OMPD_target); 6194 AllowedNameModifiers.push_back(OMPD_parallel); 6195 break; 6196 case OMPD_cancellation_point: 6197 assert(ClausesWithImplicit.empty() && 6198 "No clauses are allowed for 'omp cancellation point' directive"); 6199 assert(AStmt == nullptr && "No associated statement allowed for 'omp " 6200 "cancellation point' directive"); 6201 Res = ActOnOpenMPCancellationPointDirective(StartLoc, EndLoc, CancelRegion); 6202 break; 6203 case OMPD_cancel: 6204 assert(AStmt == nullptr && 6205 "No associated statement allowed for 'omp cancel' directive"); 6206 Res = ActOnOpenMPCancelDirective(ClausesWithImplicit, StartLoc, EndLoc, 6207 CancelRegion); 6208 AllowedNameModifiers.push_back(OMPD_cancel); 6209 break; 6210 case OMPD_target_data: 6211 Res = ActOnOpenMPTargetDataDirective(ClausesWithImplicit, AStmt, StartLoc, 6212 EndLoc); 6213 AllowedNameModifiers.push_back(OMPD_target_data); 6214 break; 6215 case OMPD_target_enter_data: 6216 Res = ActOnOpenMPTargetEnterDataDirective(ClausesWithImplicit, StartLoc, 6217 EndLoc, AStmt); 6218 AllowedNameModifiers.push_back(OMPD_target_enter_data); 6219 break; 6220 case OMPD_target_exit_data: 6221 Res = ActOnOpenMPTargetExitDataDirective(ClausesWithImplicit, StartLoc, 6222 EndLoc, AStmt); 6223 AllowedNameModifiers.push_back(OMPD_target_exit_data); 6224 break; 6225 case OMPD_taskloop: 6226 Res = ActOnOpenMPTaskLoopDirective(ClausesWithImplicit, AStmt, StartLoc, 6227 EndLoc, VarsWithInheritedDSA); 6228 AllowedNameModifiers.push_back(OMPD_taskloop); 6229 break; 6230 case OMPD_taskloop_simd: 6231 Res = ActOnOpenMPTaskLoopSimdDirective(ClausesWithImplicit, AStmt, StartLoc, 6232 EndLoc, VarsWithInheritedDSA); 6233 AllowedNameModifiers.push_back(OMPD_taskloop); 6234 if (LangOpts.OpenMP >= 50) 6235 AllowedNameModifiers.push_back(OMPD_simd); 6236 break; 6237 case OMPD_master_taskloop: 6238 Res = ActOnOpenMPMasterTaskLoopDirective( 6239 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 6240 AllowedNameModifiers.push_back(OMPD_taskloop); 6241 break; 6242 case OMPD_master_taskloop_simd: 6243 Res = ActOnOpenMPMasterTaskLoopSimdDirective( 6244 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 6245 AllowedNameModifiers.push_back(OMPD_taskloop); 6246 if (LangOpts.OpenMP >= 50) 6247 AllowedNameModifiers.push_back(OMPD_simd); 6248 break; 6249 case OMPD_parallel_master_taskloop: 6250 Res = ActOnOpenMPParallelMasterTaskLoopDirective( 6251 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 6252 AllowedNameModifiers.push_back(OMPD_taskloop); 6253 AllowedNameModifiers.push_back(OMPD_parallel); 6254 break; 6255 case OMPD_parallel_master_taskloop_simd: 6256 Res = ActOnOpenMPParallelMasterTaskLoopSimdDirective( 6257 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 6258 AllowedNameModifiers.push_back(OMPD_taskloop); 6259 AllowedNameModifiers.push_back(OMPD_parallel); 6260 if (LangOpts.OpenMP >= 50) 6261 AllowedNameModifiers.push_back(OMPD_simd); 6262 break; 6263 case OMPD_distribute: 6264 Res = ActOnOpenMPDistributeDirective(ClausesWithImplicit, AStmt, StartLoc, 6265 EndLoc, VarsWithInheritedDSA); 6266 break; 6267 case OMPD_target_update: 6268 Res = ActOnOpenMPTargetUpdateDirective(ClausesWithImplicit, StartLoc, 6269 EndLoc, AStmt); 6270 AllowedNameModifiers.push_back(OMPD_target_update); 6271 break; 6272 case OMPD_distribute_parallel_for: 6273 Res = ActOnOpenMPDistributeParallelForDirective( 6274 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 6275 AllowedNameModifiers.push_back(OMPD_parallel); 6276 break; 6277 case OMPD_distribute_parallel_for_simd: 6278 Res = ActOnOpenMPDistributeParallelForSimdDirective( 6279 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 6280 AllowedNameModifiers.push_back(OMPD_parallel); 6281 if (LangOpts.OpenMP >= 50) 6282 AllowedNameModifiers.push_back(OMPD_simd); 6283 break; 6284 case OMPD_distribute_simd: 6285 Res = ActOnOpenMPDistributeSimdDirective( 6286 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 6287 if (LangOpts.OpenMP >= 50) 6288 AllowedNameModifiers.push_back(OMPD_simd); 6289 break; 6290 case OMPD_target_parallel_for_simd: 6291 Res = ActOnOpenMPTargetParallelForSimdDirective( 6292 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 6293 AllowedNameModifiers.push_back(OMPD_target); 6294 AllowedNameModifiers.push_back(OMPD_parallel); 6295 if (LangOpts.OpenMP >= 50) 6296 AllowedNameModifiers.push_back(OMPD_simd); 6297 break; 6298 case OMPD_target_simd: 6299 Res = ActOnOpenMPTargetSimdDirective(ClausesWithImplicit, AStmt, StartLoc, 6300 EndLoc, VarsWithInheritedDSA); 6301 AllowedNameModifiers.push_back(OMPD_target); 6302 if (LangOpts.OpenMP >= 50) 6303 AllowedNameModifiers.push_back(OMPD_simd); 6304 break; 6305 case OMPD_teams_distribute: 6306 Res = ActOnOpenMPTeamsDistributeDirective( 6307 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 6308 break; 6309 case OMPD_teams_distribute_simd: 6310 Res = ActOnOpenMPTeamsDistributeSimdDirective( 6311 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 6312 if (LangOpts.OpenMP >= 50) 6313 AllowedNameModifiers.push_back(OMPD_simd); 6314 break; 6315 case OMPD_teams_distribute_parallel_for_simd: 6316 Res = ActOnOpenMPTeamsDistributeParallelForSimdDirective( 6317 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 6318 AllowedNameModifiers.push_back(OMPD_parallel); 6319 if (LangOpts.OpenMP >= 50) 6320 AllowedNameModifiers.push_back(OMPD_simd); 6321 break; 6322 case OMPD_teams_distribute_parallel_for: 6323 Res = ActOnOpenMPTeamsDistributeParallelForDirective( 6324 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 6325 AllowedNameModifiers.push_back(OMPD_parallel); 6326 break; 6327 case OMPD_target_teams: 6328 Res = ActOnOpenMPTargetTeamsDirective(ClausesWithImplicit, AStmt, StartLoc, 6329 EndLoc); 6330 AllowedNameModifiers.push_back(OMPD_target); 6331 break; 6332 case OMPD_target_teams_distribute: 6333 Res = ActOnOpenMPTargetTeamsDistributeDirective( 6334 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 6335 AllowedNameModifiers.push_back(OMPD_target); 6336 break; 6337 case OMPD_target_teams_distribute_parallel_for: 6338 Res = ActOnOpenMPTargetTeamsDistributeParallelForDirective( 6339 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 6340 AllowedNameModifiers.push_back(OMPD_target); 6341 AllowedNameModifiers.push_back(OMPD_parallel); 6342 break; 6343 case OMPD_target_teams_distribute_parallel_for_simd: 6344 Res = ActOnOpenMPTargetTeamsDistributeParallelForSimdDirective( 6345 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 6346 AllowedNameModifiers.push_back(OMPD_target); 6347 AllowedNameModifiers.push_back(OMPD_parallel); 6348 if (LangOpts.OpenMP >= 50) 6349 AllowedNameModifiers.push_back(OMPD_simd); 6350 break; 6351 case OMPD_target_teams_distribute_simd: 6352 Res = ActOnOpenMPTargetTeamsDistributeSimdDirective( 6353 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 6354 AllowedNameModifiers.push_back(OMPD_target); 6355 if (LangOpts.OpenMP >= 50) 6356 AllowedNameModifiers.push_back(OMPD_simd); 6357 break; 6358 case OMPD_interop: 6359 assert(AStmt == nullptr && 6360 "No associated statement allowed for 'omp interop' directive"); 6361 Res = ActOnOpenMPInteropDirective(ClausesWithImplicit, StartLoc, EndLoc); 6362 break; 6363 case OMPD_dispatch: 6364 Res = ActOnOpenMPDispatchDirective(ClausesWithImplicit, AStmt, StartLoc, 6365 EndLoc); 6366 break; 6367 case OMPD_loop: 6368 Res = ActOnOpenMPGenericLoopDirective(ClausesWithImplicit, AStmt, StartLoc, 6369 EndLoc, VarsWithInheritedDSA); 6370 break; 6371 case OMPD_teams_loop: 6372 Res = ActOnOpenMPTeamsGenericLoopDirective( 6373 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 6374 break; 6375 case OMPD_target_teams_loop: 6376 Res = ActOnOpenMPTargetTeamsGenericLoopDirective( 6377 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 6378 break; 6379 case OMPD_parallel_loop: 6380 Res = ActOnOpenMPParallelGenericLoopDirective( 6381 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 6382 break; 6383 case OMPD_target_parallel_loop: 6384 Res = ActOnOpenMPTargetParallelGenericLoopDirective( 6385 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 6386 break; 6387 case OMPD_declare_target: 6388 case OMPD_end_declare_target: 6389 case OMPD_threadprivate: 6390 case OMPD_allocate: 6391 case OMPD_declare_reduction: 6392 case OMPD_declare_mapper: 6393 case OMPD_declare_simd: 6394 case OMPD_requires: 6395 case OMPD_declare_variant: 6396 case OMPD_begin_declare_variant: 6397 case OMPD_end_declare_variant: 6398 llvm_unreachable("OpenMP Directive is not allowed"); 6399 case OMPD_unknown: 6400 default: 6401 llvm_unreachable("Unknown OpenMP directive"); 6402 } 6403 6404 ErrorFound = Res.isInvalid() || ErrorFound; 6405 6406 // Check variables in the clauses if default(none) or 6407 // default(firstprivate) was specified. 6408 if (DSAStack->getDefaultDSA() == DSA_none || 6409 DSAStack->getDefaultDSA() == DSA_private || 6410 DSAStack->getDefaultDSA() == DSA_firstprivate) { 6411 DSAAttrChecker DSAChecker(DSAStack, *this, nullptr); 6412 for (OMPClause *C : Clauses) { 6413 switch (C->getClauseKind()) { 6414 case OMPC_num_threads: 6415 case OMPC_dist_schedule: 6416 // Do not analyse if no parent teams directive. 6417 if (isOpenMPTeamsDirective(Kind)) 6418 break; 6419 continue; 6420 case OMPC_if: 6421 if (isOpenMPTeamsDirective(Kind) && 6422 cast<OMPIfClause>(C)->getNameModifier() != OMPD_target) 6423 break; 6424 if (isOpenMPParallelDirective(Kind) && 6425 isOpenMPTaskLoopDirective(Kind) && 6426 cast<OMPIfClause>(C)->getNameModifier() != OMPD_parallel) 6427 break; 6428 continue; 6429 case OMPC_schedule: 6430 case OMPC_detach: 6431 break; 6432 case OMPC_grainsize: 6433 case OMPC_num_tasks: 6434 case OMPC_final: 6435 case OMPC_priority: 6436 case OMPC_novariants: 6437 case OMPC_nocontext: 6438 // Do not analyze if no parent parallel directive. 6439 if (isOpenMPParallelDirective(Kind)) 6440 break; 6441 continue; 6442 case OMPC_ordered: 6443 case OMPC_device: 6444 case OMPC_num_teams: 6445 case OMPC_thread_limit: 6446 case OMPC_hint: 6447 case OMPC_collapse: 6448 case OMPC_safelen: 6449 case OMPC_simdlen: 6450 case OMPC_sizes: 6451 case OMPC_default: 6452 case OMPC_proc_bind: 6453 case OMPC_private: 6454 case OMPC_firstprivate: 6455 case OMPC_lastprivate: 6456 case OMPC_shared: 6457 case OMPC_reduction: 6458 case OMPC_task_reduction: 6459 case OMPC_in_reduction: 6460 case OMPC_linear: 6461 case OMPC_aligned: 6462 case OMPC_copyin: 6463 case OMPC_copyprivate: 6464 case OMPC_nowait: 6465 case OMPC_untied: 6466 case OMPC_mergeable: 6467 case OMPC_allocate: 6468 case OMPC_read: 6469 case OMPC_write: 6470 case OMPC_update: 6471 case OMPC_capture: 6472 case OMPC_compare: 6473 case OMPC_seq_cst: 6474 case OMPC_acq_rel: 6475 case OMPC_acquire: 6476 case OMPC_release: 6477 case OMPC_relaxed: 6478 case OMPC_depend: 6479 case OMPC_threads: 6480 case OMPC_simd: 6481 case OMPC_map: 6482 case OMPC_nogroup: 6483 case OMPC_defaultmap: 6484 case OMPC_to: 6485 case OMPC_from: 6486 case OMPC_use_device_ptr: 6487 case OMPC_use_device_addr: 6488 case OMPC_is_device_ptr: 6489 case OMPC_has_device_addr: 6490 case OMPC_nontemporal: 6491 case OMPC_order: 6492 case OMPC_destroy: 6493 case OMPC_inclusive: 6494 case OMPC_exclusive: 6495 case OMPC_uses_allocators: 6496 case OMPC_affinity: 6497 case OMPC_bind: 6498 continue; 6499 case OMPC_allocator: 6500 case OMPC_flush: 6501 case OMPC_depobj: 6502 case OMPC_threadprivate: 6503 case OMPC_uniform: 6504 case OMPC_unknown: 6505 case OMPC_unified_address: 6506 case OMPC_unified_shared_memory: 6507 case OMPC_reverse_offload: 6508 case OMPC_dynamic_allocators: 6509 case OMPC_atomic_default_mem_order: 6510 case OMPC_device_type: 6511 case OMPC_match: 6512 case OMPC_when: 6513 default: 6514 llvm_unreachable("Unexpected clause"); 6515 } 6516 for (Stmt *CC : C->children()) { 6517 if (CC) 6518 DSAChecker.Visit(CC); 6519 } 6520 } 6521 for (const auto &P : DSAChecker.getVarsWithInheritedDSA()) 6522 VarsWithInheritedDSA[P.getFirst()] = P.getSecond(); 6523 } 6524 for (const auto &P : VarsWithInheritedDSA) { 6525 if (P.getFirst()->isImplicit() || isa<OMPCapturedExprDecl>(P.getFirst())) 6526 continue; 6527 ErrorFound = true; 6528 if (DSAStack->getDefaultDSA() == DSA_none || 6529 DSAStack->getDefaultDSA() == DSA_private || 6530 DSAStack->getDefaultDSA() == DSA_firstprivate) { 6531 Diag(P.second->getExprLoc(), diag::err_omp_no_dsa_for_variable) 6532 << P.first << P.second->getSourceRange(); 6533 Diag(DSAStack->getDefaultDSALocation(), diag::note_omp_default_dsa_none); 6534 } else if (getLangOpts().OpenMP >= 50) { 6535 Diag(P.second->getExprLoc(), 6536 diag::err_omp_defaultmap_no_attr_for_variable) 6537 << P.first << P.second->getSourceRange(); 6538 Diag(DSAStack->getDefaultDSALocation(), 6539 diag::note_omp_defaultmap_attr_none); 6540 } 6541 } 6542 6543 if (!AllowedNameModifiers.empty()) 6544 ErrorFound = checkIfClauses(*this, Kind, Clauses, AllowedNameModifiers) || 6545 ErrorFound; 6546 6547 if (ErrorFound) 6548 return StmtError(); 6549 6550 if (!CurContext->isDependentContext() && 6551 isOpenMPTargetExecutionDirective(Kind) && 6552 !(DSAStack->hasRequiresDeclWithClause<OMPUnifiedSharedMemoryClause>() || 6553 DSAStack->hasRequiresDeclWithClause<OMPUnifiedAddressClause>() || 6554 DSAStack->hasRequiresDeclWithClause<OMPReverseOffloadClause>() || 6555 DSAStack->hasRequiresDeclWithClause<OMPDynamicAllocatorsClause>())) { 6556 // Register target to DSA Stack. 6557 DSAStack->addTargetDirLocation(StartLoc); 6558 } 6559 6560 return Res; 6561 } 6562 6563 Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareSimdDirective( 6564 DeclGroupPtrTy DG, OMPDeclareSimdDeclAttr::BranchStateTy BS, Expr *Simdlen, 6565 ArrayRef<Expr *> Uniforms, ArrayRef<Expr *> Aligneds, 6566 ArrayRef<Expr *> Alignments, ArrayRef<Expr *> Linears, 6567 ArrayRef<unsigned> LinModifiers, ArrayRef<Expr *> Steps, SourceRange SR) { 6568 assert(Aligneds.size() == Alignments.size()); 6569 assert(Linears.size() == LinModifiers.size()); 6570 assert(Linears.size() == Steps.size()); 6571 if (!DG || DG.get().isNull()) 6572 return DeclGroupPtrTy(); 6573 6574 const int SimdId = 0; 6575 if (!DG.get().isSingleDecl()) { 6576 Diag(SR.getBegin(), diag::err_omp_single_decl_in_declare_simd_variant) 6577 << SimdId; 6578 return DG; 6579 } 6580 Decl *ADecl = DG.get().getSingleDecl(); 6581 if (auto *FTD = dyn_cast<FunctionTemplateDecl>(ADecl)) 6582 ADecl = FTD->getTemplatedDecl(); 6583 6584 auto *FD = dyn_cast<FunctionDecl>(ADecl); 6585 if (!FD) { 6586 Diag(ADecl->getLocation(), diag::err_omp_function_expected) << SimdId; 6587 return DeclGroupPtrTy(); 6588 } 6589 6590 // OpenMP [2.8.2, declare simd construct, Description] 6591 // The parameter of the simdlen clause must be a constant positive integer 6592 // expression. 6593 ExprResult SL; 6594 if (Simdlen) 6595 SL = VerifyPositiveIntegerConstantInClause(Simdlen, OMPC_simdlen); 6596 // OpenMP [2.8.2, declare simd construct, Description] 6597 // The special this pointer can be used as if was one of the arguments to the 6598 // function in any of the linear, aligned, or uniform clauses. 6599 // The uniform clause declares one or more arguments to have an invariant 6600 // value for all concurrent invocations of the function in the execution of a 6601 // single SIMD loop. 6602 llvm::DenseMap<const Decl *, const Expr *> UniformedArgs; 6603 const Expr *UniformedLinearThis = nullptr; 6604 for (const Expr *E : Uniforms) { 6605 E = E->IgnoreParenImpCasts(); 6606 if (const auto *DRE = dyn_cast<DeclRefExpr>(E)) 6607 if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) 6608 if (FD->getNumParams() > PVD->getFunctionScopeIndex() && 6609 FD->getParamDecl(PVD->getFunctionScopeIndex()) 6610 ->getCanonicalDecl() == PVD->getCanonicalDecl()) { 6611 UniformedArgs.try_emplace(PVD->getCanonicalDecl(), E); 6612 continue; 6613 } 6614 if (isa<CXXThisExpr>(E)) { 6615 UniformedLinearThis = E; 6616 continue; 6617 } 6618 Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause) 6619 << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0); 6620 } 6621 // OpenMP [2.8.2, declare simd construct, Description] 6622 // The aligned clause declares that the object to which each list item points 6623 // is aligned to the number of bytes expressed in the optional parameter of 6624 // the aligned clause. 6625 // The special this pointer can be used as if was one of the arguments to the 6626 // function in any of the linear, aligned, or uniform clauses. 6627 // The type of list items appearing in the aligned clause must be array, 6628 // pointer, reference to array, or reference to pointer. 6629 llvm::DenseMap<const Decl *, const Expr *> AlignedArgs; 6630 const Expr *AlignedThis = nullptr; 6631 for (const Expr *E : Aligneds) { 6632 E = E->IgnoreParenImpCasts(); 6633 if (const auto *DRE = dyn_cast<DeclRefExpr>(E)) 6634 if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) { 6635 const VarDecl *CanonPVD = PVD->getCanonicalDecl(); 6636 if (FD->getNumParams() > PVD->getFunctionScopeIndex() && 6637 FD->getParamDecl(PVD->getFunctionScopeIndex()) 6638 ->getCanonicalDecl() == CanonPVD) { 6639 // OpenMP [2.8.1, simd construct, Restrictions] 6640 // A list-item cannot appear in more than one aligned clause. 6641 if (AlignedArgs.count(CanonPVD) > 0) { 6642 Diag(E->getExprLoc(), diag::err_omp_used_in_clause_twice) 6643 << 1 << getOpenMPClauseName(OMPC_aligned) 6644 << E->getSourceRange(); 6645 Diag(AlignedArgs[CanonPVD]->getExprLoc(), 6646 diag::note_omp_explicit_dsa) 6647 << getOpenMPClauseName(OMPC_aligned); 6648 continue; 6649 } 6650 AlignedArgs[CanonPVD] = E; 6651 QualType QTy = PVD->getType() 6652 .getNonReferenceType() 6653 .getUnqualifiedType() 6654 .getCanonicalType(); 6655 const Type *Ty = QTy.getTypePtrOrNull(); 6656 if (!Ty || (!Ty->isArrayType() && !Ty->isPointerType())) { 6657 Diag(E->getExprLoc(), diag::err_omp_aligned_expected_array_or_ptr) 6658 << QTy << getLangOpts().CPlusPlus << E->getSourceRange(); 6659 Diag(PVD->getLocation(), diag::note_previous_decl) << PVD; 6660 } 6661 continue; 6662 } 6663 } 6664 if (isa<CXXThisExpr>(E)) { 6665 if (AlignedThis) { 6666 Diag(E->getExprLoc(), diag::err_omp_used_in_clause_twice) 6667 << 2 << getOpenMPClauseName(OMPC_aligned) << E->getSourceRange(); 6668 Diag(AlignedThis->getExprLoc(), diag::note_omp_explicit_dsa) 6669 << getOpenMPClauseName(OMPC_aligned); 6670 } 6671 AlignedThis = E; 6672 continue; 6673 } 6674 Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause) 6675 << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0); 6676 } 6677 // The optional parameter of the aligned clause, alignment, must be a constant 6678 // positive integer expression. If no optional parameter is specified, 6679 // implementation-defined default alignments for SIMD instructions on the 6680 // target platforms are assumed. 6681 SmallVector<const Expr *, 4> NewAligns; 6682 for (Expr *E : Alignments) { 6683 ExprResult Align; 6684 if (E) 6685 Align = VerifyPositiveIntegerConstantInClause(E, OMPC_aligned); 6686 NewAligns.push_back(Align.get()); 6687 } 6688 // OpenMP [2.8.2, declare simd construct, Description] 6689 // The linear clause declares one or more list items to be private to a SIMD 6690 // lane and to have a linear relationship with respect to the iteration space 6691 // of a loop. 6692 // The special this pointer can be used as if was one of the arguments to the 6693 // function in any of the linear, aligned, or uniform clauses. 6694 // When a linear-step expression is specified in a linear clause it must be 6695 // either a constant integer expression or an integer-typed parameter that is 6696 // specified in a uniform clause on the directive. 6697 llvm::DenseMap<const Decl *, const Expr *> LinearArgs; 6698 const bool IsUniformedThis = UniformedLinearThis != nullptr; 6699 auto MI = LinModifiers.begin(); 6700 for (const Expr *E : Linears) { 6701 auto LinKind = static_cast<OpenMPLinearClauseKind>(*MI); 6702 ++MI; 6703 E = E->IgnoreParenImpCasts(); 6704 if (const auto *DRE = dyn_cast<DeclRefExpr>(E)) 6705 if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) { 6706 const VarDecl *CanonPVD = PVD->getCanonicalDecl(); 6707 if (FD->getNumParams() > PVD->getFunctionScopeIndex() && 6708 FD->getParamDecl(PVD->getFunctionScopeIndex()) 6709 ->getCanonicalDecl() == CanonPVD) { 6710 // OpenMP [2.15.3.7, linear Clause, Restrictions] 6711 // A list-item cannot appear in more than one linear clause. 6712 if (LinearArgs.count(CanonPVD) > 0) { 6713 Diag(E->getExprLoc(), diag::err_omp_wrong_dsa) 6714 << getOpenMPClauseName(OMPC_linear) 6715 << getOpenMPClauseName(OMPC_linear) << E->getSourceRange(); 6716 Diag(LinearArgs[CanonPVD]->getExprLoc(), 6717 diag::note_omp_explicit_dsa) 6718 << getOpenMPClauseName(OMPC_linear); 6719 continue; 6720 } 6721 // Each argument can appear in at most one uniform or linear clause. 6722 if (UniformedArgs.count(CanonPVD) > 0) { 6723 Diag(E->getExprLoc(), diag::err_omp_wrong_dsa) 6724 << getOpenMPClauseName(OMPC_linear) 6725 << getOpenMPClauseName(OMPC_uniform) << E->getSourceRange(); 6726 Diag(UniformedArgs[CanonPVD]->getExprLoc(), 6727 diag::note_omp_explicit_dsa) 6728 << getOpenMPClauseName(OMPC_uniform); 6729 continue; 6730 } 6731 LinearArgs[CanonPVD] = E; 6732 if (E->isValueDependent() || E->isTypeDependent() || 6733 E->isInstantiationDependent() || 6734 E->containsUnexpandedParameterPack()) 6735 continue; 6736 (void)CheckOpenMPLinearDecl(CanonPVD, E->getExprLoc(), LinKind, 6737 PVD->getOriginalType(), 6738 /*IsDeclareSimd=*/true); 6739 continue; 6740 } 6741 } 6742 if (isa<CXXThisExpr>(E)) { 6743 if (UniformedLinearThis) { 6744 Diag(E->getExprLoc(), diag::err_omp_wrong_dsa) 6745 << getOpenMPClauseName(OMPC_linear) 6746 << getOpenMPClauseName(IsUniformedThis ? OMPC_uniform : OMPC_linear) 6747 << E->getSourceRange(); 6748 Diag(UniformedLinearThis->getExprLoc(), diag::note_omp_explicit_dsa) 6749 << getOpenMPClauseName(IsUniformedThis ? OMPC_uniform 6750 : OMPC_linear); 6751 continue; 6752 } 6753 UniformedLinearThis = E; 6754 if (E->isValueDependent() || E->isTypeDependent() || 6755 E->isInstantiationDependent() || E->containsUnexpandedParameterPack()) 6756 continue; 6757 (void)CheckOpenMPLinearDecl(/*D=*/nullptr, E->getExprLoc(), LinKind, 6758 E->getType(), /*IsDeclareSimd=*/true); 6759 continue; 6760 } 6761 Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause) 6762 << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0); 6763 } 6764 Expr *Step = nullptr; 6765 Expr *NewStep = nullptr; 6766 SmallVector<Expr *, 4> NewSteps; 6767 for (Expr *E : Steps) { 6768 // Skip the same step expression, it was checked already. 6769 if (Step == E || !E) { 6770 NewSteps.push_back(E ? NewStep : nullptr); 6771 continue; 6772 } 6773 Step = E; 6774 if (const auto *DRE = dyn_cast<DeclRefExpr>(Step)) 6775 if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) { 6776 const VarDecl *CanonPVD = PVD->getCanonicalDecl(); 6777 if (UniformedArgs.count(CanonPVD) == 0) { 6778 Diag(Step->getExprLoc(), diag::err_omp_expected_uniform_param) 6779 << Step->getSourceRange(); 6780 } else if (E->isValueDependent() || E->isTypeDependent() || 6781 E->isInstantiationDependent() || 6782 E->containsUnexpandedParameterPack() || 6783 CanonPVD->getType()->hasIntegerRepresentation()) { 6784 NewSteps.push_back(Step); 6785 } else { 6786 Diag(Step->getExprLoc(), diag::err_omp_expected_int_param) 6787 << Step->getSourceRange(); 6788 } 6789 continue; 6790 } 6791 NewStep = Step; 6792 if (Step && !Step->isValueDependent() && !Step->isTypeDependent() && 6793 !Step->isInstantiationDependent() && 6794 !Step->containsUnexpandedParameterPack()) { 6795 NewStep = PerformOpenMPImplicitIntegerConversion(Step->getExprLoc(), Step) 6796 .get(); 6797 if (NewStep) 6798 NewStep = 6799 VerifyIntegerConstantExpression(NewStep, /*FIXME*/ AllowFold).get(); 6800 } 6801 NewSteps.push_back(NewStep); 6802 } 6803 auto *NewAttr = OMPDeclareSimdDeclAttr::CreateImplicit( 6804 Context, BS, SL.get(), const_cast<Expr **>(Uniforms.data()), 6805 Uniforms.size(), const_cast<Expr **>(Aligneds.data()), Aligneds.size(), 6806 const_cast<Expr **>(NewAligns.data()), NewAligns.size(), 6807 const_cast<Expr **>(Linears.data()), Linears.size(), 6808 const_cast<unsigned *>(LinModifiers.data()), LinModifiers.size(), 6809 NewSteps.data(), NewSteps.size(), SR); 6810 ADecl->addAttr(NewAttr); 6811 return DG; 6812 } 6813 6814 static void setPrototype(Sema &S, FunctionDecl *FD, FunctionDecl *FDWithProto, 6815 QualType NewType) { 6816 assert(NewType->isFunctionProtoType() && 6817 "Expected function type with prototype."); 6818 assert(FD->getType()->isFunctionNoProtoType() && 6819 "Expected function with type with no prototype."); 6820 assert(FDWithProto->getType()->isFunctionProtoType() && 6821 "Expected function with prototype."); 6822 // Synthesize parameters with the same types. 6823 FD->setType(NewType); 6824 SmallVector<ParmVarDecl *, 16> Params; 6825 for (const ParmVarDecl *P : FDWithProto->parameters()) { 6826 auto *Param = ParmVarDecl::Create(S.getASTContext(), FD, SourceLocation(), 6827 SourceLocation(), nullptr, P->getType(), 6828 /*TInfo=*/nullptr, SC_None, nullptr); 6829 Param->setScopeInfo(0, Params.size()); 6830 Param->setImplicit(); 6831 Params.push_back(Param); 6832 } 6833 6834 FD->setParams(Params); 6835 } 6836 6837 void Sema::ActOnFinishedFunctionDefinitionInOpenMPAssumeScope(Decl *D) { 6838 if (D->isInvalidDecl()) 6839 return; 6840 FunctionDecl *FD = nullptr; 6841 if (auto *UTemplDecl = dyn_cast<FunctionTemplateDecl>(D)) 6842 FD = UTemplDecl->getTemplatedDecl(); 6843 else 6844 FD = cast<FunctionDecl>(D); 6845 assert(FD && "Expected a function declaration!"); 6846 6847 // If we are instantiating templates we do *not* apply scoped assumptions but 6848 // only global ones. We apply scoped assumption to the template definition 6849 // though. 6850 if (!inTemplateInstantiation()) { 6851 for (AssumptionAttr *AA : OMPAssumeScoped) 6852 FD->addAttr(AA); 6853 } 6854 for (AssumptionAttr *AA : OMPAssumeGlobal) 6855 FD->addAttr(AA); 6856 } 6857 6858 Sema::OMPDeclareVariantScope::OMPDeclareVariantScope(OMPTraitInfo &TI) 6859 : TI(&TI), NameSuffix(TI.getMangledName()) {} 6860 6861 void Sema::ActOnStartOfFunctionDefinitionInOpenMPDeclareVariantScope( 6862 Scope *S, Declarator &D, MultiTemplateParamsArg TemplateParamLists, 6863 SmallVectorImpl<FunctionDecl *> &Bases) { 6864 if (!D.getIdentifier()) 6865 return; 6866 6867 OMPDeclareVariantScope &DVScope = OMPDeclareVariantScopes.back(); 6868 6869 // Template specialization is an extension, check if we do it. 6870 bool IsTemplated = !TemplateParamLists.empty(); 6871 if (IsTemplated & 6872 !DVScope.TI->isExtensionActive( 6873 llvm::omp::TraitProperty::implementation_extension_allow_templates)) 6874 return; 6875 6876 IdentifierInfo *BaseII = D.getIdentifier(); 6877 LookupResult Lookup(*this, DeclarationName(BaseII), D.getIdentifierLoc(), 6878 LookupOrdinaryName); 6879 LookupParsedName(Lookup, S, &D.getCXXScopeSpec()); 6880 6881 TypeSourceInfo *TInfo = GetTypeForDeclarator(D, S); 6882 QualType FType = TInfo->getType(); 6883 6884 bool IsConstexpr = 6885 D.getDeclSpec().getConstexprSpecifier() == ConstexprSpecKind::Constexpr; 6886 bool IsConsteval = 6887 D.getDeclSpec().getConstexprSpecifier() == ConstexprSpecKind::Consteval; 6888 6889 for (auto *Candidate : Lookup) { 6890 auto *CandidateDecl = Candidate->getUnderlyingDecl(); 6891 FunctionDecl *UDecl = nullptr; 6892 if (IsTemplated && isa<FunctionTemplateDecl>(CandidateDecl)) { 6893 auto *FTD = cast<FunctionTemplateDecl>(CandidateDecl); 6894 if (FTD->getTemplateParameters()->size() == TemplateParamLists.size()) 6895 UDecl = FTD->getTemplatedDecl(); 6896 } else if (!IsTemplated) 6897 UDecl = dyn_cast<FunctionDecl>(CandidateDecl); 6898 if (!UDecl) 6899 continue; 6900 6901 // Don't specialize constexpr/consteval functions with 6902 // non-constexpr/consteval functions. 6903 if (UDecl->isConstexpr() && !IsConstexpr) 6904 continue; 6905 if (UDecl->isConsteval() && !IsConsteval) 6906 continue; 6907 6908 QualType UDeclTy = UDecl->getType(); 6909 if (!UDeclTy->isDependentType()) { 6910 QualType NewType = Context.mergeFunctionTypes( 6911 FType, UDeclTy, /* OfBlockPointer */ false, 6912 /* Unqualified */ false, /* AllowCXX */ true); 6913 if (NewType.isNull()) 6914 continue; 6915 } 6916 6917 // Found a base! 6918 Bases.push_back(UDecl); 6919 } 6920 6921 bool UseImplicitBase = !DVScope.TI->isExtensionActive( 6922 llvm::omp::TraitProperty::implementation_extension_disable_implicit_base); 6923 // If no base was found we create a declaration that we use as base. 6924 if (Bases.empty() && UseImplicitBase) { 6925 D.setFunctionDefinitionKind(FunctionDefinitionKind::Declaration); 6926 Decl *BaseD = HandleDeclarator(S, D, TemplateParamLists); 6927 BaseD->setImplicit(true); 6928 if (auto *BaseTemplD = dyn_cast<FunctionTemplateDecl>(BaseD)) 6929 Bases.push_back(BaseTemplD->getTemplatedDecl()); 6930 else 6931 Bases.push_back(cast<FunctionDecl>(BaseD)); 6932 } 6933 6934 std::string MangledName; 6935 MangledName += D.getIdentifier()->getName(); 6936 MangledName += getOpenMPVariantManglingSeparatorStr(); 6937 MangledName += DVScope.NameSuffix; 6938 IdentifierInfo &VariantII = Context.Idents.get(MangledName); 6939 6940 VariantII.setMangledOpenMPVariantName(true); 6941 D.SetIdentifier(&VariantII, D.getBeginLoc()); 6942 } 6943 6944 void Sema::ActOnFinishedFunctionDefinitionInOpenMPDeclareVariantScope( 6945 Decl *D, SmallVectorImpl<FunctionDecl *> &Bases) { 6946 // Do not mark function as is used to prevent its emission if this is the 6947 // only place where it is used. 6948 EnterExpressionEvaluationContext Unevaluated( 6949 *this, Sema::ExpressionEvaluationContext::Unevaluated); 6950 6951 FunctionDecl *FD = nullptr; 6952 if (auto *UTemplDecl = dyn_cast<FunctionTemplateDecl>(D)) 6953 FD = UTemplDecl->getTemplatedDecl(); 6954 else 6955 FD = cast<FunctionDecl>(D); 6956 auto *VariantFuncRef = DeclRefExpr::Create( 6957 Context, NestedNameSpecifierLoc(), SourceLocation(), FD, 6958 /* RefersToEnclosingVariableOrCapture */ false, 6959 /* NameLoc */ FD->getLocation(), FD->getType(), 6960 ExprValueKind::VK_PRValue); 6961 6962 OMPDeclareVariantScope &DVScope = OMPDeclareVariantScopes.back(); 6963 auto *OMPDeclareVariantA = OMPDeclareVariantAttr::CreateImplicit( 6964 Context, VariantFuncRef, DVScope.TI, 6965 /*NothingArgs=*/nullptr, /*NothingArgsSize=*/0, 6966 /*NeedDevicePtrArgs=*/nullptr, /*NeedDevicePtrArgsSize=*/0, 6967 /*AppendArgs=*/nullptr, /*AppendArgsSize=*/0); 6968 for (FunctionDecl *BaseFD : Bases) 6969 BaseFD->addAttr(OMPDeclareVariantA); 6970 } 6971 6972 ExprResult Sema::ActOnOpenMPCall(ExprResult Call, Scope *Scope, 6973 SourceLocation LParenLoc, 6974 MultiExprArg ArgExprs, 6975 SourceLocation RParenLoc, Expr *ExecConfig) { 6976 // The common case is a regular call we do not want to specialize at all. Try 6977 // to make that case fast by bailing early. 6978 CallExpr *CE = dyn_cast<CallExpr>(Call.get()); 6979 if (!CE) 6980 return Call; 6981 6982 FunctionDecl *CalleeFnDecl = CE->getDirectCallee(); 6983 if (!CalleeFnDecl) 6984 return Call; 6985 6986 if (!CalleeFnDecl->hasAttr<OMPDeclareVariantAttr>()) 6987 return Call; 6988 6989 ASTContext &Context = getASTContext(); 6990 std::function<void(StringRef)> DiagUnknownTrait = [this, 6991 CE](StringRef ISATrait) { 6992 // TODO Track the selector locations in a way that is accessible here to 6993 // improve the diagnostic location. 6994 Diag(CE->getBeginLoc(), diag::warn_unknown_declare_variant_isa_trait) 6995 << ISATrait; 6996 }; 6997 TargetOMPContext OMPCtx(Context, std::move(DiagUnknownTrait), 6998 getCurFunctionDecl(), DSAStack->getConstructTraits()); 6999 7000 QualType CalleeFnType = CalleeFnDecl->getType(); 7001 7002 SmallVector<Expr *, 4> Exprs; 7003 SmallVector<VariantMatchInfo, 4> VMIs; 7004 while (CalleeFnDecl) { 7005 for (OMPDeclareVariantAttr *A : 7006 CalleeFnDecl->specific_attrs<OMPDeclareVariantAttr>()) { 7007 Expr *VariantRef = A->getVariantFuncRef(); 7008 7009 VariantMatchInfo VMI; 7010 OMPTraitInfo &TI = A->getTraitInfo(); 7011 TI.getAsVariantMatchInfo(Context, VMI); 7012 if (!isVariantApplicableInContext(VMI, OMPCtx, 7013 /* DeviceSetOnly */ false)) 7014 continue; 7015 7016 VMIs.push_back(VMI); 7017 Exprs.push_back(VariantRef); 7018 } 7019 7020 CalleeFnDecl = CalleeFnDecl->getPreviousDecl(); 7021 } 7022 7023 ExprResult NewCall; 7024 do { 7025 int BestIdx = getBestVariantMatchForContext(VMIs, OMPCtx); 7026 if (BestIdx < 0) 7027 return Call; 7028 Expr *BestExpr = cast<DeclRefExpr>(Exprs[BestIdx]); 7029 Decl *BestDecl = cast<DeclRefExpr>(BestExpr)->getDecl(); 7030 7031 { 7032 // Try to build a (member) call expression for the current best applicable 7033 // variant expression. We allow this to fail in which case we continue 7034 // with the next best variant expression. The fail case is part of the 7035 // implementation defined behavior in the OpenMP standard when it talks 7036 // about what differences in the function prototypes: "Any differences 7037 // that the specific OpenMP context requires in the prototype of the 7038 // variant from the base function prototype are implementation defined." 7039 // This wording is there to allow the specialized variant to have a 7040 // different type than the base function. This is intended and OK but if 7041 // we cannot create a call the difference is not in the "implementation 7042 // defined range" we allow. 7043 Sema::TentativeAnalysisScope Trap(*this); 7044 7045 if (auto *SpecializedMethod = dyn_cast<CXXMethodDecl>(BestDecl)) { 7046 auto *MemberCall = dyn_cast<CXXMemberCallExpr>(CE); 7047 BestExpr = MemberExpr::CreateImplicit( 7048 Context, MemberCall->getImplicitObjectArgument(), 7049 /* IsArrow */ false, SpecializedMethod, Context.BoundMemberTy, 7050 MemberCall->getValueKind(), MemberCall->getObjectKind()); 7051 } 7052 NewCall = BuildCallExpr(Scope, BestExpr, LParenLoc, ArgExprs, RParenLoc, 7053 ExecConfig); 7054 if (NewCall.isUsable()) { 7055 if (CallExpr *NCE = dyn_cast<CallExpr>(NewCall.get())) { 7056 FunctionDecl *NewCalleeFnDecl = NCE->getDirectCallee(); 7057 QualType NewType = Context.mergeFunctionTypes( 7058 CalleeFnType, NewCalleeFnDecl->getType(), 7059 /* OfBlockPointer */ false, 7060 /* Unqualified */ false, /* AllowCXX */ true); 7061 if (!NewType.isNull()) 7062 break; 7063 // Don't use the call if the function type was not compatible. 7064 NewCall = nullptr; 7065 } 7066 } 7067 } 7068 7069 VMIs.erase(VMIs.begin() + BestIdx); 7070 Exprs.erase(Exprs.begin() + BestIdx); 7071 } while (!VMIs.empty()); 7072 7073 if (!NewCall.isUsable()) 7074 return Call; 7075 return PseudoObjectExpr::Create(Context, CE, {NewCall.get()}, 0); 7076 } 7077 7078 Optional<std::pair<FunctionDecl *, Expr *>> 7079 Sema::checkOpenMPDeclareVariantFunction(Sema::DeclGroupPtrTy DG, 7080 Expr *VariantRef, OMPTraitInfo &TI, 7081 unsigned NumAppendArgs, 7082 SourceRange SR) { 7083 if (!DG || DG.get().isNull()) 7084 return None; 7085 7086 const int VariantId = 1; 7087 // Must be applied only to single decl. 7088 if (!DG.get().isSingleDecl()) { 7089 Diag(SR.getBegin(), diag::err_omp_single_decl_in_declare_simd_variant) 7090 << VariantId << SR; 7091 return None; 7092 } 7093 Decl *ADecl = DG.get().getSingleDecl(); 7094 if (auto *FTD = dyn_cast<FunctionTemplateDecl>(ADecl)) 7095 ADecl = FTD->getTemplatedDecl(); 7096 7097 // Decl must be a function. 7098 auto *FD = dyn_cast<FunctionDecl>(ADecl); 7099 if (!FD) { 7100 Diag(ADecl->getLocation(), diag::err_omp_function_expected) 7101 << VariantId << SR; 7102 return None; 7103 } 7104 7105 auto &&HasMultiVersionAttributes = [](const FunctionDecl *FD) { 7106 // The 'target' attribute needs to be separately checked because it does 7107 // not always signify a multiversion function declaration. 7108 return FD->isMultiVersion() || FD->hasAttr<TargetAttr>(); 7109 }; 7110 // OpenMP is not compatible with multiversion function attributes. 7111 if (HasMultiVersionAttributes(FD)) { 7112 Diag(FD->getLocation(), diag::err_omp_declare_variant_incompat_attributes) 7113 << SR; 7114 return None; 7115 } 7116 7117 // Allow #pragma omp declare variant only if the function is not used. 7118 if (FD->isUsed(false)) 7119 Diag(SR.getBegin(), diag::warn_omp_declare_variant_after_used) 7120 << FD->getLocation(); 7121 7122 // Check if the function was emitted already. 7123 const FunctionDecl *Definition; 7124 if (!FD->isThisDeclarationADefinition() && FD->isDefined(Definition) && 7125 (LangOpts.EmitAllDecls || Context.DeclMustBeEmitted(Definition))) 7126 Diag(SR.getBegin(), diag::warn_omp_declare_variant_after_emitted) 7127 << FD->getLocation(); 7128 7129 // The VariantRef must point to function. 7130 if (!VariantRef) { 7131 Diag(SR.getBegin(), diag::err_omp_function_expected) << VariantId; 7132 return None; 7133 } 7134 7135 auto ShouldDelayChecks = [](Expr *&E, bool) { 7136 return E && (E->isTypeDependent() || E->isValueDependent() || 7137 E->containsUnexpandedParameterPack() || 7138 E->isInstantiationDependent()); 7139 }; 7140 // Do not check templates, wait until instantiation. 7141 if (FD->isDependentContext() || ShouldDelayChecks(VariantRef, false) || 7142 TI.anyScoreOrCondition(ShouldDelayChecks)) 7143 return std::make_pair(FD, VariantRef); 7144 7145 // Deal with non-constant score and user condition expressions. 7146 auto HandleNonConstantScoresAndConditions = [this](Expr *&E, 7147 bool IsScore) -> bool { 7148 if (!E || E->isIntegerConstantExpr(Context)) 7149 return false; 7150 7151 if (IsScore) { 7152 // We warn on non-constant scores and pretend they were not present. 7153 Diag(E->getExprLoc(), diag::warn_omp_declare_variant_score_not_constant) 7154 << E; 7155 E = nullptr; 7156 } else { 7157 // We could replace a non-constant user condition with "false" but we 7158 // will soon need to handle these anyway for the dynamic version of 7159 // OpenMP context selectors. 7160 Diag(E->getExprLoc(), 7161 diag::err_omp_declare_variant_user_condition_not_constant) 7162 << E; 7163 } 7164 return true; 7165 }; 7166 if (TI.anyScoreOrCondition(HandleNonConstantScoresAndConditions)) 7167 return None; 7168 7169 QualType AdjustedFnType = FD->getType(); 7170 if (NumAppendArgs) { 7171 const auto *PTy = AdjustedFnType->getAsAdjusted<FunctionProtoType>(); 7172 if (!PTy) { 7173 Diag(FD->getLocation(), diag::err_omp_declare_variant_prototype_required) 7174 << SR; 7175 return None; 7176 } 7177 // Adjust the function type to account for an extra omp_interop_t for each 7178 // specified in the append_args clause. 7179 const TypeDecl *TD = nullptr; 7180 LookupResult Result(*this, &Context.Idents.get("omp_interop_t"), 7181 SR.getBegin(), Sema::LookupOrdinaryName); 7182 if (LookupName(Result, getCurScope())) { 7183 NamedDecl *ND = Result.getFoundDecl(); 7184 TD = dyn_cast_or_null<TypeDecl>(ND); 7185 } 7186 if (!TD) { 7187 Diag(SR.getBegin(), diag::err_omp_interop_type_not_found) << SR; 7188 return None; 7189 } 7190 QualType InteropType = Context.getTypeDeclType(TD); 7191 if (PTy->isVariadic()) { 7192 Diag(FD->getLocation(), diag::err_omp_append_args_with_varargs) << SR; 7193 return None; 7194 } 7195 llvm::SmallVector<QualType, 8> Params; 7196 Params.append(PTy->param_type_begin(), PTy->param_type_end()); 7197 Params.insert(Params.end(), NumAppendArgs, InteropType); 7198 AdjustedFnType = Context.getFunctionType(PTy->getReturnType(), Params, 7199 PTy->getExtProtoInfo()); 7200 } 7201 7202 // Convert VariantRef expression to the type of the original function to 7203 // resolve possible conflicts. 7204 ExprResult VariantRefCast = VariantRef; 7205 if (LangOpts.CPlusPlus) { 7206 QualType FnPtrType; 7207 auto *Method = dyn_cast<CXXMethodDecl>(FD); 7208 if (Method && !Method->isStatic()) { 7209 const Type *ClassType = 7210 Context.getTypeDeclType(Method->getParent()).getTypePtr(); 7211 FnPtrType = Context.getMemberPointerType(AdjustedFnType, ClassType); 7212 ExprResult ER; 7213 { 7214 // Build adrr_of unary op to correctly handle type checks for member 7215 // functions. 7216 Sema::TentativeAnalysisScope Trap(*this); 7217 ER = CreateBuiltinUnaryOp(VariantRef->getBeginLoc(), UO_AddrOf, 7218 VariantRef); 7219 } 7220 if (!ER.isUsable()) { 7221 Diag(VariantRef->getExprLoc(), diag::err_omp_function_expected) 7222 << VariantId << VariantRef->getSourceRange(); 7223 return None; 7224 } 7225 VariantRef = ER.get(); 7226 } else { 7227 FnPtrType = Context.getPointerType(AdjustedFnType); 7228 } 7229 QualType VarianPtrType = Context.getPointerType(VariantRef->getType()); 7230 if (VarianPtrType.getUnqualifiedType() != FnPtrType.getUnqualifiedType()) { 7231 ImplicitConversionSequence ICS = TryImplicitConversion( 7232 VariantRef, FnPtrType.getUnqualifiedType(), 7233 /*SuppressUserConversions=*/false, AllowedExplicit::None, 7234 /*InOverloadResolution=*/false, 7235 /*CStyle=*/false, 7236 /*AllowObjCWritebackConversion=*/false); 7237 if (ICS.isFailure()) { 7238 Diag(VariantRef->getExprLoc(), 7239 diag::err_omp_declare_variant_incompat_types) 7240 << VariantRef->getType() 7241 << ((Method && !Method->isStatic()) ? FnPtrType : FD->getType()) 7242 << (NumAppendArgs ? 1 : 0) << VariantRef->getSourceRange(); 7243 return None; 7244 } 7245 VariantRefCast = PerformImplicitConversion( 7246 VariantRef, FnPtrType.getUnqualifiedType(), AA_Converting); 7247 if (!VariantRefCast.isUsable()) 7248 return None; 7249 } 7250 // Drop previously built artificial addr_of unary op for member functions. 7251 if (Method && !Method->isStatic()) { 7252 Expr *PossibleAddrOfVariantRef = VariantRefCast.get(); 7253 if (auto *UO = dyn_cast<UnaryOperator>( 7254 PossibleAddrOfVariantRef->IgnoreImplicit())) 7255 VariantRefCast = UO->getSubExpr(); 7256 } 7257 } 7258 7259 ExprResult ER = CheckPlaceholderExpr(VariantRefCast.get()); 7260 if (!ER.isUsable() || 7261 !ER.get()->IgnoreParenImpCasts()->getType()->isFunctionType()) { 7262 Diag(VariantRef->getExprLoc(), diag::err_omp_function_expected) 7263 << VariantId << VariantRef->getSourceRange(); 7264 return None; 7265 } 7266 7267 // The VariantRef must point to function. 7268 auto *DRE = dyn_cast<DeclRefExpr>(ER.get()->IgnoreParenImpCasts()); 7269 if (!DRE) { 7270 Diag(VariantRef->getExprLoc(), diag::err_omp_function_expected) 7271 << VariantId << VariantRef->getSourceRange(); 7272 return None; 7273 } 7274 auto *NewFD = dyn_cast_or_null<FunctionDecl>(DRE->getDecl()); 7275 if (!NewFD) { 7276 Diag(VariantRef->getExprLoc(), diag::err_omp_function_expected) 7277 << VariantId << VariantRef->getSourceRange(); 7278 return None; 7279 } 7280 7281 if (FD->getCanonicalDecl() == NewFD->getCanonicalDecl()) { 7282 Diag(VariantRef->getExprLoc(), 7283 diag::err_omp_declare_variant_same_base_function) 7284 << VariantRef->getSourceRange(); 7285 return None; 7286 } 7287 7288 // Check if function types are compatible in C. 7289 if (!LangOpts.CPlusPlus) { 7290 QualType NewType = 7291 Context.mergeFunctionTypes(AdjustedFnType, NewFD->getType()); 7292 if (NewType.isNull()) { 7293 Diag(VariantRef->getExprLoc(), 7294 diag::err_omp_declare_variant_incompat_types) 7295 << NewFD->getType() << FD->getType() << (NumAppendArgs ? 1 : 0) 7296 << VariantRef->getSourceRange(); 7297 return None; 7298 } 7299 if (NewType->isFunctionProtoType()) { 7300 if (FD->getType()->isFunctionNoProtoType()) 7301 setPrototype(*this, FD, NewFD, NewType); 7302 else if (NewFD->getType()->isFunctionNoProtoType()) 7303 setPrototype(*this, NewFD, FD, NewType); 7304 } 7305 } 7306 7307 // Check if variant function is not marked with declare variant directive. 7308 if (NewFD->hasAttrs() && NewFD->hasAttr<OMPDeclareVariantAttr>()) { 7309 Diag(VariantRef->getExprLoc(), 7310 diag::warn_omp_declare_variant_marked_as_declare_variant) 7311 << VariantRef->getSourceRange(); 7312 SourceRange SR = 7313 NewFD->specific_attr_begin<OMPDeclareVariantAttr>()->getRange(); 7314 Diag(SR.getBegin(), diag::note_omp_marked_declare_variant_here) << SR; 7315 return None; 7316 } 7317 7318 enum DoesntSupport { 7319 VirtFuncs = 1, 7320 Constructors = 3, 7321 Destructors = 4, 7322 DeletedFuncs = 5, 7323 DefaultedFuncs = 6, 7324 ConstexprFuncs = 7, 7325 ConstevalFuncs = 8, 7326 }; 7327 if (const auto *CXXFD = dyn_cast<CXXMethodDecl>(FD)) { 7328 if (CXXFD->isVirtual()) { 7329 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support) 7330 << VirtFuncs; 7331 return None; 7332 } 7333 7334 if (isa<CXXConstructorDecl>(FD)) { 7335 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support) 7336 << Constructors; 7337 return None; 7338 } 7339 7340 if (isa<CXXDestructorDecl>(FD)) { 7341 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support) 7342 << Destructors; 7343 return None; 7344 } 7345 } 7346 7347 if (FD->isDeleted()) { 7348 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support) 7349 << DeletedFuncs; 7350 return None; 7351 } 7352 7353 if (FD->isDefaulted()) { 7354 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support) 7355 << DefaultedFuncs; 7356 return None; 7357 } 7358 7359 if (FD->isConstexpr()) { 7360 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support) 7361 << (NewFD->isConsteval() ? ConstevalFuncs : ConstexprFuncs); 7362 return None; 7363 } 7364 7365 // Check general compatibility. 7366 if (areMultiversionVariantFunctionsCompatible( 7367 FD, NewFD, PartialDiagnostic::NullDiagnostic(), 7368 PartialDiagnosticAt(SourceLocation(), 7369 PartialDiagnostic::NullDiagnostic()), 7370 PartialDiagnosticAt( 7371 VariantRef->getExprLoc(), 7372 PDiag(diag::err_omp_declare_variant_doesnt_support)), 7373 PartialDiagnosticAt(VariantRef->getExprLoc(), 7374 PDiag(diag::err_omp_declare_variant_diff) 7375 << FD->getLocation()), 7376 /*TemplatesSupported=*/true, /*ConstexprSupported=*/false, 7377 /*CLinkageMayDiffer=*/true)) 7378 return None; 7379 return std::make_pair(FD, cast<Expr>(DRE)); 7380 } 7381 7382 void Sema::ActOnOpenMPDeclareVariantDirective( 7383 FunctionDecl *FD, Expr *VariantRef, OMPTraitInfo &TI, 7384 ArrayRef<Expr *> AdjustArgsNothing, 7385 ArrayRef<Expr *> AdjustArgsNeedDevicePtr, 7386 ArrayRef<OMPDeclareVariantAttr::InteropType> AppendArgs, 7387 SourceLocation AdjustArgsLoc, SourceLocation AppendArgsLoc, 7388 SourceRange SR) { 7389 7390 // OpenMP 5.1 [2.3.5, declare variant directive, Restrictions] 7391 // An adjust_args clause or append_args clause can only be specified if the 7392 // dispatch selector of the construct selector set appears in the match 7393 // clause. 7394 7395 SmallVector<Expr *, 8> AllAdjustArgs; 7396 llvm::append_range(AllAdjustArgs, AdjustArgsNothing); 7397 llvm::append_range(AllAdjustArgs, AdjustArgsNeedDevicePtr); 7398 7399 if (!AllAdjustArgs.empty() || !AppendArgs.empty()) { 7400 VariantMatchInfo VMI; 7401 TI.getAsVariantMatchInfo(Context, VMI); 7402 if (!llvm::is_contained( 7403 VMI.ConstructTraits, 7404 llvm::omp::TraitProperty::construct_dispatch_dispatch)) { 7405 if (!AllAdjustArgs.empty()) 7406 Diag(AdjustArgsLoc, diag::err_omp_clause_requires_dispatch_construct) 7407 << getOpenMPClauseName(OMPC_adjust_args); 7408 if (!AppendArgs.empty()) 7409 Diag(AppendArgsLoc, diag::err_omp_clause_requires_dispatch_construct) 7410 << getOpenMPClauseName(OMPC_append_args); 7411 return; 7412 } 7413 } 7414 7415 // OpenMP 5.1 [2.3.5, declare variant directive, Restrictions] 7416 // Each argument can only appear in a single adjust_args clause for each 7417 // declare variant directive. 7418 llvm::SmallPtrSet<const VarDecl *, 4> AdjustVars; 7419 7420 for (Expr *E : AllAdjustArgs) { 7421 E = E->IgnoreParenImpCasts(); 7422 if (const auto *DRE = dyn_cast<DeclRefExpr>(E)) { 7423 if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) { 7424 const VarDecl *CanonPVD = PVD->getCanonicalDecl(); 7425 if (FD->getNumParams() > PVD->getFunctionScopeIndex() && 7426 FD->getParamDecl(PVD->getFunctionScopeIndex()) 7427 ->getCanonicalDecl() == CanonPVD) { 7428 // It's a parameter of the function, check duplicates. 7429 if (!AdjustVars.insert(CanonPVD).second) { 7430 Diag(DRE->getLocation(), diag::err_omp_adjust_arg_multiple_clauses) 7431 << PVD; 7432 return; 7433 } 7434 continue; 7435 } 7436 } 7437 } 7438 // Anything that is not a function parameter is an error. 7439 Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause) << FD << 0; 7440 return; 7441 } 7442 7443 auto *NewAttr = OMPDeclareVariantAttr::CreateImplicit( 7444 Context, VariantRef, &TI, const_cast<Expr **>(AdjustArgsNothing.data()), 7445 AdjustArgsNothing.size(), 7446 const_cast<Expr **>(AdjustArgsNeedDevicePtr.data()), 7447 AdjustArgsNeedDevicePtr.size(), 7448 const_cast<OMPDeclareVariantAttr::InteropType *>(AppendArgs.data()), 7449 AppendArgs.size(), SR); 7450 FD->addAttr(NewAttr); 7451 } 7452 7453 StmtResult Sema::ActOnOpenMPParallelDirective(ArrayRef<OMPClause *> Clauses, 7454 Stmt *AStmt, 7455 SourceLocation StartLoc, 7456 SourceLocation EndLoc) { 7457 if (!AStmt) 7458 return StmtError(); 7459 7460 auto *CS = cast<CapturedStmt>(AStmt); 7461 // 1.2.2 OpenMP Language Terminology 7462 // Structured block - An executable statement with a single entry at the 7463 // top and a single exit at the bottom. 7464 // The point of exit cannot be a branch out of the structured block. 7465 // longjmp() and throw() must not violate the entry/exit criteria. 7466 CS->getCapturedDecl()->setNothrow(); 7467 7468 setFunctionHasBranchProtectedScope(); 7469 7470 return OMPParallelDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt, 7471 DSAStack->getTaskgroupReductionRef(), 7472 DSAStack->isCancelRegion()); 7473 } 7474 7475 namespace { 7476 /// Iteration space of a single for loop. 7477 struct LoopIterationSpace final { 7478 /// True if the condition operator is the strict compare operator (<, > or 7479 /// !=). 7480 bool IsStrictCompare = false; 7481 /// Condition of the loop. 7482 Expr *PreCond = nullptr; 7483 /// This expression calculates the number of iterations in the loop. 7484 /// It is always possible to calculate it before starting the loop. 7485 Expr *NumIterations = nullptr; 7486 /// The loop counter variable. 7487 Expr *CounterVar = nullptr; 7488 /// Private loop counter variable. 7489 Expr *PrivateCounterVar = nullptr; 7490 /// This is initializer for the initial value of #CounterVar. 7491 Expr *CounterInit = nullptr; 7492 /// This is step for the #CounterVar used to generate its update: 7493 /// #CounterVar = #CounterInit + #CounterStep * CurrentIteration. 7494 Expr *CounterStep = nullptr; 7495 /// Should step be subtracted? 7496 bool Subtract = false; 7497 /// Source range of the loop init. 7498 SourceRange InitSrcRange; 7499 /// Source range of the loop condition. 7500 SourceRange CondSrcRange; 7501 /// Source range of the loop increment. 7502 SourceRange IncSrcRange; 7503 /// Minimum value that can have the loop control variable. Used to support 7504 /// non-rectangular loops. Applied only for LCV with the non-iterator types, 7505 /// since only such variables can be used in non-loop invariant expressions. 7506 Expr *MinValue = nullptr; 7507 /// Maximum value that can have the loop control variable. Used to support 7508 /// non-rectangular loops. Applied only for LCV with the non-iterator type, 7509 /// since only such variables can be used in non-loop invariant expressions. 7510 Expr *MaxValue = nullptr; 7511 /// true, if the lower bound depends on the outer loop control var. 7512 bool IsNonRectangularLB = false; 7513 /// true, if the upper bound depends on the outer loop control var. 7514 bool IsNonRectangularUB = false; 7515 /// Index of the loop this loop depends on and forms non-rectangular loop 7516 /// nest. 7517 unsigned LoopDependentIdx = 0; 7518 /// Final condition for the non-rectangular loop nest support. It is used to 7519 /// check that the number of iterations for this particular counter must be 7520 /// finished. 7521 Expr *FinalCondition = nullptr; 7522 }; 7523 7524 /// Helper class for checking canonical form of the OpenMP loops and 7525 /// extracting iteration space of each loop in the loop nest, that will be used 7526 /// for IR generation. 7527 class OpenMPIterationSpaceChecker { 7528 /// Reference to Sema. 7529 Sema &SemaRef; 7530 /// Does the loop associated directive support non-rectangular loops? 7531 bool SupportsNonRectangular; 7532 /// Data-sharing stack. 7533 DSAStackTy &Stack; 7534 /// A location for diagnostics (when there is no some better location). 7535 SourceLocation DefaultLoc; 7536 /// A location for diagnostics (when increment is not compatible). 7537 SourceLocation ConditionLoc; 7538 /// A source location for referring to loop init later. 7539 SourceRange InitSrcRange; 7540 /// A source location for referring to condition later. 7541 SourceRange ConditionSrcRange; 7542 /// A source location for referring to increment later. 7543 SourceRange IncrementSrcRange; 7544 /// Loop variable. 7545 ValueDecl *LCDecl = nullptr; 7546 /// Reference to loop variable. 7547 Expr *LCRef = nullptr; 7548 /// Lower bound (initializer for the var). 7549 Expr *LB = nullptr; 7550 /// Upper bound. 7551 Expr *UB = nullptr; 7552 /// Loop step (increment). 7553 Expr *Step = nullptr; 7554 /// This flag is true when condition is one of: 7555 /// Var < UB 7556 /// Var <= UB 7557 /// UB > Var 7558 /// UB >= Var 7559 /// This will have no value when the condition is != 7560 llvm::Optional<bool> TestIsLessOp; 7561 /// This flag is true when condition is strict ( < or > ). 7562 bool TestIsStrictOp = false; 7563 /// This flag is true when step is subtracted on each iteration. 7564 bool SubtractStep = false; 7565 /// The outer loop counter this loop depends on (if any). 7566 const ValueDecl *DepDecl = nullptr; 7567 /// Contains number of loop (starts from 1) on which loop counter init 7568 /// expression of this loop depends on. 7569 Optional<unsigned> InitDependOnLC; 7570 /// Contains number of loop (starts from 1) on which loop counter condition 7571 /// expression of this loop depends on. 7572 Optional<unsigned> CondDependOnLC; 7573 /// Checks if the provide statement depends on the loop counter. 7574 Optional<unsigned> doesDependOnLoopCounter(const Stmt *S, bool IsInitializer); 7575 /// Original condition required for checking of the exit condition for 7576 /// non-rectangular loop. 7577 Expr *Condition = nullptr; 7578 7579 public: 7580 OpenMPIterationSpaceChecker(Sema &SemaRef, bool SupportsNonRectangular, 7581 DSAStackTy &Stack, SourceLocation DefaultLoc) 7582 : SemaRef(SemaRef), SupportsNonRectangular(SupportsNonRectangular), 7583 Stack(Stack), DefaultLoc(DefaultLoc), ConditionLoc(DefaultLoc) {} 7584 /// Check init-expr for canonical loop form and save loop counter 7585 /// variable - #Var and its initialization value - #LB. 7586 bool checkAndSetInit(Stmt *S, bool EmitDiags = true); 7587 /// Check test-expr for canonical form, save upper-bound (#UB), flags 7588 /// for less/greater and for strict/non-strict comparison. 7589 bool checkAndSetCond(Expr *S); 7590 /// Check incr-expr for canonical loop form and return true if it 7591 /// does not conform, otherwise save loop step (#Step). 7592 bool checkAndSetInc(Expr *S); 7593 /// Return the loop counter variable. 7594 ValueDecl *getLoopDecl() const { return LCDecl; } 7595 /// Return the reference expression to loop counter variable. 7596 Expr *getLoopDeclRefExpr() const { return LCRef; } 7597 /// Source range of the loop init. 7598 SourceRange getInitSrcRange() const { return InitSrcRange; } 7599 /// Source range of the loop condition. 7600 SourceRange getConditionSrcRange() const { return ConditionSrcRange; } 7601 /// Source range of the loop increment. 7602 SourceRange getIncrementSrcRange() const { return IncrementSrcRange; } 7603 /// True if the step should be subtracted. 7604 bool shouldSubtractStep() const { return SubtractStep; } 7605 /// True, if the compare operator is strict (<, > or !=). 7606 bool isStrictTestOp() const { return TestIsStrictOp; } 7607 /// Build the expression to calculate the number of iterations. 7608 Expr *buildNumIterations( 7609 Scope *S, ArrayRef<LoopIterationSpace> ResultIterSpaces, bool LimitedType, 7610 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const; 7611 /// Build the precondition expression for the loops. 7612 Expr * 7613 buildPreCond(Scope *S, Expr *Cond, 7614 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const; 7615 /// Build reference expression to the counter be used for codegen. 7616 DeclRefExpr * 7617 buildCounterVar(llvm::MapVector<const Expr *, DeclRefExpr *> &Captures, 7618 DSAStackTy &DSA) const; 7619 /// Build reference expression to the private counter be used for 7620 /// codegen. 7621 Expr *buildPrivateCounterVar() const; 7622 /// Build initialization of the counter be used for codegen. 7623 Expr *buildCounterInit() const; 7624 /// Build step of the counter be used for codegen. 7625 Expr *buildCounterStep() const; 7626 /// Build loop data with counter value for depend clauses in ordered 7627 /// directives. 7628 Expr * 7629 buildOrderedLoopData(Scope *S, Expr *Counter, 7630 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures, 7631 SourceLocation Loc, Expr *Inc = nullptr, 7632 OverloadedOperatorKind OOK = OO_Amp); 7633 /// Builds the minimum value for the loop counter. 7634 std::pair<Expr *, Expr *> buildMinMaxValues( 7635 Scope *S, llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const; 7636 /// Builds final condition for the non-rectangular loops. 7637 Expr *buildFinalCondition(Scope *S) const; 7638 /// Return true if any expression is dependent. 7639 bool dependent() const; 7640 /// Returns true if the initializer forms non-rectangular loop. 7641 bool doesInitDependOnLC() const { return InitDependOnLC.hasValue(); } 7642 /// Returns true if the condition forms non-rectangular loop. 7643 bool doesCondDependOnLC() const { return CondDependOnLC.hasValue(); } 7644 /// Returns index of the loop we depend on (starting from 1), or 0 otherwise. 7645 unsigned getLoopDependentIdx() const { 7646 return InitDependOnLC.getValueOr(CondDependOnLC.getValueOr(0)); 7647 } 7648 7649 private: 7650 /// Check the right-hand side of an assignment in the increment 7651 /// expression. 7652 bool checkAndSetIncRHS(Expr *RHS); 7653 /// Helper to set loop counter variable and its initializer. 7654 bool setLCDeclAndLB(ValueDecl *NewLCDecl, Expr *NewDeclRefExpr, Expr *NewLB, 7655 bool EmitDiags); 7656 /// Helper to set upper bound. 7657 bool setUB(Expr *NewUB, llvm::Optional<bool> LessOp, bool StrictOp, 7658 SourceRange SR, SourceLocation SL); 7659 /// Helper to set loop increment. 7660 bool setStep(Expr *NewStep, bool Subtract); 7661 }; 7662 7663 bool OpenMPIterationSpaceChecker::dependent() const { 7664 if (!LCDecl) { 7665 assert(!LB && !UB && !Step); 7666 return false; 7667 } 7668 return LCDecl->getType()->isDependentType() || 7669 (LB && LB->isValueDependent()) || (UB && UB->isValueDependent()) || 7670 (Step && Step->isValueDependent()); 7671 } 7672 7673 bool OpenMPIterationSpaceChecker::setLCDeclAndLB(ValueDecl *NewLCDecl, 7674 Expr *NewLCRefExpr, 7675 Expr *NewLB, bool EmitDiags) { 7676 // State consistency checking to ensure correct usage. 7677 assert(LCDecl == nullptr && LB == nullptr && LCRef == nullptr && 7678 UB == nullptr && Step == nullptr && !TestIsLessOp && !TestIsStrictOp); 7679 if (!NewLCDecl || !NewLB || NewLB->containsErrors()) 7680 return true; 7681 LCDecl = getCanonicalDecl(NewLCDecl); 7682 LCRef = NewLCRefExpr; 7683 if (auto *CE = dyn_cast_or_null<CXXConstructExpr>(NewLB)) 7684 if (const CXXConstructorDecl *Ctor = CE->getConstructor()) 7685 if ((Ctor->isCopyOrMoveConstructor() || 7686 Ctor->isConvertingConstructor(/*AllowExplicit=*/false)) && 7687 CE->getNumArgs() > 0 && CE->getArg(0) != nullptr) 7688 NewLB = CE->getArg(0)->IgnoreParenImpCasts(); 7689 LB = NewLB; 7690 if (EmitDiags) 7691 InitDependOnLC = doesDependOnLoopCounter(LB, /*IsInitializer=*/true); 7692 return false; 7693 } 7694 7695 bool OpenMPIterationSpaceChecker::setUB(Expr *NewUB, 7696 llvm::Optional<bool> LessOp, 7697 bool StrictOp, SourceRange SR, 7698 SourceLocation SL) { 7699 // State consistency checking to ensure correct usage. 7700 assert(LCDecl != nullptr && LB != nullptr && UB == nullptr && 7701 Step == nullptr && !TestIsLessOp && !TestIsStrictOp); 7702 if (!NewUB || NewUB->containsErrors()) 7703 return true; 7704 UB = NewUB; 7705 if (LessOp) 7706 TestIsLessOp = LessOp; 7707 TestIsStrictOp = StrictOp; 7708 ConditionSrcRange = SR; 7709 ConditionLoc = SL; 7710 CondDependOnLC = doesDependOnLoopCounter(UB, /*IsInitializer=*/false); 7711 return false; 7712 } 7713 7714 bool OpenMPIterationSpaceChecker::setStep(Expr *NewStep, bool Subtract) { 7715 // State consistency checking to ensure correct usage. 7716 assert(LCDecl != nullptr && LB != nullptr && Step == nullptr); 7717 if (!NewStep || NewStep->containsErrors()) 7718 return true; 7719 if (!NewStep->isValueDependent()) { 7720 // Check that the step is integer expression. 7721 SourceLocation StepLoc = NewStep->getBeginLoc(); 7722 ExprResult Val = SemaRef.PerformOpenMPImplicitIntegerConversion( 7723 StepLoc, getExprAsWritten(NewStep)); 7724 if (Val.isInvalid()) 7725 return true; 7726 NewStep = Val.get(); 7727 7728 // OpenMP [2.6, Canonical Loop Form, Restrictions] 7729 // If test-expr is of form var relational-op b and relational-op is < or 7730 // <= then incr-expr must cause var to increase on each iteration of the 7731 // loop. If test-expr is of form var relational-op b and relational-op is 7732 // > or >= then incr-expr must cause var to decrease on each iteration of 7733 // the loop. 7734 // If test-expr is of form b relational-op var and relational-op is < or 7735 // <= then incr-expr must cause var to decrease on each iteration of the 7736 // loop. If test-expr is of form b relational-op var and relational-op is 7737 // > or >= then incr-expr must cause var to increase on each iteration of 7738 // the loop. 7739 Optional<llvm::APSInt> Result = 7740 NewStep->getIntegerConstantExpr(SemaRef.Context); 7741 bool IsUnsigned = !NewStep->getType()->hasSignedIntegerRepresentation(); 7742 bool IsConstNeg = 7743 Result && Result->isSigned() && (Subtract != Result->isNegative()); 7744 bool IsConstPos = 7745 Result && Result->isSigned() && (Subtract == Result->isNegative()); 7746 bool IsConstZero = Result && !Result->getBoolValue(); 7747 7748 // != with increment is treated as <; != with decrement is treated as > 7749 if (!TestIsLessOp.hasValue()) 7750 TestIsLessOp = IsConstPos || (IsUnsigned && !Subtract); 7751 if (UB && 7752 (IsConstZero || (TestIsLessOp.getValue() 7753 ? (IsConstNeg || (IsUnsigned && Subtract)) 7754 : (IsConstPos || (IsUnsigned && !Subtract))))) { 7755 SemaRef.Diag(NewStep->getExprLoc(), 7756 diag::err_omp_loop_incr_not_compatible) 7757 << LCDecl << TestIsLessOp.getValue() << NewStep->getSourceRange(); 7758 SemaRef.Diag(ConditionLoc, 7759 diag::note_omp_loop_cond_requres_compatible_incr) 7760 << TestIsLessOp.getValue() << ConditionSrcRange; 7761 return true; 7762 } 7763 if (TestIsLessOp.getValue() == Subtract) { 7764 NewStep = 7765 SemaRef.CreateBuiltinUnaryOp(NewStep->getExprLoc(), UO_Minus, NewStep) 7766 .get(); 7767 Subtract = !Subtract; 7768 } 7769 } 7770 7771 Step = NewStep; 7772 SubtractStep = Subtract; 7773 return false; 7774 } 7775 7776 namespace { 7777 /// Checker for the non-rectangular loops. Checks if the initializer or 7778 /// condition expression references loop counter variable. 7779 class LoopCounterRefChecker final 7780 : public ConstStmtVisitor<LoopCounterRefChecker, bool> { 7781 Sema &SemaRef; 7782 DSAStackTy &Stack; 7783 const ValueDecl *CurLCDecl = nullptr; 7784 const ValueDecl *DepDecl = nullptr; 7785 const ValueDecl *PrevDepDecl = nullptr; 7786 bool IsInitializer = true; 7787 bool SupportsNonRectangular; 7788 unsigned BaseLoopId = 0; 7789 bool checkDecl(const Expr *E, const ValueDecl *VD) { 7790 if (getCanonicalDecl(VD) == getCanonicalDecl(CurLCDecl)) { 7791 SemaRef.Diag(E->getExprLoc(), diag::err_omp_stmt_depends_on_loop_counter) 7792 << (IsInitializer ? 0 : 1); 7793 return false; 7794 } 7795 const auto &&Data = Stack.isLoopControlVariable(VD); 7796 // OpenMP, 2.9.1 Canonical Loop Form, Restrictions. 7797 // The type of the loop iterator on which we depend may not have a random 7798 // access iterator type. 7799 if (Data.first && VD->getType()->isRecordType()) { 7800 SmallString<128> Name; 7801 llvm::raw_svector_ostream OS(Name); 7802 VD->getNameForDiagnostic(OS, SemaRef.getPrintingPolicy(), 7803 /*Qualified=*/true); 7804 SemaRef.Diag(E->getExprLoc(), 7805 diag::err_omp_wrong_dependency_iterator_type) 7806 << OS.str(); 7807 SemaRef.Diag(VD->getLocation(), diag::note_previous_decl) << VD; 7808 return false; 7809 } 7810 if (Data.first && !SupportsNonRectangular) { 7811 SemaRef.Diag(E->getExprLoc(), diag::err_omp_invariant_dependency); 7812 return false; 7813 } 7814 if (Data.first && 7815 (DepDecl || (PrevDepDecl && 7816 getCanonicalDecl(VD) != getCanonicalDecl(PrevDepDecl)))) { 7817 if (!DepDecl && PrevDepDecl) 7818 DepDecl = PrevDepDecl; 7819 SmallString<128> Name; 7820 llvm::raw_svector_ostream OS(Name); 7821 DepDecl->getNameForDiagnostic(OS, SemaRef.getPrintingPolicy(), 7822 /*Qualified=*/true); 7823 SemaRef.Diag(E->getExprLoc(), 7824 diag::err_omp_invariant_or_linear_dependency) 7825 << OS.str(); 7826 return false; 7827 } 7828 if (Data.first) { 7829 DepDecl = VD; 7830 BaseLoopId = Data.first; 7831 } 7832 return Data.first; 7833 } 7834 7835 public: 7836 bool VisitDeclRefExpr(const DeclRefExpr *E) { 7837 const ValueDecl *VD = E->getDecl(); 7838 if (isa<VarDecl>(VD)) 7839 return checkDecl(E, VD); 7840 return false; 7841 } 7842 bool VisitMemberExpr(const MemberExpr *E) { 7843 if (isa<CXXThisExpr>(E->getBase()->IgnoreParens())) { 7844 const ValueDecl *VD = E->getMemberDecl(); 7845 if (isa<VarDecl>(VD) || isa<FieldDecl>(VD)) 7846 return checkDecl(E, VD); 7847 } 7848 return false; 7849 } 7850 bool VisitStmt(const Stmt *S) { 7851 bool Res = false; 7852 for (const Stmt *Child : S->children()) 7853 Res = (Child && Visit(Child)) || Res; 7854 return Res; 7855 } 7856 explicit LoopCounterRefChecker(Sema &SemaRef, DSAStackTy &Stack, 7857 const ValueDecl *CurLCDecl, bool IsInitializer, 7858 const ValueDecl *PrevDepDecl = nullptr, 7859 bool SupportsNonRectangular = true) 7860 : SemaRef(SemaRef), Stack(Stack), CurLCDecl(CurLCDecl), 7861 PrevDepDecl(PrevDepDecl), IsInitializer(IsInitializer), 7862 SupportsNonRectangular(SupportsNonRectangular) {} 7863 unsigned getBaseLoopId() const { 7864 assert(CurLCDecl && "Expected loop dependency."); 7865 return BaseLoopId; 7866 } 7867 const ValueDecl *getDepDecl() const { 7868 assert(CurLCDecl && "Expected loop dependency."); 7869 return DepDecl; 7870 } 7871 }; 7872 } // namespace 7873 7874 Optional<unsigned> 7875 OpenMPIterationSpaceChecker::doesDependOnLoopCounter(const Stmt *S, 7876 bool IsInitializer) { 7877 // Check for the non-rectangular loops. 7878 LoopCounterRefChecker LoopStmtChecker(SemaRef, Stack, LCDecl, IsInitializer, 7879 DepDecl, SupportsNonRectangular); 7880 if (LoopStmtChecker.Visit(S)) { 7881 DepDecl = LoopStmtChecker.getDepDecl(); 7882 return LoopStmtChecker.getBaseLoopId(); 7883 } 7884 return llvm::None; 7885 } 7886 7887 bool OpenMPIterationSpaceChecker::checkAndSetInit(Stmt *S, bool EmitDiags) { 7888 // Check init-expr for canonical loop form and save loop counter 7889 // variable - #Var and its initialization value - #LB. 7890 // OpenMP [2.6] Canonical loop form. init-expr may be one of the following: 7891 // var = lb 7892 // integer-type var = lb 7893 // random-access-iterator-type var = lb 7894 // pointer-type var = lb 7895 // 7896 if (!S) { 7897 if (EmitDiags) { 7898 SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_init); 7899 } 7900 return true; 7901 } 7902 if (auto *ExprTemp = dyn_cast<ExprWithCleanups>(S)) 7903 if (!ExprTemp->cleanupsHaveSideEffects()) 7904 S = ExprTemp->getSubExpr(); 7905 7906 InitSrcRange = S->getSourceRange(); 7907 if (Expr *E = dyn_cast<Expr>(S)) 7908 S = E->IgnoreParens(); 7909 if (auto *BO = dyn_cast<BinaryOperator>(S)) { 7910 if (BO->getOpcode() == BO_Assign) { 7911 Expr *LHS = BO->getLHS()->IgnoreParens(); 7912 if (auto *DRE = dyn_cast<DeclRefExpr>(LHS)) { 7913 if (auto *CED = dyn_cast<OMPCapturedExprDecl>(DRE->getDecl())) 7914 if (auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit()))) 7915 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(), 7916 EmitDiags); 7917 return setLCDeclAndLB(DRE->getDecl(), DRE, BO->getRHS(), EmitDiags); 7918 } 7919 if (auto *ME = dyn_cast<MemberExpr>(LHS)) { 7920 if (ME->isArrow() && 7921 isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts())) 7922 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(), 7923 EmitDiags); 7924 } 7925 } 7926 } else if (auto *DS = dyn_cast<DeclStmt>(S)) { 7927 if (DS->isSingleDecl()) { 7928 if (auto *Var = dyn_cast_or_null<VarDecl>(DS->getSingleDecl())) { 7929 if (Var->hasInit() && !Var->getType()->isReferenceType()) { 7930 // Accept non-canonical init form here but emit ext. warning. 7931 if (Var->getInitStyle() != VarDecl::CInit && EmitDiags) 7932 SemaRef.Diag(S->getBeginLoc(), 7933 diag::ext_omp_loop_not_canonical_init) 7934 << S->getSourceRange(); 7935 return setLCDeclAndLB( 7936 Var, 7937 buildDeclRefExpr(SemaRef, Var, 7938 Var->getType().getNonReferenceType(), 7939 DS->getBeginLoc()), 7940 Var->getInit(), EmitDiags); 7941 } 7942 } 7943 } 7944 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) { 7945 if (CE->getOperator() == OO_Equal) { 7946 Expr *LHS = CE->getArg(0); 7947 if (auto *DRE = dyn_cast<DeclRefExpr>(LHS)) { 7948 if (auto *CED = dyn_cast<OMPCapturedExprDecl>(DRE->getDecl())) 7949 if (auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit()))) 7950 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(), 7951 EmitDiags); 7952 return setLCDeclAndLB(DRE->getDecl(), DRE, CE->getArg(1), EmitDiags); 7953 } 7954 if (auto *ME = dyn_cast<MemberExpr>(LHS)) { 7955 if (ME->isArrow() && 7956 isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts())) 7957 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(), 7958 EmitDiags); 7959 } 7960 } 7961 } 7962 7963 if (dependent() || SemaRef.CurContext->isDependentContext()) 7964 return false; 7965 if (EmitDiags) { 7966 SemaRef.Diag(S->getBeginLoc(), diag::err_omp_loop_not_canonical_init) 7967 << S->getSourceRange(); 7968 } 7969 return true; 7970 } 7971 7972 /// Ignore parenthesizes, implicit casts, copy constructor and return the 7973 /// variable (which may be the loop variable) if possible. 7974 static const ValueDecl *getInitLCDecl(const Expr *E) { 7975 if (!E) 7976 return nullptr; 7977 E = getExprAsWritten(E); 7978 if (const auto *CE = dyn_cast_or_null<CXXConstructExpr>(E)) 7979 if (const CXXConstructorDecl *Ctor = CE->getConstructor()) 7980 if ((Ctor->isCopyOrMoveConstructor() || 7981 Ctor->isConvertingConstructor(/*AllowExplicit=*/false)) && 7982 CE->getNumArgs() > 0 && CE->getArg(0) != nullptr) 7983 E = CE->getArg(0)->IgnoreParenImpCasts(); 7984 if (const auto *DRE = dyn_cast_or_null<DeclRefExpr>(E)) { 7985 if (const auto *VD = dyn_cast<VarDecl>(DRE->getDecl())) 7986 return getCanonicalDecl(VD); 7987 } 7988 if (const auto *ME = dyn_cast_or_null<MemberExpr>(E)) 7989 if (ME->isArrow() && isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts())) 7990 return getCanonicalDecl(ME->getMemberDecl()); 7991 return nullptr; 7992 } 7993 7994 bool OpenMPIterationSpaceChecker::checkAndSetCond(Expr *S) { 7995 // Check test-expr for canonical form, save upper-bound UB, flags for 7996 // less/greater and for strict/non-strict comparison. 7997 // OpenMP [2.9] Canonical loop form. Test-expr may be one of the following: 7998 // var relational-op b 7999 // b relational-op var 8000 // 8001 bool IneqCondIsCanonical = SemaRef.getLangOpts().OpenMP >= 50; 8002 if (!S) { 8003 SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_cond) 8004 << (IneqCondIsCanonical ? 1 : 0) << LCDecl; 8005 return true; 8006 } 8007 Condition = S; 8008 S = getExprAsWritten(S); 8009 SourceLocation CondLoc = S->getBeginLoc(); 8010 auto &&CheckAndSetCond = [this, IneqCondIsCanonical]( 8011 BinaryOperatorKind Opcode, const Expr *LHS, 8012 const Expr *RHS, SourceRange SR, 8013 SourceLocation OpLoc) -> llvm::Optional<bool> { 8014 if (BinaryOperator::isRelationalOp(Opcode)) { 8015 if (getInitLCDecl(LHS) == LCDecl) 8016 return setUB(const_cast<Expr *>(RHS), 8017 (Opcode == BO_LT || Opcode == BO_LE), 8018 (Opcode == BO_LT || Opcode == BO_GT), SR, OpLoc); 8019 if (getInitLCDecl(RHS) == LCDecl) 8020 return setUB(const_cast<Expr *>(LHS), 8021 (Opcode == BO_GT || Opcode == BO_GE), 8022 (Opcode == BO_LT || Opcode == BO_GT), SR, OpLoc); 8023 } else if (IneqCondIsCanonical && Opcode == BO_NE) { 8024 return setUB(const_cast<Expr *>(getInitLCDecl(LHS) == LCDecl ? RHS : LHS), 8025 /*LessOp=*/llvm::None, 8026 /*StrictOp=*/true, SR, OpLoc); 8027 } 8028 return llvm::None; 8029 }; 8030 llvm::Optional<bool> Res; 8031 if (auto *RBO = dyn_cast<CXXRewrittenBinaryOperator>(S)) { 8032 CXXRewrittenBinaryOperator::DecomposedForm DF = RBO->getDecomposedForm(); 8033 Res = CheckAndSetCond(DF.Opcode, DF.LHS, DF.RHS, RBO->getSourceRange(), 8034 RBO->getOperatorLoc()); 8035 } else if (auto *BO = dyn_cast<BinaryOperator>(S)) { 8036 Res = CheckAndSetCond(BO->getOpcode(), BO->getLHS(), BO->getRHS(), 8037 BO->getSourceRange(), BO->getOperatorLoc()); 8038 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) { 8039 if (CE->getNumArgs() == 2) { 8040 Res = CheckAndSetCond( 8041 BinaryOperator::getOverloadedOpcode(CE->getOperator()), CE->getArg(0), 8042 CE->getArg(1), CE->getSourceRange(), CE->getOperatorLoc()); 8043 } 8044 } 8045 if (Res.hasValue()) 8046 return *Res; 8047 if (dependent() || SemaRef.CurContext->isDependentContext()) 8048 return false; 8049 SemaRef.Diag(CondLoc, diag::err_omp_loop_not_canonical_cond) 8050 << (IneqCondIsCanonical ? 1 : 0) << S->getSourceRange() << LCDecl; 8051 return true; 8052 } 8053 8054 bool OpenMPIterationSpaceChecker::checkAndSetIncRHS(Expr *RHS) { 8055 // RHS of canonical loop form increment can be: 8056 // var + incr 8057 // incr + var 8058 // var - incr 8059 // 8060 RHS = RHS->IgnoreParenImpCasts(); 8061 if (auto *BO = dyn_cast<BinaryOperator>(RHS)) { 8062 if (BO->isAdditiveOp()) { 8063 bool IsAdd = BO->getOpcode() == BO_Add; 8064 if (getInitLCDecl(BO->getLHS()) == LCDecl) 8065 return setStep(BO->getRHS(), !IsAdd); 8066 if (IsAdd && getInitLCDecl(BO->getRHS()) == LCDecl) 8067 return setStep(BO->getLHS(), /*Subtract=*/false); 8068 } 8069 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(RHS)) { 8070 bool IsAdd = CE->getOperator() == OO_Plus; 8071 if ((IsAdd || CE->getOperator() == OO_Minus) && CE->getNumArgs() == 2) { 8072 if (getInitLCDecl(CE->getArg(0)) == LCDecl) 8073 return setStep(CE->getArg(1), !IsAdd); 8074 if (IsAdd && getInitLCDecl(CE->getArg(1)) == LCDecl) 8075 return setStep(CE->getArg(0), /*Subtract=*/false); 8076 } 8077 } 8078 if (dependent() || SemaRef.CurContext->isDependentContext()) 8079 return false; 8080 SemaRef.Diag(RHS->getBeginLoc(), diag::err_omp_loop_not_canonical_incr) 8081 << RHS->getSourceRange() << LCDecl; 8082 return true; 8083 } 8084 8085 bool OpenMPIterationSpaceChecker::checkAndSetInc(Expr *S) { 8086 // Check incr-expr for canonical loop form and return true if it 8087 // does not conform. 8088 // OpenMP [2.6] Canonical loop form. Test-expr may be one of the following: 8089 // ++var 8090 // var++ 8091 // --var 8092 // var-- 8093 // var += incr 8094 // var -= incr 8095 // var = var + incr 8096 // var = incr + var 8097 // var = var - incr 8098 // 8099 if (!S) { 8100 SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_incr) << LCDecl; 8101 return true; 8102 } 8103 if (auto *ExprTemp = dyn_cast<ExprWithCleanups>(S)) 8104 if (!ExprTemp->cleanupsHaveSideEffects()) 8105 S = ExprTemp->getSubExpr(); 8106 8107 IncrementSrcRange = S->getSourceRange(); 8108 S = S->IgnoreParens(); 8109 if (auto *UO = dyn_cast<UnaryOperator>(S)) { 8110 if (UO->isIncrementDecrementOp() && 8111 getInitLCDecl(UO->getSubExpr()) == LCDecl) 8112 return setStep(SemaRef 8113 .ActOnIntegerConstant(UO->getBeginLoc(), 8114 (UO->isDecrementOp() ? -1 : 1)) 8115 .get(), 8116 /*Subtract=*/false); 8117 } else if (auto *BO = dyn_cast<BinaryOperator>(S)) { 8118 switch (BO->getOpcode()) { 8119 case BO_AddAssign: 8120 case BO_SubAssign: 8121 if (getInitLCDecl(BO->getLHS()) == LCDecl) 8122 return setStep(BO->getRHS(), BO->getOpcode() == BO_SubAssign); 8123 break; 8124 case BO_Assign: 8125 if (getInitLCDecl(BO->getLHS()) == LCDecl) 8126 return checkAndSetIncRHS(BO->getRHS()); 8127 break; 8128 default: 8129 break; 8130 } 8131 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) { 8132 switch (CE->getOperator()) { 8133 case OO_PlusPlus: 8134 case OO_MinusMinus: 8135 if (getInitLCDecl(CE->getArg(0)) == LCDecl) 8136 return setStep(SemaRef 8137 .ActOnIntegerConstant( 8138 CE->getBeginLoc(), 8139 ((CE->getOperator() == OO_MinusMinus) ? -1 : 1)) 8140 .get(), 8141 /*Subtract=*/false); 8142 break; 8143 case OO_PlusEqual: 8144 case OO_MinusEqual: 8145 if (getInitLCDecl(CE->getArg(0)) == LCDecl) 8146 return setStep(CE->getArg(1), CE->getOperator() == OO_MinusEqual); 8147 break; 8148 case OO_Equal: 8149 if (getInitLCDecl(CE->getArg(0)) == LCDecl) 8150 return checkAndSetIncRHS(CE->getArg(1)); 8151 break; 8152 default: 8153 break; 8154 } 8155 } 8156 if (dependent() || SemaRef.CurContext->isDependentContext()) 8157 return false; 8158 SemaRef.Diag(S->getBeginLoc(), diag::err_omp_loop_not_canonical_incr) 8159 << S->getSourceRange() << LCDecl; 8160 return true; 8161 } 8162 8163 static ExprResult 8164 tryBuildCapture(Sema &SemaRef, Expr *Capture, 8165 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) { 8166 if (SemaRef.CurContext->isDependentContext() || Capture->containsErrors()) 8167 return Capture; 8168 if (Capture->isEvaluatable(SemaRef.Context, Expr::SE_AllowSideEffects)) 8169 return SemaRef.PerformImplicitConversion( 8170 Capture->IgnoreImpCasts(), Capture->getType(), Sema::AA_Converting, 8171 /*AllowExplicit=*/true); 8172 auto I = Captures.find(Capture); 8173 if (I != Captures.end()) 8174 return buildCapture(SemaRef, Capture, I->second); 8175 DeclRefExpr *Ref = nullptr; 8176 ExprResult Res = buildCapture(SemaRef, Capture, Ref); 8177 Captures[Capture] = Ref; 8178 return Res; 8179 } 8180 8181 /// Calculate number of iterations, transforming to unsigned, if number of 8182 /// iterations may be larger than the original type. 8183 static Expr * 8184 calculateNumIters(Sema &SemaRef, Scope *S, SourceLocation DefaultLoc, 8185 Expr *Lower, Expr *Upper, Expr *Step, QualType LCTy, 8186 bool TestIsStrictOp, bool RoundToStep, 8187 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) { 8188 ExprResult NewStep = tryBuildCapture(SemaRef, Step, Captures); 8189 if (!NewStep.isUsable()) 8190 return nullptr; 8191 llvm::APSInt LRes, SRes; 8192 bool IsLowerConst = false, IsStepConst = false; 8193 if (Optional<llvm::APSInt> Res = 8194 Lower->getIntegerConstantExpr(SemaRef.Context)) { 8195 LRes = *Res; 8196 IsLowerConst = true; 8197 } 8198 if (Optional<llvm::APSInt> Res = 8199 Step->getIntegerConstantExpr(SemaRef.Context)) { 8200 SRes = *Res; 8201 IsStepConst = true; 8202 } 8203 bool NoNeedToConvert = IsLowerConst && !RoundToStep && 8204 ((!TestIsStrictOp && LRes.isNonNegative()) || 8205 (TestIsStrictOp && LRes.isStrictlyPositive())); 8206 bool NeedToReorganize = false; 8207 // Check if any subexpressions in Lower -Step [+ 1] lead to overflow. 8208 if (!NoNeedToConvert && IsLowerConst && 8209 (TestIsStrictOp || (RoundToStep && IsStepConst))) { 8210 NoNeedToConvert = true; 8211 if (RoundToStep) { 8212 unsigned BW = LRes.getBitWidth() > SRes.getBitWidth() 8213 ? LRes.getBitWidth() 8214 : SRes.getBitWidth(); 8215 LRes = LRes.extend(BW + 1); 8216 LRes.setIsSigned(true); 8217 SRes = SRes.extend(BW + 1); 8218 SRes.setIsSigned(true); 8219 LRes -= SRes; 8220 NoNeedToConvert = LRes.trunc(BW).extend(BW + 1) == LRes; 8221 LRes = LRes.trunc(BW); 8222 } 8223 if (TestIsStrictOp) { 8224 unsigned BW = LRes.getBitWidth(); 8225 LRes = LRes.extend(BW + 1); 8226 LRes.setIsSigned(true); 8227 ++LRes; 8228 NoNeedToConvert = 8229 NoNeedToConvert && LRes.trunc(BW).extend(BW + 1) == LRes; 8230 // truncate to the original bitwidth. 8231 LRes = LRes.trunc(BW); 8232 } 8233 NeedToReorganize = NoNeedToConvert; 8234 } 8235 llvm::APSInt URes; 8236 bool IsUpperConst = false; 8237 if (Optional<llvm::APSInt> Res = 8238 Upper->getIntegerConstantExpr(SemaRef.Context)) { 8239 URes = *Res; 8240 IsUpperConst = true; 8241 } 8242 if (NoNeedToConvert && IsLowerConst && IsUpperConst && 8243 (!RoundToStep || IsStepConst)) { 8244 unsigned BW = LRes.getBitWidth() > URes.getBitWidth() ? LRes.getBitWidth() 8245 : URes.getBitWidth(); 8246 LRes = LRes.extend(BW + 1); 8247 LRes.setIsSigned(true); 8248 URes = URes.extend(BW + 1); 8249 URes.setIsSigned(true); 8250 URes -= LRes; 8251 NoNeedToConvert = URes.trunc(BW).extend(BW + 1) == URes; 8252 NeedToReorganize = NoNeedToConvert; 8253 } 8254 // If the boundaries are not constant or (Lower - Step [+ 1]) is not constant 8255 // or less than zero (Upper - (Lower - Step [+ 1]) may overflow) - promote to 8256 // unsigned. 8257 if ((!NoNeedToConvert || (LRes.isNegative() && !IsUpperConst)) && 8258 !LCTy->isDependentType() && LCTy->isIntegerType()) { 8259 QualType LowerTy = Lower->getType(); 8260 QualType UpperTy = Upper->getType(); 8261 uint64_t LowerSize = SemaRef.Context.getTypeSize(LowerTy); 8262 uint64_t UpperSize = SemaRef.Context.getTypeSize(UpperTy); 8263 if ((LowerSize <= UpperSize && UpperTy->hasSignedIntegerRepresentation()) || 8264 (LowerSize > UpperSize && LowerTy->hasSignedIntegerRepresentation())) { 8265 QualType CastType = SemaRef.Context.getIntTypeForBitwidth( 8266 LowerSize > UpperSize ? LowerSize : UpperSize, /*Signed=*/0); 8267 Upper = 8268 SemaRef 8269 .PerformImplicitConversion( 8270 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Upper).get(), 8271 CastType, Sema::AA_Converting) 8272 .get(); 8273 Lower = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Lower).get(); 8274 NewStep = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, NewStep.get()); 8275 } 8276 } 8277 if (!Lower || !Upper || NewStep.isInvalid()) 8278 return nullptr; 8279 8280 ExprResult Diff; 8281 // If need to reorganize, then calculate the form as Upper - (Lower - Step [+ 8282 // 1]). 8283 if (NeedToReorganize) { 8284 Diff = Lower; 8285 8286 if (RoundToStep) { 8287 // Lower - Step 8288 Diff = 8289 SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Diff.get(), NewStep.get()); 8290 if (!Diff.isUsable()) 8291 return nullptr; 8292 } 8293 8294 // Lower - Step [+ 1] 8295 if (TestIsStrictOp) 8296 Diff = SemaRef.BuildBinOp( 8297 S, DefaultLoc, BO_Add, Diff.get(), 8298 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()); 8299 if (!Diff.isUsable()) 8300 return nullptr; 8301 8302 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get()); 8303 if (!Diff.isUsable()) 8304 return nullptr; 8305 8306 // Upper - (Lower - Step [+ 1]). 8307 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Diff.get()); 8308 if (!Diff.isUsable()) 8309 return nullptr; 8310 } else { 8311 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Lower); 8312 8313 if (!Diff.isUsable() && LCTy->getAsCXXRecordDecl()) { 8314 // BuildBinOp already emitted error, this one is to point user to upper 8315 // and lower bound, and to tell what is passed to 'operator-'. 8316 SemaRef.Diag(Upper->getBeginLoc(), diag::err_omp_loop_diff_cxx) 8317 << Upper->getSourceRange() << Lower->getSourceRange(); 8318 return nullptr; 8319 } 8320 8321 if (!Diff.isUsable()) 8322 return nullptr; 8323 8324 // Upper - Lower [- 1] 8325 if (TestIsStrictOp) 8326 Diff = SemaRef.BuildBinOp( 8327 S, DefaultLoc, BO_Sub, Diff.get(), 8328 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()); 8329 if (!Diff.isUsable()) 8330 return nullptr; 8331 8332 if (RoundToStep) { 8333 // Upper - Lower [- 1] + Step 8334 Diff = 8335 SemaRef.BuildBinOp(S, DefaultLoc, BO_Add, Diff.get(), NewStep.get()); 8336 if (!Diff.isUsable()) 8337 return nullptr; 8338 } 8339 } 8340 8341 // Parentheses (for dumping/debugging purposes only). 8342 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get()); 8343 if (!Diff.isUsable()) 8344 return nullptr; 8345 8346 // (Upper - Lower [- 1] + Step) / Step or (Upper - Lower) / Step 8347 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Div, Diff.get(), NewStep.get()); 8348 if (!Diff.isUsable()) 8349 return nullptr; 8350 8351 return Diff.get(); 8352 } 8353 8354 /// Build the expression to calculate the number of iterations. 8355 Expr *OpenMPIterationSpaceChecker::buildNumIterations( 8356 Scope *S, ArrayRef<LoopIterationSpace> ResultIterSpaces, bool LimitedType, 8357 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const { 8358 QualType VarType = LCDecl->getType().getNonReferenceType(); 8359 if (!VarType->isIntegerType() && !VarType->isPointerType() && 8360 !SemaRef.getLangOpts().CPlusPlus) 8361 return nullptr; 8362 Expr *LBVal = LB; 8363 Expr *UBVal = UB; 8364 // LB = TestIsLessOp.getValue() ? min(LB(MinVal), LB(MaxVal)) : 8365 // max(LB(MinVal), LB(MaxVal)) 8366 if (InitDependOnLC) { 8367 const LoopIterationSpace &IS = ResultIterSpaces[*InitDependOnLC - 1]; 8368 if (!IS.MinValue || !IS.MaxValue) 8369 return nullptr; 8370 // OuterVar = Min 8371 ExprResult MinValue = 8372 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MinValue); 8373 if (!MinValue.isUsable()) 8374 return nullptr; 8375 8376 ExprResult LBMinVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign, 8377 IS.CounterVar, MinValue.get()); 8378 if (!LBMinVal.isUsable()) 8379 return nullptr; 8380 // OuterVar = Min, LBVal 8381 LBMinVal = 8382 SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, LBMinVal.get(), LBVal); 8383 if (!LBMinVal.isUsable()) 8384 return nullptr; 8385 // (OuterVar = Min, LBVal) 8386 LBMinVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, LBMinVal.get()); 8387 if (!LBMinVal.isUsable()) 8388 return nullptr; 8389 8390 // OuterVar = Max 8391 ExprResult MaxValue = 8392 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MaxValue); 8393 if (!MaxValue.isUsable()) 8394 return nullptr; 8395 8396 ExprResult LBMaxVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign, 8397 IS.CounterVar, MaxValue.get()); 8398 if (!LBMaxVal.isUsable()) 8399 return nullptr; 8400 // OuterVar = Max, LBVal 8401 LBMaxVal = 8402 SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, LBMaxVal.get(), LBVal); 8403 if (!LBMaxVal.isUsable()) 8404 return nullptr; 8405 // (OuterVar = Max, LBVal) 8406 LBMaxVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, LBMaxVal.get()); 8407 if (!LBMaxVal.isUsable()) 8408 return nullptr; 8409 8410 Expr *LBMin = tryBuildCapture(SemaRef, LBMinVal.get(), Captures).get(); 8411 Expr *LBMax = tryBuildCapture(SemaRef, LBMaxVal.get(), Captures).get(); 8412 if (!LBMin || !LBMax) 8413 return nullptr; 8414 // LB(MinVal) < LB(MaxVal) 8415 ExprResult MinLessMaxRes = 8416 SemaRef.BuildBinOp(S, DefaultLoc, BO_LT, LBMin, LBMax); 8417 if (!MinLessMaxRes.isUsable()) 8418 return nullptr; 8419 Expr *MinLessMax = 8420 tryBuildCapture(SemaRef, MinLessMaxRes.get(), Captures).get(); 8421 if (!MinLessMax) 8422 return nullptr; 8423 if (TestIsLessOp.getValue()) { 8424 // LB(MinVal) < LB(MaxVal) ? LB(MinVal) : LB(MaxVal) - min(LB(MinVal), 8425 // LB(MaxVal)) 8426 ExprResult MinLB = SemaRef.ActOnConditionalOp(DefaultLoc, DefaultLoc, 8427 MinLessMax, LBMin, LBMax); 8428 if (!MinLB.isUsable()) 8429 return nullptr; 8430 LBVal = MinLB.get(); 8431 } else { 8432 // LB(MinVal) < LB(MaxVal) ? LB(MaxVal) : LB(MinVal) - max(LB(MinVal), 8433 // LB(MaxVal)) 8434 ExprResult MaxLB = SemaRef.ActOnConditionalOp(DefaultLoc, DefaultLoc, 8435 MinLessMax, LBMax, LBMin); 8436 if (!MaxLB.isUsable()) 8437 return nullptr; 8438 LBVal = MaxLB.get(); 8439 } 8440 } 8441 // UB = TestIsLessOp.getValue() ? max(UB(MinVal), UB(MaxVal)) : 8442 // min(UB(MinVal), UB(MaxVal)) 8443 if (CondDependOnLC) { 8444 const LoopIterationSpace &IS = ResultIterSpaces[*CondDependOnLC - 1]; 8445 if (!IS.MinValue || !IS.MaxValue) 8446 return nullptr; 8447 // OuterVar = Min 8448 ExprResult MinValue = 8449 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MinValue); 8450 if (!MinValue.isUsable()) 8451 return nullptr; 8452 8453 ExprResult UBMinVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign, 8454 IS.CounterVar, MinValue.get()); 8455 if (!UBMinVal.isUsable()) 8456 return nullptr; 8457 // OuterVar = Min, UBVal 8458 UBMinVal = 8459 SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, UBMinVal.get(), UBVal); 8460 if (!UBMinVal.isUsable()) 8461 return nullptr; 8462 // (OuterVar = Min, UBVal) 8463 UBMinVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, UBMinVal.get()); 8464 if (!UBMinVal.isUsable()) 8465 return nullptr; 8466 8467 // OuterVar = Max 8468 ExprResult MaxValue = 8469 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MaxValue); 8470 if (!MaxValue.isUsable()) 8471 return nullptr; 8472 8473 ExprResult UBMaxVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign, 8474 IS.CounterVar, MaxValue.get()); 8475 if (!UBMaxVal.isUsable()) 8476 return nullptr; 8477 // OuterVar = Max, UBVal 8478 UBMaxVal = 8479 SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, UBMaxVal.get(), UBVal); 8480 if (!UBMaxVal.isUsable()) 8481 return nullptr; 8482 // (OuterVar = Max, UBVal) 8483 UBMaxVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, UBMaxVal.get()); 8484 if (!UBMaxVal.isUsable()) 8485 return nullptr; 8486 8487 Expr *UBMin = tryBuildCapture(SemaRef, UBMinVal.get(), Captures).get(); 8488 Expr *UBMax = tryBuildCapture(SemaRef, UBMaxVal.get(), Captures).get(); 8489 if (!UBMin || !UBMax) 8490 return nullptr; 8491 // UB(MinVal) > UB(MaxVal) 8492 ExprResult MinGreaterMaxRes = 8493 SemaRef.BuildBinOp(S, DefaultLoc, BO_GT, UBMin, UBMax); 8494 if (!MinGreaterMaxRes.isUsable()) 8495 return nullptr; 8496 Expr *MinGreaterMax = 8497 tryBuildCapture(SemaRef, MinGreaterMaxRes.get(), Captures).get(); 8498 if (!MinGreaterMax) 8499 return nullptr; 8500 if (TestIsLessOp.getValue()) { 8501 // UB(MinVal) > UB(MaxVal) ? UB(MinVal) : UB(MaxVal) - max(UB(MinVal), 8502 // UB(MaxVal)) 8503 ExprResult MaxUB = SemaRef.ActOnConditionalOp( 8504 DefaultLoc, DefaultLoc, MinGreaterMax, UBMin, UBMax); 8505 if (!MaxUB.isUsable()) 8506 return nullptr; 8507 UBVal = MaxUB.get(); 8508 } else { 8509 // UB(MinVal) > UB(MaxVal) ? UB(MaxVal) : UB(MinVal) - min(UB(MinVal), 8510 // UB(MaxVal)) 8511 ExprResult MinUB = SemaRef.ActOnConditionalOp( 8512 DefaultLoc, DefaultLoc, MinGreaterMax, UBMax, UBMin); 8513 if (!MinUB.isUsable()) 8514 return nullptr; 8515 UBVal = MinUB.get(); 8516 } 8517 } 8518 Expr *UBExpr = TestIsLessOp.getValue() ? UBVal : LBVal; 8519 Expr *LBExpr = TestIsLessOp.getValue() ? LBVal : UBVal; 8520 Expr *Upper = tryBuildCapture(SemaRef, UBExpr, Captures).get(); 8521 Expr *Lower = tryBuildCapture(SemaRef, LBExpr, Captures).get(); 8522 if (!Upper || !Lower) 8523 return nullptr; 8524 8525 ExprResult Diff = calculateNumIters(SemaRef, S, DefaultLoc, Lower, Upper, 8526 Step, VarType, TestIsStrictOp, 8527 /*RoundToStep=*/true, Captures); 8528 if (!Diff.isUsable()) 8529 return nullptr; 8530 8531 // OpenMP runtime requires 32-bit or 64-bit loop variables. 8532 QualType Type = Diff.get()->getType(); 8533 ASTContext &C = SemaRef.Context; 8534 bool UseVarType = VarType->hasIntegerRepresentation() && 8535 C.getTypeSize(Type) > C.getTypeSize(VarType); 8536 if (!Type->isIntegerType() || UseVarType) { 8537 unsigned NewSize = 8538 UseVarType ? C.getTypeSize(VarType) : C.getTypeSize(Type); 8539 bool IsSigned = UseVarType ? VarType->hasSignedIntegerRepresentation() 8540 : Type->hasSignedIntegerRepresentation(); 8541 Type = C.getIntTypeForBitwidth(NewSize, IsSigned); 8542 if (!SemaRef.Context.hasSameType(Diff.get()->getType(), Type)) { 8543 Diff = SemaRef.PerformImplicitConversion( 8544 Diff.get(), Type, Sema::AA_Converting, /*AllowExplicit=*/true); 8545 if (!Diff.isUsable()) 8546 return nullptr; 8547 } 8548 } 8549 if (LimitedType) { 8550 unsigned NewSize = (C.getTypeSize(Type) > 32) ? 64 : 32; 8551 if (NewSize != C.getTypeSize(Type)) { 8552 if (NewSize < C.getTypeSize(Type)) { 8553 assert(NewSize == 64 && "incorrect loop var size"); 8554 SemaRef.Diag(DefaultLoc, diag::warn_omp_loop_64_bit_var) 8555 << InitSrcRange << ConditionSrcRange; 8556 } 8557 QualType NewType = C.getIntTypeForBitwidth( 8558 NewSize, Type->hasSignedIntegerRepresentation() || 8559 C.getTypeSize(Type) < NewSize); 8560 if (!SemaRef.Context.hasSameType(Diff.get()->getType(), NewType)) { 8561 Diff = SemaRef.PerformImplicitConversion(Diff.get(), NewType, 8562 Sema::AA_Converting, true); 8563 if (!Diff.isUsable()) 8564 return nullptr; 8565 } 8566 } 8567 } 8568 8569 return Diff.get(); 8570 } 8571 8572 std::pair<Expr *, Expr *> OpenMPIterationSpaceChecker::buildMinMaxValues( 8573 Scope *S, llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const { 8574 // Do not build for iterators, they cannot be used in non-rectangular loop 8575 // nests. 8576 if (LCDecl->getType()->isRecordType()) 8577 return std::make_pair(nullptr, nullptr); 8578 // If we subtract, the min is in the condition, otherwise the min is in the 8579 // init value. 8580 Expr *MinExpr = nullptr; 8581 Expr *MaxExpr = nullptr; 8582 Expr *LBExpr = TestIsLessOp.getValue() ? LB : UB; 8583 Expr *UBExpr = TestIsLessOp.getValue() ? UB : LB; 8584 bool LBNonRect = TestIsLessOp.getValue() ? InitDependOnLC.hasValue() 8585 : CondDependOnLC.hasValue(); 8586 bool UBNonRect = TestIsLessOp.getValue() ? CondDependOnLC.hasValue() 8587 : InitDependOnLC.hasValue(); 8588 Expr *Lower = 8589 LBNonRect ? LBExpr : tryBuildCapture(SemaRef, LBExpr, Captures).get(); 8590 Expr *Upper = 8591 UBNonRect ? UBExpr : tryBuildCapture(SemaRef, UBExpr, Captures).get(); 8592 if (!Upper || !Lower) 8593 return std::make_pair(nullptr, nullptr); 8594 8595 if (TestIsLessOp.getValue()) 8596 MinExpr = Lower; 8597 else 8598 MaxExpr = Upper; 8599 8600 // Build minimum/maximum value based on number of iterations. 8601 QualType VarType = LCDecl->getType().getNonReferenceType(); 8602 8603 ExprResult Diff = calculateNumIters(SemaRef, S, DefaultLoc, Lower, Upper, 8604 Step, VarType, TestIsStrictOp, 8605 /*RoundToStep=*/false, Captures); 8606 if (!Diff.isUsable()) 8607 return std::make_pair(nullptr, nullptr); 8608 8609 // ((Upper - Lower [- 1]) / Step) * Step 8610 // Parentheses (for dumping/debugging purposes only). 8611 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get()); 8612 if (!Diff.isUsable()) 8613 return std::make_pair(nullptr, nullptr); 8614 8615 ExprResult NewStep = tryBuildCapture(SemaRef, Step, Captures); 8616 if (!NewStep.isUsable()) 8617 return std::make_pair(nullptr, nullptr); 8618 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Mul, Diff.get(), NewStep.get()); 8619 if (!Diff.isUsable()) 8620 return std::make_pair(nullptr, nullptr); 8621 8622 // Parentheses (for dumping/debugging purposes only). 8623 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get()); 8624 if (!Diff.isUsable()) 8625 return std::make_pair(nullptr, nullptr); 8626 8627 // Convert to the ptrdiff_t, if original type is pointer. 8628 if (VarType->isAnyPointerType() && 8629 !SemaRef.Context.hasSameType( 8630 Diff.get()->getType(), 8631 SemaRef.Context.getUnsignedPointerDiffType())) { 8632 Diff = SemaRef.PerformImplicitConversion( 8633 Diff.get(), SemaRef.Context.getUnsignedPointerDiffType(), 8634 Sema::AA_Converting, /*AllowExplicit=*/true); 8635 } 8636 if (!Diff.isUsable()) 8637 return std::make_pair(nullptr, nullptr); 8638 8639 if (TestIsLessOp.getValue()) { 8640 // MinExpr = Lower; 8641 // MaxExpr = Lower + (((Upper - Lower [- 1]) / Step) * Step) 8642 Diff = SemaRef.BuildBinOp( 8643 S, DefaultLoc, BO_Add, 8644 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Lower).get(), 8645 Diff.get()); 8646 if (!Diff.isUsable()) 8647 return std::make_pair(nullptr, nullptr); 8648 } else { 8649 // MaxExpr = Upper; 8650 // MinExpr = Upper - (((Upper - Lower [- 1]) / Step) * Step) 8651 Diff = SemaRef.BuildBinOp( 8652 S, DefaultLoc, BO_Sub, 8653 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Upper).get(), 8654 Diff.get()); 8655 if (!Diff.isUsable()) 8656 return std::make_pair(nullptr, nullptr); 8657 } 8658 8659 // Convert to the original type. 8660 if (SemaRef.Context.hasSameType(Diff.get()->getType(), VarType)) 8661 Diff = SemaRef.PerformImplicitConversion(Diff.get(), VarType, 8662 Sema::AA_Converting, 8663 /*AllowExplicit=*/true); 8664 if (!Diff.isUsable()) 8665 return std::make_pair(nullptr, nullptr); 8666 8667 Sema::TentativeAnalysisScope Trap(SemaRef); 8668 Diff = SemaRef.ActOnFinishFullExpr(Diff.get(), /*DiscardedValue=*/false); 8669 if (!Diff.isUsable()) 8670 return std::make_pair(nullptr, nullptr); 8671 8672 if (TestIsLessOp.getValue()) 8673 MaxExpr = Diff.get(); 8674 else 8675 MinExpr = Diff.get(); 8676 8677 return std::make_pair(MinExpr, MaxExpr); 8678 } 8679 8680 Expr *OpenMPIterationSpaceChecker::buildFinalCondition(Scope *S) const { 8681 if (InitDependOnLC || CondDependOnLC) 8682 return Condition; 8683 return nullptr; 8684 } 8685 8686 Expr *OpenMPIterationSpaceChecker::buildPreCond( 8687 Scope *S, Expr *Cond, 8688 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const { 8689 // Do not build a precondition when the condition/initialization is dependent 8690 // to prevent pessimistic early loop exit. 8691 // TODO: this can be improved by calculating min/max values but not sure that 8692 // it will be very effective. 8693 if (CondDependOnLC || InitDependOnLC) 8694 return SemaRef 8695 .PerformImplicitConversion( 8696 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get(), 8697 SemaRef.Context.BoolTy, /*Action=*/Sema::AA_Casting, 8698 /*AllowExplicit=*/true) 8699 .get(); 8700 8701 // Try to build LB <op> UB, where <op> is <, >, <=, or >=. 8702 Sema::TentativeAnalysisScope Trap(SemaRef); 8703 8704 ExprResult NewLB = tryBuildCapture(SemaRef, LB, Captures); 8705 ExprResult NewUB = tryBuildCapture(SemaRef, UB, Captures); 8706 if (!NewLB.isUsable() || !NewUB.isUsable()) 8707 return nullptr; 8708 8709 ExprResult CondExpr = SemaRef.BuildBinOp( 8710 S, DefaultLoc, 8711 TestIsLessOp.getValue() ? (TestIsStrictOp ? BO_LT : BO_LE) 8712 : (TestIsStrictOp ? BO_GT : BO_GE), 8713 NewLB.get(), NewUB.get()); 8714 if (CondExpr.isUsable()) { 8715 if (!SemaRef.Context.hasSameUnqualifiedType(CondExpr.get()->getType(), 8716 SemaRef.Context.BoolTy)) 8717 CondExpr = SemaRef.PerformImplicitConversion( 8718 CondExpr.get(), SemaRef.Context.BoolTy, /*Action=*/Sema::AA_Casting, 8719 /*AllowExplicit=*/true); 8720 } 8721 8722 // Otherwise use original loop condition and evaluate it in runtime. 8723 return CondExpr.isUsable() ? CondExpr.get() : Cond; 8724 } 8725 8726 /// Build reference expression to the counter be used for codegen. 8727 DeclRefExpr *OpenMPIterationSpaceChecker::buildCounterVar( 8728 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures, 8729 DSAStackTy &DSA) const { 8730 auto *VD = dyn_cast<VarDecl>(LCDecl); 8731 if (!VD) { 8732 VD = SemaRef.isOpenMPCapturedDecl(LCDecl); 8733 DeclRefExpr *Ref = buildDeclRefExpr( 8734 SemaRef, VD, VD->getType().getNonReferenceType(), DefaultLoc); 8735 const DSAStackTy::DSAVarData Data = 8736 DSA.getTopDSA(LCDecl, /*FromParent=*/false); 8737 // If the loop control decl is explicitly marked as private, do not mark it 8738 // as captured again. 8739 if (!isOpenMPPrivate(Data.CKind) || !Data.RefExpr) 8740 Captures.insert(std::make_pair(LCRef, Ref)); 8741 return Ref; 8742 } 8743 return cast<DeclRefExpr>(LCRef); 8744 } 8745 8746 Expr *OpenMPIterationSpaceChecker::buildPrivateCounterVar() const { 8747 if (LCDecl && !LCDecl->isInvalidDecl()) { 8748 QualType Type = LCDecl->getType().getNonReferenceType(); 8749 VarDecl *PrivateVar = buildVarDecl( 8750 SemaRef, DefaultLoc, Type, LCDecl->getName(), 8751 LCDecl->hasAttrs() ? &LCDecl->getAttrs() : nullptr, 8752 isa<VarDecl>(LCDecl) 8753 ? buildDeclRefExpr(SemaRef, cast<VarDecl>(LCDecl), Type, DefaultLoc) 8754 : nullptr); 8755 if (PrivateVar->isInvalidDecl()) 8756 return nullptr; 8757 return buildDeclRefExpr(SemaRef, PrivateVar, Type, DefaultLoc); 8758 } 8759 return nullptr; 8760 } 8761 8762 /// Build initialization of the counter to be used for codegen. 8763 Expr *OpenMPIterationSpaceChecker::buildCounterInit() const { return LB; } 8764 8765 /// Build step of the counter be used for codegen. 8766 Expr *OpenMPIterationSpaceChecker::buildCounterStep() const { return Step; } 8767 8768 Expr *OpenMPIterationSpaceChecker::buildOrderedLoopData( 8769 Scope *S, Expr *Counter, 8770 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures, SourceLocation Loc, 8771 Expr *Inc, OverloadedOperatorKind OOK) { 8772 Expr *Cnt = SemaRef.DefaultLvalueConversion(Counter).get(); 8773 if (!Cnt) 8774 return nullptr; 8775 if (Inc) { 8776 assert((OOK == OO_Plus || OOK == OO_Minus) && 8777 "Expected only + or - operations for depend clauses."); 8778 BinaryOperatorKind BOK = (OOK == OO_Plus) ? BO_Add : BO_Sub; 8779 Cnt = SemaRef.BuildBinOp(S, Loc, BOK, Cnt, Inc).get(); 8780 if (!Cnt) 8781 return nullptr; 8782 } 8783 QualType VarType = LCDecl->getType().getNonReferenceType(); 8784 if (!VarType->isIntegerType() && !VarType->isPointerType() && 8785 !SemaRef.getLangOpts().CPlusPlus) 8786 return nullptr; 8787 // Upper - Lower 8788 Expr *Upper = TestIsLessOp.getValue() 8789 ? Cnt 8790 : tryBuildCapture(SemaRef, LB, Captures).get(); 8791 Expr *Lower = TestIsLessOp.getValue() 8792 ? tryBuildCapture(SemaRef, LB, Captures).get() 8793 : Cnt; 8794 if (!Upper || !Lower) 8795 return nullptr; 8796 8797 ExprResult Diff = calculateNumIters( 8798 SemaRef, S, DefaultLoc, Lower, Upper, Step, VarType, 8799 /*TestIsStrictOp=*/false, /*RoundToStep=*/false, Captures); 8800 if (!Diff.isUsable()) 8801 return nullptr; 8802 8803 return Diff.get(); 8804 } 8805 } // namespace 8806 8807 void Sema::ActOnOpenMPLoopInitialization(SourceLocation ForLoc, Stmt *Init) { 8808 assert(getLangOpts().OpenMP && "OpenMP is not active."); 8809 assert(Init && "Expected loop in canonical form."); 8810 unsigned AssociatedLoops = DSAStack->getAssociatedLoops(); 8811 if (AssociatedLoops > 0 && 8812 isOpenMPLoopDirective(DSAStack->getCurrentDirective())) { 8813 DSAStack->loopStart(); 8814 OpenMPIterationSpaceChecker ISC(*this, /*SupportsNonRectangular=*/true, 8815 *DSAStack, ForLoc); 8816 if (!ISC.checkAndSetInit(Init, /*EmitDiags=*/false)) { 8817 if (ValueDecl *D = ISC.getLoopDecl()) { 8818 auto *VD = dyn_cast<VarDecl>(D); 8819 DeclRefExpr *PrivateRef = nullptr; 8820 if (!VD) { 8821 if (VarDecl *Private = isOpenMPCapturedDecl(D)) { 8822 VD = Private; 8823 } else { 8824 PrivateRef = buildCapture(*this, D, ISC.getLoopDeclRefExpr(), 8825 /*WithInit=*/false); 8826 VD = cast<VarDecl>(PrivateRef->getDecl()); 8827 } 8828 } 8829 DSAStack->addLoopControlVariable(D, VD); 8830 const Decl *LD = DSAStack->getPossiblyLoopCunter(); 8831 if (LD != D->getCanonicalDecl()) { 8832 DSAStack->resetPossibleLoopCounter(); 8833 if (auto *Var = dyn_cast_or_null<VarDecl>(LD)) 8834 MarkDeclarationsReferencedInExpr( 8835 buildDeclRefExpr(*this, const_cast<VarDecl *>(Var), 8836 Var->getType().getNonLValueExprType(Context), 8837 ForLoc, /*RefersToCapture=*/true)); 8838 } 8839 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 8840 // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables 8841 // Referenced in a Construct, C/C++]. The loop iteration variable in the 8842 // associated for-loop of a simd construct with just one associated 8843 // for-loop may be listed in a linear clause with a constant-linear-step 8844 // that is the increment of the associated for-loop. The loop iteration 8845 // variable(s) in the associated for-loop(s) of a for or parallel for 8846 // construct may be listed in a private or lastprivate clause. 8847 DSAStackTy::DSAVarData DVar = 8848 DSAStack->getTopDSA(D, /*FromParent=*/false); 8849 // If LoopVarRefExpr is nullptr it means the corresponding loop variable 8850 // is declared in the loop and it is predetermined as a private. 8851 Expr *LoopDeclRefExpr = ISC.getLoopDeclRefExpr(); 8852 OpenMPClauseKind PredeterminedCKind = 8853 isOpenMPSimdDirective(DKind) 8854 ? (DSAStack->hasMutipleLoops() ? OMPC_lastprivate : OMPC_linear) 8855 : OMPC_private; 8856 if (((isOpenMPSimdDirective(DKind) && DVar.CKind != OMPC_unknown && 8857 DVar.CKind != PredeterminedCKind && DVar.RefExpr && 8858 (LangOpts.OpenMP <= 45 || (DVar.CKind != OMPC_lastprivate && 8859 DVar.CKind != OMPC_private))) || 8860 ((isOpenMPWorksharingDirective(DKind) || DKind == OMPD_taskloop || 8861 DKind == OMPD_master_taskloop || 8862 DKind == OMPD_parallel_master_taskloop || 8863 isOpenMPDistributeDirective(DKind)) && 8864 !isOpenMPSimdDirective(DKind) && DVar.CKind != OMPC_unknown && 8865 DVar.CKind != OMPC_private && DVar.CKind != OMPC_lastprivate)) && 8866 (DVar.CKind != OMPC_private || DVar.RefExpr)) { 8867 Diag(Init->getBeginLoc(), diag::err_omp_loop_var_dsa) 8868 << getOpenMPClauseName(DVar.CKind) 8869 << getOpenMPDirectiveName(DKind) 8870 << getOpenMPClauseName(PredeterminedCKind); 8871 if (DVar.RefExpr == nullptr) 8872 DVar.CKind = PredeterminedCKind; 8873 reportOriginalDsa(*this, DSAStack, D, DVar, 8874 /*IsLoopIterVar=*/true); 8875 } else if (LoopDeclRefExpr) { 8876 // Make the loop iteration variable private (for worksharing 8877 // constructs), linear (for simd directives with the only one 8878 // associated loop) or lastprivate (for simd directives with several 8879 // collapsed or ordered loops). 8880 if (DVar.CKind == OMPC_unknown) 8881 DSAStack->addDSA(D, LoopDeclRefExpr, PredeterminedCKind, 8882 PrivateRef); 8883 } 8884 } 8885 } 8886 DSAStack->setAssociatedLoops(AssociatedLoops - 1); 8887 } 8888 } 8889 8890 /// Called on a for stmt to check and extract its iteration space 8891 /// for further processing (such as collapsing). 8892 static bool checkOpenMPIterationSpace( 8893 OpenMPDirectiveKind DKind, Stmt *S, Sema &SemaRef, DSAStackTy &DSA, 8894 unsigned CurrentNestedLoopCount, unsigned NestedLoopCount, 8895 unsigned TotalNestedLoopCount, Expr *CollapseLoopCountExpr, 8896 Expr *OrderedLoopCountExpr, 8897 Sema::VarsWithInheritedDSAType &VarsWithImplicitDSA, 8898 llvm::MutableArrayRef<LoopIterationSpace> ResultIterSpaces, 8899 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) { 8900 bool SupportsNonRectangular = !isOpenMPLoopTransformationDirective(DKind); 8901 // OpenMP [2.9.1, Canonical Loop Form] 8902 // for (init-expr; test-expr; incr-expr) structured-block 8903 // for (range-decl: range-expr) structured-block 8904 if (auto *CanonLoop = dyn_cast_or_null<OMPCanonicalLoop>(S)) 8905 S = CanonLoop->getLoopStmt(); 8906 auto *For = dyn_cast_or_null<ForStmt>(S); 8907 auto *CXXFor = dyn_cast_or_null<CXXForRangeStmt>(S); 8908 // Ranged for is supported only in OpenMP 5.0. 8909 if (!For && (SemaRef.LangOpts.OpenMP <= 45 || !CXXFor)) { 8910 SemaRef.Diag(S->getBeginLoc(), diag::err_omp_not_for) 8911 << (CollapseLoopCountExpr != nullptr || OrderedLoopCountExpr != nullptr) 8912 << getOpenMPDirectiveName(DKind) << TotalNestedLoopCount 8913 << (CurrentNestedLoopCount > 0) << CurrentNestedLoopCount; 8914 if (TotalNestedLoopCount > 1) { 8915 if (CollapseLoopCountExpr && OrderedLoopCountExpr) 8916 SemaRef.Diag(DSA.getConstructLoc(), 8917 diag::note_omp_collapse_ordered_expr) 8918 << 2 << CollapseLoopCountExpr->getSourceRange() 8919 << OrderedLoopCountExpr->getSourceRange(); 8920 else if (CollapseLoopCountExpr) 8921 SemaRef.Diag(CollapseLoopCountExpr->getExprLoc(), 8922 diag::note_omp_collapse_ordered_expr) 8923 << 0 << CollapseLoopCountExpr->getSourceRange(); 8924 else 8925 SemaRef.Diag(OrderedLoopCountExpr->getExprLoc(), 8926 diag::note_omp_collapse_ordered_expr) 8927 << 1 << OrderedLoopCountExpr->getSourceRange(); 8928 } 8929 return true; 8930 } 8931 assert(((For && For->getBody()) || (CXXFor && CXXFor->getBody())) && 8932 "No loop body."); 8933 // Postpone analysis in dependent contexts for ranged for loops. 8934 if (CXXFor && SemaRef.CurContext->isDependentContext()) 8935 return false; 8936 8937 OpenMPIterationSpaceChecker ISC(SemaRef, SupportsNonRectangular, DSA, 8938 For ? For->getForLoc() : CXXFor->getForLoc()); 8939 8940 // Check init. 8941 Stmt *Init = For ? For->getInit() : CXXFor->getBeginStmt(); 8942 if (ISC.checkAndSetInit(Init)) 8943 return true; 8944 8945 bool HasErrors = false; 8946 8947 // Check loop variable's type. 8948 if (ValueDecl *LCDecl = ISC.getLoopDecl()) { 8949 // OpenMP [2.6, Canonical Loop Form] 8950 // Var is one of the following: 8951 // A variable of signed or unsigned integer type. 8952 // For C++, a variable of a random access iterator type. 8953 // For C, a variable of a pointer type. 8954 QualType VarType = LCDecl->getType().getNonReferenceType(); 8955 if (!VarType->isDependentType() && !VarType->isIntegerType() && 8956 !VarType->isPointerType() && 8957 !(SemaRef.getLangOpts().CPlusPlus && VarType->isOverloadableType())) { 8958 SemaRef.Diag(Init->getBeginLoc(), diag::err_omp_loop_variable_type) 8959 << SemaRef.getLangOpts().CPlusPlus; 8960 HasErrors = true; 8961 } 8962 8963 // OpenMP, 2.14.1.1 Data-sharing Attribute Rules for Variables Referenced in 8964 // a Construct 8965 // The loop iteration variable(s) in the associated for-loop(s) of a for or 8966 // parallel for construct is (are) private. 8967 // The loop iteration variable in the associated for-loop of a simd 8968 // construct with just one associated for-loop is linear with a 8969 // constant-linear-step that is the increment of the associated for-loop. 8970 // Exclude loop var from the list of variables with implicitly defined data 8971 // sharing attributes. 8972 VarsWithImplicitDSA.erase(LCDecl); 8973 8974 assert(isOpenMPLoopDirective(DKind) && "DSA for non-loop vars"); 8975 8976 // Check test-expr. 8977 HasErrors |= ISC.checkAndSetCond(For ? For->getCond() : CXXFor->getCond()); 8978 8979 // Check incr-expr. 8980 HasErrors |= ISC.checkAndSetInc(For ? For->getInc() : CXXFor->getInc()); 8981 } 8982 8983 if (ISC.dependent() || SemaRef.CurContext->isDependentContext() || HasErrors) 8984 return HasErrors; 8985 8986 // Build the loop's iteration space representation. 8987 ResultIterSpaces[CurrentNestedLoopCount].PreCond = ISC.buildPreCond( 8988 DSA.getCurScope(), For ? For->getCond() : CXXFor->getCond(), Captures); 8989 ResultIterSpaces[CurrentNestedLoopCount].NumIterations = 8990 ISC.buildNumIterations(DSA.getCurScope(), ResultIterSpaces, 8991 (isOpenMPWorksharingDirective(DKind) || 8992 isOpenMPGenericLoopDirective(DKind) || 8993 isOpenMPTaskLoopDirective(DKind) || 8994 isOpenMPDistributeDirective(DKind) || 8995 isOpenMPLoopTransformationDirective(DKind)), 8996 Captures); 8997 ResultIterSpaces[CurrentNestedLoopCount].CounterVar = 8998 ISC.buildCounterVar(Captures, DSA); 8999 ResultIterSpaces[CurrentNestedLoopCount].PrivateCounterVar = 9000 ISC.buildPrivateCounterVar(); 9001 ResultIterSpaces[CurrentNestedLoopCount].CounterInit = ISC.buildCounterInit(); 9002 ResultIterSpaces[CurrentNestedLoopCount].CounterStep = ISC.buildCounterStep(); 9003 ResultIterSpaces[CurrentNestedLoopCount].InitSrcRange = ISC.getInitSrcRange(); 9004 ResultIterSpaces[CurrentNestedLoopCount].CondSrcRange = 9005 ISC.getConditionSrcRange(); 9006 ResultIterSpaces[CurrentNestedLoopCount].IncSrcRange = 9007 ISC.getIncrementSrcRange(); 9008 ResultIterSpaces[CurrentNestedLoopCount].Subtract = ISC.shouldSubtractStep(); 9009 ResultIterSpaces[CurrentNestedLoopCount].IsStrictCompare = 9010 ISC.isStrictTestOp(); 9011 std::tie(ResultIterSpaces[CurrentNestedLoopCount].MinValue, 9012 ResultIterSpaces[CurrentNestedLoopCount].MaxValue) = 9013 ISC.buildMinMaxValues(DSA.getCurScope(), Captures); 9014 ResultIterSpaces[CurrentNestedLoopCount].FinalCondition = 9015 ISC.buildFinalCondition(DSA.getCurScope()); 9016 ResultIterSpaces[CurrentNestedLoopCount].IsNonRectangularLB = 9017 ISC.doesInitDependOnLC(); 9018 ResultIterSpaces[CurrentNestedLoopCount].IsNonRectangularUB = 9019 ISC.doesCondDependOnLC(); 9020 ResultIterSpaces[CurrentNestedLoopCount].LoopDependentIdx = 9021 ISC.getLoopDependentIdx(); 9022 9023 HasErrors |= 9024 (ResultIterSpaces[CurrentNestedLoopCount].PreCond == nullptr || 9025 ResultIterSpaces[CurrentNestedLoopCount].NumIterations == nullptr || 9026 ResultIterSpaces[CurrentNestedLoopCount].CounterVar == nullptr || 9027 ResultIterSpaces[CurrentNestedLoopCount].PrivateCounterVar == nullptr || 9028 ResultIterSpaces[CurrentNestedLoopCount].CounterInit == nullptr || 9029 ResultIterSpaces[CurrentNestedLoopCount].CounterStep == nullptr); 9030 if (!HasErrors && DSA.isOrderedRegion()) { 9031 if (DSA.getOrderedRegionParam().second->getNumForLoops()) { 9032 if (CurrentNestedLoopCount < 9033 DSA.getOrderedRegionParam().second->getLoopNumIterations().size()) { 9034 DSA.getOrderedRegionParam().second->setLoopNumIterations( 9035 CurrentNestedLoopCount, 9036 ResultIterSpaces[CurrentNestedLoopCount].NumIterations); 9037 DSA.getOrderedRegionParam().second->setLoopCounter( 9038 CurrentNestedLoopCount, 9039 ResultIterSpaces[CurrentNestedLoopCount].CounterVar); 9040 } 9041 } 9042 for (auto &Pair : DSA.getDoacrossDependClauses()) { 9043 if (CurrentNestedLoopCount >= Pair.first->getNumLoops()) { 9044 // Erroneous case - clause has some problems. 9045 continue; 9046 } 9047 if (Pair.first->getDependencyKind() == OMPC_DEPEND_sink && 9048 Pair.second.size() <= CurrentNestedLoopCount) { 9049 // Erroneous case - clause has some problems. 9050 Pair.first->setLoopData(CurrentNestedLoopCount, nullptr); 9051 continue; 9052 } 9053 Expr *CntValue; 9054 if (Pair.first->getDependencyKind() == OMPC_DEPEND_source) 9055 CntValue = ISC.buildOrderedLoopData( 9056 DSA.getCurScope(), 9057 ResultIterSpaces[CurrentNestedLoopCount].CounterVar, Captures, 9058 Pair.first->getDependencyLoc()); 9059 else 9060 CntValue = ISC.buildOrderedLoopData( 9061 DSA.getCurScope(), 9062 ResultIterSpaces[CurrentNestedLoopCount].CounterVar, Captures, 9063 Pair.first->getDependencyLoc(), 9064 Pair.second[CurrentNestedLoopCount].first, 9065 Pair.second[CurrentNestedLoopCount].second); 9066 Pair.first->setLoopData(CurrentNestedLoopCount, CntValue); 9067 } 9068 } 9069 9070 return HasErrors; 9071 } 9072 9073 /// Build 'VarRef = Start. 9074 static ExprResult 9075 buildCounterInit(Sema &SemaRef, Scope *S, SourceLocation Loc, ExprResult VarRef, 9076 ExprResult Start, bool IsNonRectangularLB, 9077 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) { 9078 // Build 'VarRef = Start. 9079 ExprResult NewStart = IsNonRectangularLB 9080 ? Start.get() 9081 : tryBuildCapture(SemaRef, Start.get(), Captures); 9082 if (!NewStart.isUsable()) 9083 return ExprError(); 9084 if (!SemaRef.Context.hasSameType(NewStart.get()->getType(), 9085 VarRef.get()->getType())) { 9086 NewStart = SemaRef.PerformImplicitConversion( 9087 NewStart.get(), VarRef.get()->getType(), Sema::AA_Converting, 9088 /*AllowExplicit=*/true); 9089 if (!NewStart.isUsable()) 9090 return ExprError(); 9091 } 9092 9093 ExprResult Init = 9094 SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), NewStart.get()); 9095 return Init; 9096 } 9097 9098 /// Build 'VarRef = Start + Iter * Step'. 9099 static ExprResult buildCounterUpdate( 9100 Sema &SemaRef, Scope *S, SourceLocation Loc, ExprResult VarRef, 9101 ExprResult Start, ExprResult Iter, ExprResult Step, bool Subtract, 9102 bool IsNonRectangularLB, 9103 llvm::MapVector<const Expr *, DeclRefExpr *> *Captures = nullptr) { 9104 // Add parentheses (for debugging purposes only). 9105 Iter = SemaRef.ActOnParenExpr(Loc, Loc, Iter.get()); 9106 if (!VarRef.isUsable() || !Start.isUsable() || !Iter.isUsable() || 9107 !Step.isUsable()) 9108 return ExprError(); 9109 9110 ExprResult NewStep = Step; 9111 if (Captures) 9112 NewStep = tryBuildCapture(SemaRef, Step.get(), *Captures); 9113 if (NewStep.isInvalid()) 9114 return ExprError(); 9115 ExprResult Update = 9116 SemaRef.BuildBinOp(S, Loc, BO_Mul, Iter.get(), NewStep.get()); 9117 if (!Update.isUsable()) 9118 return ExprError(); 9119 9120 // Try to build 'VarRef = Start, VarRef (+|-)= Iter * Step' or 9121 // 'VarRef = Start (+|-) Iter * Step'. 9122 if (!Start.isUsable()) 9123 return ExprError(); 9124 ExprResult NewStart = SemaRef.ActOnParenExpr(Loc, Loc, Start.get()); 9125 if (!NewStart.isUsable()) 9126 return ExprError(); 9127 if (Captures && !IsNonRectangularLB) 9128 NewStart = tryBuildCapture(SemaRef, Start.get(), *Captures); 9129 if (NewStart.isInvalid()) 9130 return ExprError(); 9131 9132 // First attempt: try to build 'VarRef = Start, VarRef += Iter * Step'. 9133 ExprResult SavedUpdate = Update; 9134 ExprResult UpdateVal; 9135 if (VarRef.get()->getType()->isOverloadableType() || 9136 NewStart.get()->getType()->isOverloadableType() || 9137 Update.get()->getType()->isOverloadableType()) { 9138 Sema::TentativeAnalysisScope Trap(SemaRef); 9139 9140 Update = 9141 SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), NewStart.get()); 9142 if (Update.isUsable()) { 9143 UpdateVal = 9144 SemaRef.BuildBinOp(S, Loc, Subtract ? BO_SubAssign : BO_AddAssign, 9145 VarRef.get(), SavedUpdate.get()); 9146 if (UpdateVal.isUsable()) { 9147 Update = SemaRef.CreateBuiltinBinOp(Loc, BO_Comma, Update.get(), 9148 UpdateVal.get()); 9149 } 9150 } 9151 } 9152 9153 // Second attempt: try to build 'VarRef = Start (+|-) Iter * Step'. 9154 if (!Update.isUsable() || !UpdateVal.isUsable()) { 9155 Update = SemaRef.BuildBinOp(S, Loc, Subtract ? BO_Sub : BO_Add, 9156 NewStart.get(), SavedUpdate.get()); 9157 if (!Update.isUsable()) 9158 return ExprError(); 9159 9160 if (!SemaRef.Context.hasSameType(Update.get()->getType(), 9161 VarRef.get()->getType())) { 9162 Update = SemaRef.PerformImplicitConversion( 9163 Update.get(), VarRef.get()->getType(), Sema::AA_Converting, true); 9164 if (!Update.isUsable()) 9165 return ExprError(); 9166 } 9167 9168 Update = SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), Update.get()); 9169 } 9170 return Update; 9171 } 9172 9173 /// Convert integer expression \a E to make it have at least \a Bits 9174 /// bits. 9175 static ExprResult widenIterationCount(unsigned Bits, Expr *E, Sema &SemaRef) { 9176 if (E == nullptr) 9177 return ExprError(); 9178 ASTContext &C = SemaRef.Context; 9179 QualType OldType = E->getType(); 9180 unsigned HasBits = C.getTypeSize(OldType); 9181 if (HasBits >= Bits) 9182 return ExprResult(E); 9183 // OK to convert to signed, because new type has more bits than old. 9184 QualType NewType = C.getIntTypeForBitwidth(Bits, /* Signed */ true); 9185 return SemaRef.PerformImplicitConversion(E, NewType, Sema::AA_Converting, 9186 true); 9187 } 9188 9189 /// Check if the given expression \a E is a constant integer that fits 9190 /// into \a Bits bits. 9191 static bool fitsInto(unsigned Bits, bool Signed, const Expr *E, Sema &SemaRef) { 9192 if (E == nullptr) 9193 return false; 9194 if (Optional<llvm::APSInt> Result = 9195 E->getIntegerConstantExpr(SemaRef.Context)) 9196 return Signed ? Result->isSignedIntN(Bits) : Result->isIntN(Bits); 9197 return false; 9198 } 9199 9200 /// Build preinits statement for the given declarations. 9201 static Stmt *buildPreInits(ASTContext &Context, 9202 MutableArrayRef<Decl *> PreInits) { 9203 if (!PreInits.empty()) { 9204 return new (Context) DeclStmt( 9205 DeclGroupRef::Create(Context, PreInits.begin(), PreInits.size()), 9206 SourceLocation(), SourceLocation()); 9207 } 9208 return nullptr; 9209 } 9210 9211 /// Build preinits statement for the given declarations. 9212 static Stmt * 9213 buildPreInits(ASTContext &Context, 9214 const llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) { 9215 if (!Captures.empty()) { 9216 SmallVector<Decl *, 16> PreInits; 9217 for (const auto &Pair : Captures) 9218 PreInits.push_back(Pair.second->getDecl()); 9219 return buildPreInits(Context, PreInits); 9220 } 9221 return nullptr; 9222 } 9223 9224 /// Build postupdate expression for the given list of postupdates expressions. 9225 static Expr *buildPostUpdate(Sema &S, ArrayRef<Expr *> PostUpdates) { 9226 Expr *PostUpdate = nullptr; 9227 if (!PostUpdates.empty()) { 9228 for (Expr *E : PostUpdates) { 9229 Expr *ConvE = S.BuildCStyleCastExpr( 9230 E->getExprLoc(), 9231 S.Context.getTrivialTypeSourceInfo(S.Context.VoidTy), 9232 E->getExprLoc(), E) 9233 .get(); 9234 PostUpdate = PostUpdate 9235 ? S.CreateBuiltinBinOp(ConvE->getExprLoc(), BO_Comma, 9236 PostUpdate, ConvE) 9237 .get() 9238 : ConvE; 9239 } 9240 } 9241 return PostUpdate; 9242 } 9243 9244 /// Called on a for stmt to check itself and nested loops (if any). 9245 /// \return Returns 0 if one of the collapsed stmts is not canonical for loop, 9246 /// number of collapsed loops otherwise. 9247 static unsigned 9248 checkOpenMPLoop(OpenMPDirectiveKind DKind, Expr *CollapseLoopCountExpr, 9249 Expr *OrderedLoopCountExpr, Stmt *AStmt, Sema &SemaRef, 9250 DSAStackTy &DSA, 9251 Sema::VarsWithInheritedDSAType &VarsWithImplicitDSA, 9252 OMPLoopBasedDirective::HelperExprs &Built) { 9253 unsigned NestedLoopCount = 1; 9254 bool SupportsNonPerfectlyNested = (SemaRef.LangOpts.OpenMP >= 50) && 9255 !isOpenMPLoopTransformationDirective(DKind); 9256 9257 if (CollapseLoopCountExpr) { 9258 // Found 'collapse' clause - calculate collapse number. 9259 Expr::EvalResult Result; 9260 if (!CollapseLoopCountExpr->isValueDependent() && 9261 CollapseLoopCountExpr->EvaluateAsInt(Result, SemaRef.getASTContext())) { 9262 NestedLoopCount = Result.Val.getInt().getLimitedValue(); 9263 } else { 9264 Built.clear(/*Size=*/1); 9265 return 1; 9266 } 9267 } 9268 unsigned OrderedLoopCount = 1; 9269 if (OrderedLoopCountExpr) { 9270 // Found 'ordered' clause - calculate collapse number. 9271 Expr::EvalResult EVResult; 9272 if (!OrderedLoopCountExpr->isValueDependent() && 9273 OrderedLoopCountExpr->EvaluateAsInt(EVResult, 9274 SemaRef.getASTContext())) { 9275 llvm::APSInt Result = EVResult.Val.getInt(); 9276 if (Result.getLimitedValue() < NestedLoopCount) { 9277 SemaRef.Diag(OrderedLoopCountExpr->getExprLoc(), 9278 diag::err_omp_wrong_ordered_loop_count) 9279 << OrderedLoopCountExpr->getSourceRange(); 9280 SemaRef.Diag(CollapseLoopCountExpr->getExprLoc(), 9281 diag::note_collapse_loop_count) 9282 << CollapseLoopCountExpr->getSourceRange(); 9283 } 9284 OrderedLoopCount = Result.getLimitedValue(); 9285 } else { 9286 Built.clear(/*Size=*/1); 9287 return 1; 9288 } 9289 } 9290 // This is helper routine for loop directives (e.g., 'for', 'simd', 9291 // 'for simd', etc.). 9292 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 9293 unsigned NumLoops = std::max(OrderedLoopCount, NestedLoopCount); 9294 SmallVector<LoopIterationSpace, 4> IterSpaces(NumLoops); 9295 if (!OMPLoopBasedDirective::doForAllLoops( 9296 AStmt->IgnoreContainers(!isOpenMPLoopTransformationDirective(DKind)), 9297 SupportsNonPerfectlyNested, NumLoops, 9298 [DKind, &SemaRef, &DSA, NumLoops, NestedLoopCount, 9299 CollapseLoopCountExpr, OrderedLoopCountExpr, &VarsWithImplicitDSA, 9300 &IterSpaces, &Captures](unsigned Cnt, Stmt *CurStmt) { 9301 if (checkOpenMPIterationSpace( 9302 DKind, CurStmt, SemaRef, DSA, Cnt, NestedLoopCount, 9303 NumLoops, CollapseLoopCountExpr, OrderedLoopCountExpr, 9304 VarsWithImplicitDSA, IterSpaces, Captures)) 9305 return true; 9306 if (Cnt > 0 && Cnt >= NestedLoopCount && 9307 IterSpaces[Cnt].CounterVar) { 9308 // Handle initialization of captured loop iterator variables. 9309 auto *DRE = cast<DeclRefExpr>(IterSpaces[Cnt].CounterVar); 9310 if (isa<OMPCapturedExprDecl>(DRE->getDecl())) { 9311 Captures[DRE] = DRE; 9312 } 9313 } 9314 return false; 9315 }, 9316 [&SemaRef, &Captures](OMPLoopTransformationDirective *Transform) { 9317 Stmt *DependentPreInits = Transform->getPreInits(); 9318 if (!DependentPreInits) 9319 return; 9320 for (Decl *C : cast<DeclStmt>(DependentPreInits)->getDeclGroup()) { 9321 auto *D = cast<VarDecl>(C); 9322 DeclRefExpr *Ref = buildDeclRefExpr(SemaRef, D, D->getType(), 9323 Transform->getBeginLoc()); 9324 Captures[Ref] = Ref; 9325 } 9326 })) 9327 return 0; 9328 9329 Built.clear(/* size */ NestedLoopCount); 9330 9331 if (SemaRef.CurContext->isDependentContext()) 9332 return NestedLoopCount; 9333 9334 // An example of what is generated for the following code: 9335 // 9336 // #pragma omp simd collapse(2) ordered(2) 9337 // for (i = 0; i < NI; ++i) 9338 // for (k = 0; k < NK; ++k) 9339 // for (j = J0; j < NJ; j+=2) { 9340 // <loop body> 9341 // } 9342 // 9343 // We generate the code below. 9344 // Note: the loop body may be outlined in CodeGen. 9345 // Note: some counters may be C++ classes, operator- is used to find number of 9346 // iterations and operator+= to calculate counter value. 9347 // Note: decltype(NumIterations) must be integer type (in 'omp for', only i32 9348 // or i64 is currently supported). 9349 // 9350 // #define NumIterations (NI * ((NJ - J0 - 1 + 2) / 2)) 9351 // for (int[32|64]_t IV = 0; IV < NumIterations; ++IV ) { 9352 // .local.i = IV / ((NJ - J0 - 1 + 2) / 2); 9353 // .local.j = J0 + (IV % ((NJ - J0 - 1 + 2) / 2)) * 2; 9354 // // similar updates for vars in clauses (e.g. 'linear') 9355 // <loop body (using local i and j)> 9356 // } 9357 // i = NI; // assign final values of counters 9358 // j = NJ; 9359 // 9360 9361 // Last iteration number is (I1 * I2 * ... In) - 1, where I1, I2 ... In are 9362 // the iteration counts of the collapsed for loops. 9363 // Precondition tests if there is at least one iteration (all conditions are 9364 // true). 9365 auto PreCond = ExprResult(IterSpaces[0].PreCond); 9366 Expr *N0 = IterSpaces[0].NumIterations; 9367 ExprResult LastIteration32 = 9368 widenIterationCount(/*Bits=*/32, 9369 SemaRef 9370 .PerformImplicitConversion( 9371 N0->IgnoreImpCasts(), N0->getType(), 9372 Sema::AA_Converting, /*AllowExplicit=*/true) 9373 .get(), 9374 SemaRef); 9375 ExprResult LastIteration64 = widenIterationCount( 9376 /*Bits=*/64, 9377 SemaRef 9378 .PerformImplicitConversion(N0->IgnoreImpCasts(), N0->getType(), 9379 Sema::AA_Converting, 9380 /*AllowExplicit=*/true) 9381 .get(), 9382 SemaRef); 9383 9384 if (!LastIteration32.isUsable() || !LastIteration64.isUsable()) 9385 return NestedLoopCount; 9386 9387 ASTContext &C = SemaRef.Context; 9388 bool AllCountsNeedLessThan32Bits = C.getTypeSize(N0->getType()) < 32; 9389 9390 Scope *CurScope = DSA.getCurScope(); 9391 for (unsigned Cnt = 1; Cnt < NestedLoopCount; ++Cnt) { 9392 if (PreCond.isUsable()) { 9393 PreCond = 9394 SemaRef.BuildBinOp(CurScope, PreCond.get()->getExprLoc(), BO_LAnd, 9395 PreCond.get(), IterSpaces[Cnt].PreCond); 9396 } 9397 Expr *N = IterSpaces[Cnt].NumIterations; 9398 SourceLocation Loc = N->getExprLoc(); 9399 AllCountsNeedLessThan32Bits &= C.getTypeSize(N->getType()) < 32; 9400 if (LastIteration32.isUsable()) 9401 LastIteration32 = SemaRef.BuildBinOp( 9402 CurScope, Loc, BO_Mul, LastIteration32.get(), 9403 SemaRef 9404 .PerformImplicitConversion(N->IgnoreImpCasts(), N->getType(), 9405 Sema::AA_Converting, 9406 /*AllowExplicit=*/true) 9407 .get()); 9408 if (LastIteration64.isUsable()) 9409 LastIteration64 = SemaRef.BuildBinOp( 9410 CurScope, Loc, BO_Mul, LastIteration64.get(), 9411 SemaRef 9412 .PerformImplicitConversion(N->IgnoreImpCasts(), N->getType(), 9413 Sema::AA_Converting, 9414 /*AllowExplicit=*/true) 9415 .get()); 9416 } 9417 9418 // Choose either the 32-bit or 64-bit version. 9419 ExprResult LastIteration = LastIteration64; 9420 if (SemaRef.getLangOpts().OpenMPOptimisticCollapse || 9421 (LastIteration32.isUsable() && 9422 C.getTypeSize(LastIteration32.get()->getType()) == 32 && 9423 (AllCountsNeedLessThan32Bits || NestedLoopCount == 1 || 9424 fitsInto( 9425 /*Bits=*/32, 9426 LastIteration32.get()->getType()->hasSignedIntegerRepresentation(), 9427 LastIteration64.get(), SemaRef)))) 9428 LastIteration = LastIteration32; 9429 QualType VType = LastIteration.get()->getType(); 9430 QualType RealVType = VType; 9431 QualType StrideVType = VType; 9432 if (isOpenMPTaskLoopDirective(DKind)) { 9433 VType = 9434 SemaRef.Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/0); 9435 StrideVType = 9436 SemaRef.Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/1); 9437 } 9438 9439 if (!LastIteration.isUsable()) 9440 return 0; 9441 9442 // Save the number of iterations. 9443 ExprResult NumIterations = LastIteration; 9444 { 9445 LastIteration = SemaRef.BuildBinOp( 9446 CurScope, LastIteration.get()->getExprLoc(), BO_Sub, 9447 LastIteration.get(), 9448 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()); 9449 if (!LastIteration.isUsable()) 9450 return 0; 9451 } 9452 9453 // Calculate the last iteration number beforehand instead of doing this on 9454 // each iteration. Do not do this if the number of iterations may be kfold-ed. 9455 bool IsConstant = LastIteration.get()->isIntegerConstantExpr(SemaRef.Context); 9456 ExprResult CalcLastIteration; 9457 if (!IsConstant) { 9458 ExprResult SaveRef = 9459 tryBuildCapture(SemaRef, LastIteration.get(), Captures); 9460 LastIteration = SaveRef; 9461 9462 // Prepare SaveRef + 1. 9463 NumIterations = SemaRef.BuildBinOp( 9464 CurScope, SaveRef.get()->getExprLoc(), BO_Add, SaveRef.get(), 9465 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()); 9466 if (!NumIterations.isUsable()) 9467 return 0; 9468 } 9469 9470 SourceLocation InitLoc = IterSpaces[0].InitSrcRange.getBegin(); 9471 9472 // Build variables passed into runtime, necessary for worksharing directives. 9473 ExprResult LB, UB, IL, ST, EUB, CombLB, CombUB, PrevLB, PrevUB, CombEUB; 9474 if (isOpenMPWorksharingDirective(DKind) || isOpenMPTaskLoopDirective(DKind) || 9475 isOpenMPDistributeDirective(DKind) || 9476 isOpenMPGenericLoopDirective(DKind) || 9477 isOpenMPLoopTransformationDirective(DKind)) { 9478 // Lower bound variable, initialized with zero. 9479 VarDecl *LBDecl = buildVarDecl(SemaRef, InitLoc, VType, ".omp.lb"); 9480 LB = buildDeclRefExpr(SemaRef, LBDecl, VType, InitLoc); 9481 SemaRef.AddInitializerToDecl(LBDecl, 9482 SemaRef.ActOnIntegerConstant(InitLoc, 0).get(), 9483 /*DirectInit*/ false); 9484 9485 // Upper bound variable, initialized with last iteration number. 9486 VarDecl *UBDecl = buildVarDecl(SemaRef, InitLoc, VType, ".omp.ub"); 9487 UB = buildDeclRefExpr(SemaRef, UBDecl, VType, InitLoc); 9488 SemaRef.AddInitializerToDecl(UBDecl, LastIteration.get(), 9489 /*DirectInit*/ false); 9490 9491 // A 32-bit variable-flag where runtime returns 1 for the last iteration. 9492 // This will be used to implement clause 'lastprivate'. 9493 QualType Int32Ty = SemaRef.Context.getIntTypeForBitwidth(32, true); 9494 VarDecl *ILDecl = buildVarDecl(SemaRef, InitLoc, Int32Ty, ".omp.is_last"); 9495 IL = buildDeclRefExpr(SemaRef, ILDecl, Int32Ty, InitLoc); 9496 SemaRef.AddInitializerToDecl(ILDecl, 9497 SemaRef.ActOnIntegerConstant(InitLoc, 0).get(), 9498 /*DirectInit*/ false); 9499 9500 // Stride variable returned by runtime (we initialize it to 1 by default). 9501 VarDecl *STDecl = 9502 buildVarDecl(SemaRef, InitLoc, StrideVType, ".omp.stride"); 9503 ST = buildDeclRefExpr(SemaRef, STDecl, StrideVType, InitLoc); 9504 SemaRef.AddInitializerToDecl(STDecl, 9505 SemaRef.ActOnIntegerConstant(InitLoc, 1).get(), 9506 /*DirectInit*/ false); 9507 9508 // Build expression: UB = min(UB, LastIteration) 9509 // It is necessary for CodeGen of directives with static scheduling. 9510 ExprResult IsUBGreater = SemaRef.BuildBinOp(CurScope, InitLoc, BO_GT, 9511 UB.get(), LastIteration.get()); 9512 ExprResult CondOp = SemaRef.ActOnConditionalOp( 9513 LastIteration.get()->getExprLoc(), InitLoc, IsUBGreater.get(), 9514 LastIteration.get(), UB.get()); 9515 EUB = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, UB.get(), 9516 CondOp.get()); 9517 EUB = SemaRef.ActOnFinishFullExpr(EUB.get(), /*DiscardedValue*/ false); 9518 9519 // If we have a combined directive that combines 'distribute', 'for' or 9520 // 'simd' we need to be able to access the bounds of the schedule of the 9521 // enclosing region. E.g. in 'distribute parallel for' the bounds obtained 9522 // by scheduling 'distribute' have to be passed to the schedule of 'for'. 9523 if (isOpenMPLoopBoundSharingDirective(DKind)) { 9524 // Lower bound variable, initialized with zero. 9525 VarDecl *CombLBDecl = 9526 buildVarDecl(SemaRef, InitLoc, VType, ".omp.comb.lb"); 9527 CombLB = buildDeclRefExpr(SemaRef, CombLBDecl, VType, InitLoc); 9528 SemaRef.AddInitializerToDecl( 9529 CombLBDecl, SemaRef.ActOnIntegerConstant(InitLoc, 0).get(), 9530 /*DirectInit*/ false); 9531 9532 // Upper bound variable, initialized with last iteration number. 9533 VarDecl *CombUBDecl = 9534 buildVarDecl(SemaRef, InitLoc, VType, ".omp.comb.ub"); 9535 CombUB = buildDeclRefExpr(SemaRef, CombUBDecl, VType, InitLoc); 9536 SemaRef.AddInitializerToDecl(CombUBDecl, LastIteration.get(), 9537 /*DirectInit*/ false); 9538 9539 ExprResult CombIsUBGreater = SemaRef.BuildBinOp( 9540 CurScope, InitLoc, BO_GT, CombUB.get(), LastIteration.get()); 9541 ExprResult CombCondOp = 9542 SemaRef.ActOnConditionalOp(InitLoc, InitLoc, CombIsUBGreater.get(), 9543 LastIteration.get(), CombUB.get()); 9544 CombEUB = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, CombUB.get(), 9545 CombCondOp.get()); 9546 CombEUB = 9547 SemaRef.ActOnFinishFullExpr(CombEUB.get(), /*DiscardedValue*/ false); 9548 9549 const CapturedDecl *CD = cast<CapturedStmt>(AStmt)->getCapturedDecl(); 9550 // We expect to have at least 2 more parameters than the 'parallel' 9551 // directive does - the lower and upper bounds of the previous schedule. 9552 assert(CD->getNumParams() >= 4 && 9553 "Unexpected number of parameters in loop combined directive"); 9554 9555 // Set the proper type for the bounds given what we learned from the 9556 // enclosed loops. 9557 ImplicitParamDecl *PrevLBDecl = CD->getParam(/*PrevLB=*/2); 9558 ImplicitParamDecl *PrevUBDecl = CD->getParam(/*PrevUB=*/3); 9559 9560 // Previous lower and upper bounds are obtained from the region 9561 // parameters. 9562 PrevLB = 9563 buildDeclRefExpr(SemaRef, PrevLBDecl, PrevLBDecl->getType(), InitLoc); 9564 PrevUB = 9565 buildDeclRefExpr(SemaRef, PrevUBDecl, PrevUBDecl->getType(), InitLoc); 9566 } 9567 } 9568 9569 // Build the iteration variable and its initialization before loop. 9570 ExprResult IV; 9571 ExprResult Init, CombInit; 9572 { 9573 VarDecl *IVDecl = buildVarDecl(SemaRef, InitLoc, RealVType, ".omp.iv"); 9574 IV = buildDeclRefExpr(SemaRef, IVDecl, RealVType, InitLoc); 9575 Expr *RHS = (isOpenMPWorksharingDirective(DKind) || 9576 isOpenMPGenericLoopDirective(DKind) || 9577 isOpenMPTaskLoopDirective(DKind) || 9578 isOpenMPDistributeDirective(DKind) || 9579 isOpenMPLoopTransformationDirective(DKind)) 9580 ? LB.get() 9581 : SemaRef.ActOnIntegerConstant(SourceLocation(), 0).get(); 9582 Init = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, IV.get(), RHS); 9583 Init = SemaRef.ActOnFinishFullExpr(Init.get(), /*DiscardedValue*/ false); 9584 9585 if (isOpenMPLoopBoundSharingDirective(DKind)) { 9586 Expr *CombRHS = 9587 (isOpenMPWorksharingDirective(DKind) || 9588 isOpenMPGenericLoopDirective(DKind) || 9589 isOpenMPTaskLoopDirective(DKind) || 9590 isOpenMPDistributeDirective(DKind)) 9591 ? CombLB.get() 9592 : SemaRef.ActOnIntegerConstant(SourceLocation(), 0).get(); 9593 CombInit = 9594 SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, IV.get(), CombRHS); 9595 CombInit = 9596 SemaRef.ActOnFinishFullExpr(CombInit.get(), /*DiscardedValue*/ false); 9597 } 9598 } 9599 9600 bool UseStrictCompare = 9601 RealVType->hasUnsignedIntegerRepresentation() && 9602 llvm::all_of(IterSpaces, [](const LoopIterationSpace &LIS) { 9603 return LIS.IsStrictCompare; 9604 }); 9605 // Loop condition (IV < NumIterations) or (IV <= UB or IV < UB + 1 (for 9606 // unsigned IV)) for worksharing loops. 9607 SourceLocation CondLoc = AStmt->getBeginLoc(); 9608 Expr *BoundUB = UB.get(); 9609 if (UseStrictCompare) { 9610 BoundUB = 9611 SemaRef 9612 .BuildBinOp(CurScope, CondLoc, BO_Add, BoundUB, 9613 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()) 9614 .get(); 9615 BoundUB = 9616 SemaRef.ActOnFinishFullExpr(BoundUB, /*DiscardedValue*/ false).get(); 9617 } 9618 ExprResult Cond = 9619 (isOpenMPWorksharingDirective(DKind) || 9620 isOpenMPGenericLoopDirective(DKind) || 9621 isOpenMPTaskLoopDirective(DKind) || isOpenMPDistributeDirective(DKind) || 9622 isOpenMPLoopTransformationDirective(DKind)) 9623 ? SemaRef.BuildBinOp(CurScope, CondLoc, 9624 UseStrictCompare ? BO_LT : BO_LE, IV.get(), 9625 BoundUB) 9626 : SemaRef.BuildBinOp(CurScope, CondLoc, BO_LT, IV.get(), 9627 NumIterations.get()); 9628 ExprResult CombDistCond; 9629 if (isOpenMPLoopBoundSharingDirective(DKind)) { 9630 CombDistCond = SemaRef.BuildBinOp(CurScope, CondLoc, BO_LT, IV.get(), 9631 NumIterations.get()); 9632 } 9633 9634 ExprResult CombCond; 9635 if (isOpenMPLoopBoundSharingDirective(DKind)) { 9636 Expr *BoundCombUB = CombUB.get(); 9637 if (UseStrictCompare) { 9638 BoundCombUB = 9639 SemaRef 9640 .BuildBinOp( 9641 CurScope, CondLoc, BO_Add, BoundCombUB, 9642 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()) 9643 .get(); 9644 BoundCombUB = 9645 SemaRef.ActOnFinishFullExpr(BoundCombUB, /*DiscardedValue*/ false) 9646 .get(); 9647 } 9648 CombCond = 9649 SemaRef.BuildBinOp(CurScope, CondLoc, UseStrictCompare ? BO_LT : BO_LE, 9650 IV.get(), BoundCombUB); 9651 } 9652 // Loop increment (IV = IV + 1) 9653 SourceLocation IncLoc = AStmt->getBeginLoc(); 9654 ExprResult Inc = 9655 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, IV.get(), 9656 SemaRef.ActOnIntegerConstant(IncLoc, 1).get()); 9657 if (!Inc.isUsable()) 9658 return 0; 9659 Inc = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, IV.get(), Inc.get()); 9660 Inc = SemaRef.ActOnFinishFullExpr(Inc.get(), /*DiscardedValue*/ false); 9661 if (!Inc.isUsable()) 9662 return 0; 9663 9664 // Increments for worksharing loops (LB = LB + ST; UB = UB + ST). 9665 // Used for directives with static scheduling. 9666 // In combined construct, add combined version that use CombLB and CombUB 9667 // base variables for the update 9668 ExprResult NextLB, NextUB, CombNextLB, CombNextUB; 9669 if (isOpenMPWorksharingDirective(DKind) || isOpenMPTaskLoopDirective(DKind) || 9670 isOpenMPGenericLoopDirective(DKind) || 9671 isOpenMPDistributeDirective(DKind) || 9672 isOpenMPLoopTransformationDirective(DKind)) { 9673 // LB + ST 9674 NextLB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, LB.get(), ST.get()); 9675 if (!NextLB.isUsable()) 9676 return 0; 9677 // LB = LB + ST 9678 NextLB = 9679 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, LB.get(), NextLB.get()); 9680 NextLB = 9681 SemaRef.ActOnFinishFullExpr(NextLB.get(), /*DiscardedValue*/ false); 9682 if (!NextLB.isUsable()) 9683 return 0; 9684 // UB + ST 9685 NextUB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, UB.get(), ST.get()); 9686 if (!NextUB.isUsable()) 9687 return 0; 9688 // UB = UB + ST 9689 NextUB = 9690 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, UB.get(), NextUB.get()); 9691 NextUB = 9692 SemaRef.ActOnFinishFullExpr(NextUB.get(), /*DiscardedValue*/ false); 9693 if (!NextUB.isUsable()) 9694 return 0; 9695 if (isOpenMPLoopBoundSharingDirective(DKind)) { 9696 CombNextLB = 9697 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, CombLB.get(), ST.get()); 9698 if (!NextLB.isUsable()) 9699 return 0; 9700 // LB = LB + ST 9701 CombNextLB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, CombLB.get(), 9702 CombNextLB.get()); 9703 CombNextLB = SemaRef.ActOnFinishFullExpr(CombNextLB.get(), 9704 /*DiscardedValue*/ false); 9705 if (!CombNextLB.isUsable()) 9706 return 0; 9707 // UB + ST 9708 CombNextUB = 9709 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, CombUB.get(), ST.get()); 9710 if (!CombNextUB.isUsable()) 9711 return 0; 9712 // UB = UB + ST 9713 CombNextUB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, CombUB.get(), 9714 CombNextUB.get()); 9715 CombNextUB = SemaRef.ActOnFinishFullExpr(CombNextUB.get(), 9716 /*DiscardedValue*/ false); 9717 if (!CombNextUB.isUsable()) 9718 return 0; 9719 } 9720 } 9721 9722 // Create increment expression for distribute loop when combined in a same 9723 // directive with for as IV = IV + ST; ensure upper bound expression based 9724 // on PrevUB instead of NumIterations - used to implement 'for' when found 9725 // in combination with 'distribute', like in 'distribute parallel for' 9726 SourceLocation DistIncLoc = AStmt->getBeginLoc(); 9727 ExprResult DistCond, DistInc, PrevEUB, ParForInDistCond; 9728 if (isOpenMPLoopBoundSharingDirective(DKind)) { 9729 DistCond = SemaRef.BuildBinOp( 9730 CurScope, CondLoc, UseStrictCompare ? BO_LT : BO_LE, IV.get(), BoundUB); 9731 assert(DistCond.isUsable() && "distribute cond expr was not built"); 9732 9733 DistInc = 9734 SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Add, IV.get(), ST.get()); 9735 assert(DistInc.isUsable() && "distribute inc expr was not built"); 9736 DistInc = SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Assign, IV.get(), 9737 DistInc.get()); 9738 DistInc = 9739 SemaRef.ActOnFinishFullExpr(DistInc.get(), /*DiscardedValue*/ false); 9740 assert(DistInc.isUsable() && "distribute inc expr was not built"); 9741 9742 // Build expression: UB = min(UB, prevUB) for #for in composite or combined 9743 // construct 9744 ExprResult NewPrevUB = PrevUB; 9745 SourceLocation DistEUBLoc = AStmt->getBeginLoc(); 9746 if (!SemaRef.Context.hasSameType(UB.get()->getType(), 9747 PrevUB.get()->getType())) { 9748 NewPrevUB = SemaRef.BuildCStyleCastExpr( 9749 DistEUBLoc, 9750 SemaRef.Context.getTrivialTypeSourceInfo(UB.get()->getType()), 9751 DistEUBLoc, NewPrevUB.get()); 9752 if (!NewPrevUB.isUsable()) 9753 return 0; 9754 } 9755 ExprResult IsUBGreater = SemaRef.BuildBinOp(CurScope, DistEUBLoc, BO_GT, 9756 UB.get(), NewPrevUB.get()); 9757 ExprResult CondOp = SemaRef.ActOnConditionalOp( 9758 DistEUBLoc, DistEUBLoc, IsUBGreater.get(), NewPrevUB.get(), UB.get()); 9759 PrevEUB = SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Assign, UB.get(), 9760 CondOp.get()); 9761 PrevEUB = 9762 SemaRef.ActOnFinishFullExpr(PrevEUB.get(), /*DiscardedValue*/ false); 9763 9764 // Build IV <= PrevUB or IV < PrevUB + 1 for unsigned IV to be used in 9765 // parallel for is in combination with a distribute directive with 9766 // schedule(static, 1) 9767 Expr *BoundPrevUB = PrevUB.get(); 9768 if (UseStrictCompare) { 9769 BoundPrevUB = 9770 SemaRef 9771 .BuildBinOp( 9772 CurScope, CondLoc, BO_Add, BoundPrevUB, 9773 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()) 9774 .get(); 9775 BoundPrevUB = 9776 SemaRef.ActOnFinishFullExpr(BoundPrevUB, /*DiscardedValue*/ false) 9777 .get(); 9778 } 9779 ParForInDistCond = 9780 SemaRef.BuildBinOp(CurScope, CondLoc, UseStrictCompare ? BO_LT : BO_LE, 9781 IV.get(), BoundPrevUB); 9782 } 9783 9784 // Build updates and final values of the loop counters. 9785 bool HasErrors = false; 9786 Built.Counters.resize(NestedLoopCount); 9787 Built.Inits.resize(NestedLoopCount); 9788 Built.Updates.resize(NestedLoopCount); 9789 Built.Finals.resize(NestedLoopCount); 9790 Built.DependentCounters.resize(NestedLoopCount); 9791 Built.DependentInits.resize(NestedLoopCount); 9792 Built.FinalsConditions.resize(NestedLoopCount); 9793 { 9794 // We implement the following algorithm for obtaining the 9795 // original loop iteration variable values based on the 9796 // value of the collapsed loop iteration variable IV. 9797 // 9798 // Let n+1 be the number of collapsed loops in the nest. 9799 // Iteration variables (I0, I1, .... In) 9800 // Iteration counts (N0, N1, ... Nn) 9801 // 9802 // Acc = IV; 9803 // 9804 // To compute Ik for loop k, 0 <= k <= n, generate: 9805 // Prod = N(k+1) * N(k+2) * ... * Nn; 9806 // Ik = Acc / Prod; 9807 // Acc -= Ik * Prod; 9808 // 9809 ExprResult Acc = IV; 9810 for (unsigned int Cnt = 0; Cnt < NestedLoopCount; ++Cnt) { 9811 LoopIterationSpace &IS = IterSpaces[Cnt]; 9812 SourceLocation UpdLoc = IS.IncSrcRange.getBegin(); 9813 ExprResult Iter; 9814 9815 // Compute prod 9816 ExprResult Prod = SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get(); 9817 for (unsigned int K = Cnt + 1; K < NestedLoopCount; ++K) 9818 Prod = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Mul, Prod.get(), 9819 IterSpaces[K].NumIterations); 9820 9821 // Iter = Acc / Prod 9822 // If there is at least one more inner loop to avoid 9823 // multiplication by 1. 9824 if (Cnt + 1 < NestedLoopCount) 9825 Iter = 9826 SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Div, Acc.get(), Prod.get()); 9827 else 9828 Iter = Acc; 9829 if (!Iter.isUsable()) { 9830 HasErrors = true; 9831 break; 9832 } 9833 9834 // Update Acc: 9835 // Acc -= Iter * Prod 9836 // Check if there is at least one more inner loop to avoid 9837 // multiplication by 1. 9838 if (Cnt + 1 < NestedLoopCount) 9839 Prod = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Mul, Iter.get(), 9840 Prod.get()); 9841 else 9842 Prod = Iter; 9843 Acc = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Sub, Acc.get(), Prod.get()); 9844 9845 // Build update: IS.CounterVar(Private) = IS.Start + Iter * IS.Step 9846 auto *VD = cast<VarDecl>(cast<DeclRefExpr>(IS.CounterVar)->getDecl()); 9847 DeclRefExpr *CounterVar = buildDeclRefExpr( 9848 SemaRef, VD, IS.CounterVar->getType(), IS.CounterVar->getExprLoc(), 9849 /*RefersToCapture=*/true); 9850 ExprResult Init = 9851 buildCounterInit(SemaRef, CurScope, UpdLoc, CounterVar, 9852 IS.CounterInit, IS.IsNonRectangularLB, Captures); 9853 if (!Init.isUsable()) { 9854 HasErrors = true; 9855 break; 9856 } 9857 ExprResult Update = buildCounterUpdate( 9858 SemaRef, CurScope, UpdLoc, CounterVar, IS.CounterInit, Iter, 9859 IS.CounterStep, IS.Subtract, IS.IsNonRectangularLB, &Captures); 9860 if (!Update.isUsable()) { 9861 HasErrors = true; 9862 break; 9863 } 9864 9865 // Build final: IS.CounterVar = IS.Start + IS.NumIters * IS.Step 9866 ExprResult Final = 9867 buildCounterUpdate(SemaRef, CurScope, UpdLoc, CounterVar, 9868 IS.CounterInit, IS.NumIterations, IS.CounterStep, 9869 IS.Subtract, IS.IsNonRectangularLB, &Captures); 9870 if (!Final.isUsable()) { 9871 HasErrors = true; 9872 break; 9873 } 9874 9875 if (!Update.isUsable() || !Final.isUsable()) { 9876 HasErrors = true; 9877 break; 9878 } 9879 // Save results 9880 Built.Counters[Cnt] = IS.CounterVar; 9881 Built.PrivateCounters[Cnt] = IS.PrivateCounterVar; 9882 Built.Inits[Cnt] = Init.get(); 9883 Built.Updates[Cnt] = Update.get(); 9884 Built.Finals[Cnt] = Final.get(); 9885 Built.DependentCounters[Cnt] = nullptr; 9886 Built.DependentInits[Cnt] = nullptr; 9887 Built.FinalsConditions[Cnt] = nullptr; 9888 if (IS.IsNonRectangularLB || IS.IsNonRectangularUB) { 9889 Built.DependentCounters[Cnt] = 9890 Built.Counters[NestedLoopCount - 1 - IS.LoopDependentIdx]; 9891 Built.DependentInits[Cnt] = 9892 Built.Inits[NestedLoopCount - 1 - IS.LoopDependentIdx]; 9893 Built.FinalsConditions[Cnt] = IS.FinalCondition; 9894 } 9895 } 9896 } 9897 9898 if (HasErrors) 9899 return 0; 9900 9901 // Save results 9902 Built.IterationVarRef = IV.get(); 9903 Built.LastIteration = LastIteration.get(); 9904 Built.NumIterations = NumIterations.get(); 9905 Built.CalcLastIteration = SemaRef 9906 .ActOnFinishFullExpr(CalcLastIteration.get(), 9907 /*DiscardedValue=*/false) 9908 .get(); 9909 Built.PreCond = PreCond.get(); 9910 Built.PreInits = buildPreInits(C, Captures); 9911 Built.Cond = Cond.get(); 9912 Built.Init = Init.get(); 9913 Built.Inc = Inc.get(); 9914 Built.LB = LB.get(); 9915 Built.UB = UB.get(); 9916 Built.IL = IL.get(); 9917 Built.ST = ST.get(); 9918 Built.EUB = EUB.get(); 9919 Built.NLB = NextLB.get(); 9920 Built.NUB = NextUB.get(); 9921 Built.PrevLB = PrevLB.get(); 9922 Built.PrevUB = PrevUB.get(); 9923 Built.DistInc = DistInc.get(); 9924 Built.PrevEUB = PrevEUB.get(); 9925 Built.DistCombinedFields.LB = CombLB.get(); 9926 Built.DistCombinedFields.UB = CombUB.get(); 9927 Built.DistCombinedFields.EUB = CombEUB.get(); 9928 Built.DistCombinedFields.Init = CombInit.get(); 9929 Built.DistCombinedFields.Cond = CombCond.get(); 9930 Built.DistCombinedFields.NLB = CombNextLB.get(); 9931 Built.DistCombinedFields.NUB = CombNextUB.get(); 9932 Built.DistCombinedFields.DistCond = CombDistCond.get(); 9933 Built.DistCombinedFields.ParForInDistCond = ParForInDistCond.get(); 9934 9935 return NestedLoopCount; 9936 } 9937 9938 static Expr *getCollapseNumberExpr(ArrayRef<OMPClause *> Clauses) { 9939 auto CollapseClauses = 9940 OMPExecutableDirective::getClausesOfKind<OMPCollapseClause>(Clauses); 9941 if (CollapseClauses.begin() != CollapseClauses.end()) 9942 return (*CollapseClauses.begin())->getNumForLoops(); 9943 return nullptr; 9944 } 9945 9946 static Expr *getOrderedNumberExpr(ArrayRef<OMPClause *> Clauses) { 9947 auto OrderedClauses = 9948 OMPExecutableDirective::getClausesOfKind<OMPOrderedClause>(Clauses); 9949 if (OrderedClauses.begin() != OrderedClauses.end()) 9950 return (*OrderedClauses.begin())->getNumForLoops(); 9951 return nullptr; 9952 } 9953 9954 static bool checkSimdlenSafelenSpecified(Sema &S, 9955 const ArrayRef<OMPClause *> Clauses) { 9956 const OMPSafelenClause *Safelen = nullptr; 9957 const OMPSimdlenClause *Simdlen = nullptr; 9958 9959 for (const OMPClause *Clause : Clauses) { 9960 if (Clause->getClauseKind() == OMPC_safelen) 9961 Safelen = cast<OMPSafelenClause>(Clause); 9962 else if (Clause->getClauseKind() == OMPC_simdlen) 9963 Simdlen = cast<OMPSimdlenClause>(Clause); 9964 if (Safelen && Simdlen) 9965 break; 9966 } 9967 9968 if (Simdlen && Safelen) { 9969 const Expr *SimdlenLength = Simdlen->getSimdlen(); 9970 const Expr *SafelenLength = Safelen->getSafelen(); 9971 if (SimdlenLength->isValueDependent() || SimdlenLength->isTypeDependent() || 9972 SimdlenLength->isInstantiationDependent() || 9973 SimdlenLength->containsUnexpandedParameterPack()) 9974 return false; 9975 if (SafelenLength->isValueDependent() || SafelenLength->isTypeDependent() || 9976 SafelenLength->isInstantiationDependent() || 9977 SafelenLength->containsUnexpandedParameterPack()) 9978 return false; 9979 Expr::EvalResult SimdlenResult, SafelenResult; 9980 SimdlenLength->EvaluateAsInt(SimdlenResult, S.Context); 9981 SafelenLength->EvaluateAsInt(SafelenResult, S.Context); 9982 llvm::APSInt SimdlenRes = SimdlenResult.Val.getInt(); 9983 llvm::APSInt SafelenRes = SafelenResult.Val.getInt(); 9984 // OpenMP 4.5 [2.8.1, simd Construct, Restrictions] 9985 // If both simdlen and safelen clauses are specified, the value of the 9986 // simdlen parameter must be less than or equal to the value of the safelen 9987 // parameter. 9988 if (SimdlenRes > SafelenRes) { 9989 S.Diag(SimdlenLength->getExprLoc(), 9990 diag::err_omp_wrong_simdlen_safelen_values) 9991 << SimdlenLength->getSourceRange() << SafelenLength->getSourceRange(); 9992 return true; 9993 } 9994 } 9995 return false; 9996 } 9997 9998 StmtResult 9999 Sema::ActOnOpenMPSimdDirective(ArrayRef<OMPClause *> Clauses, Stmt *AStmt, 10000 SourceLocation StartLoc, SourceLocation EndLoc, 10001 VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10002 if (!AStmt) 10003 return StmtError(); 10004 10005 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 10006 OMPLoopBasedDirective::HelperExprs B; 10007 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 10008 // define the nested loops number. 10009 unsigned NestedLoopCount = checkOpenMPLoop( 10010 OMPD_simd, getCollapseNumberExpr(Clauses), getOrderedNumberExpr(Clauses), 10011 AStmt, *this, *DSAStack, VarsWithImplicitDSA, B); 10012 if (NestedLoopCount == 0) 10013 return StmtError(); 10014 10015 assert((CurContext->isDependentContext() || B.builtAll()) && 10016 "omp simd loop exprs were not built"); 10017 10018 if (!CurContext->isDependentContext()) { 10019 // Finalize the clauses that need pre-built expressions for CodeGen. 10020 for (OMPClause *C : Clauses) { 10021 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 10022 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 10023 B.NumIterations, *this, CurScope, 10024 DSAStack)) 10025 return StmtError(); 10026 } 10027 } 10028 10029 if (checkSimdlenSafelenSpecified(*this, Clauses)) 10030 return StmtError(); 10031 10032 setFunctionHasBranchProtectedScope(); 10033 return OMPSimdDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount, 10034 Clauses, AStmt, B); 10035 } 10036 10037 StmtResult 10038 Sema::ActOnOpenMPForDirective(ArrayRef<OMPClause *> Clauses, Stmt *AStmt, 10039 SourceLocation StartLoc, SourceLocation EndLoc, 10040 VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10041 if (!AStmt) 10042 return StmtError(); 10043 10044 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 10045 OMPLoopBasedDirective::HelperExprs B; 10046 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 10047 // define the nested loops number. 10048 unsigned NestedLoopCount = checkOpenMPLoop( 10049 OMPD_for, getCollapseNumberExpr(Clauses), getOrderedNumberExpr(Clauses), 10050 AStmt, *this, *DSAStack, VarsWithImplicitDSA, B); 10051 if (NestedLoopCount == 0) 10052 return StmtError(); 10053 10054 assert((CurContext->isDependentContext() || B.builtAll()) && 10055 "omp for loop exprs were not built"); 10056 10057 if (!CurContext->isDependentContext()) { 10058 // Finalize the clauses that need pre-built expressions for CodeGen. 10059 for (OMPClause *C : Clauses) { 10060 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 10061 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 10062 B.NumIterations, *this, CurScope, 10063 DSAStack)) 10064 return StmtError(); 10065 } 10066 } 10067 10068 setFunctionHasBranchProtectedScope(); 10069 return OMPForDirective::Create( 10070 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B, 10071 DSAStack->getTaskgroupReductionRef(), DSAStack->isCancelRegion()); 10072 } 10073 10074 StmtResult Sema::ActOnOpenMPForSimdDirective( 10075 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10076 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10077 if (!AStmt) 10078 return StmtError(); 10079 10080 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 10081 OMPLoopBasedDirective::HelperExprs B; 10082 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 10083 // define the nested loops number. 10084 unsigned NestedLoopCount = 10085 checkOpenMPLoop(OMPD_for_simd, getCollapseNumberExpr(Clauses), 10086 getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack, 10087 VarsWithImplicitDSA, B); 10088 if (NestedLoopCount == 0) 10089 return StmtError(); 10090 10091 assert((CurContext->isDependentContext() || B.builtAll()) && 10092 "omp for simd loop exprs were not built"); 10093 10094 if (!CurContext->isDependentContext()) { 10095 // Finalize the clauses that need pre-built expressions for CodeGen. 10096 for (OMPClause *C : Clauses) { 10097 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 10098 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 10099 B.NumIterations, *this, CurScope, 10100 DSAStack)) 10101 return StmtError(); 10102 } 10103 } 10104 10105 if (checkSimdlenSafelenSpecified(*this, Clauses)) 10106 return StmtError(); 10107 10108 setFunctionHasBranchProtectedScope(); 10109 return OMPForSimdDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount, 10110 Clauses, AStmt, B); 10111 } 10112 10113 StmtResult Sema::ActOnOpenMPSectionsDirective(ArrayRef<OMPClause *> Clauses, 10114 Stmt *AStmt, 10115 SourceLocation StartLoc, 10116 SourceLocation EndLoc) { 10117 if (!AStmt) 10118 return StmtError(); 10119 10120 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 10121 auto BaseStmt = AStmt; 10122 while (auto *CS = dyn_cast_or_null<CapturedStmt>(BaseStmt)) 10123 BaseStmt = CS->getCapturedStmt(); 10124 if (auto *C = dyn_cast_or_null<CompoundStmt>(BaseStmt)) { 10125 auto S = C->children(); 10126 if (S.begin() == S.end()) 10127 return StmtError(); 10128 // All associated statements must be '#pragma omp section' except for 10129 // the first one. 10130 for (Stmt *SectionStmt : llvm::drop_begin(S)) { 10131 if (!SectionStmt || !isa<OMPSectionDirective>(SectionStmt)) { 10132 if (SectionStmt) 10133 Diag(SectionStmt->getBeginLoc(), 10134 diag::err_omp_sections_substmt_not_section); 10135 return StmtError(); 10136 } 10137 cast<OMPSectionDirective>(SectionStmt) 10138 ->setHasCancel(DSAStack->isCancelRegion()); 10139 } 10140 } else { 10141 Diag(AStmt->getBeginLoc(), diag::err_omp_sections_not_compound_stmt); 10142 return StmtError(); 10143 } 10144 10145 setFunctionHasBranchProtectedScope(); 10146 10147 return OMPSectionsDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt, 10148 DSAStack->getTaskgroupReductionRef(), 10149 DSAStack->isCancelRegion()); 10150 } 10151 10152 StmtResult Sema::ActOnOpenMPSectionDirective(Stmt *AStmt, 10153 SourceLocation StartLoc, 10154 SourceLocation EndLoc) { 10155 if (!AStmt) 10156 return StmtError(); 10157 10158 setFunctionHasBranchProtectedScope(); 10159 DSAStack->setParentCancelRegion(DSAStack->isCancelRegion()); 10160 10161 return OMPSectionDirective::Create(Context, StartLoc, EndLoc, AStmt, 10162 DSAStack->isCancelRegion()); 10163 } 10164 10165 static Expr *getDirectCallExpr(Expr *E) { 10166 E = E->IgnoreParenCasts()->IgnoreImplicit(); 10167 if (auto *CE = dyn_cast<CallExpr>(E)) 10168 if (CE->getDirectCallee()) 10169 return E; 10170 return nullptr; 10171 } 10172 10173 StmtResult Sema::ActOnOpenMPDispatchDirective(ArrayRef<OMPClause *> Clauses, 10174 Stmt *AStmt, 10175 SourceLocation StartLoc, 10176 SourceLocation EndLoc) { 10177 if (!AStmt) 10178 return StmtError(); 10179 10180 Stmt *S = cast<CapturedStmt>(AStmt)->getCapturedStmt(); 10181 10182 // 5.1 OpenMP 10183 // expression-stmt : an expression statement with one of the following forms: 10184 // expression = target-call ( [expression-list] ); 10185 // target-call ( [expression-list] ); 10186 10187 SourceLocation TargetCallLoc; 10188 10189 if (!CurContext->isDependentContext()) { 10190 Expr *TargetCall = nullptr; 10191 10192 auto *E = dyn_cast<Expr>(S); 10193 if (!E) { 10194 Diag(S->getBeginLoc(), diag::err_omp_dispatch_statement_call); 10195 return StmtError(); 10196 } 10197 10198 E = E->IgnoreParenCasts()->IgnoreImplicit(); 10199 10200 if (auto *BO = dyn_cast<BinaryOperator>(E)) { 10201 if (BO->getOpcode() == BO_Assign) 10202 TargetCall = getDirectCallExpr(BO->getRHS()); 10203 } else { 10204 if (auto *COCE = dyn_cast<CXXOperatorCallExpr>(E)) 10205 if (COCE->getOperator() == OO_Equal) 10206 TargetCall = getDirectCallExpr(COCE->getArg(1)); 10207 if (!TargetCall) 10208 TargetCall = getDirectCallExpr(E); 10209 } 10210 if (!TargetCall) { 10211 Diag(E->getBeginLoc(), diag::err_omp_dispatch_statement_call); 10212 return StmtError(); 10213 } 10214 TargetCallLoc = TargetCall->getExprLoc(); 10215 } 10216 10217 setFunctionHasBranchProtectedScope(); 10218 10219 return OMPDispatchDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt, 10220 TargetCallLoc); 10221 } 10222 10223 static bool checkGenericLoopLastprivate(Sema &S, ArrayRef<OMPClause *> Clauses, 10224 OpenMPDirectiveKind K, 10225 DSAStackTy *Stack) { 10226 bool ErrorFound = false; 10227 for (OMPClause *C : Clauses) { 10228 if (auto *LPC = dyn_cast<OMPLastprivateClause>(C)) { 10229 for (Expr *RefExpr : LPC->varlists()) { 10230 SourceLocation ELoc; 10231 SourceRange ERange; 10232 Expr *SimpleRefExpr = RefExpr; 10233 auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange); 10234 if (ValueDecl *D = Res.first) { 10235 auto &&Info = Stack->isLoopControlVariable(D); 10236 if (!Info.first) { 10237 S.Diag(ELoc, diag::err_omp_lastprivate_loop_var_non_loop_iteration) 10238 << getOpenMPDirectiveName(K); 10239 ErrorFound = true; 10240 } 10241 } 10242 } 10243 } 10244 } 10245 return ErrorFound; 10246 } 10247 10248 StmtResult Sema::ActOnOpenMPGenericLoopDirective( 10249 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10250 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10251 if (!AStmt) 10252 return StmtError(); 10253 10254 // OpenMP 5.1 [2.11.7, loop construct, Restrictions] 10255 // A list item may not appear in a lastprivate clause unless it is the 10256 // loop iteration variable of a loop that is associated with the construct. 10257 if (checkGenericLoopLastprivate(*this, Clauses, OMPD_loop, DSAStack)) 10258 return StmtError(); 10259 10260 auto *CS = cast<CapturedStmt>(AStmt); 10261 // 1.2.2 OpenMP Language Terminology 10262 // Structured block - An executable statement with a single entry at the 10263 // top and a single exit at the bottom. 10264 // The point of exit cannot be a branch out of the structured block. 10265 // longjmp() and throw() must not violate the entry/exit criteria. 10266 CS->getCapturedDecl()->setNothrow(); 10267 10268 OMPLoopDirective::HelperExprs B; 10269 // In presence of clause 'collapse', it will define the nested loops number. 10270 unsigned NestedLoopCount = checkOpenMPLoop( 10271 OMPD_loop, getCollapseNumberExpr(Clauses), getOrderedNumberExpr(Clauses), 10272 AStmt, *this, *DSAStack, VarsWithImplicitDSA, B); 10273 if (NestedLoopCount == 0) 10274 return StmtError(); 10275 10276 assert((CurContext->isDependentContext() || B.builtAll()) && 10277 "omp loop exprs were not built"); 10278 10279 setFunctionHasBranchProtectedScope(); 10280 return OMPGenericLoopDirective::Create(Context, StartLoc, EndLoc, 10281 NestedLoopCount, Clauses, AStmt, B); 10282 } 10283 10284 StmtResult Sema::ActOnOpenMPTeamsGenericLoopDirective( 10285 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10286 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10287 if (!AStmt) 10288 return StmtError(); 10289 10290 // OpenMP 5.1 [2.11.7, loop construct, Restrictions] 10291 // A list item may not appear in a lastprivate clause unless it is the 10292 // loop iteration variable of a loop that is associated with the construct. 10293 if (checkGenericLoopLastprivate(*this, Clauses, OMPD_teams_loop, DSAStack)) 10294 return StmtError(); 10295 10296 auto *CS = cast<CapturedStmt>(AStmt); 10297 // 1.2.2 OpenMP Language Terminology 10298 // Structured block - An executable statement with a single entry at the 10299 // top and a single exit at the bottom. 10300 // The point of exit cannot be a branch out of the structured block. 10301 // longjmp() and throw() must not violate the entry/exit criteria. 10302 CS->getCapturedDecl()->setNothrow(); 10303 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_teams_loop); 10304 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10305 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10306 // 1.2.2 OpenMP Language Terminology 10307 // Structured block - An executable statement with a single entry at the 10308 // top and a single exit at the bottom. 10309 // The point of exit cannot be a branch out of the structured block. 10310 // longjmp() and throw() must not violate the entry/exit criteria. 10311 CS->getCapturedDecl()->setNothrow(); 10312 } 10313 10314 OMPLoopDirective::HelperExprs B; 10315 // In presence of clause 'collapse', it will define the nested loops number. 10316 unsigned NestedLoopCount = 10317 checkOpenMPLoop(OMPD_teams_loop, getCollapseNumberExpr(Clauses), 10318 /*OrderedLoopCountExpr=*/nullptr, CS, *this, *DSAStack, 10319 VarsWithImplicitDSA, B); 10320 if (NestedLoopCount == 0) 10321 return StmtError(); 10322 10323 assert((CurContext->isDependentContext() || B.builtAll()) && 10324 "omp loop exprs were not built"); 10325 10326 setFunctionHasBranchProtectedScope(); 10327 DSAStack->setParentTeamsRegionLoc(StartLoc); 10328 10329 return OMPTeamsGenericLoopDirective::Create( 10330 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 10331 } 10332 10333 StmtResult Sema::ActOnOpenMPTargetTeamsGenericLoopDirective( 10334 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10335 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10336 if (!AStmt) 10337 return StmtError(); 10338 10339 // OpenMP 5.1 [2.11.7, loop construct, Restrictions] 10340 // A list item may not appear in a lastprivate clause unless it is the 10341 // loop iteration variable of a loop that is associated with the construct. 10342 if (checkGenericLoopLastprivate(*this, Clauses, OMPD_target_teams_loop, 10343 DSAStack)) 10344 return StmtError(); 10345 10346 auto *CS = cast<CapturedStmt>(AStmt); 10347 // 1.2.2 OpenMP Language Terminology 10348 // Structured block - An executable statement with a single entry at the 10349 // top and a single exit at the bottom. 10350 // The point of exit cannot be a branch out of the structured block. 10351 // longjmp() and throw() must not violate the entry/exit criteria. 10352 CS->getCapturedDecl()->setNothrow(); 10353 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_teams_loop); 10354 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10355 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10356 // 1.2.2 OpenMP Language Terminology 10357 // Structured block - An executable statement with a single entry at the 10358 // top and a single exit at the bottom. 10359 // The point of exit cannot be a branch out of the structured block. 10360 // longjmp() and throw() must not violate the entry/exit criteria. 10361 CS->getCapturedDecl()->setNothrow(); 10362 } 10363 10364 OMPLoopDirective::HelperExprs B; 10365 // In presence of clause 'collapse', it will define the nested loops number. 10366 unsigned NestedLoopCount = 10367 checkOpenMPLoop(OMPD_target_teams_loop, getCollapseNumberExpr(Clauses), 10368 /*OrderedLoopCountExpr=*/nullptr, CS, *this, *DSAStack, 10369 VarsWithImplicitDSA, B); 10370 if (NestedLoopCount == 0) 10371 return StmtError(); 10372 10373 assert((CurContext->isDependentContext() || B.builtAll()) && 10374 "omp loop exprs were not built"); 10375 10376 setFunctionHasBranchProtectedScope(); 10377 10378 return OMPTargetTeamsGenericLoopDirective::Create( 10379 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 10380 } 10381 10382 StmtResult Sema::ActOnOpenMPParallelGenericLoopDirective( 10383 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10384 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10385 if (!AStmt) 10386 return StmtError(); 10387 10388 // OpenMP 5.1 [2.11.7, loop construct, Restrictions] 10389 // A list item may not appear in a lastprivate clause unless it is the 10390 // loop iteration variable of a loop that is associated with the construct. 10391 if (checkGenericLoopLastprivate(*this, Clauses, OMPD_parallel_loop, DSAStack)) 10392 return StmtError(); 10393 10394 auto *CS = cast<CapturedStmt>(AStmt); 10395 // 1.2.2 OpenMP Language Terminology 10396 // Structured block - An executable statement with a single entry at the 10397 // top and a single exit at the bottom. 10398 // The point of exit cannot be a branch out of the structured block. 10399 // longjmp() and throw() must not violate the entry/exit criteria. 10400 CS->getCapturedDecl()->setNothrow(); 10401 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_parallel_loop); 10402 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10403 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10404 // 1.2.2 OpenMP Language Terminology 10405 // Structured block - An executable statement with a single entry at the 10406 // top and a single exit at the bottom. 10407 // The point of exit cannot be a branch out of the structured block. 10408 // longjmp() and throw() must not violate the entry/exit criteria. 10409 CS->getCapturedDecl()->setNothrow(); 10410 } 10411 10412 OMPLoopDirective::HelperExprs B; 10413 // In presence of clause 'collapse', it will define the nested loops number. 10414 unsigned NestedLoopCount = 10415 checkOpenMPLoop(OMPD_parallel_loop, getCollapseNumberExpr(Clauses), 10416 /*OrderedLoopCountExpr=*/nullptr, CS, *this, *DSAStack, 10417 VarsWithImplicitDSA, B); 10418 if (NestedLoopCount == 0) 10419 return StmtError(); 10420 10421 assert((CurContext->isDependentContext() || B.builtAll()) && 10422 "omp loop exprs were not built"); 10423 10424 setFunctionHasBranchProtectedScope(); 10425 10426 return OMPParallelGenericLoopDirective::Create( 10427 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 10428 } 10429 10430 StmtResult Sema::ActOnOpenMPTargetParallelGenericLoopDirective( 10431 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10432 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10433 if (!AStmt) 10434 return StmtError(); 10435 10436 // OpenMP 5.1 [2.11.7, loop construct, Restrictions] 10437 // A list item may not appear in a lastprivate clause unless it is the 10438 // loop iteration variable of a loop that is associated with the construct. 10439 if (checkGenericLoopLastprivate(*this, Clauses, OMPD_target_parallel_loop, 10440 DSAStack)) 10441 return StmtError(); 10442 10443 auto *CS = cast<CapturedStmt>(AStmt); 10444 // 1.2.2 OpenMP Language Terminology 10445 // Structured block - An executable statement with a single entry at the 10446 // top and a single exit at the bottom. 10447 // The point of exit cannot be a branch out of the structured block. 10448 // longjmp() and throw() must not violate the entry/exit criteria. 10449 CS->getCapturedDecl()->setNothrow(); 10450 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel_loop); 10451 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10452 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10453 // 1.2.2 OpenMP Language Terminology 10454 // Structured block - An executable statement with a single entry at the 10455 // top and a single exit at the bottom. 10456 // The point of exit cannot be a branch out of the structured block. 10457 // longjmp() and throw() must not violate the entry/exit criteria. 10458 CS->getCapturedDecl()->setNothrow(); 10459 } 10460 10461 OMPLoopDirective::HelperExprs B; 10462 // In presence of clause 'collapse', it will define the nested loops number. 10463 unsigned NestedLoopCount = 10464 checkOpenMPLoop(OMPD_target_parallel_loop, getCollapseNumberExpr(Clauses), 10465 /*OrderedLoopCountExpr=*/nullptr, CS, *this, *DSAStack, 10466 VarsWithImplicitDSA, B); 10467 if (NestedLoopCount == 0) 10468 return StmtError(); 10469 10470 assert((CurContext->isDependentContext() || B.builtAll()) && 10471 "omp loop exprs were not built"); 10472 10473 setFunctionHasBranchProtectedScope(); 10474 10475 return OMPTargetParallelGenericLoopDirective::Create( 10476 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 10477 } 10478 10479 StmtResult Sema::ActOnOpenMPSingleDirective(ArrayRef<OMPClause *> Clauses, 10480 Stmt *AStmt, 10481 SourceLocation StartLoc, 10482 SourceLocation EndLoc) { 10483 if (!AStmt) 10484 return StmtError(); 10485 10486 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 10487 10488 setFunctionHasBranchProtectedScope(); 10489 10490 // OpenMP [2.7.3, single Construct, Restrictions] 10491 // The copyprivate clause must not be used with the nowait clause. 10492 const OMPClause *Nowait = nullptr; 10493 const OMPClause *Copyprivate = nullptr; 10494 for (const OMPClause *Clause : Clauses) { 10495 if (Clause->getClauseKind() == OMPC_nowait) 10496 Nowait = Clause; 10497 else if (Clause->getClauseKind() == OMPC_copyprivate) 10498 Copyprivate = Clause; 10499 if (Copyprivate && Nowait) { 10500 Diag(Copyprivate->getBeginLoc(), 10501 diag::err_omp_single_copyprivate_with_nowait); 10502 Diag(Nowait->getBeginLoc(), diag::note_omp_nowait_clause_here); 10503 return StmtError(); 10504 } 10505 } 10506 10507 return OMPSingleDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt); 10508 } 10509 10510 StmtResult Sema::ActOnOpenMPMasterDirective(Stmt *AStmt, 10511 SourceLocation StartLoc, 10512 SourceLocation EndLoc) { 10513 if (!AStmt) 10514 return StmtError(); 10515 10516 setFunctionHasBranchProtectedScope(); 10517 10518 return OMPMasterDirective::Create(Context, StartLoc, EndLoc, AStmt); 10519 } 10520 10521 StmtResult Sema::ActOnOpenMPMaskedDirective(ArrayRef<OMPClause *> Clauses, 10522 Stmt *AStmt, 10523 SourceLocation StartLoc, 10524 SourceLocation EndLoc) { 10525 if (!AStmt) 10526 return StmtError(); 10527 10528 setFunctionHasBranchProtectedScope(); 10529 10530 return OMPMaskedDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt); 10531 } 10532 10533 StmtResult Sema::ActOnOpenMPCriticalDirective( 10534 const DeclarationNameInfo &DirName, ArrayRef<OMPClause *> Clauses, 10535 Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc) { 10536 if (!AStmt) 10537 return StmtError(); 10538 10539 bool ErrorFound = false; 10540 llvm::APSInt Hint; 10541 SourceLocation HintLoc; 10542 bool DependentHint = false; 10543 for (const OMPClause *C : Clauses) { 10544 if (C->getClauseKind() == OMPC_hint) { 10545 if (!DirName.getName()) { 10546 Diag(C->getBeginLoc(), diag::err_omp_hint_clause_no_name); 10547 ErrorFound = true; 10548 } 10549 Expr *E = cast<OMPHintClause>(C)->getHint(); 10550 if (E->isTypeDependent() || E->isValueDependent() || 10551 E->isInstantiationDependent()) { 10552 DependentHint = true; 10553 } else { 10554 Hint = E->EvaluateKnownConstInt(Context); 10555 HintLoc = C->getBeginLoc(); 10556 } 10557 } 10558 } 10559 if (ErrorFound) 10560 return StmtError(); 10561 const auto Pair = DSAStack->getCriticalWithHint(DirName); 10562 if (Pair.first && DirName.getName() && !DependentHint) { 10563 if (llvm::APSInt::compareValues(Hint, Pair.second) != 0) { 10564 Diag(StartLoc, diag::err_omp_critical_with_hint); 10565 if (HintLoc.isValid()) 10566 Diag(HintLoc, diag::note_omp_critical_hint_here) 10567 << 0 << toString(Hint, /*Radix=*/10, /*Signed=*/false); 10568 else 10569 Diag(StartLoc, diag::note_omp_critical_no_hint) << 0; 10570 if (const auto *C = Pair.first->getSingleClause<OMPHintClause>()) { 10571 Diag(C->getBeginLoc(), diag::note_omp_critical_hint_here) 10572 << 1 10573 << toString(C->getHint()->EvaluateKnownConstInt(Context), 10574 /*Radix=*/10, /*Signed=*/false); 10575 } else { 10576 Diag(Pair.first->getBeginLoc(), diag::note_omp_critical_no_hint) << 1; 10577 } 10578 } 10579 } 10580 10581 setFunctionHasBranchProtectedScope(); 10582 10583 auto *Dir = OMPCriticalDirective::Create(Context, DirName, StartLoc, EndLoc, 10584 Clauses, AStmt); 10585 if (!Pair.first && DirName.getName() && !DependentHint) 10586 DSAStack->addCriticalWithHint(Dir, Hint); 10587 return Dir; 10588 } 10589 10590 StmtResult Sema::ActOnOpenMPParallelForDirective( 10591 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10592 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10593 if (!AStmt) 10594 return StmtError(); 10595 10596 auto *CS = cast<CapturedStmt>(AStmt); 10597 // 1.2.2 OpenMP Language Terminology 10598 // Structured block - An executable statement with a single entry at the 10599 // top and a single exit at the bottom. 10600 // The point of exit cannot be a branch out of the structured block. 10601 // longjmp() and throw() must not violate the entry/exit criteria. 10602 CS->getCapturedDecl()->setNothrow(); 10603 10604 OMPLoopBasedDirective::HelperExprs B; 10605 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 10606 // define the nested loops number. 10607 unsigned NestedLoopCount = 10608 checkOpenMPLoop(OMPD_parallel_for, getCollapseNumberExpr(Clauses), 10609 getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack, 10610 VarsWithImplicitDSA, B); 10611 if (NestedLoopCount == 0) 10612 return StmtError(); 10613 10614 assert((CurContext->isDependentContext() || B.builtAll()) && 10615 "omp parallel for loop exprs were not built"); 10616 10617 if (!CurContext->isDependentContext()) { 10618 // Finalize the clauses that need pre-built expressions for CodeGen. 10619 for (OMPClause *C : Clauses) { 10620 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 10621 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 10622 B.NumIterations, *this, CurScope, 10623 DSAStack)) 10624 return StmtError(); 10625 } 10626 } 10627 10628 setFunctionHasBranchProtectedScope(); 10629 return OMPParallelForDirective::Create( 10630 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B, 10631 DSAStack->getTaskgroupReductionRef(), DSAStack->isCancelRegion()); 10632 } 10633 10634 StmtResult Sema::ActOnOpenMPParallelForSimdDirective( 10635 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10636 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10637 if (!AStmt) 10638 return StmtError(); 10639 10640 auto *CS = cast<CapturedStmt>(AStmt); 10641 // 1.2.2 OpenMP Language Terminology 10642 // Structured block - An executable statement with a single entry at the 10643 // top and a single exit at the bottom. 10644 // The point of exit cannot be a branch out of the structured block. 10645 // longjmp() and throw() must not violate the entry/exit criteria. 10646 CS->getCapturedDecl()->setNothrow(); 10647 10648 OMPLoopBasedDirective::HelperExprs B; 10649 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 10650 // define the nested loops number. 10651 unsigned NestedLoopCount = 10652 checkOpenMPLoop(OMPD_parallel_for_simd, getCollapseNumberExpr(Clauses), 10653 getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack, 10654 VarsWithImplicitDSA, B); 10655 if (NestedLoopCount == 0) 10656 return StmtError(); 10657 10658 if (!CurContext->isDependentContext()) { 10659 // Finalize the clauses that need pre-built expressions for CodeGen. 10660 for (OMPClause *C : Clauses) { 10661 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 10662 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 10663 B.NumIterations, *this, CurScope, 10664 DSAStack)) 10665 return StmtError(); 10666 } 10667 } 10668 10669 if (checkSimdlenSafelenSpecified(*this, Clauses)) 10670 return StmtError(); 10671 10672 setFunctionHasBranchProtectedScope(); 10673 return OMPParallelForSimdDirective::Create( 10674 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 10675 } 10676 10677 StmtResult 10678 Sema::ActOnOpenMPParallelMasterDirective(ArrayRef<OMPClause *> Clauses, 10679 Stmt *AStmt, SourceLocation StartLoc, 10680 SourceLocation EndLoc) { 10681 if (!AStmt) 10682 return StmtError(); 10683 10684 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 10685 auto *CS = cast<CapturedStmt>(AStmt); 10686 // 1.2.2 OpenMP Language Terminology 10687 // Structured block - An executable statement with a single entry at the 10688 // top and a single exit at the bottom. 10689 // The point of exit cannot be a branch out of the structured block. 10690 // longjmp() and throw() must not violate the entry/exit criteria. 10691 CS->getCapturedDecl()->setNothrow(); 10692 10693 setFunctionHasBranchProtectedScope(); 10694 10695 return OMPParallelMasterDirective::Create( 10696 Context, StartLoc, EndLoc, Clauses, AStmt, 10697 DSAStack->getTaskgroupReductionRef()); 10698 } 10699 10700 StmtResult 10701 Sema::ActOnOpenMPParallelSectionsDirective(ArrayRef<OMPClause *> Clauses, 10702 Stmt *AStmt, SourceLocation StartLoc, 10703 SourceLocation EndLoc) { 10704 if (!AStmt) 10705 return StmtError(); 10706 10707 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 10708 auto BaseStmt = AStmt; 10709 while (auto *CS = dyn_cast_or_null<CapturedStmt>(BaseStmt)) 10710 BaseStmt = CS->getCapturedStmt(); 10711 if (auto *C = dyn_cast_or_null<CompoundStmt>(BaseStmt)) { 10712 auto S = C->children(); 10713 if (S.begin() == S.end()) 10714 return StmtError(); 10715 // All associated statements must be '#pragma omp section' except for 10716 // the first one. 10717 for (Stmt *SectionStmt : llvm::drop_begin(S)) { 10718 if (!SectionStmt || !isa<OMPSectionDirective>(SectionStmt)) { 10719 if (SectionStmt) 10720 Diag(SectionStmt->getBeginLoc(), 10721 diag::err_omp_parallel_sections_substmt_not_section); 10722 return StmtError(); 10723 } 10724 cast<OMPSectionDirective>(SectionStmt) 10725 ->setHasCancel(DSAStack->isCancelRegion()); 10726 } 10727 } else { 10728 Diag(AStmt->getBeginLoc(), 10729 diag::err_omp_parallel_sections_not_compound_stmt); 10730 return StmtError(); 10731 } 10732 10733 setFunctionHasBranchProtectedScope(); 10734 10735 return OMPParallelSectionsDirective::Create( 10736 Context, StartLoc, EndLoc, Clauses, AStmt, 10737 DSAStack->getTaskgroupReductionRef(), DSAStack->isCancelRegion()); 10738 } 10739 10740 /// Find and diagnose mutually exclusive clause kinds. 10741 static bool checkMutuallyExclusiveClauses( 10742 Sema &S, ArrayRef<OMPClause *> Clauses, 10743 ArrayRef<OpenMPClauseKind> MutuallyExclusiveClauses) { 10744 const OMPClause *PrevClause = nullptr; 10745 bool ErrorFound = false; 10746 for (const OMPClause *C : Clauses) { 10747 if (llvm::is_contained(MutuallyExclusiveClauses, C->getClauseKind())) { 10748 if (!PrevClause) { 10749 PrevClause = C; 10750 } else if (PrevClause->getClauseKind() != C->getClauseKind()) { 10751 S.Diag(C->getBeginLoc(), diag::err_omp_clauses_mutually_exclusive) 10752 << getOpenMPClauseName(C->getClauseKind()) 10753 << getOpenMPClauseName(PrevClause->getClauseKind()); 10754 S.Diag(PrevClause->getBeginLoc(), diag::note_omp_previous_clause) 10755 << getOpenMPClauseName(PrevClause->getClauseKind()); 10756 ErrorFound = true; 10757 } 10758 } 10759 } 10760 return ErrorFound; 10761 } 10762 10763 StmtResult Sema::ActOnOpenMPTaskDirective(ArrayRef<OMPClause *> Clauses, 10764 Stmt *AStmt, SourceLocation StartLoc, 10765 SourceLocation EndLoc) { 10766 if (!AStmt) 10767 return StmtError(); 10768 10769 // OpenMP 5.0, 2.10.1 task Construct 10770 // If a detach clause appears on the directive, then a mergeable clause cannot 10771 // appear on the same directive. 10772 if (checkMutuallyExclusiveClauses(*this, Clauses, 10773 {OMPC_detach, OMPC_mergeable})) 10774 return StmtError(); 10775 10776 auto *CS = cast<CapturedStmt>(AStmt); 10777 // 1.2.2 OpenMP Language Terminology 10778 // Structured block - An executable statement with a single entry at the 10779 // top and a single exit at the bottom. 10780 // The point of exit cannot be a branch out of the structured block. 10781 // longjmp() and throw() must not violate the entry/exit criteria. 10782 CS->getCapturedDecl()->setNothrow(); 10783 10784 setFunctionHasBranchProtectedScope(); 10785 10786 return OMPTaskDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt, 10787 DSAStack->isCancelRegion()); 10788 } 10789 10790 StmtResult Sema::ActOnOpenMPTaskyieldDirective(SourceLocation StartLoc, 10791 SourceLocation EndLoc) { 10792 return OMPTaskyieldDirective::Create(Context, StartLoc, EndLoc); 10793 } 10794 10795 StmtResult Sema::ActOnOpenMPBarrierDirective(SourceLocation StartLoc, 10796 SourceLocation EndLoc) { 10797 return OMPBarrierDirective::Create(Context, StartLoc, EndLoc); 10798 } 10799 10800 StmtResult Sema::ActOnOpenMPTaskwaitDirective(ArrayRef<OMPClause *> Clauses, 10801 SourceLocation StartLoc, 10802 SourceLocation EndLoc) { 10803 return OMPTaskwaitDirective::Create(Context, StartLoc, EndLoc, Clauses); 10804 } 10805 10806 StmtResult Sema::ActOnOpenMPTaskgroupDirective(ArrayRef<OMPClause *> Clauses, 10807 Stmt *AStmt, 10808 SourceLocation StartLoc, 10809 SourceLocation EndLoc) { 10810 if (!AStmt) 10811 return StmtError(); 10812 10813 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 10814 10815 setFunctionHasBranchProtectedScope(); 10816 10817 return OMPTaskgroupDirective::Create(Context, StartLoc, EndLoc, Clauses, 10818 AStmt, 10819 DSAStack->getTaskgroupReductionRef()); 10820 } 10821 10822 StmtResult Sema::ActOnOpenMPFlushDirective(ArrayRef<OMPClause *> Clauses, 10823 SourceLocation StartLoc, 10824 SourceLocation EndLoc) { 10825 OMPFlushClause *FC = nullptr; 10826 OMPClause *OrderClause = nullptr; 10827 for (OMPClause *C : Clauses) { 10828 if (C->getClauseKind() == OMPC_flush) 10829 FC = cast<OMPFlushClause>(C); 10830 else 10831 OrderClause = C; 10832 } 10833 OpenMPClauseKind MemOrderKind = OMPC_unknown; 10834 SourceLocation MemOrderLoc; 10835 for (const OMPClause *C : Clauses) { 10836 if (C->getClauseKind() == OMPC_acq_rel || 10837 C->getClauseKind() == OMPC_acquire || 10838 C->getClauseKind() == OMPC_release) { 10839 if (MemOrderKind != OMPC_unknown) { 10840 Diag(C->getBeginLoc(), diag::err_omp_several_mem_order_clauses) 10841 << getOpenMPDirectiveName(OMPD_flush) << 1 10842 << SourceRange(C->getBeginLoc(), C->getEndLoc()); 10843 Diag(MemOrderLoc, diag::note_omp_previous_mem_order_clause) 10844 << getOpenMPClauseName(MemOrderKind); 10845 } else { 10846 MemOrderKind = C->getClauseKind(); 10847 MemOrderLoc = C->getBeginLoc(); 10848 } 10849 } 10850 } 10851 if (FC && OrderClause) { 10852 Diag(FC->getLParenLoc(), diag::err_omp_flush_order_clause_and_list) 10853 << getOpenMPClauseName(OrderClause->getClauseKind()); 10854 Diag(OrderClause->getBeginLoc(), diag::note_omp_flush_order_clause_here) 10855 << getOpenMPClauseName(OrderClause->getClauseKind()); 10856 return StmtError(); 10857 } 10858 return OMPFlushDirective::Create(Context, StartLoc, EndLoc, Clauses); 10859 } 10860 10861 StmtResult Sema::ActOnOpenMPDepobjDirective(ArrayRef<OMPClause *> Clauses, 10862 SourceLocation StartLoc, 10863 SourceLocation EndLoc) { 10864 if (Clauses.empty()) { 10865 Diag(StartLoc, diag::err_omp_depobj_expected); 10866 return StmtError(); 10867 } else if (Clauses[0]->getClauseKind() != OMPC_depobj) { 10868 Diag(Clauses[0]->getBeginLoc(), diag::err_omp_depobj_expected); 10869 return StmtError(); 10870 } 10871 // Only depobj expression and another single clause is allowed. 10872 if (Clauses.size() > 2) { 10873 Diag(Clauses[2]->getBeginLoc(), 10874 diag::err_omp_depobj_single_clause_expected); 10875 return StmtError(); 10876 } else if (Clauses.size() < 1) { 10877 Diag(Clauses[0]->getEndLoc(), diag::err_omp_depobj_single_clause_expected); 10878 return StmtError(); 10879 } 10880 return OMPDepobjDirective::Create(Context, StartLoc, EndLoc, Clauses); 10881 } 10882 10883 StmtResult Sema::ActOnOpenMPScanDirective(ArrayRef<OMPClause *> Clauses, 10884 SourceLocation StartLoc, 10885 SourceLocation EndLoc) { 10886 // Check that exactly one clause is specified. 10887 if (Clauses.size() != 1) { 10888 Diag(Clauses.empty() ? EndLoc : Clauses[1]->getBeginLoc(), 10889 diag::err_omp_scan_single_clause_expected); 10890 return StmtError(); 10891 } 10892 // Check that scan directive is used in the scopeof the OpenMP loop body. 10893 if (Scope *S = DSAStack->getCurScope()) { 10894 Scope *ParentS = S->getParent(); 10895 if (!ParentS || ParentS->getParent() != ParentS->getBreakParent() || 10896 !ParentS->getBreakParent()->isOpenMPLoopScope()) 10897 return StmtError(Diag(StartLoc, diag::err_omp_orphaned_device_directive) 10898 << getOpenMPDirectiveName(OMPD_scan) << 5); 10899 } 10900 // Check that only one instance of scan directives is used in the same outer 10901 // region. 10902 if (DSAStack->doesParentHasScanDirective()) { 10903 Diag(StartLoc, diag::err_omp_several_directives_in_region) << "scan"; 10904 Diag(DSAStack->getParentScanDirectiveLoc(), 10905 diag::note_omp_previous_directive) 10906 << "scan"; 10907 return StmtError(); 10908 } 10909 DSAStack->setParentHasScanDirective(StartLoc); 10910 return OMPScanDirective::Create(Context, StartLoc, EndLoc, Clauses); 10911 } 10912 10913 StmtResult Sema::ActOnOpenMPOrderedDirective(ArrayRef<OMPClause *> Clauses, 10914 Stmt *AStmt, 10915 SourceLocation StartLoc, 10916 SourceLocation EndLoc) { 10917 const OMPClause *DependFound = nullptr; 10918 const OMPClause *DependSourceClause = nullptr; 10919 const OMPClause *DependSinkClause = nullptr; 10920 bool ErrorFound = false; 10921 const OMPThreadsClause *TC = nullptr; 10922 const OMPSIMDClause *SC = nullptr; 10923 for (const OMPClause *C : Clauses) { 10924 if (auto *DC = dyn_cast<OMPDependClause>(C)) { 10925 DependFound = C; 10926 if (DC->getDependencyKind() == OMPC_DEPEND_source) { 10927 if (DependSourceClause) { 10928 Diag(C->getBeginLoc(), diag::err_omp_more_one_clause) 10929 << getOpenMPDirectiveName(OMPD_ordered) 10930 << getOpenMPClauseName(OMPC_depend) << 2; 10931 ErrorFound = true; 10932 } else { 10933 DependSourceClause = C; 10934 } 10935 if (DependSinkClause) { 10936 Diag(C->getBeginLoc(), diag::err_omp_depend_sink_source_not_allowed) 10937 << 0; 10938 ErrorFound = true; 10939 } 10940 } else if (DC->getDependencyKind() == OMPC_DEPEND_sink) { 10941 if (DependSourceClause) { 10942 Diag(C->getBeginLoc(), diag::err_omp_depend_sink_source_not_allowed) 10943 << 1; 10944 ErrorFound = true; 10945 } 10946 DependSinkClause = C; 10947 } 10948 } else if (C->getClauseKind() == OMPC_threads) { 10949 TC = cast<OMPThreadsClause>(C); 10950 } else if (C->getClauseKind() == OMPC_simd) { 10951 SC = cast<OMPSIMDClause>(C); 10952 } 10953 } 10954 if (!ErrorFound && !SC && 10955 isOpenMPSimdDirective(DSAStack->getParentDirective())) { 10956 // OpenMP [2.8.1,simd Construct, Restrictions] 10957 // An ordered construct with the simd clause is the only OpenMP construct 10958 // that can appear in the simd region. 10959 Diag(StartLoc, diag::err_omp_prohibited_region_simd) 10960 << (LangOpts.OpenMP >= 50 ? 1 : 0); 10961 ErrorFound = true; 10962 } else if (DependFound && (TC || SC)) { 10963 Diag(DependFound->getBeginLoc(), diag::err_omp_depend_clause_thread_simd) 10964 << getOpenMPClauseName(TC ? TC->getClauseKind() : SC->getClauseKind()); 10965 ErrorFound = true; 10966 } else if (DependFound && !DSAStack->getParentOrderedRegionParam().first) { 10967 Diag(DependFound->getBeginLoc(), 10968 diag::err_omp_ordered_directive_without_param); 10969 ErrorFound = true; 10970 } else if (TC || Clauses.empty()) { 10971 if (const Expr *Param = DSAStack->getParentOrderedRegionParam().first) { 10972 SourceLocation ErrLoc = TC ? TC->getBeginLoc() : StartLoc; 10973 Diag(ErrLoc, diag::err_omp_ordered_directive_with_param) 10974 << (TC != nullptr); 10975 Diag(Param->getBeginLoc(), diag::note_omp_ordered_param) << 1; 10976 ErrorFound = true; 10977 } 10978 } 10979 if ((!AStmt && !DependFound) || ErrorFound) 10980 return StmtError(); 10981 10982 // OpenMP 5.0, 2.17.9, ordered Construct, Restrictions. 10983 // During execution of an iteration of a worksharing-loop or a loop nest 10984 // within a worksharing-loop, simd, or worksharing-loop SIMD region, a thread 10985 // must not execute more than one ordered region corresponding to an ordered 10986 // construct without a depend clause. 10987 if (!DependFound) { 10988 if (DSAStack->doesParentHasOrderedDirective()) { 10989 Diag(StartLoc, diag::err_omp_several_directives_in_region) << "ordered"; 10990 Diag(DSAStack->getParentOrderedDirectiveLoc(), 10991 diag::note_omp_previous_directive) 10992 << "ordered"; 10993 return StmtError(); 10994 } 10995 DSAStack->setParentHasOrderedDirective(StartLoc); 10996 } 10997 10998 if (AStmt) { 10999 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 11000 11001 setFunctionHasBranchProtectedScope(); 11002 } 11003 11004 return OMPOrderedDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt); 11005 } 11006 11007 namespace { 11008 /// Helper class for checking expression in 'omp atomic [update]' 11009 /// construct. 11010 class OpenMPAtomicUpdateChecker { 11011 /// Error results for atomic update expressions. 11012 enum ExprAnalysisErrorCode { 11013 /// A statement is not an expression statement. 11014 NotAnExpression, 11015 /// Expression is not builtin binary or unary operation. 11016 NotABinaryOrUnaryExpression, 11017 /// Unary operation is not post-/pre- increment/decrement operation. 11018 NotAnUnaryIncDecExpression, 11019 /// An expression is not of scalar type. 11020 NotAScalarType, 11021 /// A binary operation is not an assignment operation. 11022 NotAnAssignmentOp, 11023 /// RHS part of the binary operation is not a binary expression. 11024 NotABinaryExpression, 11025 /// RHS part is not additive/multiplicative/shift/biwise binary 11026 /// expression. 11027 NotABinaryOperator, 11028 /// RHS binary operation does not have reference to the updated LHS 11029 /// part. 11030 NotAnUpdateExpression, 11031 /// No errors is found. 11032 NoError 11033 }; 11034 /// Reference to Sema. 11035 Sema &SemaRef; 11036 /// A location for note diagnostics (when error is found). 11037 SourceLocation NoteLoc; 11038 /// 'x' lvalue part of the source atomic expression. 11039 Expr *X; 11040 /// 'expr' rvalue part of the source atomic expression. 11041 Expr *E; 11042 /// Helper expression of the form 11043 /// 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or 11044 /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'. 11045 Expr *UpdateExpr; 11046 /// Is 'x' a LHS in a RHS part of full update expression. It is 11047 /// important for non-associative operations. 11048 bool IsXLHSInRHSPart; 11049 BinaryOperatorKind Op; 11050 SourceLocation OpLoc; 11051 /// true if the source expression is a postfix unary operation, false 11052 /// if it is a prefix unary operation. 11053 bool IsPostfixUpdate; 11054 11055 public: 11056 OpenMPAtomicUpdateChecker(Sema &SemaRef) 11057 : SemaRef(SemaRef), X(nullptr), E(nullptr), UpdateExpr(nullptr), 11058 IsXLHSInRHSPart(false), Op(BO_PtrMemD), IsPostfixUpdate(false) {} 11059 /// Check specified statement that it is suitable for 'atomic update' 11060 /// constructs and extract 'x', 'expr' and Operation from the original 11061 /// expression. If DiagId and NoteId == 0, then only check is performed 11062 /// without error notification. 11063 /// \param DiagId Diagnostic which should be emitted if error is found. 11064 /// \param NoteId Diagnostic note for the main error message. 11065 /// \return true if statement is not an update expression, false otherwise. 11066 bool checkStatement(Stmt *S, unsigned DiagId = 0, unsigned NoteId = 0); 11067 /// Return the 'x' lvalue part of the source atomic expression. 11068 Expr *getX() const { return X; } 11069 /// Return the 'expr' rvalue part of the source atomic expression. 11070 Expr *getExpr() const { return E; } 11071 /// Return the update expression used in calculation of the updated 11072 /// value. Always has form 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or 11073 /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'. 11074 Expr *getUpdateExpr() const { return UpdateExpr; } 11075 /// Return true if 'x' is LHS in RHS part of full update expression, 11076 /// false otherwise. 11077 bool isXLHSInRHSPart() const { return IsXLHSInRHSPart; } 11078 11079 /// true if the source expression is a postfix unary operation, false 11080 /// if it is a prefix unary operation. 11081 bool isPostfixUpdate() const { return IsPostfixUpdate; } 11082 11083 private: 11084 bool checkBinaryOperation(BinaryOperator *AtomicBinOp, unsigned DiagId = 0, 11085 unsigned NoteId = 0); 11086 }; 11087 11088 bool OpenMPAtomicUpdateChecker::checkBinaryOperation( 11089 BinaryOperator *AtomicBinOp, unsigned DiagId, unsigned NoteId) { 11090 ExprAnalysisErrorCode ErrorFound = NoError; 11091 SourceLocation ErrorLoc, NoteLoc; 11092 SourceRange ErrorRange, NoteRange; 11093 // Allowed constructs are: 11094 // x = x binop expr; 11095 // x = expr binop x; 11096 if (AtomicBinOp->getOpcode() == BO_Assign) { 11097 X = AtomicBinOp->getLHS(); 11098 if (const auto *AtomicInnerBinOp = dyn_cast<BinaryOperator>( 11099 AtomicBinOp->getRHS()->IgnoreParenImpCasts())) { 11100 if (AtomicInnerBinOp->isMultiplicativeOp() || 11101 AtomicInnerBinOp->isAdditiveOp() || AtomicInnerBinOp->isShiftOp() || 11102 AtomicInnerBinOp->isBitwiseOp()) { 11103 Op = AtomicInnerBinOp->getOpcode(); 11104 OpLoc = AtomicInnerBinOp->getOperatorLoc(); 11105 Expr *LHS = AtomicInnerBinOp->getLHS(); 11106 Expr *RHS = AtomicInnerBinOp->getRHS(); 11107 llvm::FoldingSetNodeID XId, LHSId, RHSId; 11108 X->IgnoreParenImpCasts()->Profile(XId, SemaRef.getASTContext(), 11109 /*Canonical=*/true); 11110 LHS->IgnoreParenImpCasts()->Profile(LHSId, SemaRef.getASTContext(), 11111 /*Canonical=*/true); 11112 RHS->IgnoreParenImpCasts()->Profile(RHSId, SemaRef.getASTContext(), 11113 /*Canonical=*/true); 11114 if (XId == LHSId) { 11115 E = RHS; 11116 IsXLHSInRHSPart = true; 11117 } else if (XId == RHSId) { 11118 E = LHS; 11119 IsXLHSInRHSPart = false; 11120 } else { 11121 ErrorLoc = AtomicInnerBinOp->getExprLoc(); 11122 ErrorRange = AtomicInnerBinOp->getSourceRange(); 11123 NoteLoc = X->getExprLoc(); 11124 NoteRange = X->getSourceRange(); 11125 ErrorFound = NotAnUpdateExpression; 11126 } 11127 } else { 11128 ErrorLoc = AtomicInnerBinOp->getExprLoc(); 11129 ErrorRange = AtomicInnerBinOp->getSourceRange(); 11130 NoteLoc = AtomicInnerBinOp->getOperatorLoc(); 11131 NoteRange = SourceRange(NoteLoc, NoteLoc); 11132 ErrorFound = NotABinaryOperator; 11133 } 11134 } else { 11135 NoteLoc = ErrorLoc = AtomicBinOp->getRHS()->getExprLoc(); 11136 NoteRange = ErrorRange = AtomicBinOp->getRHS()->getSourceRange(); 11137 ErrorFound = NotABinaryExpression; 11138 } 11139 } else { 11140 ErrorLoc = AtomicBinOp->getExprLoc(); 11141 ErrorRange = AtomicBinOp->getSourceRange(); 11142 NoteLoc = AtomicBinOp->getOperatorLoc(); 11143 NoteRange = SourceRange(NoteLoc, NoteLoc); 11144 ErrorFound = NotAnAssignmentOp; 11145 } 11146 if (ErrorFound != NoError && DiagId != 0 && NoteId != 0) { 11147 SemaRef.Diag(ErrorLoc, DiagId) << ErrorRange; 11148 SemaRef.Diag(NoteLoc, NoteId) << ErrorFound << NoteRange; 11149 return true; 11150 } 11151 if (SemaRef.CurContext->isDependentContext()) 11152 E = X = UpdateExpr = nullptr; 11153 return ErrorFound != NoError; 11154 } 11155 11156 bool OpenMPAtomicUpdateChecker::checkStatement(Stmt *S, unsigned DiagId, 11157 unsigned NoteId) { 11158 ExprAnalysisErrorCode ErrorFound = NoError; 11159 SourceLocation ErrorLoc, NoteLoc; 11160 SourceRange ErrorRange, NoteRange; 11161 // Allowed constructs are: 11162 // x++; 11163 // x--; 11164 // ++x; 11165 // --x; 11166 // x binop= expr; 11167 // x = x binop expr; 11168 // x = expr binop x; 11169 if (auto *AtomicBody = dyn_cast<Expr>(S)) { 11170 AtomicBody = AtomicBody->IgnoreParenImpCasts(); 11171 if (AtomicBody->getType()->isScalarType() || 11172 AtomicBody->isInstantiationDependent()) { 11173 if (const auto *AtomicCompAssignOp = dyn_cast<CompoundAssignOperator>( 11174 AtomicBody->IgnoreParenImpCasts())) { 11175 // Check for Compound Assignment Operation 11176 Op = BinaryOperator::getOpForCompoundAssignment( 11177 AtomicCompAssignOp->getOpcode()); 11178 OpLoc = AtomicCompAssignOp->getOperatorLoc(); 11179 E = AtomicCompAssignOp->getRHS(); 11180 X = AtomicCompAssignOp->getLHS()->IgnoreParens(); 11181 IsXLHSInRHSPart = true; 11182 } else if (auto *AtomicBinOp = dyn_cast<BinaryOperator>( 11183 AtomicBody->IgnoreParenImpCasts())) { 11184 // Check for Binary Operation 11185 if (checkBinaryOperation(AtomicBinOp, DiagId, NoteId)) 11186 return true; 11187 } else if (const auto *AtomicUnaryOp = dyn_cast<UnaryOperator>( 11188 AtomicBody->IgnoreParenImpCasts())) { 11189 // Check for Unary Operation 11190 if (AtomicUnaryOp->isIncrementDecrementOp()) { 11191 IsPostfixUpdate = AtomicUnaryOp->isPostfix(); 11192 Op = AtomicUnaryOp->isIncrementOp() ? BO_Add : BO_Sub; 11193 OpLoc = AtomicUnaryOp->getOperatorLoc(); 11194 X = AtomicUnaryOp->getSubExpr()->IgnoreParens(); 11195 E = SemaRef.ActOnIntegerConstant(OpLoc, /*uint64_t Val=*/1).get(); 11196 IsXLHSInRHSPart = true; 11197 } else { 11198 ErrorFound = NotAnUnaryIncDecExpression; 11199 ErrorLoc = AtomicUnaryOp->getExprLoc(); 11200 ErrorRange = AtomicUnaryOp->getSourceRange(); 11201 NoteLoc = AtomicUnaryOp->getOperatorLoc(); 11202 NoteRange = SourceRange(NoteLoc, NoteLoc); 11203 } 11204 } else if (!AtomicBody->isInstantiationDependent()) { 11205 ErrorFound = NotABinaryOrUnaryExpression; 11206 NoteLoc = ErrorLoc = AtomicBody->getExprLoc(); 11207 NoteRange = ErrorRange = AtomicBody->getSourceRange(); 11208 } 11209 } else { 11210 ErrorFound = NotAScalarType; 11211 NoteLoc = ErrorLoc = AtomicBody->getBeginLoc(); 11212 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc); 11213 } 11214 } else { 11215 ErrorFound = NotAnExpression; 11216 NoteLoc = ErrorLoc = S->getBeginLoc(); 11217 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc); 11218 } 11219 if (ErrorFound != NoError && DiagId != 0 && NoteId != 0) { 11220 SemaRef.Diag(ErrorLoc, DiagId) << ErrorRange; 11221 SemaRef.Diag(NoteLoc, NoteId) << ErrorFound << NoteRange; 11222 return true; 11223 } 11224 if (SemaRef.CurContext->isDependentContext()) 11225 E = X = UpdateExpr = nullptr; 11226 if (ErrorFound == NoError && E && X) { 11227 // Build an update expression of form 'OpaqueValueExpr(x) binop 11228 // OpaqueValueExpr(expr)' or 'OpaqueValueExpr(expr) binop 11229 // OpaqueValueExpr(x)' and then cast it to the type of the 'x' expression. 11230 auto *OVEX = new (SemaRef.getASTContext()) 11231 OpaqueValueExpr(X->getExprLoc(), X->getType(), VK_PRValue); 11232 auto *OVEExpr = new (SemaRef.getASTContext()) 11233 OpaqueValueExpr(E->getExprLoc(), E->getType(), VK_PRValue); 11234 ExprResult Update = 11235 SemaRef.CreateBuiltinBinOp(OpLoc, Op, IsXLHSInRHSPart ? OVEX : OVEExpr, 11236 IsXLHSInRHSPart ? OVEExpr : OVEX); 11237 if (Update.isInvalid()) 11238 return true; 11239 Update = SemaRef.PerformImplicitConversion(Update.get(), X->getType(), 11240 Sema::AA_Casting); 11241 if (Update.isInvalid()) 11242 return true; 11243 UpdateExpr = Update.get(); 11244 } 11245 return ErrorFound != NoError; 11246 } 11247 11248 /// Get the node id of the fixed point of an expression \a S. 11249 llvm::FoldingSetNodeID getNodeId(ASTContext &Context, const Expr *S) { 11250 llvm::FoldingSetNodeID Id; 11251 S->IgnoreParenImpCasts()->Profile(Id, Context, true); 11252 return Id; 11253 } 11254 11255 /// Check if two expressions are same. 11256 bool checkIfTwoExprsAreSame(ASTContext &Context, const Expr *LHS, 11257 const Expr *RHS) { 11258 return getNodeId(Context, LHS) == getNodeId(Context, RHS); 11259 } 11260 11261 class OpenMPAtomicCompareChecker { 11262 public: 11263 /// All kinds of errors that can occur in `atomic compare` 11264 enum ErrorTy { 11265 /// Empty compound statement. 11266 NoStmt = 0, 11267 /// More than one statement in a compound statement. 11268 MoreThanOneStmt, 11269 /// Not an assignment binary operator. 11270 NotAnAssignment, 11271 /// Not a conditional operator. 11272 NotCondOp, 11273 /// Wrong false expr. According to the spec, 'x' should be at the false 11274 /// expression of a conditional expression. 11275 WrongFalseExpr, 11276 /// The condition of a conditional expression is not a binary operator. 11277 NotABinaryOp, 11278 /// Invalid binary operator (not <, >, or ==). 11279 InvalidBinaryOp, 11280 /// Invalid comparison (not x == e, e == x, x ordop expr, or expr ordop x). 11281 InvalidComparison, 11282 /// X is not a lvalue. 11283 XNotLValue, 11284 /// Not a scalar. 11285 NotScalar, 11286 /// Not an integer. 11287 NotInteger, 11288 /// 'else' statement is not expected. 11289 UnexpectedElse, 11290 /// Not an equality operator. 11291 NotEQ, 11292 /// Invalid assignment (not v == x). 11293 InvalidAssignment, 11294 /// Not if statement 11295 NotIfStmt, 11296 /// More than two statements in a compund statement. 11297 MoreThanTwoStmts, 11298 /// Not a compound statement. 11299 NotCompoundStmt, 11300 /// No else statement. 11301 NoElse, 11302 /// Not 'if (r)'. 11303 InvalidCondition, 11304 /// No error. 11305 NoError, 11306 }; 11307 11308 struct ErrorInfoTy { 11309 ErrorTy Error; 11310 SourceLocation ErrorLoc; 11311 SourceRange ErrorRange; 11312 SourceLocation NoteLoc; 11313 SourceRange NoteRange; 11314 }; 11315 11316 OpenMPAtomicCompareChecker(Sema &S) : ContextRef(S.getASTContext()) {} 11317 11318 /// Check if statement \a S is valid for <tt>atomic compare</tt>. 11319 bool checkStmt(Stmt *S, ErrorInfoTy &ErrorInfo); 11320 11321 Expr *getX() const { return X; } 11322 Expr *getE() const { return E; } 11323 Expr *getD() const { return D; } 11324 Expr *getCond() const { return C; } 11325 bool isXBinopExpr() const { return IsXBinopExpr; } 11326 11327 protected: 11328 /// Reference to ASTContext 11329 ASTContext &ContextRef; 11330 /// 'x' lvalue part of the source atomic expression. 11331 Expr *X = nullptr; 11332 /// 'expr' or 'e' rvalue part of the source atomic expression. 11333 Expr *E = nullptr; 11334 /// 'd' rvalue part of the source atomic expression. 11335 Expr *D = nullptr; 11336 /// 'cond' part of the source atomic expression. It is in one of the following 11337 /// forms: 11338 /// expr ordop x 11339 /// x ordop expr 11340 /// x == e 11341 /// e == x 11342 Expr *C = nullptr; 11343 /// True if the cond expr is in the form of 'x ordop expr'. 11344 bool IsXBinopExpr = true; 11345 11346 /// Check if it is a valid conditional update statement (cond-update-stmt). 11347 bool checkCondUpdateStmt(IfStmt *S, ErrorInfoTy &ErrorInfo); 11348 11349 /// Check if it is a valid conditional expression statement (cond-expr-stmt). 11350 bool checkCondExprStmt(Stmt *S, ErrorInfoTy &ErrorInfo); 11351 11352 /// Check if all captured values have right type. 11353 bool checkType(ErrorInfoTy &ErrorInfo) const; 11354 11355 static bool CheckValue(const Expr *E, ErrorInfoTy &ErrorInfo, 11356 bool ShouldBeLValue) { 11357 if (ShouldBeLValue && !E->isLValue()) { 11358 ErrorInfo.Error = ErrorTy::XNotLValue; 11359 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = E->getExprLoc(); 11360 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = E->getSourceRange(); 11361 return false; 11362 } 11363 11364 if (!E->isInstantiationDependent()) { 11365 QualType QTy = E->getType(); 11366 if (!QTy->isScalarType()) { 11367 ErrorInfo.Error = ErrorTy::NotScalar; 11368 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = E->getExprLoc(); 11369 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = E->getSourceRange(); 11370 return false; 11371 } 11372 11373 if (!QTy->isIntegerType()) { 11374 ErrorInfo.Error = ErrorTy::NotInteger; 11375 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = E->getExprLoc(); 11376 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = E->getSourceRange(); 11377 return false; 11378 } 11379 } 11380 11381 return true; 11382 } 11383 }; 11384 11385 bool OpenMPAtomicCompareChecker::checkCondUpdateStmt(IfStmt *S, 11386 ErrorInfoTy &ErrorInfo) { 11387 auto *Then = S->getThen(); 11388 if (auto *CS = dyn_cast<CompoundStmt>(Then)) { 11389 if (CS->body_empty()) { 11390 ErrorInfo.Error = ErrorTy::NoStmt; 11391 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = CS->getBeginLoc(); 11392 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = CS->getSourceRange(); 11393 return false; 11394 } 11395 if (CS->size() > 1) { 11396 ErrorInfo.Error = ErrorTy::MoreThanOneStmt; 11397 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = CS->getBeginLoc(); 11398 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = S->getSourceRange(); 11399 return false; 11400 } 11401 Then = CS->body_front(); 11402 } 11403 11404 auto *BO = dyn_cast<BinaryOperator>(Then); 11405 if (!BO) { 11406 ErrorInfo.Error = ErrorTy::NotAnAssignment; 11407 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = Then->getBeginLoc(); 11408 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = Then->getSourceRange(); 11409 return false; 11410 } 11411 if (BO->getOpcode() != BO_Assign) { 11412 ErrorInfo.Error = ErrorTy::NotAnAssignment; 11413 ErrorInfo.ErrorLoc = BO->getExprLoc(); 11414 ErrorInfo.NoteLoc = BO->getOperatorLoc(); 11415 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = BO->getSourceRange(); 11416 return false; 11417 } 11418 11419 X = BO->getLHS(); 11420 11421 auto *Cond = dyn_cast<BinaryOperator>(S->getCond()); 11422 if (!Cond) { 11423 ErrorInfo.Error = ErrorTy::NotABinaryOp; 11424 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = S->getCond()->getExprLoc(); 11425 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = S->getCond()->getSourceRange(); 11426 return false; 11427 } 11428 11429 switch (Cond->getOpcode()) { 11430 case BO_EQ: { 11431 C = Cond; 11432 D = BO->getRHS(); 11433 if (checkIfTwoExprsAreSame(ContextRef, X, Cond->getLHS())) { 11434 E = Cond->getRHS(); 11435 } else if (checkIfTwoExprsAreSame(ContextRef, X, Cond->getRHS())) { 11436 E = Cond->getLHS(); 11437 } else { 11438 ErrorInfo.Error = ErrorTy::InvalidComparison; 11439 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = Cond->getExprLoc(); 11440 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = Cond->getSourceRange(); 11441 return false; 11442 } 11443 break; 11444 } 11445 case BO_LT: 11446 case BO_GT: { 11447 E = BO->getRHS(); 11448 if (checkIfTwoExprsAreSame(ContextRef, X, Cond->getLHS()) && 11449 checkIfTwoExprsAreSame(ContextRef, E, Cond->getRHS())) { 11450 C = Cond; 11451 } else if (checkIfTwoExprsAreSame(ContextRef, E, Cond->getLHS()) && 11452 checkIfTwoExprsAreSame(ContextRef, X, Cond->getRHS())) { 11453 C = Cond; 11454 IsXBinopExpr = false; 11455 } else { 11456 ErrorInfo.Error = ErrorTy::InvalidComparison; 11457 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = Cond->getExprLoc(); 11458 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = Cond->getSourceRange(); 11459 return false; 11460 } 11461 break; 11462 } 11463 default: 11464 ErrorInfo.Error = ErrorTy::InvalidBinaryOp; 11465 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = Cond->getExprLoc(); 11466 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = Cond->getSourceRange(); 11467 return false; 11468 } 11469 11470 if (S->getElse()) { 11471 ErrorInfo.Error = ErrorTy::UnexpectedElse; 11472 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = S->getElse()->getBeginLoc(); 11473 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = S->getElse()->getSourceRange(); 11474 return false; 11475 } 11476 11477 return true; 11478 } 11479 11480 bool OpenMPAtomicCompareChecker::checkCondExprStmt(Stmt *S, 11481 ErrorInfoTy &ErrorInfo) { 11482 auto *BO = dyn_cast<BinaryOperator>(S); 11483 if (!BO) { 11484 ErrorInfo.Error = ErrorTy::NotAnAssignment; 11485 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = S->getBeginLoc(); 11486 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = S->getSourceRange(); 11487 return false; 11488 } 11489 if (BO->getOpcode() != BO_Assign) { 11490 ErrorInfo.Error = ErrorTy::NotAnAssignment; 11491 ErrorInfo.ErrorLoc = BO->getExprLoc(); 11492 ErrorInfo.NoteLoc = BO->getOperatorLoc(); 11493 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = BO->getSourceRange(); 11494 return false; 11495 } 11496 11497 X = BO->getLHS(); 11498 11499 auto *CO = dyn_cast<ConditionalOperator>(BO->getRHS()->IgnoreParenImpCasts()); 11500 if (!CO) { 11501 ErrorInfo.Error = ErrorTy::NotCondOp; 11502 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = BO->getRHS()->getExprLoc(); 11503 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = BO->getRHS()->getSourceRange(); 11504 return false; 11505 } 11506 11507 if (!checkIfTwoExprsAreSame(ContextRef, X, CO->getFalseExpr())) { 11508 ErrorInfo.Error = ErrorTy::WrongFalseExpr; 11509 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = CO->getFalseExpr()->getExprLoc(); 11510 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = 11511 CO->getFalseExpr()->getSourceRange(); 11512 return false; 11513 } 11514 11515 auto *Cond = dyn_cast<BinaryOperator>(CO->getCond()); 11516 if (!Cond) { 11517 ErrorInfo.Error = ErrorTy::NotABinaryOp; 11518 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = CO->getCond()->getExprLoc(); 11519 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = 11520 CO->getCond()->getSourceRange(); 11521 return false; 11522 } 11523 11524 switch (Cond->getOpcode()) { 11525 case BO_EQ: { 11526 C = Cond; 11527 D = CO->getTrueExpr(); 11528 if (checkIfTwoExprsAreSame(ContextRef, X, Cond->getLHS())) { 11529 E = Cond->getRHS(); 11530 } else if (checkIfTwoExprsAreSame(ContextRef, X, Cond->getRHS())) { 11531 E = Cond->getLHS(); 11532 } else { 11533 ErrorInfo.Error = ErrorTy::InvalidComparison; 11534 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = Cond->getExprLoc(); 11535 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = Cond->getSourceRange(); 11536 return false; 11537 } 11538 break; 11539 } 11540 case BO_LT: 11541 case BO_GT: { 11542 E = CO->getTrueExpr(); 11543 if (checkIfTwoExprsAreSame(ContextRef, X, Cond->getLHS()) && 11544 checkIfTwoExprsAreSame(ContextRef, E, Cond->getRHS())) { 11545 C = Cond; 11546 } else if (checkIfTwoExprsAreSame(ContextRef, E, Cond->getLHS()) && 11547 checkIfTwoExprsAreSame(ContextRef, X, Cond->getRHS())) { 11548 C = Cond; 11549 IsXBinopExpr = false; 11550 } else { 11551 ErrorInfo.Error = ErrorTy::InvalidComparison; 11552 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = Cond->getExprLoc(); 11553 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = Cond->getSourceRange(); 11554 return false; 11555 } 11556 break; 11557 } 11558 default: 11559 ErrorInfo.Error = ErrorTy::InvalidBinaryOp; 11560 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = Cond->getExprLoc(); 11561 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = Cond->getSourceRange(); 11562 return false; 11563 } 11564 11565 return true; 11566 } 11567 11568 bool OpenMPAtomicCompareChecker::checkType(ErrorInfoTy &ErrorInfo) const { 11569 // 'x' and 'e' cannot be nullptr 11570 assert(X && E && "X and E cannot be nullptr"); 11571 11572 if (!CheckValue(X, ErrorInfo, true)) 11573 return false; 11574 11575 if (!CheckValue(E, ErrorInfo, false)) 11576 return false; 11577 11578 if (D && !CheckValue(D, ErrorInfo, false)) 11579 return false; 11580 11581 return true; 11582 } 11583 11584 bool OpenMPAtomicCompareChecker::checkStmt( 11585 Stmt *S, OpenMPAtomicCompareChecker::ErrorInfoTy &ErrorInfo) { 11586 auto *CS = dyn_cast<CompoundStmt>(S); 11587 if (CS) { 11588 if (CS->body_empty()) { 11589 ErrorInfo.Error = ErrorTy::NoStmt; 11590 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = CS->getBeginLoc(); 11591 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = CS->getSourceRange(); 11592 return false; 11593 } 11594 11595 if (CS->size() != 1) { 11596 ErrorInfo.Error = ErrorTy::MoreThanOneStmt; 11597 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = CS->getBeginLoc(); 11598 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = CS->getSourceRange(); 11599 return false; 11600 } 11601 S = CS->body_front(); 11602 } 11603 11604 auto Res = false; 11605 11606 if (auto *IS = dyn_cast<IfStmt>(S)) { 11607 // Check if the statement is in one of the following forms 11608 // (cond-update-stmt): 11609 // if (expr ordop x) { x = expr; } 11610 // if (x ordop expr) { x = expr; } 11611 // if (x == e) { x = d; } 11612 Res = checkCondUpdateStmt(IS, ErrorInfo); 11613 } else { 11614 // Check if the statement is in one of the following forms (cond-expr-stmt): 11615 // x = expr ordop x ? expr : x; 11616 // x = x ordop expr ? expr : x; 11617 // x = x == e ? d : x; 11618 Res = checkCondExprStmt(S, ErrorInfo); 11619 } 11620 11621 if (!Res) 11622 return false; 11623 11624 return checkType(ErrorInfo); 11625 } 11626 11627 class OpenMPAtomicCompareCaptureChecker final 11628 : public OpenMPAtomicCompareChecker { 11629 public: 11630 OpenMPAtomicCompareCaptureChecker(Sema &S) : OpenMPAtomicCompareChecker(S) {} 11631 11632 Expr *getV() const { return V; } 11633 Expr *getR() const { return R; } 11634 bool isFailOnly() const { return IsFailOnly; } 11635 bool isPostfixUpdate() const { return IsPostfixUpdate; } 11636 11637 /// Check if statement \a S is valid for <tt>atomic compare capture</tt>. 11638 bool checkStmt(Stmt *S, ErrorInfoTy &ErrorInfo); 11639 11640 private: 11641 bool checkType(ErrorInfoTy &ErrorInfo); 11642 11643 // NOTE: Form 3, 4, 5 in the following comments mean the 3rd, 4th, and 5th 11644 // form of 'conditional-update-capture-atomic' structured block on the v5.2 11645 // spec p.p. 82: 11646 // (1) { v = x; cond-update-stmt } 11647 // (2) { cond-update-stmt v = x; } 11648 // (3) if(x == e) { x = d; } else { v = x; } 11649 // (4) { r = x == e; if(r) { x = d; } } 11650 // (5) { r = x == e; if(r) { x = d; } else { v = x; } } 11651 11652 /// Check if it is valid 'if(x == e) { x = d; } else { v = x; }' (form 3) 11653 bool checkForm3(IfStmt *S, ErrorInfoTy &ErrorInfo); 11654 11655 /// Check if it is valid '{ r = x == e; if(r) { x = d; } }', 11656 /// or '{ r = x == e; if(r) { x = d; } else { v = x; } }' (form 4 and 5) 11657 bool checkForm45(Stmt *S, ErrorInfoTy &ErrorInfo); 11658 11659 /// 'v' lvalue part of the source atomic expression. 11660 Expr *V = nullptr; 11661 /// 'r' lvalue part of the source atomic expression. 11662 Expr *R = nullptr; 11663 /// If 'v' is only updated when the comparison fails. 11664 bool IsFailOnly = false; 11665 /// If original value of 'x' must be stored in 'v', not an updated one. 11666 bool IsPostfixUpdate = false; 11667 }; 11668 11669 bool OpenMPAtomicCompareCaptureChecker::checkType(ErrorInfoTy &ErrorInfo) { 11670 if (!OpenMPAtomicCompareChecker::checkType(ErrorInfo)) 11671 return false; 11672 11673 if (V && !CheckValue(V, ErrorInfo, true)) 11674 return false; 11675 11676 if (R && !CheckValue(R, ErrorInfo, true)) 11677 return false; 11678 11679 return true; 11680 } 11681 11682 bool OpenMPAtomicCompareCaptureChecker::checkForm3(IfStmt *S, 11683 ErrorInfoTy &ErrorInfo) { 11684 IsFailOnly = true; 11685 11686 auto *Then = S->getThen(); 11687 if (auto *CS = dyn_cast<CompoundStmt>(Then)) { 11688 if (CS->body_empty()) { 11689 ErrorInfo.Error = ErrorTy::NoStmt; 11690 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = CS->getBeginLoc(); 11691 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = CS->getSourceRange(); 11692 return false; 11693 } 11694 if (CS->size() > 1) { 11695 ErrorInfo.Error = ErrorTy::MoreThanOneStmt; 11696 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = CS->getBeginLoc(); 11697 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = CS->getSourceRange(); 11698 return false; 11699 } 11700 Then = CS->body_front(); 11701 } 11702 11703 auto *BO = dyn_cast<BinaryOperator>(Then); 11704 if (!BO) { 11705 ErrorInfo.Error = ErrorTy::NotAnAssignment; 11706 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = Then->getBeginLoc(); 11707 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = Then->getSourceRange(); 11708 return false; 11709 } 11710 if (BO->getOpcode() != BO_Assign) { 11711 ErrorInfo.Error = ErrorTy::NotAnAssignment; 11712 ErrorInfo.ErrorLoc = BO->getExprLoc(); 11713 ErrorInfo.NoteLoc = BO->getOperatorLoc(); 11714 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = BO->getSourceRange(); 11715 return false; 11716 } 11717 11718 X = BO->getLHS(); 11719 D = BO->getRHS(); 11720 11721 auto *Cond = dyn_cast<BinaryOperator>(S->getCond()); 11722 if (!Cond) { 11723 ErrorInfo.Error = ErrorTy::NotABinaryOp; 11724 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = S->getCond()->getExprLoc(); 11725 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = S->getCond()->getSourceRange(); 11726 return false; 11727 } 11728 if (Cond->getOpcode() != BO_EQ) { 11729 ErrorInfo.Error = ErrorTy::NotEQ; 11730 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = Cond->getExprLoc(); 11731 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = Cond->getSourceRange(); 11732 return false; 11733 } 11734 11735 if (checkIfTwoExprsAreSame(ContextRef, X, Cond->getLHS())) { 11736 E = Cond->getRHS(); 11737 } else if (checkIfTwoExprsAreSame(ContextRef, X, Cond->getRHS())) { 11738 E = Cond->getLHS(); 11739 } else { 11740 ErrorInfo.Error = ErrorTy::InvalidComparison; 11741 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = Cond->getExprLoc(); 11742 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = Cond->getSourceRange(); 11743 return false; 11744 } 11745 11746 C = Cond; 11747 11748 if (!S->getElse()) { 11749 ErrorInfo.Error = ErrorTy::NoElse; 11750 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = S->getBeginLoc(); 11751 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = S->getSourceRange(); 11752 return false; 11753 } 11754 11755 auto *Else = S->getElse(); 11756 if (auto *CS = dyn_cast<CompoundStmt>(Else)) { 11757 if (CS->body_empty()) { 11758 ErrorInfo.Error = ErrorTy::NoStmt; 11759 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = CS->getBeginLoc(); 11760 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = CS->getSourceRange(); 11761 return false; 11762 } 11763 if (CS->size() > 1) { 11764 ErrorInfo.Error = ErrorTy::MoreThanOneStmt; 11765 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = CS->getBeginLoc(); 11766 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = S->getSourceRange(); 11767 return false; 11768 } 11769 Else = CS->body_front(); 11770 } 11771 11772 auto *ElseBO = dyn_cast<BinaryOperator>(Else); 11773 if (!ElseBO) { 11774 ErrorInfo.Error = ErrorTy::NotAnAssignment; 11775 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = Else->getBeginLoc(); 11776 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = Else->getSourceRange(); 11777 return false; 11778 } 11779 if (ElseBO->getOpcode() != BO_Assign) { 11780 ErrorInfo.Error = ErrorTy::NotAnAssignment; 11781 ErrorInfo.ErrorLoc = ElseBO->getExprLoc(); 11782 ErrorInfo.NoteLoc = ElseBO->getOperatorLoc(); 11783 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = ElseBO->getSourceRange(); 11784 return false; 11785 } 11786 11787 if (!checkIfTwoExprsAreSame(ContextRef, X, ElseBO->getRHS())) { 11788 ErrorInfo.Error = ErrorTy::InvalidAssignment; 11789 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = ElseBO->getRHS()->getExprLoc(); 11790 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = 11791 ElseBO->getRHS()->getSourceRange(); 11792 return false; 11793 } 11794 11795 V = ElseBO->getLHS(); 11796 11797 return checkType(ErrorInfo); 11798 } 11799 11800 bool OpenMPAtomicCompareCaptureChecker::checkForm45(Stmt *S, 11801 ErrorInfoTy &ErrorInfo) { 11802 // We don't check here as they should be already done before call this 11803 // function. 11804 auto *CS = cast<CompoundStmt>(S); 11805 assert(CS->size() == 2 && "CompoundStmt size is not expected"); 11806 auto *S1 = cast<BinaryOperator>(CS->body_front()); 11807 auto *S2 = cast<IfStmt>(CS->body_back()); 11808 assert(S1->getOpcode() == BO_Assign && "unexpected binary operator"); 11809 11810 if (!checkIfTwoExprsAreSame(ContextRef, S1->getLHS(), S2->getCond())) { 11811 ErrorInfo.Error = ErrorTy::InvalidCondition; 11812 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = S2->getCond()->getExprLoc(); 11813 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = S1->getLHS()->getSourceRange(); 11814 return false; 11815 } 11816 11817 R = S1->getLHS(); 11818 11819 auto *Then = S2->getThen(); 11820 if (auto *ThenCS = dyn_cast<CompoundStmt>(Then)) { 11821 if (ThenCS->body_empty()) { 11822 ErrorInfo.Error = ErrorTy::NoStmt; 11823 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = ThenCS->getBeginLoc(); 11824 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = ThenCS->getSourceRange(); 11825 return false; 11826 } 11827 if (ThenCS->size() > 1) { 11828 ErrorInfo.Error = ErrorTy::MoreThanOneStmt; 11829 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = ThenCS->getBeginLoc(); 11830 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = ThenCS->getSourceRange(); 11831 return false; 11832 } 11833 Then = ThenCS->body_front(); 11834 } 11835 11836 auto *ThenBO = dyn_cast<BinaryOperator>(Then); 11837 if (!ThenBO) { 11838 ErrorInfo.Error = ErrorTy::NotAnAssignment; 11839 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = S2->getBeginLoc(); 11840 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = S2->getSourceRange(); 11841 return false; 11842 } 11843 if (ThenBO->getOpcode() != BO_Assign) { 11844 ErrorInfo.Error = ErrorTy::NotAnAssignment; 11845 ErrorInfo.ErrorLoc = ThenBO->getExprLoc(); 11846 ErrorInfo.NoteLoc = ThenBO->getOperatorLoc(); 11847 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = ThenBO->getSourceRange(); 11848 return false; 11849 } 11850 11851 X = ThenBO->getLHS(); 11852 D = ThenBO->getRHS(); 11853 11854 auto *BO = cast<BinaryOperator>(S1->getRHS()->IgnoreImpCasts()); 11855 if (BO->getOpcode() != BO_EQ) { 11856 ErrorInfo.Error = ErrorTy::NotEQ; 11857 ErrorInfo.ErrorLoc = BO->getExprLoc(); 11858 ErrorInfo.NoteLoc = BO->getOperatorLoc(); 11859 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = BO->getSourceRange(); 11860 return false; 11861 } 11862 11863 C = BO; 11864 11865 if (checkIfTwoExprsAreSame(ContextRef, X, BO->getLHS())) { 11866 E = BO->getRHS(); 11867 } else if (checkIfTwoExprsAreSame(ContextRef, X, BO->getRHS())) { 11868 E = BO->getLHS(); 11869 } else { 11870 ErrorInfo.Error = ErrorTy::InvalidComparison; 11871 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = BO->getExprLoc(); 11872 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = BO->getSourceRange(); 11873 return false; 11874 } 11875 11876 if (S2->getElse()) { 11877 IsFailOnly = true; 11878 11879 auto *Else = S2->getElse(); 11880 if (auto *ElseCS = dyn_cast<CompoundStmt>(Else)) { 11881 if (ElseCS->body_empty()) { 11882 ErrorInfo.Error = ErrorTy::NoStmt; 11883 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = ElseCS->getBeginLoc(); 11884 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = ElseCS->getSourceRange(); 11885 return false; 11886 } 11887 if (ElseCS->size() > 1) { 11888 ErrorInfo.Error = ErrorTy::MoreThanOneStmt; 11889 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = ElseCS->getBeginLoc(); 11890 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = ElseCS->getSourceRange(); 11891 return false; 11892 } 11893 Else = ElseCS->body_front(); 11894 } 11895 11896 auto *ElseBO = dyn_cast<BinaryOperator>(Else); 11897 if (!ElseBO) { 11898 ErrorInfo.Error = ErrorTy::NotAnAssignment; 11899 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = Else->getBeginLoc(); 11900 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = Else->getSourceRange(); 11901 return false; 11902 } 11903 if (ElseBO->getOpcode() != BO_Assign) { 11904 ErrorInfo.Error = ErrorTy::NotAnAssignment; 11905 ErrorInfo.ErrorLoc = ElseBO->getExprLoc(); 11906 ErrorInfo.NoteLoc = ElseBO->getOperatorLoc(); 11907 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = ElseBO->getSourceRange(); 11908 return false; 11909 } 11910 if (!checkIfTwoExprsAreSame(ContextRef, X, ElseBO->getRHS())) { 11911 ErrorInfo.Error = ErrorTy::InvalidAssignment; 11912 ErrorInfo.ErrorLoc = ElseBO->getRHS()->getExprLoc(); 11913 ErrorInfo.NoteLoc = X->getExprLoc(); 11914 ErrorInfo.ErrorRange = ElseBO->getRHS()->getSourceRange(); 11915 ErrorInfo.NoteRange = X->getSourceRange(); 11916 return false; 11917 } 11918 11919 V = ElseBO->getLHS(); 11920 } 11921 11922 return checkType(ErrorInfo); 11923 } 11924 11925 bool OpenMPAtomicCompareCaptureChecker::checkStmt(Stmt *S, 11926 ErrorInfoTy &ErrorInfo) { 11927 // if(x == e) { x = d; } else { v = x; } 11928 if (auto *IS = dyn_cast<IfStmt>(S)) 11929 return checkForm3(IS, ErrorInfo); 11930 11931 auto *CS = dyn_cast<CompoundStmt>(S); 11932 if (!CS) { 11933 ErrorInfo.Error = ErrorTy::NotCompoundStmt; 11934 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = S->getBeginLoc(); 11935 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = S->getSourceRange(); 11936 return false; 11937 } 11938 if (CS->body_empty()) { 11939 ErrorInfo.Error = ErrorTy::NoStmt; 11940 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = CS->getBeginLoc(); 11941 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = CS->getSourceRange(); 11942 return false; 11943 } 11944 11945 // { if(x == e) { x = d; } else { v = x; } } 11946 if (CS->size() == 1) { 11947 auto *IS = dyn_cast<IfStmt>(CS->body_front()); 11948 if (!IS) { 11949 ErrorInfo.Error = ErrorTy::NotIfStmt; 11950 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = CS->body_front()->getBeginLoc(); 11951 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = 11952 CS->body_front()->getSourceRange(); 11953 return false; 11954 } 11955 11956 return checkForm3(IS, ErrorInfo); 11957 } else if (CS->size() == 2) { 11958 auto *S1 = CS->body_front(); 11959 auto *S2 = CS->body_back(); 11960 11961 Stmt *UpdateStmt = nullptr; 11962 Stmt *CondUpdateStmt = nullptr; 11963 11964 if (auto *BO = dyn_cast<BinaryOperator>(S1)) { 11965 // { v = x; cond-update-stmt } or form 45. 11966 UpdateStmt = S1; 11967 CondUpdateStmt = S2; 11968 // Check if form 45. 11969 if (isa<BinaryOperator>(BO->getRHS()->IgnoreImpCasts()) && 11970 isa<IfStmt>(S2)) 11971 return checkForm45(CS, ErrorInfo); 11972 // It cannot be set before we the check for form45. 11973 IsPostfixUpdate = true; 11974 } else { 11975 // { cond-update-stmt v = x; } 11976 UpdateStmt = S2; 11977 CondUpdateStmt = S1; 11978 } 11979 11980 auto CheckCondUpdateStmt = [this, &ErrorInfo](Stmt *CUS) { 11981 auto *IS = dyn_cast<IfStmt>(CUS); 11982 if (!IS) { 11983 ErrorInfo.Error = ErrorTy::NotIfStmt; 11984 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = CUS->getBeginLoc(); 11985 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = CUS->getSourceRange(); 11986 return false; 11987 } 11988 11989 if (!checkCondUpdateStmt(IS, ErrorInfo)) 11990 return false; 11991 11992 return true; 11993 }; 11994 11995 // CheckUpdateStmt has to be called *after* CheckCondUpdateStmt. 11996 auto CheckUpdateStmt = [this, &ErrorInfo](Stmt *US) { 11997 auto *BO = dyn_cast<BinaryOperator>(US); 11998 if (!BO) { 11999 ErrorInfo.Error = ErrorTy::NotAnAssignment; 12000 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = US->getBeginLoc(); 12001 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = US->getSourceRange(); 12002 return false; 12003 } 12004 if (BO->getOpcode() != BO_Assign) { 12005 ErrorInfo.Error = ErrorTy::NotAnAssignment; 12006 ErrorInfo.ErrorLoc = BO->getExprLoc(); 12007 ErrorInfo.NoteLoc = BO->getOperatorLoc(); 12008 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = BO->getSourceRange(); 12009 return false; 12010 } 12011 if (!checkIfTwoExprsAreSame(ContextRef, this->X, BO->getRHS())) { 12012 ErrorInfo.Error = ErrorTy::InvalidAssignment; 12013 ErrorInfo.ErrorLoc = BO->getRHS()->getExprLoc(); 12014 ErrorInfo.NoteLoc = this->X->getExprLoc(); 12015 ErrorInfo.ErrorRange = BO->getRHS()->getSourceRange(); 12016 ErrorInfo.NoteRange = this->X->getSourceRange(); 12017 return false; 12018 } 12019 12020 this->V = BO->getLHS(); 12021 12022 return true; 12023 }; 12024 12025 if (!CheckCondUpdateStmt(CondUpdateStmt)) 12026 return false; 12027 if (!CheckUpdateStmt(UpdateStmt)) 12028 return false; 12029 } else { 12030 ErrorInfo.Error = ErrorTy::MoreThanTwoStmts; 12031 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = CS->getBeginLoc(); 12032 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = CS->getSourceRange(); 12033 return false; 12034 } 12035 12036 return checkType(ErrorInfo); 12037 } 12038 } // namespace 12039 12040 StmtResult Sema::ActOnOpenMPAtomicDirective(ArrayRef<OMPClause *> Clauses, 12041 Stmt *AStmt, 12042 SourceLocation StartLoc, 12043 SourceLocation EndLoc) { 12044 // Register location of the first atomic directive. 12045 DSAStack->addAtomicDirectiveLoc(StartLoc); 12046 if (!AStmt) 12047 return StmtError(); 12048 12049 // 1.2.2 OpenMP Language Terminology 12050 // Structured block - An executable statement with a single entry at the 12051 // top and a single exit at the bottom. 12052 // The point of exit cannot be a branch out of the structured block. 12053 // longjmp() and throw() must not violate the entry/exit criteria. 12054 OpenMPClauseKind AtomicKind = OMPC_unknown; 12055 SourceLocation AtomicKindLoc; 12056 OpenMPClauseKind MemOrderKind = OMPC_unknown; 12057 SourceLocation MemOrderLoc; 12058 bool MutexClauseEncountered = false; 12059 llvm::SmallSet<OpenMPClauseKind, 2> EncounteredAtomicKinds; 12060 for (const OMPClause *C : Clauses) { 12061 switch (C->getClauseKind()) { 12062 case OMPC_read: 12063 case OMPC_write: 12064 case OMPC_update: 12065 MutexClauseEncountered = true; 12066 LLVM_FALLTHROUGH; 12067 case OMPC_capture: 12068 case OMPC_compare: { 12069 if (AtomicKind != OMPC_unknown && MutexClauseEncountered) { 12070 Diag(C->getBeginLoc(), diag::err_omp_atomic_several_clauses) 12071 << SourceRange(C->getBeginLoc(), C->getEndLoc()); 12072 Diag(AtomicKindLoc, diag::note_omp_previous_mem_order_clause) 12073 << getOpenMPClauseName(AtomicKind); 12074 } else { 12075 AtomicKind = C->getClauseKind(); 12076 AtomicKindLoc = C->getBeginLoc(); 12077 if (!EncounteredAtomicKinds.insert(C->getClauseKind()).second) { 12078 Diag(C->getBeginLoc(), diag::err_omp_atomic_several_clauses) 12079 << SourceRange(C->getBeginLoc(), C->getEndLoc()); 12080 Diag(AtomicKindLoc, diag::note_omp_previous_mem_order_clause) 12081 << getOpenMPClauseName(AtomicKind); 12082 } 12083 } 12084 break; 12085 } 12086 case OMPC_seq_cst: 12087 case OMPC_acq_rel: 12088 case OMPC_acquire: 12089 case OMPC_release: 12090 case OMPC_relaxed: { 12091 if (MemOrderKind != OMPC_unknown) { 12092 Diag(C->getBeginLoc(), diag::err_omp_several_mem_order_clauses) 12093 << getOpenMPDirectiveName(OMPD_atomic) << 0 12094 << SourceRange(C->getBeginLoc(), C->getEndLoc()); 12095 Diag(MemOrderLoc, diag::note_omp_previous_mem_order_clause) 12096 << getOpenMPClauseName(MemOrderKind); 12097 } else { 12098 MemOrderKind = C->getClauseKind(); 12099 MemOrderLoc = C->getBeginLoc(); 12100 } 12101 break; 12102 } 12103 // The following clauses are allowed, but we don't need to do anything here. 12104 case OMPC_hint: 12105 break; 12106 default: 12107 llvm_unreachable("unknown clause is encountered"); 12108 } 12109 } 12110 bool IsCompareCapture = false; 12111 if (EncounteredAtomicKinds.contains(OMPC_compare) && 12112 EncounteredAtomicKinds.contains(OMPC_capture)) { 12113 IsCompareCapture = true; 12114 AtomicKind = OMPC_compare; 12115 } 12116 // OpenMP 5.0, 2.17.7 atomic Construct, Restrictions 12117 // If atomic-clause is read then memory-order-clause must not be acq_rel or 12118 // release. 12119 // If atomic-clause is write then memory-order-clause must not be acq_rel or 12120 // acquire. 12121 // If atomic-clause is update or not present then memory-order-clause must not 12122 // be acq_rel or acquire. 12123 if ((AtomicKind == OMPC_read && 12124 (MemOrderKind == OMPC_acq_rel || MemOrderKind == OMPC_release)) || 12125 ((AtomicKind == OMPC_write || AtomicKind == OMPC_update || 12126 AtomicKind == OMPC_unknown) && 12127 (MemOrderKind == OMPC_acq_rel || MemOrderKind == OMPC_acquire))) { 12128 SourceLocation Loc = AtomicKindLoc; 12129 if (AtomicKind == OMPC_unknown) 12130 Loc = StartLoc; 12131 Diag(Loc, diag::err_omp_atomic_incompatible_mem_order_clause) 12132 << getOpenMPClauseName(AtomicKind) 12133 << (AtomicKind == OMPC_unknown ? 1 : 0) 12134 << getOpenMPClauseName(MemOrderKind); 12135 Diag(MemOrderLoc, diag::note_omp_previous_mem_order_clause) 12136 << getOpenMPClauseName(MemOrderKind); 12137 } 12138 12139 Stmt *Body = AStmt; 12140 if (auto *EWC = dyn_cast<ExprWithCleanups>(Body)) 12141 Body = EWC->getSubExpr(); 12142 12143 Expr *X = nullptr; 12144 Expr *V = nullptr; 12145 Expr *E = nullptr; 12146 Expr *UE = nullptr; 12147 Expr *D = nullptr; 12148 Expr *CE = nullptr; 12149 Expr *R = nullptr; 12150 bool IsXLHSInRHSPart = false; 12151 bool IsPostfixUpdate = false; 12152 bool IsFailOnly = false; 12153 // OpenMP [2.12.6, atomic Construct] 12154 // In the next expressions: 12155 // * x and v (as applicable) are both l-value expressions with scalar type. 12156 // * During the execution of an atomic region, multiple syntactic 12157 // occurrences of x must designate the same storage location. 12158 // * Neither of v and expr (as applicable) may access the storage location 12159 // designated by x. 12160 // * Neither of x and expr (as applicable) may access the storage location 12161 // designated by v. 12162 // * expr is an expression with scalar type. 12163 // * binop is one of +, *, -, /, &, ^, |, <<, or >>. 12164 // * binop, binop=, ++, and -- are not overloaded operators. 12165 // * The expression x binop expr must be numerically equivalent to x binop 12166 // (expr). This requirement is satisfied if the operators in expr have 12167 // precedence greater than binop, or by using parentheses around expr or 12168 // subexpressions of expr. 12169 // * The expression expr binop x must be numerically equivalent to (expr) 12170 // binop x. This requirement is satisfied if the operators in expr have 12171 // precedence equal to or greater than binop, or by using parentheses around 12172 // expr or subexpressions of expr. 12173 // * For forms that allow multiple occurrences of x, the number of times 12174 // that x is evaluated is unspecified. 12175 if (AtomicKind == OMPC_read) { 12176 enum { 12177 NotAnExpression, 12178 NotAnAssignmentOp, 12179 NotAScalarType, 12180 NotAnLValue, 12181 NoError 12182 } ErrorFound = NoError; 12183 SourceLocation ErrorLoc, NoteLoc; 12184 SourceRange ErrorRange, NoteRange; 12185 // If clause is read: 12186 // v = x; 12187 if (const auto *AtomicBody = dyn_cast<Expr>(Body)) { 12188 const auto *AtomicBinOp = 12189 dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts()); 12190 if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) { 12191 X = AtomicBinOp->getRHS()->IgnoreParenImpCasts(); 12192 V = AtomicBinOp->getLHS()->IgnoreParenImpCasts(); 12193 if ((X->isInstantiationDependent() || X->getType()->isScalarType()) && 12194 (V->isInstantiationDependent() || V->getType()->isScalarType())) { 12195 if (!X->isLValue() || !V->isLValue()) { 12196 const Expr *NotLValueExpr = X->isLValue() ? V : X; 12197 ErrorFound = NotAnLValue; 12198 ErrorLoc = AtomicBinOp->getExprLoc(); 12199 ErrorRange = AtomicBinOp->getSourceRange(); 12200 NoteLoc = NotLValueExpr->getExprLoc(); 12201 NoteRange = NotLValueExpr->getSourceRange(); 12202 } 12203 } else if (!X->isInstantiationDependent() || 12204 !V->isInstantiationDependent()) { 12205 const Expr *NotScalarExpr = 12206 (X->isInstantiationDependent() || X->getType()->isScalarType()) 12207 ? V 12208 : X; 12209 ErrorFound = NotAScalarType; 12210 ErrorLoc = AtomicBinOp->getExprLoc(); 12211 ErrorRange = AtomicBinOp->getSourceRange(); 12212 NoteLoc = NotScalarExpr->getExprLoc(); 12213 NoteRange = NotScalarExpr->getSourceRange(); 12214 } 12215 } else if (!AtomicBody->isInstantiationDependent()) { 12216 ErrorFound = NotAnAssignmentOp; 12217 ErrorLoc = AtomicBody->getExprLoc(); 12218 ErrorRange = AtomicBody->getSourceRange(); 12219 NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc() 12220 : AtomicBody->getExprLoc(); 12221 NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange() 12222 : AtomicBody->getSourceRange(); 12223 } 12224 } else { 12225 ErrorFound = NotAnExpression; 12226 NoteLoc = ErrorLoc = Body->getBeginLoc(); 12227 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc); 12228 } 12229 if (ErrorFound != NoError) { 12230 Diag(ErrorLoc, diag::err_omp_atomic_read_not_expression_statement) 12231 << ErrorRange; 12232 Diag(NoteLoc, diag::note_omp_atomic_read_write) 12233 << ErrorFound << NoteRange; 12234 return StmtError(); 12235 } 12236 if (CurContext->isDependentContext()) 12237 V = X = nullptr; 12238 } else if (AtomicKind == OMPC_write) { 12239 enum { 12240 NotAnExpression, 12241 NotAnAssignmentOp, 12242 NotAScalarType, 12243 NotAnLValue, 12244 NoError 12245 } ErrorFound = NoError; 12246 SourceLocation ErrorLoc, NoteLoc; 12247 SourceRange ErrorRange, NoteRange; 12248 // If clause is write: 12249 // x = expr; 12250 if (const auto *AtomicBody = dyn_cast<Expr>(Body)) { 12251 const auto *AtomicBinOp = 12252 dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts()); 12253 if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) { 12254 X = AtomicBinOp->getLHS(); 12255 E = AtomicBinOp->getRHS(); 12256 if ((X->isInstantiationDependent() || X->getType()->isScalarType()) && 12257 (E->isInstantiationDependent() || E->getType()->isScalarType())) { 12258 if (!X->isLValue()) { 12259 ErrorFound = NotAnLValue; 12260 ErrorLoc = AtomicBinOp->getExprLoc(); 12261 ErrorRange = AtomicBinOp->getSourceRange(); 12262 NoteLoc = X->getExprLoc(); 12263 NoteRange = X->getSourceRange(); 12264 } 12265 } else if (!X->isInstantiationDependent() || 12266 !E->isInstantiationDependent()) { 12267 const Expr *NotScalarExpr = 12268 (X->isInstantiationDependent() || X->getType()->isScalarType()) 12269 ? E 12270 : X; 12271 ErrorFound = NotAScalarType; 12272 ErrorLoc = AtomicBinOp->getExprLoc(); 12273 ErrorRange = AtomicBinOp->getSourceRange(); 12274 NoteLoc = NotScalarExpr->getExprLoc(); 12275 NoteRange = NotScalarExpr->getSourceRange(); 12276 } 12277 } else if (!AtomicBody->isInstantiationDependent()) { 12278 ErrorFound = NotAnAssignmentOp; 12279 ErrorLoc = AtomicBody->getExprLoc(); 12280 ErrorRange = AtomicBody->getSourceRange(); 12281 NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc() 12282 : AtomicBody->getExprLoc(); 12283 NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange() 12284 : AtomicBody->getSourceRange(); 12285 } 12286 } else { 12287 ErrorFound = NotAnExpression; 12288 NoteLoc = ErrorLoc = Body->getBeginLoc(); 12289 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc); 12290 } 12291 if (ErrorFound != NoError) { 12292 Diag(ErrorLoc, diag::err_omp_atomic_write_not_expression_statement) 12293 << ErrorRange; 12294 Diag(NoteLoc, diag::note_omp_atomic_read_write) 12295 << ErrorFound << NoteRange; 12296 return StmtError(); 12297 } 12298 if (CurContext->isDependentContext()) 12299 E = X = nullptr; 12300 } else if (AtomicKind == OMPC_update || AtomicKind == OMPC_unknown) { 12301 // If clause is update: 12302 // x++; 12303 // x--; 12304 // ++x; 12305 // --x; 12306 // x binop= expr; 12307 // x = x binop expr; 12308 // x = expr binop x; 12309 OpenMPAtomicUpdateChecker Checker(*this); 12310 if (Checker.checkStatement( 12311 Body, 12312 (AtomicKind == OMPC_update) 12313 ? diag::err_omp_atomic_update_not_expression_statement 12314 : diag::err_omp_atomic_not_expression_statement, 12315 diag::note_omp_atomic_update)) 12316 return StmtError(); 12317 if (!CurContext->isDependentContext()) { 12318 E = Checker.getExpr(); 12319 X = Checker.getX(); 12320 UE = Checker.getUpdateExpr(); 12321 IsXLHSInRHSPart = Checker.isXLHSInRHSPart(); 12322 } 12323 } else if (AtomicKind == OMPC_capture) { 12324 enum { 12325 NotAnAssignmentOp, 12326 NotACompoundStatement, 12327 NotTwoSubstatements, 12328 NotASpecificExpression, 12329 NoError 12330 } ErrorFound = NoError; 12331 SourceLocation ErrorLoc, NoteLoc; 12332 SourceRange ErrorRange, NoteRange; 12333 if (const auto *AtomicBody = dyn_cast<Expr>(Body)) { 12334 // If clause is a capture: 12335 // v = x++; 12336 // v = x--; 12337 // v = ++x; 12338 // v = --x; 12339 // v = x binop= expr; 12340 // v = x = x binop expr; 12341 // v = x = expr binop x; 12342 const auto *AtomicBinOp = 12343 dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts()); 12344 if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) { 12345 V = AtomicBinOp->getLHS(); 12346 Body = AtomicBinOp->getRHS()->IgnoreParenImpCasts(); 12347 OpenMPAtomicUpdateChecker Checker(*this); 12348 if (Checker.checkStatement( 12349 Body, diag::err_omp_atomic_capture_not_expression_statement, 12350 diag::note_omp_atomic_update)) 12351 return StmtError(); 12352 E = Checker.getExpr(); 12353 X = Checker.getX(); 12354 UE = Checker.getUpdateExpr(); 12355 IsXLHSInRHSPart = Checker.isXLHSInRHSPart(); 12356 IsPostfixUpdate = Checker.isPostfixUpdate(); 12357 } else if (!AtomicBody->isInstantiationDependent()) { 12358 ErrorLoc = AtomicBody->getExprLoc(); 12359 ErrorRange = AtomicBody->getSourceRange(); 12360 NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc() 12361 : AtomicBody->getExprLoc(); 12362 NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange() 12363 : AtomicBody->getSourceRange(); 12364 ErrorFound = NotAnAssignmentOp; 12365 } 12366 if (ErrorFound != NoError) { 12367 Diag(ErrorLoc, diag::err_omp_atomic_capture_not_expression_statement) 12368 << ErrorRange; 12369 Diag(NoteLoc, diag::note_omp_atomic_capture) << ErrorFound << NoteRange; 12370 return StmtError(); 12371 } 12372 if (CurContext->isDependentContext()) 12373 UE = V = E = X = nullptr; 12374 } else { 12375 // If clause is a capture: 12376 // { v = x; x = expr; } 12377 // { v = x; x++; } 12378 // { v = x; x--; } 12379 // { v = x; ++x; } 12380 // { v = x; --x; } 12381 // { v = x; x binop= expr; } 12382 // { v = x; x = x binop expr; } 12383 // { v = x; x = expr binop x; } 12384 // { x++; v = x; } 12385 // { x--; v = x; } 12386 // { ++x; v = x; } 12387 // { --x; v = x; } 12388 // { x binop= expr; v = x; } 12389 // { x = x binop expr; v = x; } 12390 // { x = expr binop x; v = x; } 12391 if (auto *CS = dyn_cast<CompoundStmt>(Body)) { 12392 // Check that this is { expr1; expr2; } 12393 if (CS->size() == 2) { 12394 Stmt *First = CS->body_front(); 12395 Stmt *Second = CS->body_back(); 12396 if (auto *EWC = dyn_cast<ExprWithCleanups>(First)) 12397 First = EWC->getSubExpr()->IgnoreParenImpCasts(); 12398 if (auto *EWC = dyn_cast<ExprWithCleanups>(Second)) 12399 Second = EWC->getSubExpr()->IgnoreParenImpCasts(); 12400 // Need to find what subexpression is 'v' and what is 'x'. 12401 OpenMPAtomicUpdateChecker Checker(*this); 12402 bool IsUpdateExprFound = !Checker.checkStatement(Second); 12403 BinaryOperator *BinOp = nullptr; 12404 if (IsUpdateExprFound) { 12405 BinOp = dyn_cast<BinaryOperator>(First); 12406 IsUpdateExprFound = BinOp && BinOp->getOpcode() == BO_Assign; 12407 } 12408 if (IsUpdateExprFound && !CurContext->isDependentContext()) { 12409 // { v = x; x++; } 12410 // { v = x; x--; } 12411 // { v = x; ++x; } 12412 // { v = x; --x; } 12413 // { v = x; x binop= expr; } 12414 // { v = x; x = x binop expr; } 12415 // { v = x; x = expr binop x; } 12416 // Check that the first expression has form v = x. 12417 Expr *PossibleX = BinOp->getRHS()->IgnoreParenImpCasts(); 12418 llvm::FoldingSetNodeID XId, PossibleXId; 12419 Checker.getX()->Profile(XId, Context, /*Canonical=*/true); 12420 PossibleX->Profile(PossibleXId, Context, /*Canonical=*/true); 12421 IsUpdateExprFound = XId == PossibleXId; 12422 if (IsUpdateExprFound) { 12423 V = BinOp->getLHS(); 12424 X = Checker.getX(); 12425 E = Checker.getExpr(); 12426 UE = Checker.getUpdateExpr(); 12427 IsXLHSInRHSPart = Checker.isXLHSInRHSPart(); 12428 IsPostfixUpdate = true; 12429 } 12430 } 12431 if (!IsUpdateExprFound) { 12432 IsUpdateExprFound = !Checker.checkStatement(First); 12433 BinOp = nullptr; 12434 if (IsUpdateExprFound) { 12435 BinOp = dyn_cast<BinaryOperator>(Second); 12436 IsUpdateExprFound = BinOp && BinOp->getOpcode() == BO_Assign; 12437 } 12438 if (IsUpdateExprFound && !CurContext->isDependentContext()) { 12439 // { x++; v = x; } 12440 // { x--; v = x; } 12441 // { ++x; v = x; } 12442 // { --x; v = x; } 12443 // { x binop= expr; v = x; } 12444 // { x = x binop expr; v = x; } 12445 // { x = expr binop x; v = x; } 12446 // Check that the second expression has form v = x. 12447 Expr *PossibleX = BinOp->getRHS()->IgnoreParenImpCasts(); 12448 llvm::FoldingSetNodeID XId, PossibleXId; 12449 Checker.getX()->Profile(XId, Context, /*Canonical=*/true); 12450 PossibleX->Profile(PossibleXId, Context, /*Canonical=*/true); 12451 IsUpdateExprFound = XId == PossibleXId; 12452 if (IsUpdateExprFound) { 12453 V = BinOp->getLHS(); 12454 X = Checker.getX(); 12455 E = Checker.getExpr(); 12456 UE = Checker.getUpdateExpr(); 12457 IsXLHSInRHSPart = Checker.isXLHSInRHSPart(); 12458 IsPostfixUpdate = false; 12459 } 12460 } 12461 } 12462 if (!IsUpdateExprFound) { 12463 // { v = x; x = expr; } 12464 auto *FirstExpr = dyn_cast<Expr>(First); 12465 auto *SecondExpr = dyn_cast<Expr>(Second); 12466 if (!FirstExpr || !SecondExpr || 12467 !(FirstExpr->isInstantiationDependent() || 12468 SecondExpr->isInstantiationDependent())) { 12469 auto *FirstBinOp = dyn_cast<BinaryOperator>(First); 12470 if (!FirstBinOp || FirstBinOp->getOpcode() != BO_Assign) { 12471 ErrorFound = NotAnAssignmentOp; 12472 NoteLoc = ErrorLoc = FirstBinOp ? FirstBinOp->getOperatorLoc() 12473 : First->getBeginLoc(); 12474 NoteRange = ErrorRange = FirstBinOp 12475 ? FirstBinOp->getSourceRange() 12476 : SourceRange(ErrorLoc, ErrorLoc); 12477 } else { 12478 auto *SecondBinOp = dyn_cast<BinaryOperator>(Second); 12479 if (!SecondBinOp || SecondBinOp->getOpcode() != BO_Assign) { 12480 ErrorFound = NotAnAssignmentOp; 12481 NoteLoc = ErrorLoc = SecondBinOp 12482 ? SecondBinOp->getOperatorLoc() 12483 : Second->getBeginLoc(); 12484 NoteRange = ErrorRange = 12485 SecondBinOp ? SecondBinOp->getSourceRange() 12486 : SourceRange(ErrorLoc, ErrorLoc); 12487 } else { 12488 Expr *PossibleXRHSInFirst = 12489 FirstBinOp->getRHS()->IgnoreParenImpCasts(); 12490 Expr *PossibleXLHSInSecond = 12491 SecondBinOp->getLHS()->IgnoreParenImpCasts(); 12492 llvm::FoldingSetNodeID X1Id, X2Id; 12493 PossibleXRHSInFirst->Profile(X1Id, Context, 12494 /*Canonical=*/true); 12495 PossibleXLHSInSecond->Profile(X2Id, Context, 12496 /*Canonical=*/true); 12497 IsUpdateExprFound = X1Id == X2Id; 12498 if (IsUpdateExprFound) { 12499 V = FirstBinOp->getLHS(); 12500 X = SecondBinOp->getLHS(); 12501 E = SecondBinOp->getRHS(); 12502 UE = nullptr; 12503 IsXLHSInRHSPart = false; 12504 IsPostfixUpdate = true; 12505 } else { 12506 ErrorFound = NotASpecificExpression; 12507 ErrorLoc = FirstBinOp->getExprLoc(); 12508 ErrorRange = FirstBinOp->getSourceRange(); 12509 NoteLoc = SecondBinOp->getLHS()->getExprLoc(); 12510 NoteRange = SecondBinOp->getRHS()->getSourceRange(); 12511 } 12512 } 12513 } 12514 } 12515 } 12516 } else { 12517 NoteLoc = ErrorLoc = Body->getBeginLoc(); 12518 NoteRange = ErrorRange = 12519 SourceRange(Body->getBeginLoc(), Body->getBeginLoc()); 12520 ErrorFound = NotTwoSubstatements; 12521 } 12522 } else { 12523 NoteLoc = ErrorLoc = Body->getBeginLoc(); 12524 NoteRange = ErrorRange = 12525 SourceRange(Body->getBeginLoc(), Body->getBeginLoc()); 12526 ErrorFound = NotACompoundStatement; 12527 } 12528 } 12529 if (ErrorFound != NoError) { 12530 Diag(ErrorLoc, diag::err_omp_atomic_capture_not_compound_statement) 12531 << ErrorRange; 12532 Diag(NoteLoc, diag::note_omp_atomic_capture) << ErrorFound << NoteRange; 12533 return StmtError(); 12534 } 12535 if (CurContext->isDependentContext()) 12536 UE = V = E = X = nullptr; 12537 } else if (AtomicKind == OMPC_compare) { 12538 if (IsCompareCapture) { 12539 OpenMPAtomicCompareCaptureChecker::ErrorInfoTy ErrorInfo; 12540 OpenMPAtomicCompareCaptureChecker Checker(*this); 12541 if (!Checker.checkStmt(Body, ErrorInfo)) { 12542 Diag(ErrorInfo.ErrorLoc, diag::err_omp_atomic_compare_capture) 12543 << ErrorInfo.ErrorRange; 12544 Diag(ErrorInfo.NoteLoc, diag::note_omp_atomic_compare) 12545 << ErrorInfo.Error << ErrorInfo.NoteRange; 12546 return StmtError(); 12547 } 12548 X = Checker.getX(); 12549 E = Checker.getE(); 12550 D = Checker.getD(); 12551 CE = Checker.getCond(); 12552 V = Checker.getV(); 12553 R = Checker.getR(); 12554 // We reuse IsXLHSInRHSPart to tell if it is in the form 'x ordop expr'. 12555 IsXLHSInRHSPart = Checker.isXBinopExpr(); 12556 IsFailOnly = Checker.isFailOnly(); 12557 IsPostfixUpdate = Checker.isPostfixUpdate(); 12558 } else { 12559 OpenMPAtomicCompareChecker::ErrorInfoTy ErrorInfo; 12560 OpenMPAtomicCompareChecker Checker(*this); 12561 if (!Checker.checkStmt(Body, ErrorInfo)) { 12562 Diag(ErrorInfo.ErrorLoc, diag::err_omp_atomic_compare) 12563 << ErrorInfo.ErrorRange; 12564 Diag(ErrorInfo.NoteLoc, diag::note_omp_atomic_compare) 12565 << ErrorInfo.Error << ErrorInfo.NoteRange; 12566 return StmtError(); 12567 } 12568 X = Checker.getX(); 12569 E = Checker.getE(); 12570 D = Checker.getD(); 12571 CE = Checker.getCond(); 12572 // We reuse IsXLHSInRHSPart to tell if it is in the form 'x ordop expr'. 12573 IsXLHSInRHSPart = Checker.isXBinopExpr(); 12574 } 12575 } 12576 12577 setFunctionHasBranchProtectedScope(); 12578 12579 return OMPAtomicDirective::Create( 12580 Context, StartLoc, EndLoc, Clauses, AStmt, 12581 {X, V, R, E, UE, D, CE, IsXLHSInRHSPart, IsPostfixUpdate, IsFailOnly}); 12582 } 12583 12584 StmtResult Sema::ActOnOpenMPTargetDirective(ArrayRef<OMPClause *> Clauses, 12585 Stmt *AStmt, 12586 SourceLocation StartLoc, 12587 SourceLocation EndLoc) { 12588 if (!AStmt) 12589 return StmtError(); 12590 12591 auto *CS = cast<CapturedStmt>(AStmt); 12592 // 1.2.2 OpenMP Language Terminology 12593 // Structured block - An executable statement with a single entry at the 12594 // top and a single exit at the bottom. 12595 // The point of exit cannot be a branch out of the structured block. 12596 // longjmp() and throw() must not violate the entry/exit criteria. 12597 CS->getCapturedDecl()->setNothrow(); 12598 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target); 12599 ThisCaptureLevel > 1; --ThisCaptureLevel) { 12600 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 12601 // 1.2.2 OpenMP Language Terminology 12602 // Structured block - An executable statement with a single entry at the 12603 // top and a single exit at the bottom. 12604 // The point of exit cannot be a branch out of the structured block. 12605 // longjmp() and throw() must not violate the entry/exit criteria. 12606 CS->getCapturedDecl()->setNothrow(); 12607 } 12608 12609 // OpenMP [2.16, Nesting of Regions] 12610 // If specified, a teams construct must be contained within a target 12611 // construct. That target construct must contain no statements or directives 12612 // outside of the teams construct. 12613 if (DSAStack->hasInnerTeamsRegion()) { 12614 const Stmt *S = CS->IgnoreContainers(/*IgnoreCaptured=*/true); 12615 bool OMPTeamsFound = true; 12616 if (const auto *CS = dyn_cast<CompoundStmt>(S)) { 12617 auto I = CS->body_begin(); 12618 while (I != CS->body_end()) { 12619 const auto *OED = dyn_cast<OMPExecutableDirective>(*I); 12620 if (!OED || !isOpenMPTeamsDirective(OED->getDirectiveKind()) || 12621 OMPTeamsFound) { 12622 12623 OMPTeamsFound = false; 12624 break; 12625 } 12626 ++I; 12627 } 12628 assert(I != CS->body_end() && "Not found statement"); 12629 S = *I; 12630 } else { 12631 const auto *OED = dyn_cast<OMPExecutableDirective>(S); 12632 OMPTeamsFound = OED && isOpenMPTeamsDirective(OED->getDirectiveKind()); 12633 } 12634 if (!OMPTeamsFound) { 12635 Diag(StartLoc, diag::err_omp_target_contains_not_only_teams); 12636 Diag(DSAStack->getInnerTeamsRegionLoc(), 12637 diag::note_omp_nested_teams_construct_here); 12638 Diag(S->getBeginLoc(), diag::note_omp_nested_statement_here) 12639 << isa<OMPExecutableDirective>(S); 12640 return StmtError(); 12641 } 12642 } 12643 12644 setFunctionHasBranchProtectedScope(); 12645 12646 return OMPTargetDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt); 12647 } 12648 12649 StmtResult 12650 Sema::ActOnOpenMPTargetParallelDirective(ArrayRef<OMPClause *> Clauses, 12651 Stmt *AStmt, SourceLocation StartLoc, 12652 SourceLocation EndLoc) { 12653 if (!AStmt) 12654 return StmtError(); 12655 12656 auto *CS = cast<CapturedStmt>(AStmt); 12657 // 1.2.2 OpenMP Language Terminology 12658 // Structured block - An executable statement with a single entry at the 12659 // top and a single exit at the bottom. 12660 // The point of exit cannot be a branch out of the structured block. 12661 // longjmp() and throw() must not violate the entry/exit criteria. 12662 CS->getCapturedDecl()->setNothrow(); 12663 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel); 12664 ThisCaptureLevel > 1; --ThisCaptureLevel) { 12665 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 12666 // 1.2.2 OpenMP Language Terminology 12667 // Structured block - An executable statement with a single entry at the 12668 // top and a single exit at the bottom. 12669 // The point of exit cannot be a branch out of the structured block. 12670 // longjmp() and throw() must not violate the entry/exit criteria. 12671 CS->getCapturedDecl()->setNothrow(); 12672 } 12673 12674 setFunctionHasBranchProtectedScope(); 12675 12676 return OMPTargetParallelDirective::Create( 12677 Context, StartLoc, EndLoc, Clauses, AStmt, 12678 DSAStack->getTaskgroupReductionRef(), DSAStack->isCancelRegion()); 12679 } 12680 12681 StmtResult Sema::ActOnOpenMPTargetParallelForDirective( 12682 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 12683 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 12684 if (!AStmt) 12685 return StmtError(); 12686 12687 auto *CS = cast<CapturedStmt>(AStmt); 12688 // 1.2.2 OpenMP Language Terminology 12689 // Structured block - An executable statement with a single entry at the 12690 // top and a single exit at the bottom. 12691 // The point of exit cannot be a branch out of the structured block. 12692 // longjmp() and throw() must not violate the entry/exit criteria. 12693 CS->getCapturedDecl()->setNothrow(); 12694 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel_for); 12695 ThisCaptureLevel > 1; --ThisCaptureLevel) { 12696 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 12697 // 1.2.2 OpenMP Language Terminology 12698 // Structured block - An executable statement with a single entry at the 12699 // top and a single exit at the bottom. 12700 // The point of exit cannot be a branch out of the structured block. 12701 // longjmp() and throw() must not violate the entry/exit criteria. 12702 CS->getCapturedDecl()->setNothrow(); 12703 } 12704 12705 OMPLoopBasedDirective::HelperExprs B; 12706 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 12707 // define the nested loops number. 12708 unsigned NestedLoopCount = 12709 checkOpenMPLoop(OMPD_target_parallel_for, getCollapseNumberExpr(Clauses), 12710 getOrderedNumberExpr(Clauses), CS, *this, *DSAStack, 12711 VarsWithImplicitDSA, B); 12712 if (NestedLoopCount == 0) 12713 return StmtError(); 12714 12715 assert((CurContext->isDependentContext() || B.builtAll()) && 12716 "omp target parallel for loop exprs were not built"); 12717 12718 if (!CurContext->isDependentContext()) { 12719 // Finalize the clauses that need pre-built expressions for CodeGen. 12720 for (OMPClause *C : Clauses) { 12721 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 12722 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 12723 B.NumIterations, *this, CurScope, 12724 DSAStack)) 12725 return StmtError(); 12726 } 12727 } 12728 12729 setFunctionHasBranchProtectedScope(); 12730 return OMPTargetParallelForDirective::Create( 12731 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B, 12732 DSAStack->getTaskgroupReductionRef(), DSAStack->isCancelRegion()); 12733 } 12734 12735 /// Check for existence of a map clause in the list of clauses. 12736 static bool hasClauses(ArrayRef<OMPClause *> Clauses, 12737 const OpenMPClauseKind K) { 12738 return llvm::any_of( 12739 Clauses, [K](const OMPClause *C) { return C->getClauseKind() == K; }); 12740 } 12741 12742 template <typename... Params> 12743 static bool hasClauses(ArrayRef<OMPClause *> Clauses, const OpenMPClauseKind K, 12744 const Params... ClauseTypes) { 12745 return hasClauses(Clauses, K) || hasClauses(Clauses, ClauseTypes...); 12746 } 12747 12748 /// Check if the variables in the mapping clause are externally visible. 12749 static bool isClauseMappable(ArrayRef<OMPClause *> Clauses) { 12750 for (const OMPClause *C : Clauses) { 12751 if (auto *TC = dyn_cast<OMPToClause>(C)) 12752 return llvm::all_of(TC->all_decls(), [](ValueDecl *VD) { 12753 return !VD || !VD->hasAttr<OMPDeclareTargetDeclAttr>() || 12754 (VD->isExternallyVisible() && 12755 VD->getVisibility() != HiddenVisibility); 12756 }); 12757 else if (auto *FC = dyn_cast<OMPFromClause>(C)) 12758 return llvm::all_of(FC->all_decls(), [](ValueDecl *VD) { 12759 return !VD || !VD->hasAttr<OMPDeclareTargetDeclAttr>() || 12760 (VD->isExternallyVisible() && 12761 VD->getVisibility() != HiddenVisibility); 12762 }); 12763 } 12764 12765 return true; 12766 } 12767 12768 StmtResult Sema::ActOnOpenMPTargetDataDirective(ArrayRef<OMPClause *> Clauses, 12769 Stmt *AStmt, 12770 SourceLocation StartLoc, 12771 SourceLocation EndLoc) { 12772 if (!AStmt) 12773 return StmtError(); 12774 12775 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 12776 12777 // OpenMP [2.12.2, target data Construct, Restrictions] 12778 // At least one map, use_device_addr or use_device_ptr clause must appear on 12779 // the directive. 12780 if (!hasClauses(Clauses, OMPC_map, OMPC_use_device_ptr) && 12781 (LangOpts.OpenMP < 50 || !hasClauses(Clauses, OMPC_use_device_addr))) { 12782 StringRef Expected; 12783 if (LangOpts.OpenMP < 50) 12784 Expected = "'map' or 'use_device_ptr'"; 12785 else 12786 Expected = "'map', 'use_device_ptr', or 'use_device_addr'"; 12787 Diag(StartLoc, diag::err_omp_no_clause_for_directive) 12788 << Expected << getOpenMPDirectiveName(OMPD_target_data); 12789 return StmtError(); 12790 } 12791 12792 setFunctionHasBranchProtectedScope(); 12793 12794 return OMPTargetDataDirective::Create(Context, StartLoc, EndLoc, Clauses, 12795 AStmt); 12796 } 12797 12798 StmtResult 12799 Sema::ActOnOpenMPTargetEnterDataDirective(ArrayRef<OMPClause *> Clauses, 12800 SourceLocation StartLoc, 12801 SourceLocation EndLoc, Stmt *AStmt) { 12802 if (!AStmt) 12803 return StmtError(); 12804 12805 auto *CS = cast<CapturedStmt>(AStmt); 12806 // 1.2.2 OpenMP Language Terminology 12807 // Structured block - An executable statement with a single entry at the 12808 // top and a single exit at the bottom. 12809 // The point of exit cannot be a branch out of the structured block. 12810 // longjmp() and throw() must not violate the entry/exit criteria. 12811 CS->getCapturedDecl()->setNothrow(); 12812 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_enter_data); 12813 ThisCaptureLevel > 1; --ThisCaptureLevel) { 12814 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 12815 // 1.2.2 OpenMP Language Terminology 12816 // Structured block - An executable statement with a single entry at the 12817 // top and a single exit at the bottom. 12818 // The point of exit cannot be a branch out of the structured block. 12819 // longjmp() and throw() must not violate the entry/exit criteria. 12820 CS->getCapturedDecl()->setNothrow(); 12821 } 12822 12823 // OpenMP [2.10.2, Restrictions, p. 99] 12824 // At least one map clause must appear on the directive. 12825 if (!hasClauses(Clauses, OMPC_map)) { 12826 Diag(StartLoc, diag::err_omp_no_clause_for_directive) 12827 << "'map'" << getOpenMPDirectiveName(OMPD_target_enter_data); 12828 return StmtError(); 12829 } 12830 12831 return OMPTargetEnterDataDirective::Create(Context, StartLoc, EndLoc, Clauses, 12832 AStmt); 12833 } 12834 12835 StmtResult 12836 Sema::ActOnOpenMPTargetExitDataDirective(ArrayRef<OMPClause *> Clauses, 12837 SourceLocation StartLoc, 12838 SourceLocation EndLoc, Stmt *AStmt) { 12839 if (!AStmt) 12840 return StmtError(); 12841 12842 auto *CS = cast<CapturedStmt>(AStmt); 12843 // 1.2.2 OpenMP Language Terminology 12844 // Structured block - An executable statement with a single entry at the 12845 // top and a single exit at the bottom. 12846 // The point of exit cannot be a branch out of the structured block. 12847 // longjmp() and throw() must not violate the entry/exit criteria. 12848 CS->getCapturedDecl()->setNothrow(); 12849 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_exit_data); 12850 ThisCaptureLevel > 1; --ThisCaptureLevel) { 12851 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 12852 // 1.2.2 OpenMP Language Terminology 12853 // Structured block - An executable statement with a single entry at the 12854 // top and a single exit at the bottom. 12855 // The point of exit cannot be a branch out of the structured block. 12856 // longjmp() and throw() must not violate the entry/exit criteria. 12857 CS->getCapturedDecl()->setNothrow(); 12858 } 12859 12860 // OpenMP [2.10.3, Restrictions, p. 102] 12861 // At least one map clause must appear on the directive. 12862 if (!hasClauses(Clauses, OMPC_map)) { 12863 Diag(StartLoc, diag::err_omp_no_clause_for_directive) 12864 << "'map'" << getOpenMPDirectiveName(OMPD_target_exit_data); 12865 return StmtError(); 12866 } 12867 12868 return OMPTargetExitDataDirective::Create(Context, StartLoc, EndLoc, Clauses, 12869 AStmt); 12870 } 12871 12872 StmtResult Sema::ActOnOpenMPTargetUpdateDirective(ArrayRef<OMPClause *> Clauses, 12873 SourceLocation StartLoc, 12874 SourceLocation EndLoc, 12875 Stmt *AStmt) { 12876 if (!AStmt) 12877 return StmtError(); 12878 12879 auto *CS = cast<CapturedStmt>(AStmt); 12880 // 1.2.2 OpenMP Language Terminology 12881 // Structured block - An executable statement with a single entry at the 12882 // top and a single exit at the bottom. 12883 // The point of exit cannot be a branch out of the structured block. 12884 // longjmp() and throw() must not violate the entry/exit criteria. 12885 CS->getCapturedDecl()->setNothrow(); 12886 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_update); 12887 ThisCaptureLevel > 1; --ThisCaptureLevel) { 12888 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 12889 // 1.2.2 OpenMP Language Terminology 12890 // Structured block - An executable statement with a single entry at the 12891 // top and a single exit at the bottom. 12892 // The point of exit cannot be a branch out of the structured block. 12893 // longjmp() and throw() must not violate the entry/exit criteria. 12894 CS->getCapturedDecl()->setNothrow(); 12895 } 12896 12897 if (!hasClauses(Clauses, OMPC_to, OMPC_from)) { 12898 Diag(StartLoc, diag::err_omp_at_least_one_motion_clause_required); 12899 return StmtError(); 12900 } 12901 12902 if (!isClauseMappable(Clauses)) { 12903 Diag(StartLoc, diag::err_omp_cannot_update_with_internal_linkage); 12904 return StmtError(); 12905 } 12906 12907 return OMPTargetUpdateDirective::Create(Context, StartLoc, EndLoc, Clauses, 12908 AStmt); 12909 } 12910 12911 StmtResult Sema::ActOnOpenMPTeamsDirective(ArrayRef<OMPClause *> Clauses, 12912 Stmt *AStmt, SourceLocation StartLoc, 12913 SourceLocation EndLoc) { 12914 if (!AStmt) 12915 return StmtError(); 12916 12917 auto *CS = cast<CapturedStmt>(AStmt); 12918 // 1.2.2 OpenMP Language Terminology 12919 // Structured block - An executable statement with a single entry at the 12920 // top and a single exit at the bottom. 12921 // The point of exit cannot be a branch out of the structured block. 12922 // longjmp() and throw() must not violate the entry/exit criteria. 12923 CS->getCapturedDecl()->setNothrow(); 12924 12925 setFunctionHasBranchProtectedScope(); 12926 12927 DSAStack->setParentTeamsRegionLoc(StartLoc); 12928 12929 return OMPTeamsDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt); 12930 } 12931 12932 StmtResult 12933 Sema::ActOnOpenMPCancellationPointDirective(SourceLocation StartLoc, 12934 SourceLocation EndLoc, 12935 OpenMPDirectiveKind CancelRegion) { 12936 if (DSAStack->isParentNowaitRegion()) { 12937 Diag(StartLoc, diag::err_omp_parent_cancel_region_nowait) << 0; 12938 return StmtError(); 12939 } 12940 if (DSAStack->isParentOrderedRegion()) { 12941 Diag(StartLoc, diag::err_omp_parent_cancel_region_ordered) << 0; 12942 return StmtError(); 12943 } 12944 return OMPCancellationPointDirective::Create(Context, StartLoc, EndLoc, 12945 CancelRegion); 12946 } 12947 12948 StmtResult Sema::ActOnOpenMPCancelDirective(ArrayRef<OMPClause *> Clauses, 12949 SourceLocation StartLoc, 12950 SourceLocation EndLoc, 12951 OpenMPDirectiveKind CancelRegion) { 12952 if (DSAStack->isParentNowaitRegion()) { 12953 Diag(StartLoc, diag::err_omp_parent_cancel_region_nowait) << 1; 12954 return StmtError(); 12955 } 12956 if (DSAStack->isParentOrderedRegion()) { 12957 Diag(StartLoc, diag::err_omp_parent_cancel_region_ordered) << 1; 12958 return StmtError(); 12959 } 12960 DSAStack->setParentCancelRegion(/*Cancel=*/true); 12961 return OMPCancelDirective::Create(Context, StartLoc, EndLoc, Clauses, 12962 CancelRegion); 12963 } 12964 12965 static bool checkReductionClauseWithNogroup(Sema &S, 12966 ArrayRef<OMPClause *> Clauses) { 12967 const OMPClause *ReductionClause = nullptr; 12968 const OMPClause *NogroupClause = nullptr; 12969 for (const OMPClause *C : Clauses) { 12970 if (C->getClauseKind() == OMPC_reduction) { 12971 ReductionClause = C; 12972 if (NogroupClause) 12973 break; 12974 continue; 12975 } 12976 if (C->getClauseKind() == OMPC_nogroup) { 12977 NogroupClause = C; 12978 if (ReductionClause) 12979 break; 12980 continue; 12981 } 12982 } 12983 if (ReductionClause && NogroupClause) { 12984 S.Diag(ReductionClause->getBeginLoc(), diag::err_omp_reduction_with_nogroup) 12985 << SourceRange(NogroupClause->getBeginLoc(), 12986 NogroupClause->getEndLoc()); 12987 return true; 12988 } 12989 return false; 12990 } 12991 12992 StmtResult Sema::ActOnOpenMPTaskLoopDirective( 12993 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 12994 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 12995 if (!AStmt) 12996 return StmtError(); 12997 12998 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 12999 OMPLoopBasedDirective::HelperExprs B; 13000 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 13001 // define the nested loops number. 13002 unsigned NestedLoopCount = 13003 checkOpenMPLoop(OMPD_taskloop, getCollapseNumberExpr(Clauses), 13004 /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack, 13005 VarsWithImplicitDSA, B); 13006 if (NestedLoopCount == 0) 13007 return StmtError(); 13008 13009 assert((CurContext->isDependentContext() || B.builtAll()) && 13010 "omp for loop exprs were not built"); 13011 13012 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 13013 // The grainsize clause and num_tasks clause are mutually exclusive and may 13014 // not appear on the same taskloop directive. 13015 if (checkMutuallyExclusiveClauses(*this, Clauses, 13016 {OMPC_grainsize, OMPC_num_tasks})) 13017 return StmtError(); 13018 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 13019 // If a reduction clause is present on the taskloop directive, the nogroup 13020 // clause must not be specified. 13021 if (checkReductionClauseWithNogroup(*this, Clauses)) 13022 return StmtError(); 13023 13024 setFunctionHasBranchProtectedScope(); 13025 return OMPTaskLoopDirective::Create(Context, StartLoc, EndLoc, 13026 NestedLoopCount, Clauses, AStmt, B, 13027 DSAStack->isCancelRegion()); 13028 } 13029 13030 StmtResult Sema::ActOnOpenMPTaskLoopSimdDirective( 13031 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 13032 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 13033 if (!AStmt) 13034 return StmtError(); 13035 13036 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 13037 OMPLoopBasedDirective::HelperExprs B; 13038 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 13039 // define the nested loops number. 13040 unsigned NestedLoopCount = 13041 checkOpenMPLoop(OMPD_taskloop_simd, getCollapseNumberExpr(Clauses), 13042 /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack, 13043 VarsWithImplicitDSA, B); 13044 if (NestedLoopCount == 0) 13045 return StmtError(); 13046 13047 assert((CurContext->isDependentContext() || B.builtAll()) && 13048 "omp for loop exprs were not built"); 13049 13050 if (!CurContext->isDependentContext()) { 13051 // Finalize the clauses that need pre-built expressions for CodeGen. 13052 for (OMPClause *C : Clauses) { 13053 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 13054 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 13055 B.NumIterations, *this, CurScope, 13056 DSAStack)) 13057 return StmtError(); 13058 } 13059 } 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 if (checkSimdlenSafelenSpecified(*this, Clauses)) 13073 return StmtError(); 13074 13075 setFunctionHasBranchProtectedScope(); 13076 return OMPTaskLoopSimdDirective::Create(Context, StartLoc, EndLoc, 13077 NestedLoopCount, Clauses, AStmt, B); 13078 } 13079 13080 StmtResult Sema::ActOnOpenMPMasterTaskLoopDirective( 13081 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 13082 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 13083 if (!AStmt) 13084 return StmtError(); 13085 13086 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 13087 OMPLoopBasedDirective::HelperExprs B; 13088 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 13089 // define the nested loops number. 13090 unsigned NestedLoopCount = 13091 checkOpenMPLoop(OMPD_master_taskloop, getCollapseNumberExpr(Clauses), 13092 /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack, 13093 VarsWithImplicitDSA, B); 13094 if (NestedLoopCount == 0) 13095 return StmtError(); 13096 13097 assert((CurContext->isDependentContext() || B.builtAll()) && 13098 "omp for loop exprs were not built"); 13099 13100 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 13101 // The grainsize clause and num_tasks clause are mutually exclusive and may 13102 // not appear on the same taskloop directive. 13103 if (checkMutuallyExclusiveClauses(*this, Clauses, 13104 {OMPC_grainsize, OMPC_num_tasks})) 13105 return StmtError(); 13106 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 13107 // If a reduction clause is present on the taskloop directive, the nogroup 13108 // clause must not be specified. 13109 if (checkReductionClauseWithNogroup(*this, Clauses)) 13110 return StmtError(); 13111 13112 setFunctionHasBranchProtectedScope(); 13113 return OMPMasterTaskLoopDirective::Create(Context, StartLoc, EndLoc, 13114 NestedLoopCount, Clauses, AStmt, B, 13115 DSAStack->isCancelRegion()); 13116 } 13117 13118 StmtResult Sema::ActOnOpenMPMasterTaskLoopSimdDirective( 13119 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 13120 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 13121 if (!AStmt) 13122 return StmtError(); 13123 13124 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 13125 OMPLoopBasedDirective::HelperExprs B; 13126 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 13127 // define the nested loops number. 13128 unsigned NestedLoopCount = 13129 checkOpenMPLoop(OMPD_master_taskloop_simd, getCollapseNumberExpr(Clauses), 13130 /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack, 13131 VarsWithImplicitDSA, B); 13132 if (NestedLoopCount == 0) 13133 return StmtError(); 13134 13135 assert((CurContext->isDependentContext() || B.builtAll()) && 13136 "omp for loop exprs were not built"); 13137 13138 if (!CurContext->isDependentContext()) { 13139 // Finalize the clauses that need pre-built expressions for CodeGen. 13140 for (OMPClause *C : Clauses) { 13141 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 13142 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 13143 B.NumIterations, *this, CurScope, 13144 DSAStack)) 13145 return StmtError(); 13146 } 13147 } 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 if (checkSimdlenSafelenSpecified(*this, Clauses)) 13161 return StmtError(); 13162 13163 setFunctionHasBranchProtectedScope(); 13164 return OMPMasterTaskLoopSimdDirective::Create( 13165 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 13166 } 13167 13168 StmtResult Sema::ActOnOpenMPParallelMasterTaskLoopDirective( 13169 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 13170 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 13171 if (!AStmt) 13172 return StmtError(); 13173 13174 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 13175 auto *CS = cast<CapturedStmt>(AStmt); 13176 // 1.2.2 OpenMP Language Terminology 13177 // Structured block - An executable statement with a single entry at the 13178 // top and a single exit at the bottom. 13179 // The point of exit cannot be a branch out of the structured block. 13180 // longjmp() and throw() must not violate the entry/exit criteria. 13181 CS->getCapturedDecl()->setNothrow(); 13182 for (int ThisCaptureLevel = 13183 getOpenMPCaptureLevels(OMPD_parallel_master_taskloop); 13184 ThisCaptureLevel > 1; --ThisCaptureLevel) { 13185 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 13186 // 1.2.2 OpenMP Language Terminology 13187 // Structured block - An executable statement with a single entry at the 13188 // top and a single exit at the bottom. 13189 // The point of exit cannot be a branch out of the structured block. 13190 // longjmp() and throw() must not violate the entry/exit criteria. 13191 CS->getCapturedDecl()->setNothrow(); 13192 } 13193 13194 OMPLoopBasedDirective::HelperExprs B; 13195 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 13196 // define the nested loops number. 13197 unsigned NestedLoopCount = checkOpenMPLoop( 13198 OMPD_parallel_master_taskloop, getCollapseNumberExpr(Clauses), 13199 /*OrderedLoopCountExpr=*/nullptr, CS, *this, *DSAStack, 13200 VarsWithImplicitDSA, B); 13201 if (NestedLoopCount == 0) 13202 return StmtError(); 13203 13204 assert((CurContext->isDependentContext() || B.builtAll()) && 13205 "omp for loop exprs were not built"); 13206 13207 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 13208 // The grainsize clause and num_tasks clause are mutually exclusive and may 13209 // not appear on the same taskloop directive. 13210 if (checkMutuallyExclusiveClauses(*this, Clauses, 13211 {OMPC_grainsize, OMPC_num_tasks})) 13212 return StmtError(); 13213 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 13214 // If a reduction clause is present on the taskloop directive, the nogroup 13215 // clause must not be specified. 13216 if (checkReductionClauseWithNogroup(*this, Clauses)) 13217 return StmtError(); 13218 13219 setFunctionHasBranchProtectedScope(); 13220 return OMPParallelMasterTaskLoopDirective::Create( 13221 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B, 13222 DSAStack->isCancelRegion()); 13223 } 13224 13225 StmtResult Sema::ActOnOpenMPParallelMasterTaskLoopSimdDirective( 13226 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 13227 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 13228 if (!AStmt) 13229 return StmtError(); 13230 13231 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 13232 auto *CS = cast<CapturedStmt>(AStmt); 13233 // 1.2.2 OpenMP Language Terminology 13234 // Structured block - An executable statement with a single entry at the 13235 // top and a single exit at the bottom. 13236 // The point of exit cannot be a branch out of the structured block. 13237 // longjmp() and throw() must not violate the entry/exit criteria. 13238 CS->getCapturedDecl()->setNothrow(); 13239 for (int ThisCaptureLevel = 13240 getOpenMPCaptureLevels(OMPD_parallel_master_taskloop_simd); 13241 ThisCaptureLevel > 1; --ThisCaptureLevel) { 13242 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 13243 // 1.2.2 OpenMP Language Terminology 13244 // Structured block - An executable statement with a single entry at the 13245 // top and a single exit at the bottom. 13246 // The point of exit cannot be a branch out of the structured block. 13247 // longjmp() and throw() must not violate the entry/exit criteria. 13248 CS->getCapturedDecl()->setNothrow(); 13249 } 13250 13251 OMPLoopBasedDirective::HelperExprs B; 13252 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 13253 // define the nested loops number. 13254 unsigned NestedLoopCount = checkOpenMPLoop( 13255 OMPD_parallel_master_taskloop_simd, getCollapseNumberExpr(Clauses), 13256 /*OrderedLoopCountExpr=*/nullptr, CS, *this, *DSAStack, 13257 VarsWithImplicitDSA, B); 13258 if (NestedLoopCount == 0) 13259 return StmtError(); 13260 13261 assert((CurContext->isDependentContext() || B.builtAll()) && 13262 "omp for loop exprs were not built"); 13263 13264 if (!CurContext->isDependentContext()) { 13265 // Finalize the clauses that need pre-built expressions for CodeGen. 13266 for (OMPClause *C : Clauses) { 13267 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 13268 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 13269 B.NumIterations, *this, CurScope, 13270 DSAStack)) 13271 return StmtError(); 13272 } 13273 } 13274 13275 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 13276 // The grainsize clause and num_tasks clause are mutually exclusive and may 13277 // not appear on the same taskloop directive. 13278 if (checkMutuallyExclusiveClauses(*this, Clauses, 13279 {OMPC_grainsize, OMPC_num_tasks})) 13280 return StmtError(); 13281 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 13282 // If a reduction clause is present on the taskloop directive, the nogroup 13283 // clause must not be specified. 13284 if (checkReductionClauseWithNogroup(*this, Clauses)) 13285 return StmtError(); 13286 if (checkSimdlenSafelenSpecified(*this, Clauses)) 13287 return StmtError(); 13288 13289 setFunctionHasBranchProtectedScope(); 13290 return OMPParallelMasterTaskLoopSimdDirective::Create( 13291 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 13292 } 13293 13294 StmtResult Sema::ActOnOpenMPDistributeDirective( 13295 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 13296 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 13297 if (!AStmt) 13298 return StmtError(); 13299 13300 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 13301 OMPLoopBasedDirective::HelperExprs B; 13302 // In presence of clause 'collapse' with number of loops, it will 13303 // define the nested loops number. 13304 unsigned NestedLoopCount = 13305 checkOpenMPLoop(OMPD_distribute, getCollapseNumberExpr(Clauses), 13306 nullptr /*ordered not a clause on distribute*/, AStmt, 13307 *this, *DSAStack, VarsWithImplicitDSA, B); 13308 if (NestedLoopCount == 0) 13309 return StmtError(); 13310 13311 assert((CurContext->isDependentContext() || B.builtAll()) && 13312 "omp for loop exprs were not built"); 13313 13314 setFunctionHasBranchProtectedScope(); 13315 return OMPDistributeDirective::Create(Context, StartLoc, EndLoc, 13316 NestedLoopCount, Clauses, AStmt, B); 13317 } 13318 13319 StmtResult Sema::ActOnOpenMPDistributeParallelForDirective( 13320 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 13321 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 13322 if (!AStmt) 13323 return StmtError(); 13324 13325 auto *CS = cast<CapturedStmt>(AStmt); 13326 // 1.2.2 OpenMP Language Terminology 13327 // Structured block - An executable statement with a single entry at the 13328 // top and a single exit at the bottom. 13329 // The point of exit cannot be a branch out of the structured block. 13330 // longjmp() and throw() must not violate the entry/exit criteria. 13331 CS->getCapturedDecl()->setNothrow(); 13332 for (int ThisCaptureLevel = 13333 getOpenMPCaptureLevels(OMPD_distribute_parallel_for); 13334 ThisCaptureLevel > 1; --ThisCaptureLevel) { 13335 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 13336 // 1.2.2 OpenMP Language Terminology 13337 // Structured block - An executable statement with a single entry at the 13338 // top and a single exit at the bottom. 13339 // The point of exit cannot be a branch out of the structured block. 13340 // longjmp() and throw() must not violate the entry/exit criteria. 13341 CS->getCapturedDecl()->setNothrow(); 13342 } 13343 13344 OMPLoopBasedDirective::HelperExprs B; 13345 // In presence of clause 'collapse' with number of loops, it will 13346 // define the nested loops number. 13347 unsigned NestedLoopCount = checkOpenMPLoop( 13348 OMPD_distribute_parallel_for, getCollapseNumberExpr(Clauses), 13349 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 13350 VarsWithImplicitDSA, B); 13351 if (NestedLoopCount == 0) 13352 return StmtError(); 13353 13354 assert((CurContext->isDependentContext() || B.builtAll()) && 13355 "omp for loop exprs were not built"); 13356 13357 setFunctionHasBranchProtectedScope(); 13358 return OMPDistributeParallelForDirective::Create( 13359 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B, 13360 DSAStack->getTaskgroupReductionRef(), DSAStack->isCancelRegion()); 13361 } 13362 13363 StmtResult Sema::ActOnOpenMPDistributeParallelForSimdDirective( 13364 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 13365 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 13366 if (!AStmt) 13367 return StmtError(); 13368 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_distribute_parallel_for_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' with number of loops, it will 13390 // define the nested loops number. 13391 unsigned NestedLoopCount = checkOpenMPLoop( 13392 OMPD_distribute_parallel_for_simd, getCollapseNumberExpr(Clauses), 13393 nullptr /*ordered not a clause on distribute*/, 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 if (checkSimdlenSafelenSpecified(*this, Clauses)) 13413 return StmtError(); 13414 13415 setFunctionHasBranchProtectedScope(); 13416 return OMPDistributeParallelForSimdDirective::Create( 13417 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 13418 } 13419 13420 StmtResult Sema::ActOnOpenMPDistributeSimdDirective( 13421 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 13422 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 13423 if (!AStmt) 13424 return StmtError(); 13425 13426 auto *CS = cast<CapturedStmt>(AStmt); 13427 // 1.2.2 OpenMP Language Terminology 13428 // Structured block - An executable statement with a single entry at the 13429 // top and a single exit at the bottom. 13430 // The point of exit cannot be a branch out of the structured block. 13431 // longjmp() and throw() must not violate the entry/exit criteria. 13432 CS->getCapturedDecl()->setNothrow(); 13433 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_distribute_simd); 13434 ThisCaptureLevel > 1; --ThisCaptureLevel) { 13435 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 13436 // 1.2.2 OpenMP Language Terminology 13437 // Structured block - An executable statement with a single entry at the 13438 // top and a single exit at the bottom. 13439 // The point of exit cannot be a branch out of the structured block. 13440 // longjmp() and throw() must not violate the entry/exit criteria. 13441 CS->getCapturedDecl()->setNothrow(); 13442 } 13443 13444 OMPLoopBasedDirective::HelperExprs B; 13445 // In presence of clause 'collapse' with number of loops, it will 13446 // define the nested loops number. 13447 unsigned NestedLoopCount = 13448 checkOpenMPLoop(OMPD_distribute_simd, getCollapseNumberExpr(Clauses), 13449 nullptr /*ordered not a clause on distribute*/, CS, *this, 13450 *DSAStack, VarsWithImplicitDSA, B); 13451 if (NestedLoopCount == 0) 13452 return StmtError(); 13453 13454 assert((CurContext->isDependentContext() || B.builtAll()) && 13455 "omp for loop exprs were not built"); 13456 13457 if (!CurContext->isDependentContext()) { 13458 // Finalize the clauses that need pre-built expressions for CodeGen. 13459 for (OMPClause *C : Clauses) { 13460 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 13461 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 13462 B.NumIterations, *this, CurScope, 13463 DSAStack)) 13464 return StmtError(); 13465 } 13466 } 13467 13468 if (checkSimdlenSafelenSpecified(*this, Clauses)) 13469 return StmtError(); 13470 13471 setFunctionHasBranchProtectedScope(); 13472 return OMPDistributeSimdDirective::Create(Context, StartLoc, EndLoc, 13473 NestedLoopCount, Clauses, AStmt, B); 13474 } 13475 13476 StmtResult Sema::ActOnOpenMPTargetParallelForSimdDirective( 13477 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 13478 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 13479 if (!AStmt) 13480 return StmtError(); 13481 13482 auto *CS = cast<CapturedStmt>(AStmt); 13483 // 1.2.2 OpenMP Language Terminology 13484 // Structured block - An executable statement with a single entry at the 13485 // top and a single exit at the bottom. 13486 // The point of exit cannot be a branch out of the structured block. 13487 // longjmp() and throw() must not violate the entry/exit criteria. 13488 CS->getCapturedDecl()->setNothrow(); 13489 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel_for); 13490 ThisCaptureLevel > 1; --ThisCaptureLevel) { 13491 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 13492 // 1.2.2 OpenMP Language Terminology 13493 // Structured block - An executable statement with a single entry at the 13494 // top and a single exit at the bottom. 13495 // The point of exit cannot be a branch out of the structured block. 13496 // longjmp() and throw() must not violate the entry/exit criteria. 13497 CS->getCapturedDecl()->setNothrow(); 13498 } 13499 13500 OMPLoopBasedDirective::HelperExprs B; 13501 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 13502 // define the nested loops number. 13503 unsigned NestedLoopCount = checkOpenMPLoop( 13504 OMPD_target_parallel_for_simd, getCollapseNumberExpr(Clauses), 13505 getOrderedNumberExpr(Clauses), CS, *this, *DSAStack, VarsWithImplicitDSA, 13506 B); 13507 if (NestedLoopCount == 0) 13508 return StmtError(); 13509 13510 assert((CurContext->isDependentContext() || B.builtAll()) && 13511 "omp target parallel for simd loop exprs were not built"); 13512 13513 if (!CurContext->isDependentContext()) { 13514 // Finalize the clauses that need pre-built expressions for CodeGen. 13515 for (OMPClause *C : Clauses) { 13516 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 13517 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 13518 B.NumIterations, *this, CurScope, 13519 DSAStack)) 13520 return StmtError(); 13521 } 13522 } 13523 if (checkSimdlenSafelenSpecified(*this, Clauses)) 13524 return StmtError(); 13525 13526 setFunctionHasBranchProtectedScope(); 13527 return OMPTargetParallelForSimdDirective::Create( 13528 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 13529 } 13530 13531 StmtResult Sema::ActOnOpenMPTargetSimdDirective( 13532 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 13533 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 13534 if (!AStmt) 13535 return StmtError(); 13536 13537 auto *CS = cast<CapturedStmt>(AStmt); 13538 // 1.2.2 OpenMP Language Terminology 13539 // Structured block - An executable statement with a single entry at the 13540 // top and a single exit at the bottom. 13541 // The point of exit cannot be a branch out of the structured block. 13542 // longjmp() and throw() must not violate the entry/exit criteria. 13543 CS->getCapturedDecl()->setNothrow(); 13544 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_simd); 13545 ThisCaptureLevel > 1; --ThisCaptureLevel) { 13546 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 13547 // 1.2.2 OpenMP Language Terminology 13548 // Structured block - An executable statement with a single entry at the 13549 // top and a single exit at the bottom. 13550 // The point of exit cannot be a branch out of the structured block. 13551 // longjmp() and throw() must not violate the entry/exit criteria. 13552 CS->getCapturedDecl()->setNothrow(); 13553 } 13554 13555 OMPLoopBasedDirective::HelperExprs B; 13556 // In presence of clause 'collapse' with number of loops, it will define the 13557 // nested loops number. 13558 unsigned NestedLoopCount = 13559 checkOpenMPLoop(OMPD_target_simd, getCollapseNumberExpr(Clauses), 13560 getOrderedNumberExpr(Clauses), CS, *this, *DSAStack, 13561 VarsWithImplicitDSA, B); 13562 if (NestedLoopCount == 0) 13563 return StmtError(); 13564 13565 assert((CurContext->isDependentContext() || B.builtAll()) && 13566 "omp target simd loop exprs were not built"); 13567 13568 if (!CurContext->isDependentContext()) { 13569 // Finalize the clauses that need pre-built expressions for CodeGen. 13570 for (OMPClause *C : Clauses) { 13571 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 13572 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 13573 B.NumIterations, *this, CurScope, 13574 DSAStack)) 13575 return StmtError(); 13576 } 13577 } 13578 13579 if (checkSimdlenSafelenSpecified(*this, Clauses)) 13580 return StmtError(); 13581 13582 setFunctionHasBranchProtectedScope(); 13583 return OMPTargetSimdDirective::Create(Context, StartLoc, EndLoc, 13584 NestedLoopCount, Clauses, AStmt, B); 13585 } 13586 13587 StmtResult Sema::ActOnOpenMPTeamsDistributeDirective( 13588 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 13589 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 13590 if (!AStmt) 13591 return StmtError(); 13592 13593 auto *CS = cast<CapturedStmt>(AStmt); 13594 // 1.2.2 OpenMP Language Terminology 13595 // Structured block - An executable statement with a single entry at the 13596 // top and a single exit at the bottom. 13597 // The point of exit cannot be a branch out of the structured block. 13598 // longjmp() and throw() must not violate the entry/exit criteria. 13599 CS->getCapturedDecl()->setNothrow(); 13600 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_teams_distribute); 13601 ThisCaptureLevel > 1; --ThisCaptureLevel) { 13602 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 13603 // 1.2.2 OpenMP Language Terminology 13604 // Structured block - An executable statement with a single entry at the 13605 // top and a single exit at the bottom. 13606 // The point of exit cannot be a branch out of the structured block. 13607 // longjmp() and throw() must not violate the entry/exit criteria. 13608 CS->getCapturedDecl()->setNothrow(); 13609 } 13610 13611 OMPLoopBasedDirective::HelperExprs B; 13612 // In presence of clause 'collapse' with number of loops, it will 13613 // define the nested loops number. 13614 unsigned NestedLoopCount = 13615 checkOpenMPLoop(OMPD_teams_distribute, getCollapseNumberExpr(Clauses), 13616 nullptr /*ordered not a clause on distribute*/, CS, *this, 13617 *DSAStack, VarsWithImplicitDSA, B); 13618 if (NestedLoopCount == 0) 13619 return StmtError(); 13620 13621 assert((CurContext->isDependentContext() || B.builtAll()) && 13622 "omp teams distribute loop exprs were not built"); 13623 13624 setFunctionHasBranchProtectedScope(); 13625 13626 DSAStack->setParentTeamsRegionLoc(StartLoc); 13627 13628 return OMPTeamsDistributeDirective::Create( 13629 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 13630 } 13631 13632 StmtResult Sema::ActOnOpenMPTeamsDistributeSimdDirective( 13633 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 13634 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 13635 if (!AStmt) 13636 return StmtError(); 13637 13638 auto *CS = cast<CapturedStmt>(AStmt); 13639 // 1.2.2 OpenMP Language Terminology 13640 // Structured block - An executable statement with a single entry at the 13641 // top and a single exit at the bottom. 13642 // The point of exit cannot be a branch out of the structured block. 13643 // longjmp() and throw() must not violate the entry/exit criteria. 13644 CS->getCapturedDecl()->setNothrow(); 13645 for (int ThisCaptureLevel = 13646 getOpenMPCaptureLevels(OMPD_teams_distribute_simd); 13647 ThisCaptureLevel > 1; --ThisCaptureLevel) { 13648 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 13649 // 1.2.2 OpenMP Language Terminology 13650 // Structured block - An executable statement with a single entry at the 13651 // top and a single exit at the bottom. 13652 // The point of exit cannot be a branch out of the structured block. 13653 // longjmp() and throw() must not violate the entry/exit criteria. 13654 CS->getCapturedDecl()->setNothrow(); 13655 } 13656 13657 OMPLoopBasedDirective::HelperExprs B; 13658 // In presence of clause 'collapse' with number of loops, it will 13659 // define the nested loops number. 13660 unsigned NestedLoopCount = checkOpenMPLoop( 13661 OMPD_teams_distribute_simd, getCollapseNumberExpr(Clauses), 13662 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 13663 VarsWithImplicitDSA, B); 13664 13665 if (NestedLoopCount == 0) 13666 return StmtError(); 13667 13668 assert((CurContext->isDependentContext() || B.builtAll()) && 13669 "omp teams distribute simd loop exprs were not built"); 13670 13671 if (!CurContext->isDependentContext()) { 13672 // Finalize the clauses that need pre-built expressions for CodeGen. 13673 for (OMPClause *C : Clauses) { 13674 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 13675 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 13676 B.NumIterations, *this, CurScope, 13677 DSAStack)) 13678 return StmtError(); 13679 } 13680 } 13681 13682 if (checkSimdlenSafelenSpecified(*this, Clauses)) 13683 return StmtError(); 13684 13685 setFunctionHasBranchProtectedScope(); 13686 13687 DSAStack->setParentTeamsRegionLoc(StartLoc); 13688 13689 return OMPTeamsDistributeSimdDirective::Create( 13690 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 13691 } 13692 13693 StmtResult Sema::ActOnOpenMPTeamsDistributeParallelForSimdDirective( 13694 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 13695 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 13696 if (!AStmt) 13697 return StmtError(); 13698 13699 auto *CS = cast<CapturedStmt>(AStmt); 13700 // 1.2.2 OpenMP Language Terminology 13701 // Structured block - An executable statement with a single entry at the 13702 // top and a single exit at the bottom. 13703 // The point of exit cannot be a branch out of the structured block. 13704 // longjmp() and throw() must not violate the entry/exit criteria. 13705 CS->getCapturedDecl()->setNothrow(); 13706 13707 for (int ThisCaptureLevel = 13708 getOpenMPCaptureLevels(OMPD_teams_distribute_parallel_for_simd); 13709 ThisCaptureLevel > 1; --ThisCaptureLevel) { 13710 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 13711 // 1.2.2 OpenMP Language Terminology 13712 // Structured block - An executable statement with a single entry at the 13713 // top and a single exit at the bottom. 13714 // The point of exit cannot be a branch out of the structured block. 13715 // longjmp() and throw() must not violate the entry/exit criteria. 13716 CS->getCapturedDecl()->setNothrow(); 13717 } 13718 13719 OMPLoopBasedDirective::HelperExprs B; 13720 // In presence of clause 'collapse' with number of loops, it will 13721 // define the nested loops number. 13722 unsigned NestedLoopCount = checkOpenMPLoop( 13723 OMPD_teams_distribute_parallel_for_simd, getCollapseNumberExpr(Clauses), 13724 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 13725 VarsWithImplicitDSA, B); 13726 13727 if (NestedLoopCount == 0) 13728 return StmtError(); 13729 13730 assert((CurContext->isDependentContext() || B.builtAll()) && 13731 "omp for loop exprs were not built"); 13732 13733 if (!CurContext->isDependentContext()) { 13734 // Finalize the clauses that need pre-built expressions for CodeGen. 13735 for (OMPClause *C : Clauses) { 13736 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 13737 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 13738 B.NumIterations, *this, CurScope, 13739 DSAStack)) 13740 return StmtError(); 13741 } 13742 } 13743 13744 if (checkSimdlenSafelenSpecified(*this, Clauses)) 13745 return StmtError(); 13746 13747 setFunctionHasBranchProtectedScope(); 13748 13749 DSAStack->setParentTeamsRegionLoc(StartLoc); 13750 13751 return OMPTeamsDistributeParallelForSimdDirective::Create( 13752 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 13753 } 13754 13755 StmtResult Sema::ActOnOpenMPTeamsDistributeParallelForDirective( 13756 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 13757 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 13758 if (!AStmt) 13759 return StmtError(); 13760 13761 auto *CS = cast<CapturedStmt>(AStmt); 13762 // 1.2.2 OpenMP Language Terminology 13763 // Structured block - An executable statement with a single entry at the 13764 // top and a single exit at the bottom. 13765 // The point of exit cannot be a branch out of the structured block. 13766 // longjmp() and throw() must not violate the entry/exit criteria. 13767 CS->getCapturedDecl()->setNothrow(); 13768 13769 for (int ThisCaptureLevel = 13770 getOpenMPCaptureLevels(OMPD_teams_distribute_parallel_for); 13771 ThisCaptureLevel > 1; --ThisCaptureLevel) { 13772 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 13773 // 1.2.2 OpenMP Language Terminology 13774 // Structured block - An executable statement with a single entry at the 13775 // top and a single exit at the bottom. 13776 // The point of exit cannot be a branch out of the structured block. 13777 // longjmp() and throw() must not violate the entry/exit criteria. 13778 CS->getCapturedDecl()->setNothrow(); 13779 } 13780 13781 OMPLoopBasedDirective::HelperExprs B; 13782 // In presence of clause 'collapse' with number of loops, it will 13783 // define the nested loops number. 13784 unsigned NestedLoopCount = checkOpenMPLoop( 13785 OMPD_teams_distribute_parallel_for, getCollapseNumberExpr(Clauses), 13786 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 13787 VarsWithImplicitDSA, B); 13788 13789 if (NestedLoopCount == 0) 13790 return StmtError(); 13791 13792 assert((CurContext->isDependentContext() || B.builtAll()) && 13793 "omp for loop exprs were not built"); 13794 13795 setFunctionHasBranchProtectedScope(); 13796 13797 DSAStack->setParentTeamsRegionLoc(StartLoc); 13798 13799 return OMPTeamsDistributeParallelForDirective::Create( 13800 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B, 13801 DSAStack->getTaskgroupReductionRef(), DSAStack->isCancelRegion()); 13802 } 13803 13804 StmtResult Sema::ActOnOpenMPTargetTeamsDirective(ArrayRef<OMPClause *> Clauses, 13805 Stmt *AStmt, 13806 SourceLocation StartLoc, 13807 SourceLocation EndLoc) { 13808 if (!AStmt) 13809 return StmtError(); 13810 13811 auto *CS = cast<CapturedStmt>(AStmt); 13812 // 1.2.2 OpenMP Language Terminology 13813 // Structured block - An executable statement with a single entry at the 13814 // top and a single exit at the bottom. 13815 // The point of exit cannot be a branch out of the structured block. 13816 // longjmp() and throw() must not violate the entry/exit criteria. 13817 CS->getCapturedDecl()->setNothrow(); 13818 13819 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_teams); 13820 ThisCaptureLevel > 1; --ThisCaptureLevel) { 13821 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 13822 // 1.2.2 OpenMP Language Terminology 13823 // Structured block - An executable statement with a single entry at the 13824 // top and a single exit at the bottom. 13825 // The point of exit cannot be a branch out of the structured block. 13826 // longjmp() and throw() must not violate the entry/exit criteria. 13827 CS->getCapturedDecl()->setNothrow(); 13828 } 13829 setFunctionHasBranchProtectedScope(); 13830 13831 return OMPTargetTeamsDirective::Create(Context, StartLoc, EndLoc, Clauses, 13832 AStmt); 13833 } 13834 13835 StmtResult Sema::ActOnOpenMPTargetTeamsDistributeDirective( 13836 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 13837 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 13838 if (!AStmt) 13839 return StmtError(); 13840 13841 auto *CS = cast<CapturedStmt>(AStmt); 13842 // 1.2.2 OpenMP Language Terminology 13843 // Structured block - An executable statement with a single entry at the 13844 // top and a single exit at the bottom. 13845 // The point of exit cannot be a branch out of the structured block. 13846 // longjmp() and throw() must not violate the entry/exit criteria. 13847 CS->getCapturedDecl()->setNothrow(); 13848 for (int ThisCaptureLevel = 13849 getOpenMPCaptureLevels(OMPD_target_teams_distribute); 13850 ThisCaptureLevel > 1; --ThisCaptureLevel) { 13851 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 13852 // 1.2.2 OpenMP Language Terminology 13853 // Structured block - An executable statement with a single entry at the 13854 // top and a single exit at the bottom. 13855 // The point of exit cannot be a branch out of the structured block. 13856 // longjmp() and throw() must not violate the entry/exit criteria. 13857 CS->getCapturedDecl()->setNothrow(); 13858 } 13859 13860 OMPLoopBasedDirective::HelperExprs B; 13861 // In presence of clause 'collapse' with number of loops, it will 13862 // define the nested loops number. 13863 unsigned NestedLoopCount = checkOpenMPLoop( 13864 OMPD_target_teams_distribute, getCollapseNumberExpr(Clauses), 13865 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 13866 VarsWithImplicitDSA, B); 13867 if (NestedLoopCount == 0) 13868 return StmtError(); 13869 13870 assert((CurContext->isDependentContext() || B.builtAll()) && 13871 "omp target teams distribute loop exprs were not built"); 13872 13873 setFunctionHasBranchProtectedScope(); 13874 return OMPTargetTeamsDistributeDirective::Create( 13875 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 13876 } 13877 13878 StmtResult Sema::ActOnOpenMPTargetTeamsDistributeParallelForDirective( 13879 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 13880 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 13881 if (!AStmt) 13882 return StmtError(); 13883 13884 auto *CS = cast<CapturedStmt>(AStmt); 13885 // 1.2.2 OpenMP Language Terminology 13886 // Structured block - An executable statement with a single entry at the 13887 // top and a single exit at the bottom. 13888 // The point of exit cannot be a branch out of the structured block. 13889 // longjmp() and throw() must not violate the entry/exit criteria. 13890 CS->getCapturedDecl()->setNothrow(); 13891 for (int ThisCaptureLevel = 13892 getOpenMPCaptureLevels(OMPD_target_teams_distribute_parallel_for); 13893 ThisCaptureLevel > 1; --ThisCaptureLevel) { 13894 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 13895 // 1.2.2 OpenMP Language Terminology 13896 // Structured block - An executable statement with a single entry at the 13897 // top and a single exit at the bottom. 13898 // The point of exit cannot be a branch out of the structured block. 13899 // longjmp() and throw() must not violate the entry/exit criteria. 13900 CS->getCapturedDecl()->setNothrow(); 13901 } 13902 13903 OMPLoopBasedDirective::HelperExprs B; 13904 // In presence of clause 'collapse' with number of loops, it will 13905 // define the nested loops number. 13906 unsigned NestedLoopCount = checkOpenMPLoop( 13907 OMPD_target_teams_distribute_parallel_for, getCollapseNumberExpr(Clauses), 13908 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 13909 VarsWithImplicitDSA, B); 13910 if (NestedLoopCount == 0) 13911 return StmtError(); 13912 13913 assert((CurContext->isDependentContext() || B.builtAll()) && 13914 "omp target teams distribute parallel for loop exprs were not built"); 13915 13916 if (!CurContext->isDependentContext()) { 13917 // Finalize the clauses that need pre-built expressions for CodeGen. 13918 for (OMPClause *C : Clauses) { 13919 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 13920 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 13921 B.NumIterations, *this, CurScope, 13922 DSAStack)) 13923 return StmtError(); 13924 } 13925 } 13926 13927 setFunctionHasBranchProtectedScope(); 13928 return OMPTargetTeamsDistributeParallelForDirective::Create( 13929 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B, 13930 DSAStack->getTaskgroupReductionRef(), DSAStack->isCancelRegion()); 13931 } 13932 13933 StmtResult Sema::ActOnOpenMPTargetTeamsDistributeParallelForSimdDirective( 13934 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 13935 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 13936 if (!AStmt) 13937 return StmtError(); 13938 13939 auto *CS = cast<CapturedStmt>(AStmt); 13940 // 1.2.2 OpenMP Language Terminology 13941 // Structured block - An executable statement with a single entry at the 13942 // top and a single exit at the bottom. 13943 // The point of exit cannot be a branch out of the structured block. 13944 // longjmp() and throw() must not violate the entry/exit criteria. 13945 CS->getCapturedDecl()->setNothrow(); 13946 for (int ThisCaptureLevel = getOpenMPCaptureLevels( 13947 OMPD_target_teams_distribute_parallel_for_simd); 13948 ThisCaptureLevel > 1; --ThisCaptureLevel) { 13949 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 13950 // 1.2.2 OpenMP Language Terminology 13951 // Structured block - An executable statement with a single entry at the 13952 // top and a single exit at the bottom. 13953 // The point of exit cannot be a branch out of the structured block. 13954 // longjmp() and throw() must not violate the entry/exit criteria. 13955 CS->getCapturedDecl()->setNothrow(); 13956 } 13957 13958 OMPLoopBasedDirective::HelperExprs B; 13959 // In presence of clause 'collapse' with number of loops, it will 13960 // define the nested loops number. 13961 unsigned NestedLoopCount = 13962 checkOpenMPLoop(OMPD_target_teams_distribute_parallel_for_simd, 13963 getCollapseNumberExpr(Clauses), 13964 nullptr /*ordered not a clause on distribute*/, CS, *this, 13965 *DSAStack, VarsWithImplicitDSA, B); 13966 if (NestedLoopCount == 0) 13967 return StmtError(); 13968 13969 assert((CurContext->isDependentContext() || B.builtAll()) && 13970 "omp target teams distribute parallel for simd loop exprs were not " 13971 "built"); 13972 13973 if (!CurContext->isDependentContext()) { 13974 // Finalize the clauses that need pre-built expressions for CodeGen. 13975 for (OMPClause *C : Clauses) { 13976 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 13977 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 13978 B.NumIterations, *this, CurScope, 13979 DSAStack)) 13980 return StmtError(); 13981 } 13982 } 13983 13984 if (checkSimdlenSafelenSpecified(*this, Clauses)) 13985 return StmtError(); 13986 13987 setFunctionHasBranchProtectedScope(); 13988 return OMPTargetTeamsDistributeParallelForSimdDirective::Create( 13989 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 13990 } 13991 13992 StmtResult Sema::ActOnOpenMPTargetTeamsDistributeSimdDirective( 13993 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 13994 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 13995 if (!AStmt) 13996 return StmtError(); 13997 13998 auto *CS = cast<CapturedStmt>(AStmt); 13999 // 1.2.2 OpenMP Language Terminology 14000 // Structured block - An executable statement with a single entry at the 14001 // top and a single exit at the bottom. 14002 // The point of exit cannot be a branch out of the structured block. 14003 // longjmp() and throw() must not violate the entry/exit criteria. 14004 CS->getCapturedDecl()->setNothrow(); 14005 for (int ThisCaptureLevel = 14006 getOpenMPCaptureLevels(OMPD_target_teams_distribute_simd); 14007 ThisCaptureLevel > 1; --ThisCaptureLevel) { 14008 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 14009 // 1.2.2 OpenMP Language Terminology 14010 // Structured block - An executable statement with a single entry at the 14011 // top and a single exit at the bottom. 14012 // The point of exit cannot be a branch out of the structured block. 14013 // longjmp() and throw() must not violate the entry/exit criteria. 14014 CS->getCapturedDecl()->setNothrow(); 14015 } 14016 14017 OMPLoopBasedDirective::HelperExprs B; 14018 // In presence of clause 'collapse' with number of loops, it will 14019 // define the nested loops number. 14020 unsigned NestedLoopCount = checkOpenMPLoop( 14021 OMPD_target_teams_distribute_simd, getCollapseNumberExpr(Clauses), 14022 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 14023 VarsWithImplicitDSA, B); 14024 if (NestedLoopCount == 0) 14025 return StmtError(); 14026 14027 assert((CurContext->isDependentContext() || B.builtAll()) && 14028 "omp target teams distribute simd loop exprs were not built"); 14029 14030 if (!CurContext->isDependentContext()) { 14031 // Finalize the clauses that need pre-built expressions for CodeGen. 14032 for (OMPClause *C : Clauses) { 14033 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 14034 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 14035 B.NumIterations, *this, CurScope, 14036 DSAStack)) 14037 return StmtError(); 14038 } 14039 } 14040 14041 if (checkSimdlenSafelenSpecified(*this, Clauses)) 14042 return StmtError(); 14043 14044 setFunctionHasBranchProtectedScope(); 14045 return OMPTargetTeamsDistributeSimdDirective::Create( 14046 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 14047 } 14048 14049 bool Sema::checkTransformableLoopNest( 14050 OpenMPDirectiveKind Kind, Stmt *AStmt, int NumLoops, 14051 SmallVectorImpl<OMPLoopBasedDirective::HelperExprs> &LoopHelpers, 14052 Stmt *&Body, 14053 SmallVectorImpl<SmallVector<llvm::PointerUnion<Stmt *, Decl *>, 0>> 14054 &OriginalInits) { 14055 OriginalInits.emplace_back(); 14056 bool Result = OMPLoopBasedDirective::doForAllLoops( 14057 AStmt->IgnoreContainers(), /*TryImperfectlyNestedLoops=*/false, NumLoops, 14058 [this, &LoopHelpers, &Body, &OriginalInits, Kind](unsigned Cnt, 14059 Stmt *CurStmt) { 14060 VarsWithInheritedDSAType TmpDSA; 14061 unsigned SingleNumLoops = 14062 checkOpenMPLoop(Kind, nullptr, nullptr, CurStmt, *this, *DSAStack, 14063 TmpDSA, LoopHelpers[Cnt]); 14064 if (SingleNumLoops == 0) 14065 return true; 14066 assert(SingleNumLoops == 1 && "Expect single loop iteration space"); 14067 if (auto *For = dyn_cast<ForStmt>(CurStmt)) { 14068 OriginalInits.back().push_back(For->getInit()); 14069 Body = For->getBody(); 14070 } else { 14071 assert(isa<CXXForRangeStmt>(CurStmt) && 14072 "Expected canonical for or range-based for loops."); 14073 auto *CXXFor = cast<CXXForRangeStmt>(CurStmt); 14074 OriginalInits.back().push_back(CXXFor->getBeginStmt()); 14075 Body = CXXFor->getBody(); 14076 } 14077 OriginalInits.emplace_back(); 14078 return false; 14079 }, 14080 [&OriginalInits](OMPLoopBasedDirective *Transform) { 14081 Stmt *DependentPreInits; 14082 if (auto *Dir = dyn_cast<OMPTileDirective>(Transform)) 14083 DependentPreInits = Dir->getPreInits(); 14084 else if (auto *Dir = dyn_cast<OMPUnrollDirective>(Transform)) 14085 DependentPreInits = Dir->getPreInits(); 14086 else 14087 llvm_unreachable("Unhandled loop transformation"); 14088 if (!DependentPreInits) 14089 return; 14090 llvm::append_range(OriginalInits.back(), 14091 cast<DeclStmt>(DependentPreInits)->getDeclGroup()); 14092 }); 14093 assert(OriginalInits.back().empty() && "No preinit after innermost loop"); 14094 OriginalInits.pop_back(); 14095 return Result; 14096 } 14097 14098 StmtResult Sema::ActOnOpenMPTileDirective(ArrayRef<OMPClause *> Clauses, 14099 Stmt *AStmt, SourceLocation StartLoc, 14100 SourceLocation EndLoc) { 14101 auto SizesClauses = 14102 OMPExecutableDirective::getClausesOfKind<OMPSizesClause>(Clauses); 14103 if (SizesClauses.empty()) { 14104 // A missing 'sizes' clause is already reported by the parser. 14105 return StmtError(); 14106 } 14107 const OMPSizesClause *SizesClause = *SizesClauses.begin(); 14108 unsigned NumLoops = SizesClause->getNumSizes(); 14109 14110 // Empty statement should only be possible if there already was an error. 14111 if (!AStmt) 14112 return StmtError(); 14113 14114 // Verify and diagnose loop nest. 14115 SmallVector<OMPLoopBasedDirective::HelperExprs, 4> LoopHelpers(NumLoops); 14116 Stmt *Body = nullptr; 14117 SmallVector<SmallVector<llvm::PointerUnion<Stmt *, Decl *>, 0>, 4> 14118 OriginalInits; 14119 if (!checkTransformableLoopNest(OMPD_tile, AStmt, NumLoops, LoopHelpers, Body, 14120 OriginalInits)) 14121 return StmtError(); 14122 14123 // Delay tiling to when template is completely instantiated. 14124 if (CurContext->isDependentContext()) 14125 return OMPTileDirective::Create(Context, StartLoc, EndLoc, Clauses, 14126 NumLoops, AStmt, nullptr, nullptr); 14127 14128 SmallVector<Decl *, 4> PreInits; 14129 14130 // Create iteration variables for the generated loops. 14131 SmallVector<VarDecl *, 4> FloorIndVars; 14132 SmallVector<VarDecl *, 4> TileIndVars; 14133 FloorIndVars.resize(NumLoops); 14134 TileIndVars.resize(NumLoops); 14135 for (unsigned I = 0; I < NumLoops; ++I) { 14136 OMPLoopBasedDirective::HelperExprs &LoopHelper = LoopHelpers[I]; 14137 14138 assert(LoopHelper.Counters.size() == 1 && 14139 "Expect single-dimensional loop iteration space"); 14140 auto *OrigCntVar = cast<DeclRefExpr>(LoopHelper.Counters.front()); 14141 std::string OrigVarName = OrigCntVar->getNameInfo().getAsString(); 14142 DeclRefExpr *IterVarRef = cast<DeclRefExpr>(LoopHelper.IterationVarRef); 14143 QualType CntTy = IterVarRef->getType(); 14144 14145 // Iteration variable for the floor (i.e. outer) loop. 14146 { 14147 std::string FloorCntName = 14148 (Twine(".floor_") + llvm::utostr(I) + ".iv." + OrigVarName).str(); 14149 VarDecl *FloorCntDecl = 14150 buildVarDecl(*this, {}, CntTy, FloorCntName, nullptr, OrigCntVar); 14151 FloorIndVars[I] = FloorCntDecl; 14152 } 14153 14154 // Iteration variable for the tile (i.e. inner) loop. 14155 { 14156 std::string TileCntName = 14157 (Twine(".tile_") + llvm::utostr(I) + ".iv." + OrigVarName).str(); 14158 14159 // Reuse the iteration variable created by checkOpenMPLoop. It is also 14160 // used by the expressions to derive the original iteration variable's 14161 // value from the logical iteration number. 14162 auto *TileCntDecl = cast<VarDecl>(IterVarRef->getDecl()); 14163 TileCntDecl->setDeclName(&PP.getIdentifierTable().get(TileCntName)); 14164 TileIndVars[I] = TileCntDecl; 14165 } 14166 for (auto &P : OriginalInits[I]) { 14167 if (auto *D = P.dyn_cast<Decl *>()) 14168 PreInits.push_back(D); 14169 else if (auto *PI = dyn_cast_or_null<DeclStmt>(P.dyn_cast<Stmt *>())) 14170 PreInits.append(PI->decl_begin(), PI->decl_end()); 14171 } 14172 if (auto *PI = cast_or_null<DeclStmt>(LoopHelper.PreInits)) 14173 PreInits.append(PI->decl_begin(), PI->decl_end()); 14174 // Gather declarations for the data members used as counters. 14175 for (Expr *CounterRef : LoopHelper.Counters) { 14176 auto *CounterDecl = cast<DeclRefExpr>(CounterRef)->getDecl(); 14177 if (isa<OMPCapturedExprDecl>(CounterDecl)) 14178 PreInits.push_back(CounterDecl); 14179 } 14180 } 14181 14182 // Once the original iteration values are set, append the innermost body. 14183 Stmt *Inner = Body; 14184 14185 // Create tile loops from the inside to the outside. 14186 for (int I = NumLoops - 1; I >= 0; --I) { 14187 OMPLoopBasedDirective::HelperExprs &LoopHelper = LoopHelpers[I]; 14188 Expr *NumIterations = LoopHelper.NumIterations; 14189 auto *OrigCntVar = cast<DeclRefExpr>(LoopHelper.Counters[0]); 14190 QualType CntTy = OrigCntVar->getType(); 14191 Expr *DimTileSize = SizesClause->getSizesRefs()[I]; 14192 Scope *CurScope = getCurScope(); 14193 14194 // Commonly used variables. 14195 DeclRefExpr *TileIV = buildDeclRefExpr(*this, TileIndVars[I], CntTy, 14196 OrigCntVar->getExprLoc()); 14197 DeclRefExpr *FloorIV = buildDeclRefExpr(*this, FloorIndVars[I], CntTy, 14198 OrigCntVar->getExprLoc()); 14199 14200 // For init-statement: auto .tile.iv = .floor.iv 14201 AddInitializerToDecl(TileIndVars[I], DefaultLvalueConversion(FloorIV).get(), 14202 /*DirectInit=*/false); 14203 Decl *CounterDecl = TileIndVars[I]; 14204 StmtResult InitStmt = new (Context) 14205 DeclStmt(DeclGroupRef::Create(Context, &CounterDecl, 1), 14206 OrigCntVar->getBeginLoc(), OrigCntVar->getEndLoc()); 14207 if (!InitStmt.isUsable()) 14208 return StmtError(); 14209 14210 // For cond-expression: .tile.iv < min(.floor.iv + DimTileSize, 14211 // NumIterations) 14212 ExprResult EndOfTile = BuildBinOp(CurScope, LoopHelper.Cond->getExprLoc(), 14213 BO_Add, FloorIV, DimTileSize); 14214 if (!EndOfTile.isUsable()) 14215 return StmtError(); 14216 ExprResult IsPartialTile = 14217 BuildBinOp(CurScope, LoopHelper.Cond->getExprLoc(), BO_LT, 14218 NumIterations, EndOfTile.get()); 14219 if (!IsPartialTile.isUsable()) 14220 return StmtError(); 14221 ExprResult MinTileAndIterSpace = ActOnConditionalOp( 14222 LoopHelper.Cond->getBeginLoc(), LoopHelper.Cond->getEndLoc(), 14223 IsPartialTile.get(), NumIterations, EndOfTile.get()); 14224 if (!MinTileAndIterSpace.isUsable()) 14225 return StmtError(); 14226 ExprResult CondExpr = BuildBinOp(CurScope, LoopHelper.Cond->getExprLoc(), 14227 BO_LT, TileIV, MinTileAndIterSpace.get()); 14228 if (!CondExpr.isUsable()) 14229 return StmtError(); 14230 14231 // For incr-statement: ++.tile.iv 14232 ExprResult IncrStmt = 14233 BuildUnaryOp(CurScope, LoopHelper.Inc->getExprLoc(), UO_PreInc, TileIV); 14234 if (!IncrStmt.isUsable()) 14235 return StmtError(); 14236 14237 // Statements to set the original iteration variable's value from the 14238 // logical iteration number. 14239 // Generated for loop is: 14240 // Original_for_init; 14241 // for (auto .tile.iv = .floor.iv; .tile.iv < min(.floor.iv + DimTileSize, 14242 // NumIterations); ++.tile.iv) { 14243 // Original_Body; 14244 // Original_counter_update; 14245 // } 14246 // FIXME: If the innermost body is an loop itself, inserting these 14247 // statements stops it being recognized as a perfectly nested loop (e.g. 14248 // for applying tiling again). If this is the case, sink the expressions 14249 // further into the inner loop. 14250 SmallVector<Stmt *, 4> BodyParts; 14251 BodyParts.append(LoopHelper.Updates.begin(), LoopHelper.Updates.end()); 14252 BodyParts.push_back(Inner); 14253 Inner = CompoundStmt::Create(Context, BodyParts, Inner->getBeginLoc(), 14254 Inner->getEndLoc()); 14255 Inner = new (Context) 14256 ForStmt(Context, InitStmt.get(), CondExpr.get(), nullptr, 14257 IncrStmt.get(), Inner, LoopHelper.Init->getBeginLoc(), 14258 LoopHelper.Init->getBeginLoc(), LoopHelper.Inc->getEndLoc()); 14259 } 14260 14261 // Create floor loops from the inside to the outside. 14262 for (int I = NumLoops - 1; I >= 0; --I) { 14263 auto &LoopHelper = LoopHelpers[I]; 14264 Expr *NumIterations = LoopHelper.NumIterations; 14265 DeclRefExpr *OrigCntVar = cast<DeclRefExpr>(LoopHelper.Counters[0]); 14266 QualType CntTy = OrigCntVar->getType(); 14267 Expr *DimTileSize = SizesClause->getSizesRefs()[I]; 14268 Scope *CurScope = getCurScope(); 14269 14270 // Commonly used variables. 14271 DeclRefExpr *FloorIV = buildDeclRefExpr(*this, FloorIndVars[I], CntTy, 14272 OrigCntVar->getExprLoc()); 14273 14274 // For init-statement: auto .floor.iv = 0 14275 AddInitializerToDecl( 14276 FloorIndVars[I], 14277 ActOnIntegerConstant(LoopHelper.Init->getExprLoc(), 0).get(), 14278 /*DirectInit=*/false); 14279 Decl *CounterDecl = FloorIndVars[I]; 14280 StmtResult InitStmt = new (Context) 14281 DeclStmt(DeclGroupRef::Create(Context, &CounterDecl, 1), 14282 OrigCntVar->getBeginLoc(), OrigCntVar->getEndLoc()); 14283 if (!InitStmt.isUsable()) 14284 return StmtError(); 14285 14286 // For cond-expression: .floor.iv < NumIterations 14287 ExprResult CondExpr = BuildBinOp(CurScope, LoopHelper.Cond->getExprLoc(), 14288 BO_LT, FloorIV, NumIterations); 14289 if (!CondExpr.isUsable()) 14290 return StmtError(); 14291 14292 // For incr-statement: .floor.iv += DimTileSize 14293 ExprResult IncrStmt = BuildBinOp(CurScope, LoopHelper.Inc->getExprLoc(), 14294 BO_AddAssign, FloorIV, DimTileSize); 14295 if (!IncrStmt.isUsable()) 14296 return StmtError(); 14297 14298 Inner = new (Context) 14299 ForStmt(Context, InitStmt.get(), CondExpr.get(), nullptr, 14300 IncrStmt.get(), Inner, LoopHelper.Init->getBeginLoc(), 14301 LoopHelper.Init->getBeginLoc(), LoopHelper.Inc->getEndLoc()); 14302 } 14303 14304 return OMPTileDirective::Create(Context, StartLoc, EndLoc, Clauses, NumLoops, 14305 AStmt, Inner, 14306 buildPreInits(Context, PreInits)); 14307 } 14308 14309 StmtResult Sema::ActOnOpenMPUnrollDirective(ArrayRef<OMPClause *> Clauses, 14310 Stmt *AStmt, 14311 SourceLocation StartLoc, 14312 SourceLocation EndLoc) { 14313 // Empty statement should only be possible if there already was an error. 14314 if (!AStmt) 14315 return StmtError(); 14316 14317 if (checkMutuallyExclusiveClauses(*this, Clauses, {OMPC_partial, OMPC_full})) 14318 return StmtError(); 14319 14320 const OMPFullClause *FullClause = 14321 OMPExecutableDirective::getSingleClause<OMPFullClause>(Clauses); 14322 const OMPPartialClause *PartialClause = 14323 OMPExecutableDirective::getSingleClause<OMPPartialClause>(Clauses); 14324 assert(!(FullClause && PartialClause) && 14325 "mutual exclusivity must have been checked before"); 14326 14327 constexpr unsigned NumLoops = 1; 14328 Stmt *Body = nullptr; 14329 SmallVector<OMPLoopBasedDirective::HelperExprs, NumLoops> LoopHelpers( 14330 NumLoops); 14331 SmallVector<SmallVector<llvm::PointerUnion<Stmt *, Decl *>, 0>, NumLoops + 1> 14332 OriginalInits; 14333 if (!checkTransformableLoopNest(OMPD_unroll, AStmt, NumLoops, LoopHelpers, 14334 Body, OriginalInits)) 14335 return StmtError(); 14336 14337 unsigned NumGeneratedLoops = PartialClause ? 1 : 0; 14338 14339 // Delay unrolling to when template is completely instantiated. 14340 if (CurContext->isDependentContext()) 14341 return OMPUnrollDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt, 14342 NumGeneratedLoops, nullptr, nullptr); 14343 14344 OMPLoopBasedDirective::HelperExprs &LoopHelper = LoopHelpers.front(); 14345 14346 if (FullClause) { 14347 if (!VerifyPositiveIntegerConstantInClause( 14348 LoopHelper.NumIterations, OMPC_full, /*StrictlyPositive=*/false, 14349 /*SuppressExprDiags=*/true) 14350 .isUsable()) { 14351 Diag(AStmt->getBeginLoc(), diag::err_omp_unroll_full_variable_trip_count); 14352 Diag(FullClause->getBeginLoc(), diag::note_omp_directive_here) 14353 << "#pragma omp unroll full"; 14354 return StmtError(); 14355 } 14356 } 14357 14358 // The generated loop may only be passed to other loop-associated directive 14359 // when a partial clause is specified. Without the requirement it is 14360 // sufficient to generate loop unroll metadata at code-generation. 14361 if (NumGeneratedLoops == 0) 14362 return OMPUnrollDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt, 14363 NumGeneratedLoops, nullptr, nullptr); 14364 14365 // Otherwise, we need to provide a de-sugared/transformed AST that can be 14366 // associated with another loop directive. 14367 // 14368 // The canonical loop analysis return by checkTransformableLoopNest assumes 14369 // the following structure to be the same loop without transformations or 14370 // directives applied: \code OriginalInits; LoopHelper.PreInits; 14371 // LoopHelper.Counters; 14372 // for (; IV < LoopHelper.NumIterations; ++IV) { 14373 // LoopHelper.Updates; 14374 // Body; 14375 // } 14376 // \endcode 14377 // where IV is a variable declared and initialized to 0 in LoopHelper.PreInits 14378 // and referenced by LoopHelper.IterationVarRef. 14379 // 14380 // The unrolling directive transforms this into the following loop: 14381 // \code 14382 // OriginalInits; \ 14383 // LoopHelper.PreInits; > NewPreInits 14384 // LoopHelper.Counters; / 14385 // for (auto UIV = 0; UIV < LoopHelper.NumIterations; UIV+=Factor) { 14386 // #pragma clang loop unroll_count(Factor) 14387 // for (IV = UIV; IV < UIV + Factor && UIV < LoopHelper.NumIterations; ++IV) 14388 // { 14389 // LoopHelper.Updates; 14390 // Body; 14391 // } 14392 // } 14393 // \endcode 14394 // where UIV is a new logical iteration counter. IV must be the same VarDecl 14395 // as the original LoopHelper.IterationVarRef because LoopHelper.Updates 14396 // references it. If the partially unrolled loop is associated with another 14397 // loop directive (like an OMPForDirective), it will use checkOpenMPLoop to 14398 // analyze this loop, i.e. the outer loop must fulfill the constraints of an 14399 // OpenMP canonical loop. The inner loop is not an associable canonical loop 14400 // and only exists to defer its unrolling to LLVM's LoopUnroll instead of 14401 // doing it in the frontend (by adding loop metadata). NewPreInits becomes a 14402 // property of the OMPLoopBasedDirective instead of statements in 14403 // CompoundStatement. This is to allow the loop to become a non-outermost loop 14404 // of a canonical loop nest where these PreInits are emitted before the 14405 // outermost directive. 14406 14407 // Determine the PreInit declarations. 14408 SmallVector<Decl *, 4> PreInits; 14409 assert(OriginalInits.size() == 1 && 14410 "Expecting a single-dimensional loop iteration space"); 14411 for (auto &P : OriginalInits[0]) { 14412 if (auto *D = P.dyn_cast<Decl *>()) 14413 PreInits.push_back(D); 14414 else if (auto *PI = dyn_cast_or_null<DeclStmt>(P.dyn_cast<Stmt *>())) 14415 PreInits.append(PI->decl_begin(), PI->decl_end()); 14416 } 14417 if (auto *PI = cast_or_null<DeclStmt>(LoopHelper.PreInits)) 14418 PreInits.append(PI->decl_begin(), PI->decl_end()); 14419 // Gather declarations for the data members used as counters. 14420 for (Expr *CounterRef : LoopHelper.Counters) { 14421 auto *CounterDecl = cast<DeclRefExpr>(CounterRef)->getDecl(); 14422 if (isa<OMPCapturedExprDecl>(CounterDecl)) 14423 PreInits.push_back(CounterDecl); 14424 } 14425 14426 auto *IterationVarRef = cast<DeclRefExpr>(LoopHelper.IterationVarRef); 14427 QualType IVTy = IterationVarRef->getType(); 14428 assert(LoopHelper.Counters.size() == 1 && 14429 "Expecting a single-dimensional loop iteration space"); 14430 auto *OrigVar = cast<DeclRefExpr>(LoopHelper.Counters.front()); 14431 14432 // Determine the unroll factor. 14433 uint64_t Factor; 14434 SourceLocation FactorLoc; 14435 if (Expr *FactorVal = PartialClause->getFactor()) { 14436 Factor = 14437 FactorVal->getIntegerConstantExpr(Context).getValue().getZExtValue(); 14438 FactorLoc = FactorVal->getExprLoc(); 14439 } else { 14440 // TODO: Use a better profitability model. 14441 Factor = 2; 14442 } 14443 assert(Factor > 0 && "Expected positive unroll factor"); 14444 auto MakeFactorExpr = [this, Factor, IVTy, FactorLoc]() { 14445 return IntegerLiteral::Create( 14446 Context, llvm::APInt(Context.getIntWidth(IVTy), Factor), IVTy, 14447 FactorLoc); 14448 }; 14449 14450 // Iteration variable SourceLocations. 14451 SourceLocation OrigVarLoc = OrigVar->getExprLoc(); 14452 SourceLocation OrigVarLocBegin = OrigVar->getBeginLoc(); 14453 SourceLocation OrigVarLocEnd = OrigVar->getEndLoc(); 14454 14455 // Internal variable names. 14456 std::string OrigVarName = OrigVar->getNameInfo().getAsString(); 14457 std::string OuterIVName = (Twine(".unrolled.iv.") + OrigVarName).str(); 14458 std::string InnerIVName = (Twine(".unroll_inner.iv.") + OrigVarName).str(); 14459 std::string InnerTripCountName = 14460 (Twine(".unroll_inner.tripcount.") + OrigVarName).str(); 14461 14462 // Create the iteration variable for the unrolled loop. 14463 VarDecl *OuterIVDecl = 14464 buildVarDecl(*this, {}, IVTy, OuterIVName, nullptr, OrigVar); 14465 auto MakeOuterRef = [this, OuterIVDecl, IVTy, OrigVarLoc]() { 14466 return buildDeclRefExpr(*this, OuterIVDecl, IVTy, OrigVarLoc); 14467 }; 14468 14469 // Iteration variable for the inner loop: Reuse the iteration variable created 14470 // by checkOpenMPLoop. 14471 auto *InnerIVDecl = cast<VarDecl>(IterationVarRef->getDecl()); 14472 InnerIVDecl->setDeclName(&PP.getIdentifierTable().get(InnerIVName)); 14473 auto MakeInnerRef = [this, InnerIVDecl, IVTy, OrigVarLoc]() { 14474 return buildDeclRefExpr(*this, InnerIVDecl, IVTy, OrigVarLoc); 14475 }; 14476 14477 // Make a copy of the NumIterations expression for each use: By the AST 14478 // constraints, every expression object in a DeclContext must be unique. 14479 CaptureVars CopyTransformer(*this); 14480 auto MakeNumIterations = [&CopyTransformer, &LoopHelper]() -> Expr * { 14481 return AssertSuccess( 14482 CopyTransformer.TransformExpr(LoopHelper.NumIterations)); 14483 }; 14484 14485 // Inner For init-statement: auto .unroll_inner.iv = .unrolled.iv 14486 ExprResult LValueConv = DefaultLvalueConversion(MakeOuterRef()); 14487 AddInitializerToDecl(InnerIVDecl, LValueConv.get(), /*DirectInit=*/false); 14488 StmtResult InnerInit = new (Context) 14489 DeclStmt(DeclGroupRef(InnerIVDecl), OrigVarLocBegin, OrigVarLocEnd); 14490 if (!InnerInit.isUsable()) 14491 return StmtError(); 14492 14493 // Inner For cond-expression: 14494 // \code 14495 // .unroll_inner.iv < .unrolled.iv + Factor && 14496 // .unroll_inner.iv < NumIterations 14497 // \endcode 14498 // This conjunction of two conditions allows ScalarEvolution to derive the 14499 // maximum trip count of the inner loop. 14500 ExprResult EndOfTile = BuildBinOp(CurScope, LoopHelper.Cond->getExprLoc(), 14501 BO_Add, MakeOuterRef(), MakeFactorExpr()); 14502 if (!EndOfTile.isUsable()) 14503 return StmtError(); 14504 ExprResult InnerCond1 = BuildBinOp(CurScope, LoopHelper.Cond->getExprLoc(), 14505 BO_LT, MakeInnerRef(), EndOfTile.get()); 14506 if (!InnerCond1.isUsable()) 14507 return StmtError(); 14508 ExprResult InnerCond2 = 14509 BuildBinOp(CurScope, LoopHelper.Cond->getExprLoc(), BO_LT, MakeInnerRef(), 14510 MakeNumIterations()); 14511 if (!InnerCond2.isUsable()) 14512 return StmtError(); 14513 ExprResult InnerCond = 14514 BuildBinOp(CurScope, LoopHelper.Cond->getExprLoc(), BO_LAnd, 14515 InnerCond1.get(), InnerCond2.get()); 14516 if (!InnerCond.isUsable()) 14517 return StmtError(); 14518 14519 // Inner For incr-statement: ++.unroll_inner.iv 14520 ExprResult InnerIncr = BuildUnaryOp(CurScope, LoopHelper.Inc->getExprLoc(), 14521 UO_PreInc, MakeInnerRef()); 14522 if (!InnerIncr.isUsable()) 14523 return StmtError(); 14524 14525 // Inner For statement. 14526 SmallVector<Stmt *> InnerBodyStmts; 14527 InnerBodyStmts.append(LoopHelper.Updates.begin(), LoopHelper.Updates.end()); 14528 InnerBodyStmts.push_back(Body); 14529 CompoundStmt *InnerBody = CompoundStmt::Create( 14530 Context, InnerBodyStmts, Body->getBeginLoc(), Body->getEndLoc()); 14531 ForStmt *InnerFor = new (Context) 14532 ForStmt(Context, InnerInit.get(), InnerCond.get(), nullptr, 14533 InnerIncr.get(), InnerBody, LoopHelper.Init->getBeginLoc(), 14534 LoopHelper.Init->getBeginLoc(), LoopHelper.Inc->getEndLoc()); 14535 14536 // Unroll metadata for the inner loop. 14537 // This needs to take into account the remainder portion of the unrolled loop, 14538 // hence `unroll(full)` does not apply here, even though the LoopUnroll pass 14539 // supports multiple loop exits. Instead, unroll using a factor equivalent to 14540 // the maximum trip count, which will also generate a remainder loop. Just 14541 // `unroll(enable)` (which could have been useful if the user has not 14542 // specified a concrete factor; even though the outer loop cannot be 14543 // influenced anymore, would avoid more code bloat than necessary) will refuse 14544 // the loop because "Won't unroll; remainder loop could not be generated when 14545 // assuming runtime trip count". Even if it did work, it must not choose a 14546 // larger unroll factor than the maximum loop length, or it would always just 14547 // execute the remainder loop. 14548 LoopHintAttr *UnrollHintAttr = 14549 LoopHintAttr::CreateImplicit(Context, LoopHintAttr::UnrollCount, 14550 LoopHintAttr::Numeric, MakeFactorExpr()); 14551 AttributedStmt *InnerUnrolled = 14552 AttributedStmt::Create(Context, StartLoc, {UnrollHintAttr}, InnerFor); 14553 14554 // Outer For init-statement: auto .unrolled.iv = 0 14555 AddInitializerToDecl( 14556 OuterIVDecl, ActOnIntegerConstant(LoopHelper.Init->getExprLoc(), 0).get(), 14557 /*DirectInit=*/false); 14558 StmtResult OuterInit = new (Context) 14559 DeclStmt(DeclGroupRef(OuterIVDecl), OrigVarLocBegin, OrigVarLocEnd); 14560 if (!OuterInit.isUsable()) 14561 return StmtError(); 14562 14563 // Outer For cond-expression: .unrolled.iv < NumIterations 14564 ExprResult OuterConde = 14565 BuildBinOp(CurScope, LoopHelper.Cond->getExprLoc(), BO_LT, MakeOuterRef(), 14566 MakeNumIterations()); 14567 if (!OuterConde.isUsable()) 14568 return StmtError(); 14569 14570 // Outer For incr-statement: .unrolled.iv += Factor 14571 ExprResult OuterIncr = 14572 BuildBinOp(CurScope, LoopHelper.Inc->getExprLoc(), BO_AddAssign, 14573 MakeOuterRef(), MakeFactorExpr()); 14574 if (!OuterIncr.isUsable()) 14575 return StmtError(); 14576 14577 // Outer For statement. 14578 ForStmt *OuterFor = new (Context) 14579 ForStmt(Context, OuterInit.get(), OuterConde.get(), nullptr, 14580 OuterIncr.get(), InnerUnrolled, LoopHelper.Init->getBeginLoc(), 14581 LoopHelper.Init->getBeginLoc(), LoopHelper.Inc->getEndLoc()); 14582 14583 return OMPUnrollDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt, 14584 NumGeneratedLoops, OuterFor, 14585 buildPreInits(Context, PreInits)); 14586 } 14587 14588 OMPClause *Sema::ActOnOpenMPSingleExprClause(OpenMPClauseKind Kind, Expr *Expr, 14589 SourceLocation StartLoc, 14590 SourceLocation LParenLoc, 14591 SourceLocation EndLoc) { 14592 OMPClause *Res = nullptr; 14593 switch (Kind) { 14594 case OMPC_final: 14595 Res = ActOnOpenMPFinalClause(Expr, StartLoc, LParenLoc, EndLoc); 14596 break; 14597 case OMPC_num_threads: 14598 Res = ActOnOpenMPNumThreadsClause(Expr, StartLoc, LParenLoc, EndLoc); 14599 break; 14600 case OMPC_safelen: 14601 Res = ActOnOpenMPSafelenClause(Expr, StartLoc, LParenLoc, EndLoc); 14602 break; 14603 case OMPC_simdlen: 14604 Res = ActOnOpenMPSimdlenClause(Expr, StartLoc, LParenLoc, EndLoc); 14605 break; 14606 case OMPC_allocator: 14607 Res = ActOnOpenMPAllocatorClause(Expr, StartLoc, LParenLoc, EndLoc); 14608 break; 14609 case OMPC_collapse: 14610 Res = ActOnOpenMPCollapseClause(Expr, StartLoc, LParenLoc, EndLoc); 14611 break; 14612 case OMPC_ordered: 14613 Res = ActOnOpenMPOrderedClause(StartLoc, EndLoc, LParenLoc, Expr); 14614 break; 14615 case OMPC_num_teams: 14616 Res = ActOnOpenMPNumTeamsClause(Expr, StartLoc, LParenLoc, EndLoc); 14617 break; 14618 case OMPC_thread_limit: 14619 Res = ActOnOpenMPThreadLimitClause(Expr, StartLoc, LParenLoc, EndLoc); 14620 break; 14621 case OMPC_priority: 14622 Res = ActOnOpenMPPriorityClause(Expr, StartLoc, LParenLoc, EndLoc); 14623 break; 14624 case OMPC_grainsize: 14625 Res = ActOnOpenMPGrainsizeClause(Expr, StartLoc, LParenLoc, EndLoc); 14626 break; 14627 case OMPC_num_tasks: 14628 Res = ActOnOpenMPNumTasksClause(Expr, StartLoc, LParenLoc, EndLoc); 14629 break; 14630 case OMPC_hint: 14631 Res = ActOnOpenMPHintClause(Expr, StartLoc, LParenLoc, EndLoc); 14632 break; 14633 case OMPC_depobj: 14634 Res = ActOnOpenMPDepobjClause(Expr, StartLoc, LParenLoc, EndLoc); 14635 break; 14636 case OMPC_detach: 14637 Res = ActOnOpenMPDetachClause(Expr, StartLoc, LParenLoc, EndLoc); 14638 break; 14639 case OMPC_novariants: 14640 Res = ActOnOpenMPNovariantsClause(Expr, StartLoc, LParenLoc, EndLoc); 14641 break; 14642 case OMPC_nocontext: 14643 Res = ActOnOpenMPNocontextClause(Expr, StartLoc, LParenLoc, EndLoc); 14644 break; 14645 case OMPC_filter: 14646 Res = ActOnOpenMPFilterClause(Expr, StartLoc, LParenLoc, EndLoc); 14647 break; 14648 case OMPC_partial: 14649 Res = ActOnOpenMPPartialClause(Expr, StartLoc, LParenLoc, EndLoc); 14650 break; 14651 case OMPC_align: 14652 Res = ActOnOpenMPAlignClause(Expr, StartLoc, LParenLoc, EndLoc); 14653 break; 14654 case OMPC_device: 14655 case OMPC_if: 14656 case OMPC_default: 14657 case OMPC_proc_bind: 14658 case OMPC_schedule: 14659 case OMPC_private: 14660 case OMPC_firstprivate: 14661 case OMPC_lastprivate: 14662 case OMPC_shared: 14663 case OMPC_reduction: 14664 case OMPC_task_reduction: 14665 case OMPC_in_reduction: 14666 case OMPC_linear: 14667 case OMPC_aligned: 14668 case OMPC_copyin: 14669 case OMPC_copyprivate: 14670 case OMPC_nowait: 14671 case OMPC_untied: 14672 case OMPC_mergeable: 14673 case OMPC_threadprivate: 14674 case OMPC_sizes: 14675 case OMPC_allocate: 14676 case OMPC_flush: 14677 case OMPC_read: 14678 case OMPC_write: 14679 case OMPC_update: 14680 case OMPC_capture: 14681 case OMPC_compare: 14682 case OMPC_seq_cst: 14683 case OMPC_acq_rel: 14684 case OMPC_acquire: 14685 case OMPC_release: 14686 case OMPC_relaxed: 14687 case OMPC_depend: 14688 case OMPC_threads: 14689 case OMPC_simd: 14690 case OMPC_map: 14691 case OMPC_nogroup: 14692 case OMPC_dist_schedule: 14693 case OMPC_defaultmap: 14694 case OMPC_unknown: 14695 case OMPC_uniform: 14696 case OMPC_to: 14697 case OMPC_from: 14698 case OMPC_use_device_ptr: 14699 case OMPC_use_device_addr: 14700 case OMPC_is_device_ptr: 14701 case OMPC_unified_address: 14702 case OMPC_unified_shared_memory: 14703 case OMPC_reverse_offload: 14704 case OMPC_dynamic_allocators: 14705 case OMPC_atomic_default_mem_order: 14706 case OMPC_device_type: 14707 case OMPC_match: 14708 case OMPC_nontemporal: 14709 case OMPC_order: 14710 case OMPC_destroy: 14711 case OMPC_inclusive: 14712 case OMPC_exclusive: 14713 case OMPC_uses_allocators: 14714 case OMPC_affinity: 14715 case OMPC_when: 14716 case OMPC_bind: 14717 default: 14718 llvm_unreachable("Clause is not allowed."); 14719 } 14720 return Res; 14721 } 14722 14723 // An OpenMP directive such as 'target parallel' has two captured regions: 14724 // for the 'target' and 'parallel' respectively. This function returns 14725 // the region in which to capture expressions associated with a clause. 14726 // A return value of OMPD_unknown signifies that the expression should not 14727 // be captured. 14728 static OpenMPDirectiveKind getOpenMPCaptureRegionForClause( 14729 OpenMPDirectiveKind DKind, OpenMPClauseKind CKind, unsigned OpenMPVersion, 14730 OpenMPDirectiveKind NameModifier = OMPD_unknown) { 14731 OpenMPDirectiveKind CaptureRegion = OMPD_unknown; 14732 switch (CKind) { 14733 case OMPC_if: 14734 switch (DKind) { 14735 case OMPD_target_parallel_for_simd: 14736 if (OpenMPVersion >= 50 && 14737 (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)) { 14738 CaptureRegion = OMPD_parallel; 14739 break; 14740 } 14741 LLVM_FALLTHROUGH; 14742 case OMPD_target_parallel: 14743 case OMPD_target_parallel_for: 14744 case OMPD_target_parallel_loop: 14745 // If this clause applies to the nested 'parallel' region, capture within 14746 // the 'target' region, otherwise do not capture. 14747 if (NameModifier == OMPD_unknown || NameModifier == OMPD_parallel) 14748 CaptureRegion = OMPD_target; 14749 break; 14750 case OMPD_target_teams_distribute_parallel_for_simd: 14751 if (OpenMPVersion >= 50 && 14752 (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)) { 14753 CaptureRegion = OMPD_parallel; 14754 break; 14755 } 14756 LLVM_FALLTHROUGH; 14757 case OMPD_target_teams_distribute_parallel_for: 14758 // If this clause applies to the nested 'parallel' region, capture within 14759 // the 'teams' region, otherwise do not capture. 14760 if (NameModifier == OMPD_unknown || NameModifier == OMPD_parallel) 14761 CaptureRegion = OMPD_teams; 14762 break; 14763 case OMPD_teams_distribute_parallel_for_simd: 14764 if (OpenMPVersion >= 50 && 14765 (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)) { 14766 CaptureRegion = OMPD_parallel; 14767 break; 14768 } 14769 LLVM_FALLTHROUGH; 14770 case OMPD_teams_distribute_parallel_for: 14771 CaptureRegion = OMPD_teams; 14772 break; 14773 case OMPD_target_update: 14774 case OMPD_target_enter_data: 14775 case OMPD_target_exit_data: 14776 CaptureRegion = OMPD_task; 14777 break; 14778 case OMPD_parallel_master_taskloop: 14779 if (NameModifier == OMPD_unknown || NameModifier == OMPD_taskloop) 14780 CaptureRegion = OMPD_parallel; 14781 break; 14782 case OMPD_parallel_master_taskloop_simd: 14783 if ((OpenMPVersion <= 45 && NameModifier == OMPD_unknown) || 14784 NameModifier == OMPD_taskloop) { 14785 CaptureRegion = OMPD_parallel; 14786 break; 14787 } 14788 if (OpenMPVersion <= 45) 14789 break; 14790 if (NameModifier == OMPD_unknown || NameModifier == OMPD_simd) 14791 CaptureRegion = OMPD_taskloop; 14792 break; 14793 case OMPD_parallel_for_simd: 14794 if (OpenMPVersion <= 45) 14795 break; 14796 if (NameModifier == OMPD_unknown || NameModifier == OMPD_simd) 14797 CaptureRegion = OMPD_parallel; 14798 break; 14799 case OMPD_taskloop_simd: 14800 case OMPD_master_taskloop_simd: 14801 if (OpenMPVersion <= 45) 14802 break; 14803 if (NameModifier == OMPD_unknown || NameModifier == OMPD_simd) 14804 CaptureRegion = OMPD_taskloop; 14805 break; 14806 case OMPD_distribute_parallel_for_simd: 14807 if (OpenMPVersion <= 45) 14808 break; 14809 if (NameModifier == OMPD_unknown || NameModifier == OMPD_simd) 14810 CaptureRegion = OMPD_parallel; 14811 break; 14812 case OMPD_target_simd: 14813 if (OpenMPVersion >= 50 && 14814 (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)) 14815 CaptureRegion = OMPD_target; 14816 break; 14817 case OMPD_teams_distribute_simd: 14818 case OMPD_target_teams_distribute_simd: 14819 if (OpenMPVersion >= 50 && 14820 (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)) 14821 CaptureRegion = OMPD_teams; 14822 break; 14823 case OMPD_cancel: 14824 case OMPD_parallel: 14825 case OMPD_parallel_master: 14826 case OMPD_parallel_sections: 14827 case OMPD_parallel_for: 14828 case OMPD_parallel_loop: 14829 case OMPD_target: 14830 case OMPD_target_teams: 14831 case OMPD_target_teams_distribute: 14832 case OMPD_target_teams_loop: 14833 case OMPD_distribute_parallel_for: 14834 case OMPD_task: 14835 case OMPD_taskloop: 14836 case OMPD_master_taskloop: 14837 case OMPD_target_data: 14838 case OMPD_simd: 14839 case OMPD_for_simd: 14840 case OMPD_distribute_simd: 14841 // Do not capture if-clause expressions. 14842 break; 14843 case OMPD_threadprivate: 14844 case OMPD_allocate: 14845 case OMPD_taskyield: 14846 case OMPD_barrier: 14847 case OMPD_taskwait: 14848 case OMPD_cancellation_point: 14849 case OMPD_flush: 14850 case OMPD_depobj: 14851 case OMPD_scan: 14852 case OMPD_declare_reduction: 14853 case OMPD_declare_mapper: 14854 case OMPD_declare_simd: 14855 case OMPD_declare_variant: 14856 case OMPD_begin_declare_variant: 14857 case OMPD_end_declare_variant: 14858 case OMPD_declare_target: 14859 case OMPD_end_declare_target: 14860 case OMPD_loop: 14861 case OMPD_teams_loop: 14862 case OMPD_teams: 14863 case OMPD_tile: 14864 case OMPD_unroll: 14865 case OMPD_for: 14866 case OMPD_sections: 14867 case OMPD_section: 14868 case OMPD_single: 14869 case OMPD_master: 14870 case OMPD_masked: 14871 case OMPD_critical: 14872 case OMPD_taskgroup: 14873 case OMPD_distribute: 14874 case OMPD_ordered: 14875 case OMPD_atomic: 14876 case OMPD_teams_distribute: 14877 case OMPD_requires: 14878 case OMPD_metadirective: 14879 llvm_unreachable("Unexpected OpenMP directive with if-clause"); 14880 case OMPD_unknown: 14881 default: 14882 llvm_unreachable("Unknown OpenMP directive"); 14883 } 14884 break; 14885 case OMPC_num_threads: 14886 switch (DKind) { 14887 case OMPD_target_parallel: 14888 case OMPD_target_parallel_for: 14889 case OMPD_target_parallel_for_simd: 14890 case OMPD_target_parallel_loop: 14891 CaptureRegion = OMPD_target; 14892 break; 14893 case OMPD_teams_distribute_parallel_for: 14894 case OMPD_teams_distribute_parallel_for_simd: 14895 case OMPD_target_teams_distribute_parallel_for: 14896 case OMPD_target_teams_distribute_parallel_for_simd: 14897 CaptureRegion = OMPD_teams; 14898 break; 14899 case OMPD_parallel: 14900 case OMPD_parallel_master: 14901 case OMPD_parallel_sections: 14902 case OMPD_parallel_for: 14903 case OMPD_parallel_for_simd: 14904 case OMPD_parallel_loop: 14905 case OMPD_distribute_parallel_for: 14906 case OMPD_distribute_parallel_for_simd: 14907 case OMPD_parallel_master_taskloop: 14908 case OMPD_parallel_master_taskloop_simd: 14909 // Do not capture num_threads-clause expressions. 14910 break; 14911 case OMPD_target_data: 14912 case OMPD_target_enter_data: 14913 case OMPD_target_exit_data: 14914 case OMPD_target_update: 14915 case OMPD_target: 14916 case OMPD_target_simd: 14917 case OMPD_target_teams: 14918 case OMPD_target_teams_distribute: 14919 case OMPD_target_teams_distribute_simd: 14920 case OMPD_cancel: 14921 case OMPD_task: 14922 case OMPD_taskloop: 14923 case OMPD_taskloop_simd: 14924 case OMPD_master_taskloop: 14925 case OMPD_master_taskloop_simd: 14926 case OMPD_threadprivate: 14927 case OMPD_allocate: 14928 case OMPD_taskyield: 14929 case OMPD_barrier: 14930 case OMPD_taskwait: 14931 case OMPD_cancellation_point: 14932 case OMPD_flush: 14933 case OMPD_depobj: 14934 case OMPD_scan: 14935 case OMPD_declare_reduction: 14936 case OMPD_declare_mapper: 14937 case OMPD_declare_simd: 14938 case OMPD_declare_variant: 14939 case OMPD_begin_declare_variant: 14940 case OMPD_end_declare_variant: 14941 case OMPD_declare_target: 14942 case OMPD_end_declare_target: 14943 case OMPD_loop: 14944 case OMPD_teams_loop: 14945 case OMPD_target_teams_loop: 14946 case OMPD_teams: 14947 case OMPD_simd: 14948 case OMPD_tile: 14949 case OMPD_unroll: 14950 case OMPD_for: 14951 case OMPD_for_simd: 14952 case OMPD_sections: 14953 case OMPD_section: 14954 case OMPD_single: 14955 case OMPD_master: 14956 case OMPD_masked: 14957 case OMPD_critical: 14958 case OMPD_taskgroup: 14959 case OMPD_distribute: 14960 case OMPD_ordered: 14961 case OMPD_atomic: 14962 case OMPD_distribute_simd: 14963 case OMPD_teams_distribute: 14964 case OMPD_teams_distribute_simd: 14965 case OMPD_requires: 14966 case OMPD_metadirective: 14967 llvm_unreachable("Unexpected OpenMP directive with num_threads-clause"); 14968 case OMPD_unknown: 14969 default: 14970 llvm_unreachable("Unknown OpenMP directive"); 14971 } 14972 break; 14973 case OMPC_num_teams: 14974 switch (DKind) { 14975 case OMPD_target_teams: 14976 case OMPD_target_teams_distribute: 14977 case OMPD_target_teams_distribute_simd: 14978 case OMPD_target_teams_distribute_parallel_for: 14979 case OMPD_target_teams_distribute_parallel_for_simd: 14980 case OMPD_target_teams_loop: 14981 CaptureRegion = OMPD_target; 14982 break; 14983 case OMPD_teams_distribute_parallel_for: 14984 case OMPD_teams_distribute_parallel_for_simd: 14985 case OMPD_teams: 14986 case OMPD_teams_distribute: 14987 case OMPD_teams_distribute_simd: 14988 case OMPD_teams_loop: 14989 // Do not capture num_teams-clause expressions. 14990 break; 14991 case OMPD_distribute_parallel_for: 14992 case OMPD_distribute_parallel_for_simd: 14993 case OMPD_task: 14994 case OMPD_taskloop: 14995 case OMPD_taskloop_simd: 14996 case OMPD_master_taskloop: 14997 case OMPD_master_taskloop_simd: 14998 case OMPD_parallel_master_taskloop: 14999 case OMPD_parallel_master_taskloop_simd: 15000 case OMPD_target_data: 15001 case OMPD_target_enter_data: 15002 case OMPD_target_exit_data: 15003 case OMPD_target_update: 15004 case OMPD_cancel: 15005 case OMPD_parallel: 15006 case OMPD_parallel_master: 15007 case OMPD_parallel_sections: 15008 case OMPD_parallel_for: 15009 case OMPD_parallel_for_simd: 15010 case OMPD_parallel_loop: 15011 case OMPD_target: 15012 case OMPD_target_simd: 15013 case OMPD_target_parallel: 15014 case OMPD_target_parallel_for: 15015 case OMPD_target_parallel_for_simd: 15016 case OMPD_target_parallel_loop: 15017 case OMPD_threadprivate: 15018 case OMPD_allocate: 15019 case OMPD_taskyield: 15020 case OMPD_barrier: 15021 case OMPD_taskwait: 15022 case OMPD_cancellation_point: 15023 case OMPD_flush: 15024 case OMPD_depobj: 15025 case OMPD_scan: 15026 case OMPD_declare_reduction: 15027 case OMPD_declare_mapper: 15028 case OMPD_declare_simd: 15029 case OMPD_declare_variant: 15030 case OMPD_begin_declare_variant: 15031 case OMPD_end_declare_variant: 15032 case OMPD_declare_target: 15033 case OMPD_end_declare_target: 15034 case OMPD_loop: 15035 case OMPD_simd: 15036 case OMPD_tile: 15037 case OMPD_unroll: 15038 case OMPD_for: 15039 case OMPD_for_simd: 15040 case OMPD_sections: 15041 case OMPD_section: 15042 case OMPD_single: 15043 case OMPD_master: 15044 case OMPD_masked: 15045 case OMPD_critical: 15046 case OMPD_taskgroup: 15047 case OMPD_distribute: 15048 case OMPD_ordered: 15049 case OMPD_atomic: 15050 case OMPD_distribute_simd: 15051 case OMPD_requires: 15052 case OMPD_metadirective: 15053 llvm_unreachable("Unexpected OpenMP directive with num_teams-clause"); 15054 case OMPD_unknown: 15055 default: 15056 llvm_unreachable("Unknown OpenMP directive"); 15057 } 15058 break; 15059 case OMPC_thread_limit: 15060 switch (DKind) { 15061 case OMPD_target_teams: 15062 case OMPD_target_teams_distribute: 15063 case OMPD_target_teams_distribute_simd: 15064 case OMPD_target_teams_distribute_parallel_for: 15065 case OMPD_target_teams_distribute_parallel_for_simd: 15066 case OMPD_target_teams_loop: 15067 CaptureRegion = OMPD_target; 15068 break; 15069 case OMPD_teams_distribute_parallel_for: 15070 case OMPD_teams_distribute_parallel_for_simd: 15071 case OMPD_teams: 15072 case OMPD_teams_distribute: 15073 case OMPD_teams_distribute_simd: 15074 case OMPD_teams_loop: 15075 // Do not capture thread_limit-clause expressions. 15076 break; 15077 case OMPD_distribute_parallel_for: 15078 case OMPD_distribute_parallel_for_simd: 15079 case OMPD_task: 15080 case OMPD_taskloop: 15081 case OMPD_taskloop_simd: 15082 case OMPD_master_taskloop: 15083 case OMPD_master_taskloop_simd: 15084 case OMPD_parallel_master_taskloop: 15085 case OMPD_parallel_master_taskloop_simd: 15086 case OMPD_target_data: 15087 case OMPD_target_enter_data: 15088 case OMPD_target_exit_data: 15089 case OMPD_target_update: 15090 case OMPD_cancel: 15091 case OMPD_parallel: 15092 case OMPD_parallel_master: 15093 case OMPD_parallel_sections: 15094 case OMPD_parallel_for: 15095 case OMPD_parallel_for_simd: 15096 case OMPD_parallel_loop: 15097 case OMPD_target: 15098 case OMPD_target_simd: 15099 case OMPD_target_parallel: 15100 case OMPD_target_parallel_for: 15101 case OMPD_target_parallel_for_simd: 15102 case OMPD_target_parallel_loop: 15103 case OMPD_threadprivate: 15104 case OMPD_allocate: 15105 case OMPD_taskyield: 15106 case OMPD_barrier: 15107 case OMPD_taskwait: 15108 case OMPD_cancellation_point: 15109 case OMPD_flush: 15110 case OMPD_depobj: 15111 case OMPD_scan: 15112 case OMPD_declare_reduction: 15113 case OMPD_declare_mapper: 15114 case OMPD_declare_simd: 15115 case OMPD_declare_variant: 15116 case OMPD_begin_declare_variant: 15117 case OMPD_end_declare_variant: 15118 case OMPD_declare_target: 15119 case OMPD_end_declare_target: 15120 case OMPD_loop: 15121 case OMPD_simd: 15122 case OMPD_tile: 15123 case OMPD_unroll: 15124 case OMPD_for: 15125 case OMPD_for_simd: 15126 case OMPD_sections: 15127 case OMPD_section: 15128 case OMPD_single: 15129 case OMPD_master: 15130 case OMPD_masked: 15131 case OMPD_critical: 15132 case OMPD_taskgroup: 15133 case OMPD_distribute: 15134 case OMPD_ordered: 15135 case OMPD_atomic: 15136 case OMPD_distribute_simd: 15137 case OMPD_requires: 15138 case OMPD_metadirective: 15139 llvm_unreachable("Unexpected OpenMP directive with thread_limit-clause"); 15140 case OMPD_unknown: 15141 default: 15142 llvm_unreachable("Unknown OpenMP directive"); 15143 } 15144 break; 15145 case OMPC_schedule: 15146 switch (DKind) { 15147 case OMPD_parallel_for: 15148 case OMPD_parallel_for_simd: 15149 case OMPD_distribute_parallel_for: 15150 case OMPD_distribute_parallel_for_simd: 15151 case OMPD_teams_distribute_parallel_for: 15152 case OMPD_teams_distribute_parallel_for_simd: 15153 case OMPD_target_parallel_for: 15154 case OMPD_target_parallel_for_simd: 15155 case OMPD_target_teams_distribute_parallel_for: 15156 case OMPD_target_teams_distribute_parallel_for_simd: 15157 CaptureRegion = OMPD_parallel; 15158 break; 15159 case OMPD_for: 15160 case OMPD_for_simd: 15161 // Do not capture schedule-clause expressions. 15162 break; 15163 case OMPD_task: 15164 case OMPD_taskloop: 15165 case OMPD_taskloop_simd: 15166 case OMPD_master_taskloop: 15167 case OMPD_master_taskloop_simd: 15168 case OMPD_parallel_master_taskloop: 15169 case OMPD_parallel_master_taskloop_simd: 15170 case OMPD_target_data: 15171 case OMPD_target_enter_data: 15172 case OMPD_target_exit_data: 15173 case OMPD_target_update: 15174 case OMPD_teams: 15175 case OMPD_teams_distribute: 15176 case OMPD_teams_distribute_simd: 15177 case OMPD_target_teams_distribute: 15178 case OMPD_target_teams_distribute_simd: 15179 case OMPD_target: 15180 case OMPD_target_simd: 15181 case OMPD_target_parallel: 15182 case OMPD_cancel: 15183 case OMPD_parallel: 15184 case OMPD_parallel_master: 15185 case OMPD_parallel_sections: 15186 case OMPD_threadprivate: 15187 case OMPD_allocate: 15188 case OMPD_taskyield: 15189 case OMPD_barrier: 15190 case OMPD_taskwait: 15191 case OMPD_cancellation_point: 15192 case OMPD_flush: 15193 case OMPD_depobj: 15194 case OMPD_scan: 15195 case OMPD_declare_reduction: 15196 case OMPD_declare_mapper: 15197 case OMPD_declare_simd: 15198 case OMPD_declare_variant: 15199 case OMPD_begin_declare_variant: 15200 case OMPD_end_declare_variant: 15201 case OMPD_declare_target: 15202 case OMPD_end_declare_target: 15203 case OMPD_loop: 15204 case OMPD_teams_loop: 15205 case OMPD_target_teams_loop: 15206 case OMPD_parallel_loop: 15207 case OMPD_target_parallel_loop: 15208 case OMPD_simd: 15209 case OMPD_tile: 15210 case OMPD_unroll: 15211 case OMPD_sections: 15212 case OMPD_section: 15213 case OMPD_single: 15214 case OMPD_master: 15215 case OMPD_masked: 15216 case OMPD_critical: 15217 case OMPD_taskgroup: 15218 case OMPD_distribute: 15219 case OMPD_ordered: 15220 case OMPD_atomic: 15221 case OMPD_distribute_simd: 15222 case OMPD_target_teams: 15223 case OMPD_requires: 15224 case OMPD_metadirective: 15225 llvm_unreachable("Unexpected OpenMP directive with schedule clause"); 15226 case OMPD_unknown: 15227 default: 15228 llvm_unreachable("Unknown OpenMP directive"); 15229 } 15230 break; 15231 case OMPC_dist_schedule: 15232 switch (DKind) { 15233 case OMPD_teams_distribute_parallel_for: 15234 case OMPD_teams_distribute_parallel_for_simd: 15235 case OMPD_teams_distribute: 15236 case OMPD_teams_distribute_simd: 15237 case OMPD_target_teams_distribute_parallel_for: 15238 case OMPD_target_teams_distribute_parallel_for_simd: 15239 case OMPD_target_teams_distribute: 15240 case OMPD_target_teams_distribute_simd: 15241 CaptureRegion = OMPD_teams; 15242 break; 15243 case OMPD_distribute_parallel_for: 15244 case OMPD_distribute_parallel_for_simd: 15245 case OMPD_distribute: 15246 case OMPD_distribute_simd: 15247 // Do not capture dist_schedule-clause expressions. 15248 break; 15249 case OMPD_parallel_for: 15250 case OMPD_parallel_for_simd: 15251 case OMPD_target_parallel_for_simd: 15252 case OMPD_target_parallel_for: 15253 case OMPD_task: 15254 case OMPD_taskloop: 15255 case OMPD_taskloop_simd: 15256 case OMPD_master_taskloop: 15257 case OMPD_master_taskloop_simd: 15258 case OMPD_parallel_master_taskloop: 15259 case OMPD_parallel_master_taskloop_simd: 15260 case OMPD_target_data: 15261 case OMPD_target_enter_data: 15262 case OMPD_target_exit_data: 15263 case OMPD_target_update: 15264 case OMPD_teams: 15265 case OMPD_target: 15266 case OMPD_target_simd: 15267 case OMPD_target_parallel: 15268 case OMPD_cancel: 15269 case OMPD_parallel: 15270 case OMPD_parallel_master: 15271 case OMPD_parallel_sections: 15272 case OMPD_threadprivate: 15273 case OMPD_allocate: 15274 case OMPD_taskyield: 15275 case OMPD_barrier: 15276 case OMPD_taskwait: 15277 case OMPD_cancellation_point: 15278 case OMPD_flush: 15279 case OMPD_depobj: 15280 case OMPD_scan: 15281 case OMPD_declare_reduction: 15282 case OMPD_declare_mapper: 15283 case OMPD_declare_simd: 15284 case OMPD_declare_variant: 15285 case OMPD_begin_declare_variant: 15286 case OMPD_end_declare_variant: 15287 case OMPD_declare_target: 15288 case OMPD_end_declare_target: 15289 case OMPD_loop: 15290 case OMPD_teams_loop: 15291 case OMPD_target_teams_loop: 15292 case OMPD_parallel_loop: 15293 case OMPD_target_parallel_loop: 15294 case OMPD_simd: 15295 case OMPD_tile: 15296 case OMPD_unroll: 15297 case OMPD_for: 15298 case OMPD_for_simd: 15299 case OMPD_sections: 15300 case OMPD_section: 15301 case OMPD_single: 15302 case OMPD_master: 15303 case OMPD_masked: 15304 case OMPD_critical: 15305 case OMPD_taskgroup: 15306 case OMPD_ordered: 15307 case OMPD_atomic: 15308 case OMPD_target_teams: 15309 case OMPD_requires: 15310 case OMPD_metadirective: 15311 llvm_unreachable("Unexpected OpenMP directive with dist_schedule clause"); 15312 case OMPD_unknown: 15313 default: 15314 llvm_unreachable("Unknown OpenMP directive"); 15315 } 15316 break; 15317 case OMPC_device: 15318 switch (DKind) { 15319 case OMPD_target_update: 15320 case OMPD_target_enter_data: 15321 case OMPD_target_exit_data: 15322 case OMPD_target: 15323 case OMPD_target_simd: 15324 case OMPD_target_teams: 15325 case OMPD_target_parallel: 15326 case OMPD_target_teams_distribute: 15327 case OMPD_target_teams_distribute_simd: 15328 case OMPD_target_parallel_for: 15329 case OMPD_target_parallel_for_simd: 15330 case OMPD_target_parallel_loop: 15331 case OMPD_target_teams_distribute_parallel_for: 15332 case OMPD_target_teams_distribute_parallel_for_simd: 15333 case OMPD_target_teams_loop: 15334 case OMPD_dispatch: 15335 CaptureRegion = OMPD_task; 15336 break; 15337 case OMPD_target_data: 15338 case OMPD_interop: 15339 // Do not capture device-clause expressions. 15340 break; 15341 case OMPD_teams_distribute_parallel_for: 15342 case OMPD_teams_distribute_parallel_for_simd: 15343 case OMPD_teams: 15344 case OMPD_teams_distribute: 15345 case OMPD_teams_distribute_simd: 15346 case OMPD_distribute_parallel_for: 15347 case OMPD_distribute_parallel_for_simd: 15348 case OMPD_task: 15349 case OMPD_taskloop: 15350 case OMPD_taskloop_simd: 15351 case OMPD_master_taskloop: 15352 case OMPD_master_taskloop_simd: 15353 case OMPD_parallel_master_taskloop: 15354 case OMPD_parallel_master_taskloop_simd: 15355 case OMPD_cancel: 15356 case OMPD_parallel: 15357 case OMPD_parallel_master: 15358 case OMPD_parallel_sections: 15359 case OMPD_parallel_for: 15360 case OMPD_parallel_for_simd: 15361 case OMPD_threadprivate: 15362 case OMPD_allocate: 15363 case OMPD_taskyield: 15364 case OMPD_barrier: 15365 case OMPD_taskwait: 15366 case OMPD_cancellation_point: 15367 case OMPD_flush: 15368 case OMPD_depobj: 15369 case OMPD_scan: 15370 case OMPD_declare_reduction: 15371 case OMPD_declare_mapper: 15372 case OMPD_declare_simd: 15373 case OMPD_declare_variant: 15374 case OMPD_begin_declare_variant: 15375 case OMPD_end_declare_variant: 15376 case OMPD_declare_target: 15377 case OMPD_end_declare_target: 15378 case OMPD_loop: 15379 case OMPD_teams_loop: 15380 case OMPD_parallel_loop: 15381 case OMPD_simd: 15382 case OMPD_tile: 15383 case OMPD_unroll: 15384 case OMPD_for: 15385 case OMPD_for_simd: 15386 case OMPD_sections: 15387 case OMPD_section: 15388 case OMPD_single: 15389 case OMPD_master: 15390 case OMPD_masked: 15391 case OMPD_critical: 15392 case OMPD_taskgroup: 15393 case OMPD_distribute: 15394 case OMPD_ordered: 15395 case OMPD_atomic: 15396 case OMPD_distribute_simd: 15397 case OMPD_requires: 15398 case OMPD_metadirective: 15399 llvm_unreachable("Unexpected OpenMP directive with device-clause"); 15400 case OMPD_unknown: 15401 default: 15402 llvm_unreachable("Unknown OpenMP directive"); 15403 } 15404 break; 15405 case OMPC_grainsize: 15406 case OMPC_num_tasks: 15407 case OMPC_final: 15408 case OMPC_priority: 15409 switch (DKind) { 15410 case OMPD_task: 15411 case OMPD_taskloop: 15412 case OMPD_taskloop_simd: 15413 case OMPD_master_taskloop: 15414 case OMPD_master_taskloop_simd: 15415 break; 15416 case OMPD_parallel_master_taskloop: 15417 case OMPD_parallel_master_taskloop_simd: 15418 CaptureRegion = OMPD_parallel; 15419 break; 15420 case OMPD_target_update: 15421 case OMPD_target_enter_data: 15422 case OMPD_target_exit_data: 15423 case OMPD_target: 15424 case OMPD_target_simd: 15425 case OMPD_target_teams: 15426 case OMPD_target_parallel: 15427 case OMPD_target_teams_distribute: 15428 case OMPD_target_teams_distribute_simd: 15429 case OMPD_target_parallel_for: 15430 case OMPD_target_parallel_for_simd: 15431 case OMPD_target_teams_distribute_parallel_for: 15432 case OMPD_target_teams_distribute_parallel_for_simd: 15433 case OMPD_target_data: 15434 case OMPD_teams_distribute_parallel_for: 15435 case OMPD_teams_distribute_parallel_for_simd: 15436 case OMPD_teams: 15437 case OMPD_teams_distribute: 15438 case OMPD_teams_distribute_simd: 15439 case OMPD_distribute_parallel_for: 15440 case OMPD_distribute_parallel_for_simd: 15441 case OMPD_cancel: 15442 case OMPD_parallel: 15443 case OMPD_parallel_master: 15444 case OMPD_parallel_sections: 15445 case OMPD_parallel_for: 15446 case OMPD_parallel_for_simd: 15447 case OMPD_threadprivate: 15448 case OMPD_allocate: 15449 case OMPD_taskyield: 15450 case OMPD_barrier: 15451 case OMPD_taskwait: 15452 case OMPD_cancellation_point: 15453 case OMPD_flush: 15454 case OMPD_depobj: 15455 case OMPD_scan: 15456 case OMPD_declare_reduction: 15457 case OMPD_declare_mapper: 15458 case OMPD_declare_simd: 15459 case OMPD_declare_variant: 15460 case OMPD_begin_declare_variant: 15461 case OMPD_end_declare_variant: 15462 case OMPD_declare_target: 15463 case OMPD_end_declare_target: 15464 case OMPD_loop: 15465 case OMPD_teams_loop: 15466 case OMPD_target_teams_loop: 15467 case OMPD_parallel_loop: 15468 case OMPD_target_parallel_loop: 15469 case OMPD_simd: 15470 case OMPD_tile: 15471 case OMPD_unroll: 15472 case OMPD_for: 15473 case OMPD_for_simd: 15474 case OMPD_sections: 15475 case OMPD_section: 15476 case OMPD_single: 15477 case OMPD_master: 15478 case OMPD_masked: 15479 case OMPD_critical: 15480 case OMPD_taskgroup: 15481 case OMPD_distribute: 15482 case OMPD_ordered: 15483 case OMPD_atomic: 15484 case OMPD_distribute_simd: 15485 case OMPD_requires: 15486 case OMPD_metadirective: 15487 llvm_unreachable("Unexpected OpenMP directive with grainsize-clause"); 15488 case OMPD_unknown: 15489 default: 15490 llvm_unreachable("Unknown OpenMP directive"); 15491 } 15492 break; 15493 case OMPC_novariants: 15494 case OMPC_nocontext: 15495 switch (DKind) { 15496 case OMPD_dispatch: 15497 CaptureRegion = OMPD_task; 15498 break; 15499 default: 15500 llvm_unreachable("Unexpected OpenMP directive"); 15501 } 15502 break; 15503 case OMPC_filter: 15504 // Do not capture filter-clause expressions. 15505 break; 15506 case OMPC_when: 15507 if (DKind == OMPD_metadirective) { 15508 CaptureRegion = OMPD_metadirective; 15509 } else if (DKind == OMPD_unknown) { 15510 llvm_unreachable("Unknown OpenMP directive"); 15511 } else { 15512 llvm_unreachable("Unexpected OpenMP directive with when clause"); 15513 } 15514 break; 15515 case OMPC_firstprivate: 15516 case OMPC_lastprivate: 15517 case OMPC_reduction: 15518 case OMPC_task_reduction: 15519 case OMPC_in_reduction: 15520 case OMPC_linear: 15521 case OMPC_default: 15522 case OMPC_proc_bind: 15523 case OMPC_safelen: 15524 case OMPC_simdlen: 15525 case OMPC_sizes: 15526 case OMPC_allocator: 15527 case OMPC_collapse: 15528 case OMPC_private: 15529 case OMPC_shared: 15530 case OMPC_aligned: 15531 case OMPC_copyin: 15532 case OMPC_copyprivate: 15533 case OMPC_ordered: 15534 case OMPC_nowait: 15535 case OMPC_untied: 15536 case OMPC_mergeable: 15537 case OMPC_threadprivate: 15538 case OMPC_allocate: 15539 case OMPC_flush: 15540 case OMPC_depobj: 15541 case OMPC_read: 15542 case OMPC_write: 15543 case OMPC_update: 15544 case OMPC_capture: 15545 case OMPC_compare: 15546 case OMPC_seq_cst: 15547 case OMPC_acq_rel: 15548 case OMPC_acquire: 15549 case OMPC_release: 15550 case OMPC_relaxed: 15551 case OMPC_depend: 15552 case OMPC_threads: 15553 case OMPC_simd: 15554 case OMPC_map: 15555 case OMPC_nogroup: 15556 case OMPC_hint: 15557 case OMPC_defaultmap: 15558 case OMPC_unknown: 15559 case OMPC_uniform: 15560 case OMPC_to: 15561 case OMPC_from: 15562 case OMPC_use_device_ptr: 15563 case OMPC_use_device_addr: 15564 case OMPC_is_device_ptr: 15565 case OMPC_unified_address: 15566 case OMPC_unified_shared_memory: 15567 case OMPC_reverse_offload: 15568 case OMPC_dynamic_allocators: 15569 case OMPC_atomic_default_mem_order: 15570 case OMPC_device_type: 15571 case OMPC_match: 15572 case OMPC_nontemporal: 15573 case OMPC_order: 15574 case OMPC_destroy: 15575 case OMPC_detach: 15576 case OMPC_inclusive: 15577 case OMPC_exclusive: 15578 case OMPC_uses_allocators: 15579 case OMPC_affinity: 15580 case OMPC_bind: 15581 default: 15582 llvm_unreachable("Unexpected OpenMP clause."); 15583 } 15584 return CaptureRegion; 15585 } 15586 15587 OMPClause *Sema::ActOnOpenMPIfClause(OpenMPDirectiveKind NameModifier, 15588 Expr *Condition, SourceLocation StartLoc, 15589 SourceLocation LParenLoc, 15590 SourceLocation NameModifierLoc, 15591 SourceLocation ColonLoc, 15592 SourceLocation EndLoc) { 15593 Expr *ValExpr = Condition; 15594 Stmt *HelperValStmt = nullptr; 15595 OpenMPDirectiveKind CaptureRegion = OMPD_unknown; 15596 if (!Condition->isValueDependent() && !Condition->isTypeDependent() && 15597 !Condition->isInstantiationDependent() && 15598 !Condition->containsUnexpandedParameterPack()) { 15599 ExprResult Val = CheckBooleanCondition(StartLoc, Condition); 15600 if (Val.isInvalid()) 15601 return nullptr; 15602 15603 ValExpr = Val.get(); 15604 15605 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 15606 CaptureRegion = getOpenMPCaptureRegionForClause( 15607 DKind, OMPC_if, LangOpts.OpenMP, NameModifier); 15608 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 15609 ValExpr = MakeFullExpr(ValExpr).get(); 15610 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 15611 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 15612 HelperValStmt = buildPreInits(Context, Captures); 15613 } 15614 } 15615 15616 return new (Context) 15617 OMPIfClause(NameModifier, ValExpr, HelperValStmt, CaptureRegion, StartLoc, 15618 LParenLoc, NameModifierLoc, ColonLoc, EndLoc); 15619 } 15620 15621 OMPClause *Sema::ActOnOpenMPFinalClause(Expr *Condition, 15622 SourceLocation StartLoc, 15623 SourceLocation LParenLoc, 15624 SourceLocation EndLoc) { 15625 Expr *ValExpr = Condition; 15626 Stmt *HelperValStmt = nullptr; 15627 OpenMPDirectiveKind CaptureRegion = OMPD_unknown; 15628 if (!Condition->isValueDependent() && !Condition->isTypeDependent() && 15629 !Condition->isInstantiationDependent() && 15630 !Condition->containsUnexpandedParameterPack()) { 15631 ExprResult Val = CheckBooleanCondition(StartLoc, Condition); 15632 if (Val.isInvalid()) 15633 return nullptr; 15634 15635 ValExpr = MakeFullExpr(Val.get()).get(); 15636 15637 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 15638 CaptureRegion = 15639 getOpenMPCaptureRegionForClause(DKind, OMPC_final, LangOpts.OpenMP); 15640 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 15641 ValExpr = MakeFullExpr(ValExpr).get(); 15642 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 15643 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 15644 HelperValStmt = buildPreInits(Context, Captures); 15645 } 15646 } 15647 15648 return new (Context) OMPFinalClause(ValExpr, HelperValStmt, CaptureRegion, 15649 StartLoc, LParenLoc, EndLoc); 15650 } 15651 15652 ExprResult Sema::PerformOpenMPImplicitIntegerConversion(SourceLocation Loc, 15653 Expr *Op) { 15654 if (!Op) 15655 return ExprError(); 15656 15657 class IntConvertDiagnoser : public ICEConvertDiagnoser { 15658 public: 15659 IntConvertDiagnoser() 15660 : ICEConvertDiagnoser(/*AllowScopedEnumerations*/ false, false, true) {} 15661 SemaDiagnosticBuilder diagnoseNotInt(Sema &S, SourceLocation Loc, 15662 QualType T) override { 15663 return S.Diag(Loc, diag::err_omp_not_integral) << T; 15664 } 15665 SemaDiagnosticBuilder diagnoseIncomplete(Sema &S, SourceLocation Loc, 15666 QualType T) override { 15667 return S.Diag(Loc, diag::err_omp_incomplete_type) << T; 15668 } 15669 SemaDiagnosticBuilder diagnoseExplicitConv(Sema &S, SourceLocation Loc, 15670 QualType T, 15671 QualType ConvTy) override { 15672 return S.Diag(Loc, diag::err_omp_explicit_conversion) << T << ConvTy; 15673 } 15674 SemaDiagnosticBuilder noteExplicitConv(Sema &S, CXXConversionDecl *Conv, 15675 QualType ConvTy) override { 15676 return S.Diag(Conv->getLocation(), diag::note_omp_conversion_here) 15677 << ConvTy->isEnumeralType() << ConvTy; 15678 } 15679 SemaDiagnosticBuilder diagnoseAmbiguous(Sema &S, SourceLocation Loc, 15680 QualType T) override { 15681 return S.Diag(Loc, diag::err_omp_ambiguous_conversion) << T; 15682 } 15683 SemaDiagnosticBuilder noteAmbiguous(Sema &S, CXXConversionDecl *Conv, 15684 QualType ConvTy) override { 15685 return S.Diag(Conv->getLocation(), diag::note_omp_conversion_here) 15686 << ConvTy->isEnumeralType() << ConvTy; 15687 } 15688 SemaDiagnosticBuilder diagnoseConversion(Sema &, SourceLocation, QualType, 15689 QualType) override { 15690 llvm_unreachable("conversion functions are permitted"); 15691 } 15692 } ConvertDiagnoser; 15693 return PerformContextualImplicitConversion(Loc, Op, ConvertDiagnoser); 15694 } 15695 15696 static bool 15697 isNonNegativeIntegerValue(Expr *&ValExpr, Sema &SemaRef, OpenMPClauseKind CKind, 15698 bool StrictlyPositive, bool BuildCapture = false, 15699 OpenMPDirectiveKind DKind = OMPD_unknown, 15700 OpenMPDirectiveKind *CaptureRegion = nullptr, 15701 Stmt **HelperValStmt = nullptr) { 15702 if (!ValExpr->isTypeDependent() && !ValExpr->isValueDependent() && 15703 !ValExpr->isInstantiationDependent()) { 15704 SourceLocation Loc = ValExpr->getExprLoc(); 15705 ExprResult Value = 15706 SemaRef.PerformOpenMPImplicitIntegerConversion(Loc, ValExpr); 15707 if (Value.isInvalid()) 15708 return false; 15709 15710 ValExpr = Value.get(); 15711 // The expression must evaluate to a non-negative integer value. 15712 if (Optional<llvm::APSInt> Result = 15713 ValExpr->getIntegerConstantExpr(SemaRef.Context)) { 15714 if (Result->isSigned() && 15715 !((!StrictlyPositive && Result->isNonNegative()) || 15716 (StrictlyPositive && Result->isStrictlyPositive()))) { 15717 SemaRef.Diag(Loc, diag::err_omp_negative_expression_in_clause) 15718 << getOpenMPClauseName(CKind) << (StrictlyPositive ? 1 : 0) 15719 << ValExpr->getSourceRange(); 15720 return false; 15721 } 15722 } 15723 if (!BuildCapture) 15724 return true; 15725 *CaptureRegion = 15726 getOpenMPCaptureRegionForClause(DKind, CKind, SemaRef.LangOpts.OpenMP); 15727 if (*CaptureRegion != OMPD_unknown && 15728 !SemaRef.CurContext->isDependentContext()) { 15729 ValExpr = SemaRef.MakeFullExpr(ValExpr).get(); 15730 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 15731 ValExpr = tryBuildCapture(SemaRef, ValExpr, Captures).get(); 15732 *HelperValStmt = buildPreInits(SemaRef.Context, Captures); 15733 } 15734 } 15735 return true; 15736 } 15737 15738 OMPClause *Sema::ActOnOpenMPNumThreadsClause(Expr *NumThreads, 15739 SourceLocation StartLoc, 15740 SourceLocation LParenLoc, 15741 SourceLocation EndLoc) { 15742 Expr *ValExpr = NumThreads; 15743 Stmt *HelperValStmt = nullptr; 15744 15745 // OpenMP [2.5, Restrictions] 15746 // The num_threads expression must evaluate to a positive integer value. 15747 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_num_threads, 15748 /*StrictlyPositive=*/true)) 15749 return nullptr; 15750 15751 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 15752 OpenMPDirectiveKind CaptureRegion = 15753 getOpenMPCaptureRegionForClause(DKind, OMPC_num_threads, LangOpts.OpenMP); 15754 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 15755 ValExpr = MakeFullExpr(ValExpr).get(); 15756 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 15757 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 15758 HelperValStmt = buildPreInits(Context, Captures); 15759 } 15760 15761 return new (Context) OMPNumThreadsClause( 15762 ValExpr, HelperValStmt, CaptureRegion, StartLoc, LParenLoc, EndLoc); 15763 } 15764 15765 ExprResult Sema::VerifyPositiveIntegerConstantInClause(Expr *E, 15766 OpenMPClauseKind CKind, 15767 bool StrictlyPositive, 15768 bool SuppressExprDiags) { 15769 if (!E) 15770 return ExprError(); 15771 if (E->isValueDependent() || E->isTypeDependent() || 15772 E->isInstantiationDependent() || E->containsUnexpandedParameterPack()) 15773 return E; 15774 15775 llvm::APSInt Result; 15776 ExprResult ICE; 15777 if (SuppressExprDiags) { 15778 // Use a custom diagnoser that suppresses 'note' diagnostics about the 15779 // expression. 15780 struct SuppressedDiagnoser : public Sema::VerifyICEDiagnoser { 15781 SuppressedDiagnoser() : VerifyICEDiagnoser(/*Suppress=*/true) {} 15782 Sema::SemaDiagnosticBuilder diagnoseNotICE(Sema &S, 15783 SourceLocation Loc) override { 15784 llvm_unreachable("Diagnostic suppressed"); 15785 } 15786 } Diagnoser; 15787 ICE = VerifyIntegerConstantExpression(E, &Result, Diagnoser, AllowFold); 15788 } else { 15789 ICE = VerifyIntegerConstantExpression(E, &Result, /*FIXME*/ AllowFold); 15790 } 15791 if (ICE.isInvalid()) 15792 return ExprError(); 15793 15794 if ((StrictlyPositive && !Result.isStrictlyPositive()) || 15795 (!StrictlyPositive && !Result.isNonNegative())) { 15796 Diag(E->getExprLoc(), diag::err_omp_negative_expression_in_clause) 15797 << getOpenMPClauseName(CKind) << (StrictlyPositive ? 1 : 0) 15798 << E->getSourceRange(); 15799 return ExprError(); 15800 } 15801 if ((CKind == OMPC_aligned || CKind == OMPC_align) && !Result.isPowerOf2()) { 15802 Diag(E->getExprLoc(), diag::warn_omp_alignment_not_power_of_two) 15803 << E->getSourceRange(); 15804 return ExprError(); 15805 } 15806 if (CKind == OMPC_collapse && DSAStack->getAssociatedLoops() == 1) 15807 DSAStack->setAssociatedLoops(Result.getExtValue()); 15808 else if (CKind == OMPC_ordered) 15809 DSAStack->setAssociatedLoops(Result.getExtValue()); 15810 return ICE; 15811 } 15812 15813 OMPClause *Sema::ActOnOpenMPSafelenClause(Expr *Len, SourceLocation StartLoc, 15814 SourceLocation LParenLoc, 15815 SourceLocation EndLoc) { 15816 // OpenMP [2.8.1, simd construct, Description] 15817 // The parameter of the safelen clause must be a constant 15818 // positive integer expression. 15819 ExprResult Safelen = VerifyPositiveIntegerConstantInClause(Len, OMPC_safelen); 15820 if (Safelen.isInvalid()) 15821 return nullptr; 15822 return new (Context) 15823 OMPSafelenClause(Safelen.get(), StartLoc, LParenLoc, EndLoc); 15824 } 15825 15826 OMPClause *Sema::ActOnOpenMPSimdlenClause(Expr *Len, SourceLocation StartLoc, 15827 SourceLocation LParenLoc, 15828 SourceLocation EndLoc) { 15829 // OpenMP [2.8.1, simd construct, Description] 15830 // The parameter of the simdlen clause must be a constant 15831 // positive integer expression. 15832 ExprResult Simdlen = VerifyPositiveIntegerConstantInClause(Len, OMPC_simdlen); 15833 if (Simdlen.isInvalid()) 15834 return nullptr; 15835 return new (Context) 15836 OMPSimdlenClause(Simdlen.get(), StartLoc, LParenLoc, EndLoc); 15837 } 15838 15839 /// Tries to find omp_allocator_handle_t type. 15840 static bool findOMPAllocatorHandleT(Sema &S, SourceLocation Loc, 15841 DSAStackTy *Stack) { 15842 QualType OMPAllocatorHandleT = Stack->getOMPAllocatorHandleT(); 15843 if (!OMPAllocatorHandleT.isNull()) 15844 return true; 15845 // Build the predefined allocator expressions. 15846 bool ErrorFound = false; 15847 for (int I = 0; I < OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; ++I) { 15848 auto AllocatorKind = static_cast<OMPAllocateDeclAttr::AllocatorTypeTy>(I); 15849 StringRef Allocator = 15850 OMPAllocateDeclAttr::ConvertAllocatorTypeTyToStr(AllocatorKind); 15851 DeclarationName AllocatorName = &S.getASTContext().Idents.get(Allocator); 15852 auto *VD = dyn_cast_or_null<ValueDecl>( 15853 S.LookupSingleName(S.TUScope, AllocatorName, Loc, Sema::LookupAnyName)); 15854 if (!VD) { 15855 ErrorFound = true; 15856 break; 15857 } 15858 QualType AllocatorType = 15859 VD->getType().getNonLValueExprType(S.getASTContext()); 15860 ExprResult Res = S.BuildDeclRefExpr(VD, AllocatorType, VK_LValue, Loc); 15861 if (!Res.isUsable()) { 15862 ErrorFound = true; 15863 break; 15864 } 15865 if (OMPAllocatorHandleT.isNull()) 15866 OMPAllocatorHandleT = AllocatorType; 15867 if (!S.getASTContext().hasSameType(OMPAllocatorHandleT, AllocatorType)) { 15868 ErrorFound = true; 15869 break; 15870 } 15871 Stack->setAllocator(AllocatorKind, Res.get()); 15872 } 15873 if (ErrorFound) { 15874 S.Diag(Loc, diag::err_omp_implied_type_not_found) 15875 << "omp_allocator_handle_t"; 15876 return false; 15877 } 15878 OMPAllocatorHandleT.addConst(); 15879 Stack->setOMPAllocatorHandleT(OMPAllocatorHandleT); 15880 return true; 15881 } 15882 15883 OMPClause *Sema::ActOnOpenMPAllocatorClause(Expr *A, SourceLocation StartLoc, 15884 SourceLocation LParenLoc, 15885 SourceLocation EndLoc) { 15886 // OpenMP [2.11.3, allocate Directive, Description] 15887 // allocator is an expression of omp_allocator_handle_t type. 15888 if (!findOMPAllocatorHandleT(*this, A->getExprLoc(), DSAStack)) 15889 return nullptr; 15890 15891 ExprResult Allocator = DefaultLvalueConversion(A); 15892 if (Allocator.isInvalid()) 15893 return nullptr; 15894 Allocator = PerformImplicitConversion(Allocator.get(), 15895 DSAStack->getOMPAllocatorHandleT(), 15896 Sema::AA_Initializing, 15897 /*AllowExplicit=*/true); 15898 if (Allocator.isInvalid()) 15899 return nullptr; 15900 return new (Context) 15901 OMPAllocatorClause(Allocator.get(), StartLoc, LParenLoc, EndLoc); 15902 } 15903 15904 OMPClause *Sema::ActOnOpenMPCollapseClause(Expr *NumForLoops, 15905 SourceLocation StartLoc, 15906 SourceLocation LParenLoc, 15907 SourceLocation EndLoc) { 15908 // OpenMP [2.7.1, loop construct, Description] 15909 // OpenMP [2.8.1, simd construct, Description] 15910 // OpenMP [2.9.6, distribute construct, Description] 15911 // The parameter of the collapse clause must be a constant 15912 // positive integer expression. 15913 ExprResult NumForLoopsResult = 15914 VerifyPositiveIntegerConstantInClause(NumForLoops, OMPC_collapse); 15915 if (NumForLoopsResult.isInvalid()) 15916 return nullptr; 15917 return new (Context) 15918 OMPCollapseClause(NumForLoopsResult.get(), StartLoc, LParenLoc, EndLoc); 15919 } 15920 15921 OMPClause *Sema::ActOnOpenMPOrderedClause(SourceLocation StartLoc, 15922 SourceLocation EndLoc, 15923 SourceLocation LParenLoc, 15924 Expr *NumForLoops) { 15925 // OpenMP [2.7.1, loop construct, Description] 15926 // OpenMP [2.8.1, simd construct, Description] 15927 // OpenMP [2.9.6, distribute construct, Description] 15928 // The parameter of the ordered clause must be a constant 15929 // positive integer expression if any. 15930 if (NumForLoops && LParenLoc.isValid()) { 15931 ExprResult NumForLoopsResult = 15932 VerifyPositiveIntegerConstantInClause(NumForLoops, OMPC_ordered); 15933 if (NumForLoopsResult.isInvalid()) 15934 return nullptr; 15935 NumForLoops = NumForLoopsResult.get(); 15936 } else { 15937 NumForLoops = nullptr; 15938 } 15939 auto *Clause = OMPOrderedClause::Create( 15940 Context, NumForLoops, NumForLoops ? DSAStack->getAssociatedLoops() : 0, 15941 StartLoc, LParenLoc, EndLoc); 15942 DSAStack->setOrderedRegion(/*IsOrdered=*/true, NumForLoops, Clause); 15943 return Clause; 15944 } 15945 15946 OMPClause *Sema::ActOnOpenMPSimpleClause( 15947 OpenMPClauseKind Kind, unsigned Argument, SourceLocation ArgumentLoc, 15948 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) { 15949 OMPClause *Res = nullptr; 15950 switch (Kind) { 15951 case OMPC_default: 15952 Res = ActOnOpenMPDefaultClause(static_cast<DefaultKind>(Argument), 15953 ArgumentLoc, StartLoc, LParenLoc, EndLoc); 15954 break; 15955 case OMPC_proc_bind: 15956 Res = ActOnOpenMPProcBindClause(static_cast<ProcBindKind>(Argument), 15957 ArgumentLoc, StartLoc, LParenLoc, EndLoc); 15958 break; 15959 case OMPC_atomic_default_mem_order: 15960 Res = ActOnOpenMPAtomicDefaultMemOrderClause( 15961 static_cast<OpenMPAtomicDefaultMemOrderClauseKind>(Argument), 15962 ArgumentLoc, StartLoc, LParenLoc, EndLoc); 15963 break; 15964 case OMPC_order: 15965 Res = ActOnOpenMPOrderClause(static_cast<OpenMPOrderClauseKind>(Argument), 15966 ArgumentLoc, StartLoc, LParenLoc, EndLoc); 15967 break; 15968 case OMPC_update: 15969 Res = ActOnOpenMPUpdateClause(static_cast<OpenMPDependClauseKind>(Argument), 15970 ArgumentLoc, StartLoc, LParenLoc, EndLoc); 15971 break; 15972 case OMPC_bind: 15973 Res = ActOnOpenMPBindClause(static_cast<OpenMPBindClauseKind>(Argument), 15974 ArgumentLoc, StartLoc, LParenLoc, EndLoc); 15975 break; 15976 case OMPC_if: 15977 case OMPC_final: 15978 case OMPC_num_threads: 15979 case OMPC_safelen: 15980 case OMPC_simdlen: 15981 case OMPC_sizes: 15982 case OMPC_allocator: 15983 case OMPC_collapse: 15984 case OMPC_schedule: 15985 case OMPC_private: 15986 case OMPC_firstprivate: 15987 case OMPC_lastprivate: 15988 case OMPC_shared: 15989 case OMPC_reduction: 15990 case OMPC_task_reduction: 15991 case OMPC_in_reduction: 15992 case OMPC_linear: 15993 case OMPC_aligned: 15994 case OMPC_copyin: 15995 case OMPC_copyprivate: 15996 case OMPC_ordered: 15997 case OMPC_nowait: 15998 case OMPC_untied: 15999 case OMPC_mergeable: 16000 case OMPC_threadprivate: 16001 case OMPC_allocate: 16002 case OMPC_flush: 16003 case OMPC_depobj: 16004 case OMPC_read: 16005 case OMPC_write: 16006 case OMPC_capture: 16007 case OMPC_compare: 16008 case OMPC_seq_cst: 16009 case OMPC_acq_rel: 16010 case OMPC_acquire: 16011 case OMPC_release: 16012 case OMPC_relaxed: 16013 case OMPC_depend: 16014 case OMPC_device: 16015 case OMPC_threads: 16016 case OMPC_simd: 16017 case OMPC_map: 16018 case OMPC_num_teams: 16019 case OMPC_thread_limit: 16020 case OMPC_priority: 16021 case OMPC_grainsize: 16022 case OMPC_nogroup: 16023 case OMPC_num_tasks: 16024 case OMPC_hint: 16025 case OMPC_dist_schedule: 16026 case OMPC_defaultmap: 16027 case OMPC_unknown: 16028 case OMPC_uniform: 16029 case OMPC_to: 16030 case OMPC_from: 16031 case OMPC_use_device_ptr: 16032 case OMPC_use_device_addr: 16033 case OMPC_is_device_ptr: 16034 case OMPC_has_device_addr: 16035 case OMPC_unified_address: 16036 case OMPC_unified_shared_memory: 16037 case OMPC_reverse_offload: 16038 case OMPC_dynamic_allocators: 16039 case OMPC_device_type: 16040 case OMPC_match: 16041 case OMPC_nontemporal: 16042 case OMPC_destroy: 16043 case OMPC_novariants: 16044 case OMPC_nocontext: 16045 case OMPC_detach: 16046 case OMPC_inclusive: 16047 case OMPC_exclusive: 16048 case OMPC_uses_allocators: 16049 case OMPC_affinity: 16050 case OMPC_when: 16051 default: 16052 llvm_unreachable("Clause is not allowed."); 16053 } 16054 return Res; 16055 } 16056 16057 static std::string 16058 getListOfPossibleValues(OpenMPClauseKind K, unsigned First, unsigned Last, 16059 ArrayRef<unsigned> Exclude = llvm::None) { 16060 SmallString<256> Buffer; 16061 llvm::raw_svector_ostream Out(Buffer); 16062 unsigned Skipped = Exclude.size(); 16063 auto S = Exclude.begin(), E = Exclude.end(); 16064 for (unsigned I = First; I < Last; ++I) { 16065 if (std::find(S, E, I) != E) { 16066 --Skipped; 16067 continue; 16068 } 16069 Out << "'" << getOpenMPSimpleClauseTypeName(K, I) << "'"; 16070 if (I + Skipped + 2 == Last) 16071 Out << " or "; 16072 else if (I + Skipped + 1 != Last) 16073 Out << ", "; 16074 } 16075 return std::string(Out.str()); 16076 } 16077 16078 OMPClause *Sema::ActOnOpenMPDefaultClause(DefaultKind Kind, 16079 SourceLocation KindKwLoc, 16080 SourceLocation StartLoc, 16081 SourceLocation LParenLoc, 16082 SourceLocation EndLoc) { 16083 if (Kind == OMP_DEFAULT_unknown) { 16084 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value) 16085 << getListOfPossibleValues(OMPC_default, /*First=*/0, 16086 /*Last=*/unsigned(OMP_DEFAULT_unknown)) 16087 << getOpenMPClauseName(OMPC_default); 16088 return nullptr; 16089 } 16090 16091 switch (Kind) { 16092 case OMP_DEFAULT_none: 16093 DSAStack->setDefaultDSANone(KindKwLoc); 16094 break; 16095 case OMP_DEFAULT_shared: 16096 DSAStack->setDefaultDSAShared(KindKwLoc); 16097 break; 16098 case OMP_DEFAULT_firstprivate: 16099 DSAStack->setDefaultDSAFirstPrivate(KindKwLoc); 16100 break; 16101 case OMP_DEFAULT_private: 16102 DSAStack->setDefaultDSAPrivate(KindKwLoc); 16103 break; 16104 default: 16105 llvm_unreachable("DSA unexpected in OpenMP default clause"); 16106 } 16107 16108 return new (Context) 16109 OMPDefaultClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc); 16110 } 16111 16112 OMPClause *Sema::ActOnOpenMPProcBindClause(ProcBindKind Kind, 16113 SourceLocation KindKwLoc, 16114 SourceLocation StartLoc, 16115 SourceLocation LParenLoc, 16116 SourceLocation EndLoc) { 16117 if (Kind == OMP_PROC_BIND_unknown) { 16118 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value) 16119 << getListOfPossibleValues(OMPC_proc_bind, 16120 /*First=*/unsigned(OMP_PROC_BIND_master), 16121 /*Last=*/ 16122 unsigned(LangOpts.OpenMP > 50 16123 ? OMP_PROC_BIND_primary 16124 : OMP_PROC_BIND_spread) + 16125 1) 16126 << getOpenMPClauseName(OMPC_proc_bind); 16127 return nullptr; 16128 } 16129 if (Kind == OMP_PROC_BIND_primary && LangOpts.OpenMP < 51) 16130 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value) 16131 << getListOfPossibleValues(OMPC_proc_bind, 16132 /*First=*/unsigned(OMP_PROC_BIND_master), 16133 /*Last=*/ 16134 unsigned(OMP_PROC_BIND_spread) + 1) 16135 << getOpenMPClauseName(OMPC_proc_bind); 16136 return new (Context) 16137 OMPProcBindClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc); 16138 } 16139 16140 OMPClause *Sema::ActOnOpenMPAtomicDefaultMemOrderClause( 16141 OpenMPAtomicDefaultMemOrderClauseKind Kind, SourceLocation KindKwLoc, 16142 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) { 16143 if (Kind == OMPC_ATOMIC_DEFAULT_MEM_ORDER_unknown) { 16144 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value) 16145 << getListOfPossibleValues( 16146 OMPC_atomic_default_mem_order, /*First=*/0, 16147 /*Last=*/OMPC_ATOMIC_DEFAULT_MEM_ORDER_unknown) 16148 << getOpenMPClauseName(OMPC_atomic_default_mem_order); 16149 return nullptr; 16150 } 16151 return new (Context) OMPAtomicDefaultMemOrderClause(Kind, KindKwLoc, StartLoc, 16152 LParenLoc, EndLoc); 16153 } 16154 16155 OMPClause *Sema::ActOnOpenMPOrderClause(OpenMPOrderClauseKind Kind, 16156 SourceLocation KindKwLoc, 16157 SourceLocation StartLoc, 16158 SourceLocation LParenLoc, 16159 SourceLocation EndLoc) { 16160 if (Kind == OMPC_ORDER_unknown) { 16161 static_assert(OMPC_ORDER_unknown > 0, 16162 "OMPC_ORDER_unknown not greater than 0"); 16163 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value) 16164 << getListOfPossibleValues(OMPC_order, /*First=*/0, 16165 /*Last=*/OMPC_ORDER_unknown) 16166 << getOpenMPClauseName(OMPC_order); 16167 return nullptr; 16168 } 16169 return new (Context) 16170 OMPOrderClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc); 16171 } 16172 16173 OMPClause *Sema::ActOnOpenMPUpdateClause(OpenMPDependClauseKind Kind, 16174 SourceLocation KindKwLoc, 16175 SourceLocation StartLoc, 16176 SourceLocation LParenLoc, 16177 SourceLocation EndLoc) { 16178 if (Kind == OMPC_DEPEND_unknown || Kind == OMPC_DEPEND_source || 16179 Kind == OMPC_DEPEND_sink || Kind == OMPC_DEPEND_depobj) { 16180 SmallVector<unsigned> Except = { 16181 OMPC_DEPEND_source, OMPC_DEPEND_sink, OMPC_DEPEND_depobj, 16182 OMPC_DEPEND_outallmemory, OMPC_DEPEND_inoutallmemory}; 16183 if (LangOpts.OpenMP < 51) 16184 Except.push_back(OMPC_DEPEND_inoutset); 16185 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value) 16186 << getListOfPossibleValues(OMPC_depend, /*First=*/0, 16187 /*Last=*/OMPC_DEPEND_unknown, Except) 16188 << getOpenMPClauseName(OMPC_update); 16189 return nullptr; 16190 } 16191 return OMPUpdateClause::Create(Context, StartLoc, LParenLoc, KindKwLoc, Kind, 16192 EndLoc); 16193 } 16194 16195 OMPClause *Sema::ActOnOpenMPSizesClause(ArrayRef<Expr *> SizeExprs, 16196 SourceLocation StartLoc, 16197 SourceLocation LParenLoc, 16198 SourceLocation EndLoc) { 16199 for (Expr *SizeExpr : SizeExprs) { 16200 ExprResult NumForLoopsResult = VerifyPositiveIntegerConstantInClause( 16201 SizeExpr, OMPC_sizes, /*StrictlyPositive=*/true); 16202 if (!NumForLoopsResult.isUsable()) 16203 return nullptr; 16204 } 16205 16206 DSAStack->setAssociatedLoops(SizeExprs.size()); 16207 return OMPSizesClause::Create(Context, StartLoc, LParenLoc, EndLoc, 16208 SizeExprs); 16209 } 16210 16211 OMPClause *Sema::ActOnOpenMPFullClause(SourceLocation StartLoc, 16212 SourceLocation EndLoc) { 16213 return OMPFullClause::Create(Context, StartLoc, EndLoc); 16214 } 16215 16216 OMPClause *Sema::ActOnOpenMPPartialClause(Expr *FactorExpr, 16217 SourceLocation StartLoc, 16218 SourceLocation LParenLoc, 16219 SourceLocation EndLoc) { 16220 if (FactorExpr) { 16221 // If an argument is specified, it must be a constant (or an unevaluated 16222 // template expression). 16223 ExprResult FactorResult = VerifyPositiveIntegerConstantInClause( 16224 FactorExpr, OMPC_partial, /*StrictlyPositive=*/true); 16225 if (FactorResult.isInvalid()) 16226 return nullptr; 16227 FactorExpr = FactorResult.get(); 16228 } 16229 16230 return OMPPartialClause::Create(Context, StartLoc, LParenLoc, EndLoc, 16231 FactorExpr); 16232 } 16233 16234 OMPClause *Sema::ActOnOpenMPAlignClause(Expr *A, SourceLocation StartLoc, 16235 SourceLocation LParenLoc, 16236 SourceLocation EndLoc) { 16237 ExprResult AlignVal; 16238 AlignVal = VerifyPositiveIntegerConstantInClause(A, OMPC_align); 16239 if (AlignVal.isInvalid()) 16240 return nullptr; 16241 return OMPAlignClause::Create(Context, AlignVal.get(), StartLoc, LParenLoc, 16242 EndLoc); 16243 } 16244 16245 OMPClause *Sema::ActOnOpenMPSingleExprWithArgClause( 16246 OpenMPClauseKind Kind, ArrayRef<unsigned> Argument, Expr *Expr, 16247 SourceLocation StartLoc, SourceLocation LParenLoc, 16248 ArrayRef<SourceLocation> ArgumentLoc, SourceLocation DelimLoc, 16249 SourceLocation EndLoc) { 16250 OMPClause *Res = nullptr; 16251 switch (Kind) { 16252 case OMPC_schedule: 16253 enum { Modifier1, Modifier2, ScheduleKind, NumberOfElements }; 16254 assert(Argument.size() == NumberOfElements && 16255 ArgumentLoc.size() == NumberOfElements); 16256 Res = ActOnOpenMPScheduleClause( 16257 static_cast<OpenMPScheduleClauseModifier>(Argument[Modifier1]), 16258 static_cast<OpenMPScheduleClauseModifier>(Argument[Modifier2]), 16259 static_cast<OpenMPScheduleClauseKind>(Argument[ScheduleKind]), Expr, 16260 StartLoc, LParenLoc, ArgumentLoc[Modifier1], ArgumentLoc[Modifier2], 16261 ArgumentLoc[ScheduleKind], DelimLoc, EndLoc); 16262 break; 16263 case OMPC_if: 16264 assert(Argument.size() == 1 && ArgumentLoc.size() == 1); 16265 Res = ActOnOpenMPIfClause(static_cast<OpenMPDirectiveKind>(Argument.back()), 16266 Expr, StartLoc, LParenLoc, ArgumentLoc.back(), 16267 DelimLoc, EndLoc); 16268 break; 16269 case OMPC_dist_schedule: 16270 Res = ActOnOpenMPDistScheduleClause( 16271 static_cast<OpenMPDistScheduleClauseKind>(Argument.back()), Expr, 16272 StartLoc, LParenLoc, ArgumentLoc.back(), DelimLoc, EndLoc); 16273 break; 16274 case OMPC_defaultmap: 16275 enum { Modifier, DefaultmapKind }; 16276 Res = ActOnOpenMPDefaultmapClause( 16277 static_cast<OpenMPDefaultmapClauseModifier>(Argument[Modifier]), 16278 static_cast<OpenMPDefaultmapClauseKind>(Argument[DefaultmapKind]), 16279 StartLoc, LParenLoc, ArgumentLoc[Modifier], ArgumentLoc[DefaultmapKind], 16280 EndLoc); 16281 break; 16282 case OMPC_device: 16283 assert(Argument.size() == 1 && ArgumentLoc.size() == 1); 16284 Res = ActOnOpenMPDeviceClause( 16285 static_cast<OpenMPDeviceClauseModifier>(Argument.back()), Expr, 16286 StartLoc, LParenLoc, ArgumentLoc.back(), EndLoc); 16287 break; 16288 case OMPC_final: 16289 case OMPC_num_threads: 16290 case OMPC_safelen: 16291 case OMPC_simdlen: 16292 case OMPC_sizes: 16293 case OMPC_allocator: 16294 case OMPC_collapse: 16295 case OMPC_default: 16296 case OMPC_proc_bind: 16297 case OMPC_private: 16298 case OMPC_firstprivate: 16299 case OMPC_lastprivate: 16300 case OMPC_shared: 16301 case OMPC_reduction: 16302 case OMPC_task_reduction: 16303 case OMPC_in_reduction: 16304 case OMPC_linear: 16305 case OMPC_aligned: 16306 case OMPC_copyin: 16307 case OMPC_copyprivate: 16308 case OMPC_ordered: 16309 case OMPC_nowait: 16310 case OMPC_untied: 16311 case OMPC_mergeable: 16312 case OMPC_threadprivate: 16313 case OMPC_allocate: 16314 case OMPC_flush: 16315 case OMPC_depobj: 16316 case OMPC_read: 16317 case OMPC_write: 16318 case OMPC_update: 16319 case OMPC_capture: 16320 case OMPC_compare: 16321 case OMPC_seq_cst: 16322 case OMPC_acq_rel: 16323 case OMPC_acquire: 16324 case OMPC_release: 16325 case OMPC_relaxed: 16326 case OMPC_depend: 16327 case OMPC_threads: 16328 case OMPC_simd: 16329 case OMPC_map: 16330 case OMPC_num_teams: 16331 case OMPC_thread_limit: 16332 case OMPC_priority: 16333 case OMPC_grainsize: 16334 case OMPC_nogroup: 16335 case OMPC_num_tasks: 16336 case OMPC_hint: 16337 case OMPC_unknown: 16338 case OMPC_uniform: 16339 case OMPC_to: 16340 case OMPC_from: 16341 case OMPC_use_device_ptr: 16342 case OMPC_use_device_addr: 16343 case OMPC_is_device_ptr: 16344 case OMPC_has_device_addr: 16345 case OMPC_unified_address: 16346 case OMPC_unified_shared_memory: 16347 case OMPC_reverse_offload: 16348 case OMPC_dynamic_allocators: 16349 case OMPC_atomic_default_mem_order: 16350 case OMPC_device_type: 16351 case OMPC_match: 16352 case OMPC_nontemporal: 16353 case OMPC_order: 16354 case OMPC_destroy: 16355 case OMPC_novariants: 16356 case OMPC_nocontext: 16357 case OMPC_detach: 16358 case OMPC_inclusive: 16359 case OMPC_exclusive: 16360 case OMPC_uses_allocators: 16361 case OMPC_affinity: 16362 case OMPC_when: 16363 case OMPC_bind: 16364 default: 16365 llvm_unreachable("Clause is not allowed."); 16366 } 16367 return Res; 16368 } 16369 16370 static bool checkScheduleModifiers(Sema &S, OpenMPScheduleClauseModifier M1, 16371 OpenMPScheduleClauseModifier M2, 16372 SourceLocation M1Loc, SourceLocation M2Loc) { 16373 if (M1 == OMPC_SCHEDULE_MODIFIER_unknown && M1Loc.isValid()) { 16374 SmallVector<unsigned, 2> Excluded; 16375 if (M2 != OMPC_SCHEDULE_MODIFIER_unknown) 16376 Excluded.push_back(M2); 16377 if (M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) 16378 Excluded.push_back(OMPC_SCHEDULE_MODIFIER_monotonic); 16379 if (M2 == OMPC_SCHEDULE_MODIFIER_monotonic) 16380 Excluded.push_back(OMPC_SCHEDULE_MODIFIER_nonmonotonic); 16381 S.Diag(M1Loc, diag::err_omp_unexpected_clause_value) 16382 << getListOfPossibleValues(OMPC_schedule, 16383 /*First=*/OMPC_SCHEDULE_MODIFIER_unknown + 1, 16384 /*Last=*/OMPC_SCHEDULE_MODIFIER_last, 16385 Excluded) 16386 << getOpenMPClauseName(OMPC_schedule); 16387 return true; 16388 } 16389 return false; 16390 } 16391 16392 OMPClause *Sema::ActOnOpenMPScheduleClause( 16393 OpenMPScheduleClauseModifier M1, OpenMPScheduleClauseModifier M2, 16394 OpenMPScheduleClauseKind Kind, Expr *ChunkSize, SourceLocation StartLoc, 16395 SourceLocation LParenLoc, SourceLocation M1Loc, SourceLocation M2Loc, 16396 SourceLocation KindLoc, SourceLocation CommaLoc, SourceLocation EndLoc) { 16397 if (checkScheduleModifiers(*this, M1, M2, M1Loc, M2Loc) || 16398 checkScheduleModifiers(*this, M2, M1, M2Loc, M1Loc)) 16399 return nullptr; 16400 // OpenMP, 2.7.1, Loop Construct, Restrictions 16401 // Either the monotonic modifier or the nonmonotonic modifier can be specified 16402 // but not both. 16403 if ((M1 == M2 && M1 != OMPC_SCHEDULE_MODIFIER_unknown) || 16404 (M1 == OMPC_SCHEDULE_MODIFIER_monotonic && 16405 M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) || 16406 (M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic && 16407 M2 == OMPC_SCHEDULE_MODIFIER_monotonic)) { 16408 Diag(M2Loc, diag::err_omp_unexpected_schedule_modifier) 16409 << getOpenMPSimpleClauseTypeName(OMPC_schedule, M2) 16410 << getOpenMPSimpleClauseTypeName(OMPC_schedule, M1); 16411 return nullptr; 16412 } 16413 if (Kind == OMPC_SCHEDULE_unknown) { 16414 std::string Values; 16415 if (M1Loc.isInvalid() && M2Loc.isInvalid()) { 16416 unsigned Exclude[] = {OMPC_SCHEDULE_unknown}; 16417 Values = getListOfPossibleValues(OMPC_schedule, /*First=*/0, 16418 /*Last=*/OMPC_SCHEDULE_MODIFIER_last, 16419 Exclude); 16420 } else { 16421 Values = getListOfPossibleValues(OMPC_schedule, /*First=*/0, 16422 /*Last=*/OMPC_SCHEDULE_unknown); 16423 } 16424 Diag(KindLoc, diag::err_omp_unexpected_clause_value) 16425 << Values << getOpenMPClauseName(OMPC_schedule); 16426 return nullptr; 16427 } 16428 // OpenMP, 2.7.1, Loop Construct, Restrictions 16429 // The nonmonotonic modifier can only be specified with schedule(dynamic) or 16430 // schedule(guided). 16431 // OpenMP 5.0 does not have this restriction. 16432 if (LangOpts.OpenMP < 50 && 16433 (M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic || 16434 M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) && 16435 Kind != OMPC_SCHEDULE_dynamic && Kind != OMPC_SCHEDULE_guided) { 16436 Diag(M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic ? M1Loc : M2Loc, 16437 diag::err_omp_schedule_nonmonotonic_static); 16438 return nullptr; 16439 } 16440 Expr *ValExpr = ChunkSize; 16441 Stmt *HelperValStmt = nullptr; 16442 if (ChunkSize) { 16443 if (!ChunkSize->isValueDependent() && !ChunkSize->isTypeDependent() && 16444 !ChunkSize->isInstantiationDependent() && 16445 !ChunkSize->containsUnexpandedParameterPack()) { 16446 SourceLocation ChunkSizeLoc = ChunkSize->getBeginLoc(); 16447 ExprResult Val = 16448 PerformOpenMPImplicitIntegerConversion(ChunkSizeLoc, ChunkSize); 16449 if (Val.isInvalid()) 16450 return nullptr; 16451 16452 ValExpr = Val.get(); 16453 16454 // OpenMP [2.7.1, Restrictions] 16455 // chunk_size must be a loop invariant integer expression with a positive 16456 // value. 16457 if (Optional<llvm::APSInt> Result = 16458 ValExpr->getIntegerConstantExpr(Context)) { 16459 if (Result->isSigned() && !Result->isStrictlyPositive()) { 16460 Diag(ChunkSizeLoc, diag::err_omp_negative_expression_in_clause) 16461 << "schedule" << 1 << ChunkSize->getSourceRange(); 16462 return nullptr; 16463 } 16464 } else if (getOpenMPCaptureRegionForClause( 16465 DSAStack->getCurrentDirective(), OMPC_schedule, 16466 LangOpts.OpenMP) != OMPD_unknown && 16467 !CurContext->isDependentContext()) { 16468 ValExpr = MakeFullExpr(ValExpr).get(); 16469 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 16470 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 16471 HelperValStmt = buildPreInits(Context, Captures); 16472 } 16473 } 16474 } 16475 16476 return new (Context) 16477 OMPScheduleClause(StartLoc, LParenLoc, KindLoc, CommaLoc, EndLoc, Kind, 16478 ValExpr, HelperValStmt, M1, M1Loc, M2, M2Loc); 16479 } 16480 16481 OMPClause *Sema::ActOnOpenMPClause(OpenMPClauseKind Kind, 16482 SourceLocation StartLoc, 16483 SourceLocation EndLoc) { 16484 OMPClause *Res = nullptr; 16485 switch (Kind) { 16486 case OMPC_ordered: 16487 Res = ActOnOpenMPOrderedClause(StartLoc, EndLoc); 16488 break; 16489 case OMPC_nowait: 16490 Res = ActOnOpenMPNowaitClause(StartLoc, EndLoc); 16491 break; 16492 case OMPC_untied: 16493 Res = ActOnOpenMPUntiedClause(StartLoc, EndLoc); 16494 break; 16495 case OMPC_mergeable: 16496 Res = ActOnOpenMPMergeableClause(StartLoc, EndLoc); 16497 break; 16498 case OMPC_read: 16499 Res = ActOnOpenMPReadClause(StartLoc, EndLoc); 16500 break; 16501 case OMPC_write: 16502 Res = ActOnOpenMPWriteClause(StartLoc, EndLoc); 16503 break; 16504 case OMPC_update: 16505 Res = ActOnOpenMPUpdateClause(StartLoc, EndLoc); 16506 break; 16507 case OMPC_capture: 16508 Res = ActOnOpenMPCaptureClause(StartLoc, EndLoc); 16509 break; 16510 case OMPC_compare: 16511 Res = ActOnOpenMPCompareClause(StartLoc, EndLoc); 16512 break; 16513 case OMPC_seq_cst: 16514 Res = ActOnOpenMPSeqCstClause(StartLoc, EndLoc); 16515 break; 16516 case OMPC_acq_rel: 16517 Res = ActOnOpenMPAcqRelClause(StartLoc, EndLoc); 16518 break; 16519 case OMPC_acquire: 16520 Res = ActOnOpenMPAcquireClause(StartLoc, EndLoc); 16521 break; 16522 case OMPC_release: 16523 Res = ActOnOpenMPReleaseClause(StartLoc, EndLoc); 16524 break; 16525 case OMPC_relaxed: 16526 Res = ActOnOpenMPRelaxedClause(StartLoc, EndLoc); 16527 break; 16528 case OMPC_threads: 16529 Res = ActOnOpenMPThreadsClause(StartLoc, EndLoc); 16530 break; 16531 case OMPC_simd: 16532 Res = ActOnOpenMPSIMDClause(StartLoc, EndLoc); 16533 break; 16534 case OMPC_nogroup: 16535 Res = ActOnOpenMPNogroupClause(StartLoc, EndLoc); 16536 break; 16537 case OMPC_unified_address: 16538 Res = ActOnOpenMPUnifiedAddressClause(StartLoc, EndLoc); 16539 break; 16540 case OMPC_unified_shared_memory: 16541 Res = ActOnOpenMPUnifiedSharedMemoryClause(StartLoc, EndLoc); 16542 break; 16543 case OMPC_reverse_offload: 16544 Res = ActOnOpenMPReverseOffloadClause(StartLoc, EndLoc); 16545 break; 16546 case OMPC_dynamic_allocators: 16547 Res = ActOnOpenMPDynamicAllocatorsClause(StartLoc, EndLoc); 16548 break; 16549 case OMPC_destroy: 16550 Res = ActOnOpenMPDestroyClause(/*InteropVar=*/nullptr, StartLoc, 16551 /*LParenLoc=*/SourceLocation(), 16552 /*VarLoc=*/SourceLocation(), EndLoc); 16553 break; 16554 case OMPC_full: 16555 Res = ActOnOpenMPFullClause(StartLoc, EndLoc); 16556 break; 16557 case OMPC_partial: 16558 Res = ActOnOpenMPPartialClause(nullptr, StartLoc, /*LParenLoc=*/{}, EndLoc); 16559 break; 16560 case OMPC_if: 16561 case OMPC_final: 16562 case OMPC_num_threads: 16563 case OMPC_safelen: 16564 case OMPC_simdlen: 16565 case OMPC_sizes: 16566 case OMPC_allocator: 16567 case OMPC_collapse: 16568 case OMPC_schedule: 16569 case OMPC_private: 16570 case OMPC_firstprivate: 16571 case OMPC_lastprivate: 16572 case OMPC_shared: 16573 case OMPC_reduction: 16574 case OMPC_task_reduction: 16575 case OMPC_in_reduction: 16576 case OMPC_linear: 16577 case OMPC_aligned: 16578 case OMPC_copyin: 16579 case OMPC_copyprivate: 16580 case OMPC_default: 16581 case OMPC_proc_bind: 16582 case OMPC_threadprivate: 16583 case OMPC_allocate: 16584 case OMPC_flush: 16585 case OMPC_depobj: 16586 case OMPC_depend: 16587 case OMPC_device: 16588 case OMPC_map: 16589 case OMPC_num_teams: 16590 case OMPC_thread_limit: 16591 case OMPC_priority: 16592 case OMPC_grainsize: 16593 case OMPC_num_tasks: 16594 case OMPC_hint: 16595 case OMPC_dist_schedule: 16596 case OMPC_defaultmap: 16597 case OMPC_unknown: 16598 case OMPC_uniform: 16599 case OMPC_to: 16600 case OMPC_from: 16601 case OMPC_use_device_ptr: 16602 case OMPC_use_device_addr: 16603 case OMPC_is_device_ptr: 16604 case OMPC_has_device_addr: 16605 case OMPC_atomic_default_mem_order: 16606 case OMPC_device_type: 16607 case OMPC_match: 16608 case OMPC_nontemporal: 16609 case OMPC_order: 16610 case OMPC_novariants: 16611 case OMPC_nocontext: 16612 case OMPC_detach: 16613 case OMPC_inclusive: 16614 case OMPC_exclusive: 16615 case OMPC_uses_allocators: 16616 case OMPC_affinity: 16617 case OMPC_when: 16618 default: 16619 llvm_unreachable("Clause is not allowed."); 16620 } 16621 return Res; 16622 } 16623 16624 OMPClause *Sema::ActOnOpenMPNowaitClause(SourceLocation StartLoc, 16625 SourceLocation EndLoc) { 16626 DSAStack->setNowaitRegion(); 16627 return new (Context) OMPNowaitClause(StartLoc, EndLoc); 16628 } 16629 16630 OMPClause *Sema::ActOnOpenMPUntiedClause(SourceLocation StartLoc, 16631 SourceLocation EndLoc) { 16632 DSAStack->setUntiedRegion(); 16633 return new (Context) OMPUntiedClause(StartLoc, EndLoc); 16634 } 16635 16636 OMPClause *Sema::ActOnOpenMPMergeableClause(SourceLocation StartLoc, 16637 SourceLocation EndLoc) { 16638 return new (Context) OMPMergeableClause(StartLoc, EndLoc); 16639 } 16640 16641 OMPClause *Sema::ActOnOpenMPReadClause(SourceLocation StartLoc, 16642 SourceLocation EndLoc) { 16643 return new (Context) OMPReadClause(StartLoc, EndLoc); 16644 } 16645 16646 OMPClause *Sema::ActOnOpenMPWriteClause(SourceLocation StartLoc, 16647 SourceLocation EndLoc) { 16648 return new (Context) OMPWriteClause(StartLoc, EndLoc); 16649 } 16650 16651 OMPClause *Sema::ActOnOpenMPUpdateClause(SourceLocation StartLoc, 16652 SourceLocation EndLoc) { 16653 return OMPUpdateClause::Create(Context, StartLoc, EndLoc); 16654 } 16655 16656 OMPClause *Sema::ActOnOpenMPCaptureClause(SourceLocation StartLoc, 16657 SourceLocation EndLoc) { 16658 return new (Context) OMPCaptureClause(StartLoc, EndLoc); 16659 } 16660 16661 OMPClause *Sema::ActOnOpenMPCompareClause(SourceLocation StartLoc, 16662 SourceLocation EndLoc) { 16663 return new (Context) OMPCompareClause(StartLoc, EndLoc); 16664 } 16665 16666 OMPClause *Sema::ActOnOpenMPSeqCstClause(SourceLocation StartLoc, 16667 SourceLocation EndLoc) { 16668 return new (Context) OMPSeqCstClause(StartLoc, EndLoc); 16669 } 16670 16671 OMPClause *Sema::ActOnOpenMPAcqRelClause(SourceLocation StartLoc, 16672 SourceLocation EndLoc) { 16673 return new (Context) OMPAcqRelClause(StartLoc, EndLoc); 16674 } 16675 16676 OMPClause *Sema::ActOnOpenMPAcquireClause(SourceLocation StartLoc, 16677 SourceLocation EndLoc) { 16678 return new (Context) OMPAcquireClause(StartLoc, EndLoc); 16679 } 16680 16681 OMPClause *Sema::ActOnOpenMPReleaseClause(SourceLocation StartLoc, 16682 SourceLocation EndLoc) { 16683 return new (Context) OMPReleaseClause(StartLoc, EndLoc); 16684 } 16685 16686 OMPClause *Sema::ActOnOpenMPRelaxedClause(SourceLocation StartLoc, 16687 SourceLocation EndLoc) { 16688 return new (Context) OMPRelaxedClause(StartLoc, EndLoc); 16689 } 16690 16691 OMPClause *Sema::ActOnOpenMPThreadsClause(SourceLocation StartLoc, 16692 SourceLocation EndLoc) { 16693 return new (Context) OMPThreadsClause(StartLoc, EndLoc); 16694 } 16695 16696 OMPClause *Sema::ActOnOpenMPSIMDClause(SourceLocation StartLoc, 16697 SourceLocation EndLoc) { 16698 return new (Context) OMPSIMDClause(StartLoc, EndLoc); 16699 } 16700 16701 OMPClause *Sema::ActOnOpenMPNogroupClause(SourceLocation StartLoc, 16702 SourceLocation EndLoc) { 16703 return new (Context) OMPNogroupClause(StartLoc, EndLoc); 16704 } 16705 16706 OMPClause *Sema::ActOnOpenMPUnifiedAddressClause(SourceLocation StartLoc, 16707 SourceLocation EndLoc) { 16708 return new (Context) OMPUnifiedAddressClause(StartLoc, EndLoc); 16709 } 16710 16711 OMPClause *Sema::ActOnOpenMPUnifiedSharedMemoryClause(SourceLocation StartLoc, 16712 SourceLocation EndLoc) { 16713 return new (Context) OMPUnifiedSharedMemoryClause(StartLoc, EndLoc); 16714 } 16715 16716 OMPClause *Sema::ActOnOpenMPReverseOffloadClause(SourceLocation StartLoc, 16717 SourceLocation EndLoc) { 16718 return new (Context) OMPReverseOffloadClause(StartLoc, EndLoc); 16719 } 16720 16721 OMPClause *Sema::ActOnOpenMPDynamicAllocatorsClause(SourceLocation StartLoc, 16722 SourceLocation EndLoc) { 16723 return new (Context) OMPDynamicAllocatorsClause(StartLoc, EndLoc); 16724 } 16725 16726 StmtResult Sema::ActOnOpenMPInteropDirective(ArrayRef<OMPClause *> Clauses, 16727 SourceLocation StartLoc, 16728 SourceLocation EndLoc) { 16729 16730 // OpenMP 5.1 [2.15.1, interop Construct, Restrictions] 16731 // At least one action-clause must appear on a directive. 16732 if (!hasClauses(Clauses, OMPC_init, OMPC_use, OMPC_destroy, OMPC_nowait)) { 16733 StringRef Expected = "'init', 'use', 'destroy', or 'nowait'"; 16734 Diag(StartLoc, diag::err_omp_no_clause_for_directive) 16735 << Expected << getOpenMPDirectiveName(OMPD_interop); 16736 return StmtError(); 16737 } 16738 16739 // OpenMP 5.1 [2.15.1, interop Construct, Restrictions] 16740 // A depend clause can only appear on the directive if a targetsync 16741 // interop-type is present or the interop-var was initialized with 16742 // the targetsync interop-type. 16743 16744 // If there is any 'init' clause diagnose if there is no 'init' clause with 16745 // interop-type of 'targetsync'. Cases involving other directives cannot be 16746 // diagnosed. 16747 const OMPDependClause *DependClause = nullptr; 16748 bool HasInitClause = false; 16749 bool IsTargetSync = false; 16750 for (const OMPClause *C : Clauses) { 16751 if (IsTargetSync) 16752 break; 16753 if (const auto *InitClause = dyn_cast<OMPInitClause>(C)) { 16754 HasInitClause = true; 16755 if (InitClause->getIsTargetSync()) 16756 IsTargetSync = true; 16757 } else if (const auto *DC = dyn_cast<OMPDependClause>(C)) { 16758 DependClause = DC; 16759 } 16760 } 16761 if (DependClause && HasInitClause && !IsTargetSync) { 16762 Diag(DependClause->getBeginLoc(), diag::err_omp_interop_bad_depend_clause); 16763 return StmtError(); 16764 } 16765 16766 // OpenMP 5.1 [2.15.1, interop Construct, Restrictions] 16767 // Each interop-var may be specified for at most one action-clause of each 16768 // interop construct. 16769 llvm::SmallPtrSet<const VarDecl *, 4> InteropVars; 16770 for (const OMPClause *C : Clauses) { 16771 OpenMPClauseKind ClauseKind = C->getClauseKind(); 16772 const DeclRefExpr *DRE = nullptr; 16773 SourceLocation VarLoc; 16774 16775 if (ClauseKind == OMPC_init) { 16776 const auto *IC = cast<OMPInitClause>(C); 16777 VarLoc = IC->getVarLoc(); 16778 DRE = dyn_cast_or_null<DeclRefExpr>(IC->getInteropVar()); 16779 } else if (ClauseKind == OMPC_use) { 16780 const auto *UC = cast<OMPUseClause>(C); 16781 VarLoc = UC->getVarLoc(); 16782 DRE = dyn_cast_or_null<DeclRefExpr>(UC->getInteropVar()); 16783 } else if (ClauseKind == OMPC_destroy) { 16784 const auto *DC = cast<OMPDestroyClause>(C); 16785 VarLoc = DC->getVarLoc(); 16786 DRE = dyn_cast_or_null<DeclRefExpr>(DC->getInteropVar()); 16787 } 16788 16789 if (!DRE) 16790 continue; 16791 16792 if (const auto *VD = dyn_cast<VarDecl>(DRE->getDecl())) { 16793 if (!InteropVars.insert(VD->getCanonicalDecl()).second) { 16794 Diag(VarLoc, diag::err_omp_interop_var_multiple_actions) << VD; 16795 return StmtError(); 16796 } 16797 } 16798 } 16799 16800 return OMPInteropDirective::Create(Context, StartLoc, EndLoc, Clauses); 16801 } 16802 16803 static bool isValidInteropVariable(Sema &SemaRef, Expr *InteropVarExpr, 16804 SourceLocation VarLoc, 16805 OpenMPClauseKind Kind) { 16806 if (InteropVarExpr->isValueDependent() || InteropVarExpr->isTypeDependent() || 16807 InteropVarExpr->isInstantiationDependent() || 16808 InteropVarExpr->containsUnexpandedParameterPack()) 16809 return true; 16810 16811 const auto *DRE = dyn_cast<DeclRefExpr>(InteropVarExpr); 16812 if (!DRE || !isa<VarDecl>(DRE->getDecl())) { 16813 SemaRef.Diag(VarLoc, diag::err_omp_interop_variable_expected) << 0; 16814 return false; 16815 } 16816 16817 // Interop variable should be of type omp_interop_t. 16818 bool HasError = false; 16819 QualType InteropType; 16820 LookupResult Result(SemaRef, &SemaRef.Context.Idents.get("omp_interop_t"), 16821 VarLoc, Sema::LookupOrdinaryName); 16822 if (SemaRef.LookupName(Result, SemaRef.getCurScope())) { 16823 NamedDecl *ND = Result.getFoundDecl(); 16824 if (const auto *TD = dyn_cast<TypeDecl>(ND)) { 16825 InteropType = QualType(TD->getTypeForDecl(), 0); 16826 } else { 16827 HasError = true; 16828 } 16829 } else { 16830 HasError = true; 16831 } 16832 16833 if (HasError) { 16834 SemaRef.Diag(VarLoc, diag::err_omp_implied_type_not_found) 16835 << "omp_interop_t"; 16836 return false; 16837 } 16838 16839 QualType VarType = InteropVarExpr->getType().getUnqualifiedType(); 16840 if (!SemaRef.Context.hasSameType(InteropType, VarType)) { 16841 SemaRef.Diag(VarLoc, diag::err_omp_interop_variable_wrong_type); 16842 return false; 16843 } 16844 16845 // OpenMP 5.1 [2.15.1, interop Construct, Restrictions] 16846 // The interop-var passed to init or destroy must be non-const. 16847 if ((Kind == OMPC_init || Kind == OMPC_destroy) && 16848 isConstNotMutableType(SemaRef, InteropVarExpr->getType())) { 16849 SemaRef.Diag(VarLoc, diag::err_omp_interop_variable_expected) 16850 << /*non-const*/ 1; 16851 return false; 16852 } 16853 return true; 16854 } 16855 16856 OMPClause * 16857 Sema::ActOnOpenMPInitClause(Expr *InteropVar, ArrayRef<Expr *> PrefExprs, 16858 bool IsTarget, bool IsTargetSync, 16859 SourceLocation StartLoc, SourceLocation LParenLoc, 16860 SourceLocation VarLoc, SourceLocation EndLoc) { 16861 16862 if (!isValidInteropVariable(*this, InteropVar, VarLoc, OMPC_init)) 16863 return nullptr; 16864 16865 // Check prefer_type values. These foreign-runtime-id values are either 16866 // string literals or constant integral expressions. 16867 for (const Expr *E : PrefExprs) { 16868 if (E->isValueDependent() || E->isTypeDependent() || 16869 E->isInstantiationDependent() || E->containsUnexpandedParameterPack()) 16870 continue; 16871 if (E->isIntegerConstantExpr(Context)) 16872 continue; 16873 if (isa<StringLiteral>(E)) 16874 continue; 16875 Diag(E->getExprLoc(), diag::err_omp_interop_prefer_type); 16876 return nullptr; 16877 } 16878 16879 return OMPInitClause::Create(Context, InteropVar, PrefExprs, IsTarget, 16880 IsTargetSync, StartLoc, LParenLoc, VarLoc, 16881 EndLoc); 16882 } 16883 16884 OMPClause *Sema::ActOnOpenMPUseClause(Expr *InteropVar, SourceLocation StartLoc, 16885 SourceLocation LParenLoc, 16886 SourceLocation VarLoc, 16887 SourceLocation EndLoc) { 16888 16889 if (!isValidInteropVariable(*this, InteropVar, VarLoc, OMPC_use)) 16890 return nullptr; 16891 16892 return new (Context) 16893 OMPUseClause(InteropVar, StartLoc, LParenLoc, VarLoc, EndLoc); 16894 } 16895 16896 OMPClause *Sema::ActOnOpenMPDestroyClause(Expr *InteropVar, 16897 SourceLocation StartLoc, 16898 SourceLocation LParenLoc, 16899 SourceLocation VarLoc, 16900 SourceLocation EndLoc) { 16901 if (InteropVar && 16902 !isValidInteropVariable(*this, InteropVar, VarLoc, OMPC_destroy)) 16903 return nullptr; 16904 16905 return new (Context) 16906 OMPDestroyClause(InteropVar, StartLoc, LParenLoc, VarLoc, EndLoc); 16907 } 16908 16909 OMPClause *Sema::ActOnOpenMPNovariantsClause(Expr *Condition, 16910 SourceLocation StartLoc, 16911 SourceLocation LParenLoc, 16912 SourceLocation EndLoc) { 16913 Expr *ValExpr = Condition; 16914 Stmt *HelperValStmt = nullptr; 16915 OpenMPDirectiveKind CaptureRegion = OMPD_unknown; 16916 if (!Condition->isValueDependent() && !Condition->isTypeDependent() && 16917 !Condition->isInstantiationDependent() && 16918 !Condition->containsUnexpandedParameterPack()) { 16919 ExprResult Val = CheckBooleanCondition(StartLoc, Condition); 16920 if (Val.isInvalid()) 16921 return nullptr; 16922 16923 ValExpr = MakeFullExpr(Val.get()).get(); 16924 16925 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 16926 CaptureRegion = getOpenMPCaptureRegionForClause(DKind, OMPC_novariants, 16927 LangOpts.OpenMP); 16928 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 16929 ValExpr = MakeFullExpr(ValExpr).get(); 16930 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 16931 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 16932 HelperValStmt = buildPreInits(Context, Captures); 16933 } 16934 } 16935 16936 return new (Context) OMPNovariantsClause( 16937 ValExpr, HelperValStmt, CaptureRegion, StartLoc, LParenLoc, EndLoc); 16938 } 16939 16940 OMPClause *Sema::ActOnOpenMPNocontextClause(Expr *Condition, 16941 SourceLocation StartLoc, 16942 SourceLocation LParenLoc, 16943 SourceLocation EndLoc) { 16944 Expr *ValExpr = Condition; 16945 Stmt *HelperValStmt = nullptr; 16946 OpenMPDirectiveKind CaptureRegion = OMPD_unknown; 16947 if (!Condition->isValueDependent() && !Condition->isTypeDependent() && 16948 !Condition->isInstantiationDependent() && 16949 !Condition->containsUnexpandedParameterPack()) { 16950 ExprResult Val = CheckBooleanCondition(StartLoc, Condition); 16951 if (Val.isInvalid()) 16952 return nullptr; 16953 16954 ValExpr = MakeFullExpr(Val.get()).get(); 16955 16956 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 16957 CaptureRegion = 16958 getOpenMPCaptureRegionForClause(DKind, OMPC_nocontext, LangOpts.OpenMP); 16959 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 16960 ValExpr = MakeFullExpr(ValExpr).get(); 16961 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 16962 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 16963 HelperValStmt = buildPreInits(Context, Captures); 16964 } 16965 } 16966 16967 return new (Context) OMPNocontextClause(ValExpr, HelperValStmt, CaptureRegion, 16968 StartLoc, LParenLoc, EndLoc); 16969 } 16970 16971 OMPClause *Sema::ActOnOpenMPFilterClause(Expr *ThreadID, 16972 SourceLocation StartLoc, 16973 SourceLocation LParenLoc, 16974 SourceLocation EndLoc) { 16975 Expr *ValExpr = ThreadID; 16976 Stmt *HelperValStmt = nullptr; 16977 16978 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 16979 OpenMPDirectiveKind CaptureRegion = 16980 getOpenMPCaptureRegionForClause(DKind, OMPC_filter, LangOpts.OpenMP); 16981 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 16982 ValExpr = MakeFullExpr(ValExpr).get(); 16983 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 16984 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 16985 HelperValStmt = buildPreInits(Context, Captures); 16986 } 16987 16988 return new (Context) OMPFilterClause(ValExpr, HelperValStmt, CaptureRegion, 16989 StartLoc, LParenLoc, EndLoc); 16990 } 16991 16992 OMPClause *Sema::ActOnOpenMPVarListClause(OpenMPClauseKind Kind, 16993 ArrayRef<Expr *> VarList, 16994 const OMPVarListLocTy &Locs, 16995 OpenMPVarListDataTy &Data) { 16996 SourceLocation StartLoc = Locs.StartLoc; 16997 SourceLocation LParenLoc = Locs.LParenLoc; 16998 SourceLocation EndLoc = Locs.EndLoc; 16999 OMPClause *Res = nullptr; 17000 int ExtraModifier = Data.ExtraModifier; 17001 SourceLocation ExtraModifierLoc = Data.ExtraModifierLoc; 17002 SourceLocation ColonLoc = Data.ColonLoc; 17003 switch (Kind) { 17004 case OMPC_private: 17005 Res = ActOnOpenMPPrivateClause(VarList, StartLoc, LParenLoc, EndLoc); 17006 break; 17007 case OMPC_firstprivate: 17008 Res = ActOnOpenMPFirstprivateClause(VarList, StartLoc, LParenLoc, EndLoc); 17009 break; 17010 case OMPC_lastprivate: 17011 assert(0 <= ExtraModifier && ExtraModifier <= OMPC_LASTPRIVATE_unknown && 17012 "Unexpected lastprivate modifier."); 17013 Res = ActOnOpenMPLastprivateClause( 17014 VarList, static_cast<OpenMPLastprivateModifier>(ExtraModifier), 17015 ExtraModifierLoc, ColonLoc, StartLoc, LParenLoc, EndLoc); 17016 break; 17017 case OMPC_shared: 17018 Res = ActOnOpenMPSharedClause(VarList, StartLoc, LParenLoc, EndLoc); 17019 break; 17020 case OMPC_reduction: 17021 assert(0 <= ExtraModifier && ExtraModifier <= OMPC_REDUCTION_unknown && 17022 "Unexpected lastprivate modifier."); 17023 Res = ActOnOpenMPReductionClause( 17024 VarList, static_cast<OpenMPReductionClauseModifier>(ExtraModifier), 17025 StartLoc, LParenLoc, ExtraModifierLoc, ColonLoc, EndLoc, 17026 Data.ReductionOrMapperIdScopeSpec, Data.ReductionOrMapperId); 17027 break; 17028 case OMPC_task_reduction: 17029 Res = ActOnOpenMPTaskReductionClause( 17030 VarList, StartLoc, LParenLoc, ColonLoc, EndLoc, 17031 Data.ReductionOrMapperIdScopeSpec, Data.ReductionOrMapperId); 17032 break; 17033 case OMPC_in_reduction: 17034 Res = ActOnOpenMPInReductionClause( 17035 VarList, StartLoc, LParenLoc, ColonLoc, EndLoc, 17036 Data.ReductionOrMapperIdScopeSpec, Data.ReductionOrMapperId); 17037 break; 17038 case OMPC_linear: 17039 assert(0 <= ExtraModifier && ExtraModifier <= OMPC_LINEAR_unknown && 17040 "Unexpected linear modifier."); 17041 Res = ActOnOpenMPLinearClause( 17042 VarList, Data.DepModOrTailExpr, StartLoc, LParenLoc, 17043 static_cast<OpenMPLinearClauseKind>(ExtraModifier), ExtraModifierLoc, 17044 ColonLoc, EndLoc); 17045 break; 17046 case OMPC_aligned: 17047 Res = ActOnOpenMPAlignedClause(VarList, Data.DepModOrTailExpr, StartLoc, 17048 LParenLoc, ColonLoc, EndLoc); 17049 break; 17050 case OMPC_copyin: 17051 Res = ActOnOpenMPCopyinClause(VarList, StartLoc, LParenLoc, EndLoc); 17052 break; 17053 case OMPC_copyprivate: 17054 Res = ActOnOpenMPCopyprivateClause(VarList, StartLoc, LParenLoc, EndLoc); 17055 break; 17056 case OMPC_flush: 17057 Res = ActOnOpenMPFlushClause(VarList, StartLoc, LParenLoc, EndLoc); 17058 break; 17059 case OMPC_depend: 17060 assert(0 <= ExtraModifier && ExtraModifier <= OMPC_DEPEND_unknown && 17061 "Unexpected depend modifier."); 17062 Res = ActOnOpenMPDependClause( 17063 {static_cast<OpenMPDependClauseKind>(ExtraModifier), ExtraModifierLoc, 17064 ColonLoc, Data.OmpAllMemoryLoc}, 17065 Data.DepModOrTailExpr, VarList, StartLoc, LParenLoc, EndLoc); 17066 break; 17067 case OMPC_map: 17068 assert(0 <= ExtraModifier && ExtraModifier <= OMPC_MAP_unknown && 17069 "Unexpected map modifier."); 17070 Res = ActOnOpenMPMapClause( 17071 Data.MapTypeModifiers, Data.MapTypeModifiersLoc, 17072 Data.ReductionOrMapperIdScopeSpec, Data.ReductionOrMapperId, 17073 static_cast<OpenMPMapClauseKind>(ExtraModifier), Data.IsMapTypeImplicit, 17074 ExtraModifierLoc, ColonLoc, VarList, Locs); 17075 break; 17076 case OMPC_to: 17077 Res = 17078 ActOnOpenMPToClause(Data.MotionModifiers, Data.MotionModifiersLoc, 17079 Data.ReductionOrMapperIdScopeSpec, 17080 Data.ReductionOrMapperId, ColonLoc, VarList, Locs); 17081 break; 17082 case OMPC_from: 17083 Res = ActOnOpenMPFromClause(Data.MotionModifiers, Data.MotionModifiersLoc, 17084 Data.ReductionOrMapperIdScopeSpec, 17085 Data.ReductionOrMapperId, ColonLoc, VarList, 17086 Locs); 17087 break; 17088 case OMPC_use_device_ptr: 17089 Res = ActOnOpenMPUseDevicePtrClause(VarList, Locs); 17090 break; 17091 case OMPC_use_device_addr: 17092 Res = ActOnOpenMPUseDeviceAddrClause(VarList, Locs); 17093 break; 17094 case OMPC_is_device_ptr: 17095 Res = ActOnOpenMPIsDevicePtrClause(VarList, Locs); 17096 break; 17097 case OMPC_has_device_addr: 17098 Res = ActOnOpenMPHasDeviceAddrClause(VarList, Locs); 17099 break; 17100 case OMPC_allocate: 17101 Res = ActOnOpenMPAllocateClause(Data.DepModOrTailExpr, VarList, StartLoc, 17102 LParenLoc, ColonLoc, EndLoc); 17103 break; 17104 case OMPC_nontemporal: 17105 Res = ActOnOpenMPNontemporalClause(VarList, StartLoc, LParenLoc, EndLoc); 17106 break; 17107 case OMPC_inclusive: 17108 Res = ActOnOpenMPInclusiveClause(VarList, StartLoc, LParenLoc, EndLoc); 17109 break; 17110 case OMPC_exclusive: 17111 Res = ActOnOpenMPExclusiveClause(VarList, StartLoc, LParenLoc, EndLoc); 17112 break; 17113 case OMPC_affinity: 17114 Res = ActOnOpenMPAffinityClause(StartLoc, LParenLoc, ColonLoc, EndLoc, 17115 Data.DepModOrTailExpr, VarList); 17116 break; 17117 case OMPC_if: 17118 case OMPC_depobj: 17119 case OMPC_final: 17120 case OMPC_num_threads: 17121 case OMPC_safelen: 17122 case OMPC_simdlen: 17123 case OMPC_sizes: 17124 case OMPC_allocator: 17125 case OMPC_collapse: 17126 case OMPC_default: 17127 case OMPC_proc_bind: 17128 case OMPC_schedule: 17129 case OMPC_ordered: 17130 case OMPC_nowait: 17131 case OMPC_untied: 17132 case OMPC_mergeable: 17133 case OMPC_threadprivate: 17134 case OMPC_read: 17135 case OMPC_write: 17136 case OMPC_update: 17137 case OMPC_capture: 17138 case OMPC_compare: 17139 case OMPC_seq_cst: 17140 case OMPC_acq_rel: 17141 case OMPC_acquire: 17142 case OMPC_release: 17143 case OMPC_relaxed: 17144 case OMPC_device: 17145 case OMPC_threads: 17146 case OMPC_simd: 17147 case OMPC_num_teams: 17148 case OMPC_thread_limit: 17149 case OMPC_priority: 17150 case OMPC_grainsize: 17151 case OMPC_nogroup: 17152 case OMPC_num_tasks: 17153 case OMPC_hint: 17154 case OMPC_dist_schedule: 17155 case OMPC_defaultmap: 17156 case OMPC_unknown: 17157 case OMPC_uniform: 17158 case OMPC_unified_address: 17159 case OMPC_unified_shared_memory: 17160 case OMPC_reverse_offload: 17161 case OMPC_dynamic_allocators: 17162 case OMPC_atomic_default_mem_order: 17163 case OMPC_device_type: 17164 case OMPC_match: 17165 case OMPC_order: 17166 case OMPC_destroy: 17167 case OMPC_novariants: 17168 case OMPC_nocontext: 17169 case OMPC_detach: 17170 case OMPC_uses_allocators: 17171 case OMPC_when: 17172 case OMPC_bind: 17173 default: 17174 llvm_unreachable("Clause is not allowed."); 17175 } 17176 return Res; 17177 } 17178 17179 ExprResult Sema::getOpenMPCapturedExpr(VarDecl *Capture, ExprValueKind VK, 17180 ExprObjectKind OK, SourceLocation Loc) { 17181 ExprResult Res = BuildDeclRefExpr( 17182 Capture, Capture->getType().getNonReferenceType(), VK_LValue, Loc); 17183 if (!Res.isUsable()) 17184 return ExprError(); 17185 if (OK == OK_Ordinary && !getLangOpts().CPlusPlus) { 17186 Res = CreateBuiltinUnaryOp(Loc, UO_Deref, Res.get()); 17187 if (!Res.isUsable()) 17188 return ExprError(); 17189 } 17190 if (VK != VK_LValue && Res.get()->isGLValue()) { 17191 Res = DefaultLvalueConversion(Res.get()); 17192 if (!Res.isUsable()) 17193 return ExprError(); 17194 } 17195 return Res; 17196 } 17197 17198 OMPClause *Sema::ActOnOpenMPPrivateClause(ArrayRef<Expr *> VarList, 17199 SourceLocation StartLoc, 17200 SourceLocation LParenLoc, 17201 SourceLocation EndLoc) { 17202 SmallVector<Expr *, 8> Vars; 17203 SmallVector<Expr *, 8> PrivateCopies; 17204 for (Expr *RefExpr : VarList) { 17205 assert(RefExpr && "NULL expr in OpenMP private clause."); 17206 SourceLocation ELoc; 17207 SourceRange ERange; 17208 Expr *SimpleRefExpr = RefExpr; 17209 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 17210 if (Res.second) { 17211 // It will be analyzed later. 17212 Vars.push_back(RefExpr); 17213 PrivateCopies.push_back(nullptr); 17214 } 17215 ValueDecl *D = Res.first; 17216 if (!D) 17217 continue; 17218 17219 QualType Type = D->getType(); 17220 auto *VD = dyn_cast<VarDecl>(D); 17221 17222 // OpenMP [2.9.3.3, Restrictions, C/C++, p.3] 17223 // A variable that appears in a private clause must not have an incomplete 17224 // type or a reference type. 17225 if (RequireCompleteType(ELoc, Type, diag::err_omp_private_incomplete_type)) 17226 continue; 17227 Type = Type.getNonReferenceType(); 17228 17229 // OpenMP 5.0 [2.19.3, List Item Privatization, Restrictions] 17230 // A variable that is privatized must not have a const-qualified type 17231 // unless it is of class type with a mutable member. This restriction does 17232 // not apply to the firstprivate clause. 17233 // 17234 // OpenMP 3.1 [2.9.3.3, private clause, Restrictions] 17235 // A variable that appears in a private clause must not have a 17236 // const-qualified type unless it is of class type with a mutable member. 17237 if (rejectConstNotMutableType(*this, D, Type, OMPC_private, ELoc)) 17238 continue; 17239 17240 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 17241 // in a Construct] 17242 // Variables with the predetermined data-sharing attributes may not be 17243 // listed in data-sharing attributes clauses, except for the cases 17244 // listed below. For these exceptions only, listing a predetermined 17245 // variable in a data-sharing attribute clause is allowed and overrides 17246 // the variable's predetermined data-sharing attributes. 17247 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false); 17248 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_private) { 17249 Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind) 17250 << getOpenMPClauseName(OMPC_private); 17251 reportOriginalDsa(*this, DSAStack, D, DVar); 17252 continue; 17253 } 17254 17255 OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective(); 17256 // Variably modified types are not supported for tasks. 17257 if (!Type->isAnyPointerType() && Type->isVariablyModifiedType() && 17258 isOpenMPTaskingDirective(CurrDir)) { 17259 Diag(ELoc, diag::err_omp_variably_modified_type_not_supported) 17260 << getOpenMPClauseName(OMPC_private) << Type 17261 << getOpenMPDirectiveName(CurrDir); 17262 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) == 17263 VarDecl::DeclarationOnly; 17264 Diag(D->getLocation(), 17265 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 17266 << D; 17267 continue; 17268 } 17269 17270 // OpenMP 4.5 [2.15.5.1, Restrictions, p.3] 17271 // A list item cannot appear in both a map clause and a data-sharing 17272 // attribute clause on the same construct 17273 // 17274 // OpenMP 5.0 [2.19.7.1, Restrictions, p.7] 17275 // A list item cannot appear in both a map clause and a data-sharing 17276 // attribute clause on the same construct unless the construct is a 17277 // combined construct. 17278 if ((LangOpts.OpenMP <= 45 && isOpenMPTargetExecutionDirective(CurrDir)) || 17279 CurrDir == OMPD_target) { 17280 OpenMPClauseKind ConflictKind; 17281 if (DSAStack->checkMappableExprComponentListsForDecl( 17282 VD, /*CurrentRegionOnly=*/true, 17283 [&](OMPClauseMappableExprCommon::MappableExprComponentListRef, 17284 OpenMPClauseKind WhereFoundClauseKind) -> bool { 17285 ConflictKind = WhereFoundClauseKind; 17286 return true; 17287 })) { 17288 Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa) 17289 << getOpenMPClauseName(OMPC_private) 17290 << getOpenMPClauseName(ConflictKind) 17291 << getOpenMPDirectiveName(CurrDir); 17292 reportOriginalDsa(*this, DSAStack, D, DVar); 17293 continue; 17294 } 17295 } 17296 17297 // OpenMP [2.9.3.3, Restrictions, C/C++, p.1] 17298 // A variable of class type (or array thereof) that appears in a private 17299 // clause requires an accessible, unambiguous default constructor for the 17300 // class type. 17301 // Generate helper private variable and initialize it with the default 17302 // value. The address of the original variable is replaced by the address of 17303 // the new private variable in CodeGen. This new variable is not added to 17304 // IdResolver, so the code in the OpenMP region uses original variable for 17305 // proper diagnostics. 17306 Type = Type.getUnqualifiedType(); 17307 VarDecl *VDPrivate = 17308 buildVarDecl(*this, ELoc, Type, D->getName(), 17309 D->hasAttrs() ? &D->getAttrs() : nullptr, 17310 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr); 17311 ActOnUninitializedDecl(VDPrivate); 17312 if (VDPrivate->isInvalidDecl()) 17313 continue; 17314 DeclRefExpr *VDPrivateRefExpr = buildDeclRefExpr( 17315 *this, VDPrivate, RefExpr->getType().getUnqualifiedType(), ELoc); 17316 17317 DeclRefExpr *Ref = nullptr; 17318 if (!VD && !CurContext->isDependentContext()) 17319 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false); 17320 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_private, Ref); 17321 Vars.push_back((VD || CurContext->isDependentContext()) 17322 ? RefExpr->IgnoreParens() 17323 : Ref); 17324 PrivateCopies.push_back(VDPrivateRefExpr); 17325 } 17326 17327 if (Vars.empty()) 17328 return nullptr; 17329 17330 return OMPPrivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars, 17331 PrivateCopies); 17332 } 17333 17334 OMPClause *Sema::ActOnOpenMPFirstprivateClause(ArrayRef<Expr *> VarList, 17335 SourceLocation StartLoc, 17336 SourceLocation LParenLoc, 17337 SourceLocation EndLoc) { 17338 SmallVector<Expr *, 8> Vars; 17339 SmallVector<Expr *, 8> PrivateCopies; 17340 SmallVector<Expr *, 8> Inits; 17341 SmallVector<Decl *, 4> ExprCaptures; 17342 bool IsImplicitClause = 17343 StartLoc.isInvalid() && LParenLoc.isInvalid() && EndLoc.isInvalid(); 17344 SourceLocation ImplicitClauseLoc = DSAStack->getConstructLoc(); 17345 17346 for (Expr *RefExpr : VarList) { 17347 assert(RefExpr && "NULL expr in OpenMP firstprivate clause."); 17348 SourceLocation ELoc; 17349 SourceRange ERange; 17350 Expr *SimpleRefExpr = RefExpr; 17351 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 17352 if (Res.second) { 17353 // It will be analyzed later. 17354 Vars.push_back(RefExpr); 17355 PrivateCopies.push_back(nullptr); 17356 Inits.push_back(nullptr); 17357 } 17358 ValueDecl *D = Res.first; 17359 if (!D) 17360 continue; 17361 17362 ELoc = IsImplicitClause ? ImplicitClauseLoc : ELoc; 17363 QualType Type = D->getType(); 17364 auto *VD = dyn_cast<VarDecl>(D); 17365 17366 // OpenMP [2.9.3.3, Restrictions, C/C++, p.3] 17367 // A variable that appears in a private clause must not have an incomplete 17368 // type or a reference type. 17369 if (RequireCompleteType(ELoc, Type, 17370 diag::err_omp_firstprivate_incomplete_type)) 17371 continue; 17372 Type = Type.getNonReferenceType(); 17373 17374 // OpenMP [2.9.3.4, Restrictions, C/C++, p.1] 17375 // A variable of class type (or array thereof) that appears in a private 17376 // clause requires an accessible, unambiguous copy constructor for the 17377 // class type. 17378 QualType ElemType = Context.getBaseElementType(Type).getNonReferenceType(); 17379 17380 // If an implicit firstprivate variable found it was checked already. 17381 DSAStackTy::DSAVarData TopDVar; 17382 if (!IsImplicitClause) { 17383 DSAStackTy::DSAVarData DVar = 17384 DSAStack->getTopDSA(D, /*FromParent=*/false); 17385 TopDVar = DVar; 17386 OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective(); 17387 bool IsConstant = ElemType.isConstant(Context); 17388 // OpenMP [2.4.13, Data-sharing Attribute Clauses] 17389 // A list item that specifies a given variable may not appear in more 17390 // than one clause on the same directive, except that a variable may be 17391 // specified in both firstprivate and lastprivate clauses. 17392 // OpenMP 4.5 [2.10.8, Distribute Construct, p.3] 17393 // A list item may appear in a firstprivate or lastprivate clause but not 17394 // both. 17395 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_firstprivate && 17396 (isOpenMPDistributeDirective(CurrDir) || 17397 DVar.CKind != OMPC_lastprivate) && 17398 DVar.RefExpr) { 17399 Diag(ELoc, diag::err_omp_wrong_dsa) 17400 << getOpenMPClauseName(DVar.CKind) 17401 << getOpenMPClauseName(OMPC_firstprivate); 17402 reportOriginalDsa(*this, DSAStack, D, DVar); 17403 continue; 17404 } 17405 17406 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 17407 // in a Construct] 17408 // Variables with the predetermined data-sharing attributes may not be 17409 // listed in data-sharing attributes clauses, except for the cases 17410 // listed below. For these exceptions only, listing a predetermined 17411 // variable in a data-sharing attribute clause is allowed and overrides 17412 // the variable's predetermined data-sharing attributes. 17413 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 17414 // in a Construct, C/C++, p.2] 17415 // Variables with const-qualified type having no mutable member may be 17416 // listed in a firstprivate clause, even if they are static data members. 17417 if (!(IsConstant || (VD && VD->isStaticDataMember())) && !DVar.RefExpr && 17418 DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_shared) { 17419 Diag(ELoc, diag::err_omp_wrong_dsa) 17420 << getOpenMPClauseName(DVar.CKind) 17421 << getOpenMPClauseName(OMPC_firstprivate); 17422 reportOriginalDsa(*this, DSAStack, D, DVar); 17423 continue; 17424 } 17425 17426 // OpenMP [2.9.3.4, Restrictions, p.2] 17427 // A list item that is private within a parallel region must not appear 17428 // in a firstprivate clause on a worksharing construct if any of the 17429 // worksharing regions arising from the worksharing construct ever bind 17430 // to any of the parallel regions arising from the parallel construct. 17431 // OpenMP 4.5 [2.15.3.4, Restrictions, p.3] 17432 // A list item that is private within a teams region must not appear in a 17433 // firstprivate clause on a distribute construct if any of the distribute 17434 // regions arising from the distribute construct ever bind to any of the 17435 // teams regions arising from the teams construct. 17436 // OpenMP 4.5 [2.15.3.4, Restrictions, p.3] 17437 // A list item that appears in a reduction clause of a teams construct 17438 // must not appear in a firstprivate clause on a distribute construct if 17439 // any of the distribute regions arising from the distribute construct 17440 // ever bind to any of the teams regions arising from the teams construct. 17441 if ((isOpenMPWorksharingDirective(CurrDir) || 17442 isOpenMPDistributeDirective(CurrDir)) && 17443 !isOpenMPParallelDirective(CurrDir) && 17444 !isOpenMPTeamsDirective(CurrDir)) { 17445 DVar = DSAStack->getImplicitDSA(D, true); 17446 if (DVar.CKind != OMPC_shared && 17447 (isOpenMPParallelDirective(DVar.DKind) || 17448 isOpenMPTeamsDirective(DVar.DKind) || 17449 DVar.DKind == OMPD_unknown)) { 17450 Diag(ELoc, diag::err_omp_required_access) 17451 << getOpenMPClauseName(OMPC_firstprivate) 17452 << getOpenMPClauseName(OMPC_shared); 17453 reportOriginalDsa(*this, DSAStack, D, DVar); 17454 continue; 17455 } 17456 } 17457 // OpenMP [2.9.3.4, Restrictions, p.3] 17458 // A list item that appears in a reduction clause of a parallel construct 17459 // must not appear in a firstprivate clause on a worksharing or task 17460 // construct if any of the worksharing or task regions arising from the 17461 // worksharing or task construct ever bind to any of the parallel regions 17462 // arising from the parallel construct. 17463 // OpenMP [2.9.3.4, Restrictions, p.4] 17464 // A list item that appears in a reduction clause in worksharing 17465 // construct must not appear in a firstprivate clause in a task construct 17466 // encountered during execution of any of the worksharing regions arising 17467 // from the worksharing construct. 17468 if (isOpenMPTaskingDirective(CurrDir)) { 17469 DVar = DSAStack->hasInnermostDSA( 17470 D, 17471 [](OpenMPClauseKind C, bool AppliedToPointee) { 17472 return C == OMPC_reduction && !AppliedToPointee; 17473 }, 17474 [](OpenMPDirectiveKind K) { 17475 return isOpenMPParallelDirective(K) || 17476 isOpenMPWorksharingDirective(K) || 17477 isOpenMPTeamsDirective(K); 17478 }, 17479 /*FromParent=*/true); 17480 if (DVar.CKind == OMPC_reduction && 17481 (isOpenMPParallelDirective(DVar.DKind) || 17482 isOpenMPWorksharingDirective(DVar.DKind) || 17483 isOpenMPTeamsDirective(DVar.DKind))) { 17484 Diag(ELoc, diag::err_omp_parallel_reduction_in_task_firstprivate) 17485 << getOpenMPDirectiveName(DVar.DKind); 17486 reportOriginalDsa(*this, DSAStack, D, DVar); 17487 continue; 17488 } 17489 } 17490 17491 // OpenMP 4.5 [2.15.5.1, Restrictions, p.3] 17492 // A list item cannot appear in both a map clause and a data-sharing 17493 // attribute clause on the same construct 17494 // 17495 // OpenMP 5.0 [2.19.7.1, Restrictions, p.7] 17496 // A list item cannot appear in both a map clause and a data-sharing 17497 // attribute clause on the same construct unless the construct is a 17498 // combined construct. 17499 if ((LangOpts.OpenMP <= 45 && 17500 isOpenMPTargetExecutionDirective(CurrDir)) || 17501 CurrDir == OMPD_target) { 17502 OpenMPClauseKind ConflictKind; 17503 if (DSAStack->checkMappableExprComponentListsForDecl( 17504 VD, /*CurrentRegionOnly=*/true, 17505 [&ConflictKind]( 17506 OMPClauseMappableExprCommon::MappableExprComponentListRef, 17507 OpenMPClauseKind WhereFoundClauseKind) { 17508 ConflictKind = WhereFoundClauseKind; 17509 return true; 17510 })) { 17511 Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa) 17512 << getOpenMPClauseName(OMPC_firstprivate) 17513 << getOpenMPClauseName(ConflictKind) 17514 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 17515 reportOriginalDsa(*this, DSAStack, D, DVar); 17516 continue; 17517 } 17518 } 17519 } 17520 17521 // Variably modified types are not supported for tasks. 17522 if (!Type->isAnyPointerType() && Type->isVariablyModifiedType() && 17523 isOpenMPTaskingDirective(DSAStack->getCurrentDirective())) { 17524 Diag(ELoc, diag::err_omp_variably_modified_type_not_supported) 17525 << getOpenMPClauseName(OMPC_firstprivate) << Type 17526 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 17527 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) == 17528 VarDecl::DeclarationOnly; 17529 Diag(D->getLocation(), 17530 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 17531 << D; 17532 continue; 17533 } 17534 17535 Type = Type.getUnqualifiedType(); 17536 VarDecl *VDPrivate = 17537 buildVarDecl(*this, ELoc, Type, D->getName(), 17538 D->hasAttrs() ? &D->getAttrs() : nullptr, 17539 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr); 17540 // Generate helper private variable and initialize it with the value of the 17541 // original variable. The address of the original variable is replaced by 17542 // the address of the new private variable in the CodeGen. This new variable 17543 // is not added to IdResolver, so the code in the OpenMP region uses 17544 // original variable for proper diagnostics and variable capturing. 17545 Expr *VDInitRefExpr = nullptr; 17546 // For arrays generate initializer for single element and replace it by the 17547 // original array element in CodeGen. 17548 if (Type->isArrayType()) { 17549 VarDecl *VDInit = 17550 buildVarDecl(*this, RefExpr->getExprLoc(), ElemType, D->getName()); 17551 VDInitRefExpr = buildDeclRefExpr(*this, VDInit, ElemType, ELoc); 17552 Expr *Init = DefaultLvalueConversion(VDInitRefExpr).get(); 17553 ElemType = ElemType.getUnqualifiedType(); 17554 VarDecl *VDInitTemp = buildVarDecl(*this, RefExpr->getExprLoc(), ElemType, 17555 ".firstprivate.temp"); 17556 InitializedEntity Entity = 17557 InitializedEntity::InitializeVariable(VDInitTemp); 17558 InitializationKind Kind = InitializationKind::CreateCopy(ELoc, ELoc); 17559 17560 InitializationSequence InitSeq(*this, Entity, Kind, Init); 17561 ExprResult Result = InitSeq.Perform(*this, Entity, Kind, Init); 17562 if (Result.isInvalid()) 17563 VDPrivate->setInvalidDecl(); 17564 else 17565 VDPrivate->setInit(Result.getAs<Expr>()); 17566 // Remove temp variable declaration. 17567 Context.Deallocate(VDInitTemp); 17568 } else { 17569 VarDecl *VDInit = buildVarDecl(*this, RefExpr->getExprLoc(), Type, 17570 ".firstprivate.temp"); 17571 VDInitRefExpr = buildDeclRefExpr(*this, VDInit, RefExpr->getType(), 17572 RefExpr->getExprLoc()); 17573 AddInitializerToDecl(VDPrivate, 17574 DefaultLvalueConversion(VDInitRefExpr).get(), 17575 /*DirectInit=*/false); 17576 } 17577 if (VDPrivate->isInvalidDecl()) { 17578 if (IsImplicitClause) { 17579 Diag(RefExpr->getExprLoc(), 17580 diag::note_omp_task_predetermined_firstprivate_here); 17581 } 17582 continue; 17583 } 17584 CurContext->addDecl(VDPrivate); 17585 DeclRefExpr *VDPrivateRefExpr = buildDeclRefExpr( 17586 *this, VDPrivate, RefExpr->getType().getUnqualifiedType(), 17587 RefExpr->getExprLoc()); 17588 DeclRefExpr *Ref = nullptr; 17589 if (!VD && !CurContext->isDependentContext()) { 17590 if (TopDVar.CKind == OMPC_lastprivate) { 17591 Ref = TopDVar.PrivateCopy; 17592 } else { 17593 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true); 17594 if (!isOpenMPCapturedDecl(D)) 17595 ExprCaptures.push_back(Ref->getDecl()); 17596 } 17597 } 17598 if (!IsImplicitClause) 17599 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_firstprivate, Ref); 17600 Vars.push_back((VD || CurContext->isDependentContext()) 17601 ? RefExpr->IgnoreParens() 17602 : Ref); 17603 PrivateCopies.push_back(VDPrivateRefExpr); 17604 Inits.push_back(VDInitRefExpr); 17605 } 17606 17607 if (Vars.empty()) 17608 return nullptr; 17609 17610 return OMPFirstprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, 17611 Vars, PrivateCopies, Inits, 17612 buildPreInits(Context, ExprCaptures)); 17613 } 17614 17615 OMPClause *Sema::ActOnOpenMPLastprivateClause( 17616 ArrayRef<Expr *> VarList, OpenMPLastprivateModifier LPKind, 17617 SourceLocation LPKindLoc, SourceLocation ColonLoc, SourceLocation StartLoc, 17618 SourceLocation LParenLoc, SourceLocation EndLoc) { 17619 if (LPKind == OMPC_LASTPRIVATE_unknown && LPKindLoc.isValid()) { 17620 assert(ColonLoc.isValid() && "Colon location must be valid."); 17621 Diag(LPKindLoc, diag::err_omp_unexpected_clause_value) 17622 << getListOfPossibleValues(OMPC_lastprivate, /*First=*/0, 17623 /*Last=*/OMPC_LASTPRIVATE_unknown) 17624 << getOpenMPClauseName(OMPC_lastprivate); 17625 return nullptr; 17626 } 17627 17628 SmallVector<Expr *, 8> Vars; 17629 SmallVector<Expr *, 8> SrcExprs; 17630 SmallVector<Expr *, 8> DstExprs; 17631 SmallVector<Expr *, 8> AssignmentOps; 17632 SmallVector<Decl *, 4> ExprCaptures; 17633 SmallVector<Expr *, 4> ExprPostUpdates; 17634 for (Expr *RefExpr : VarList) { 17635 assert(RefExpr && "NULL expr in OpenMP lastprivate clause."); 17636 SourceLocation ELoc; 17637 SourceRange ERange; 17638 Expr *SimpleRefExpr = RefExpr; 17639 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 17640 if (Res.second) { 17641 // It will be analyzed later. 17642 Vars.push_back(RefExpr); 17643 SrcExprs.push_back(nullptr); 17644 DstExprs.push_back(nullptr); 17645 AssignmentOps.push_back(nullptr); 17646 } 17647 ValueDecl *D = Res.first; 17648 if (!D) 17649 continue; 17650 17651 QualType Type = D->getType(); 17652 auto *VD = dyn_cast<VarDecl>(D); 17653 17654 // OpenMP [2.14.3.5, Restrictions, C/C++, p.2] 17655 // A variable that appears in a lastprivate clause must not have an 17656 // incomplete type or a reference type. 17657 if (RequireCompleteType(ELoc, Type, 17658 diag::err_omp_lastprivate_incomplete_type)) 17659 continue; 17660 Type = Type.getNonReferenceType(); 17661 17662 // OpenMP 5.0 [2.19.3, List Item Privatization, Restrictions] 17663 // A variable that is privatized must not have a const-qualified type 17664 // unless it is of class type with a mutable member. This restriction does 17665 // not apply to the firstprivate clause. 17666 // 17667 // OpenMP 3.1 [2.9.3.5, lastprivate clause, Restrictions] 17668 // A variable that appears in a lastprivate clause must not have a 17669 // const-qualified type unless it is of class type with a mutable member. 17670 if (rejectConstNotMutableType(*this, D, Type, OMPC_lastprivate, ELoc)) 17671 continue; 17672 17673 // OpenMP 5.0 [2.19.4.5 lastprivate Clause, Restrictions] 17674 // A list item that appears in a lastprivate clause with the conditional 17675 // modifier must be a scalar variable. 17676 if (LPKind == OMPC_LASTPRIVATE_conditional && !Type->isScalarType()) { 17677 Diag(ELoc, diag::err_omp_lastprivate_conditional_non_scalar); 17678 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) == 17679 VarDecl::DeclarationOnly; 17680 Diag(D->getLocation(), 17681 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 17682 << D; 17683 continue; 17684 } 17685 17686 OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective(); 17687 // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables Referenced 17688 // in a Construct] 17689 // Variables with the predetermined data-sharing attributes may not be 17690 // listed in data-sharing attributes clauses, except for the cases 17691 // listed below. 17692 // OpenMP 4.5 [2.10.8, Distribute Construct, p.3] 17693 // A list item may appear in a firstprivate or lastprivate clause but not 17694 // both. 17695 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false); 17696 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_lastprivate && 17697 (isOpenMPDistributeDirective(CurrDir) || 17698 DVar.CKind != OMPC_firstprivate) && 17699 (DVar.CKind != OMPC_private || DVar.RefExpr != nullptr)) { 17700 Diag(ELoc, diag::err_omp_wrong_dsa) 17701 << getOpenMPClauseName(DVar.CKind) 17702 << getOpenMPClauseName(OMPC_lastprivate); 17703 reportOriginalDsa(*this, DSAStack, D, DVar); 17704 continue; 17705 } 17706 17707 // OpenMP [2.14.3.5, Restrictions, p.2] 17708 // A list item that is private within a parallel region, or that appears in 17709 // the reduction clause of a parallel construct, must not appear in a 17710 // lastprivate clause on a worksharing construct if any of the corresponding 17711 // worksharing regions ever binds to any of the corresponding parallel 17712 // regions. 17713 DSAStackTy::DSAVarData TopDVar = DVar; 17714 if (isOpenMPWorksharingDirective(CurrDir) && 17715 !isOpenMPParallelDirective(CurrDir) && 17716 !isOpenMPTeamsDirective(CurrDir)) { 17717 DVar = DSAStack->getImplicitDSA(D, true); 17718 if (DVar.CKind != OMPC_shared) { 17719 Diag(ELoc, diag::err_omp_required_access) 17720 << getOpenMPClauseName(OMPC_lastprivate) 17721 << getOpenMPClauseName(OMPC_shared); 17722 reportOriginalDsa(*this, DSAStack, D, DVar); 17723 continue; 17724 } 17725 } 17726 17727 // OpenMP [2.14.3.5, Restrictions, C++, p.1,2] 17728 // A variable of class type (or array thereof) that appears in a 17729 // lastprivate clause requires an accessible, unambiguous default 17730 // constructor for the class type, unless the list item is also specified 17731 // in a firstprivate clause. 17732 // A variable of class type (or array thereof) that appears in a 17733 // lastprivate clause requires an accessible, unambiguous copy assignment 17734 // operator for the class type. 17735 Type = Context.getBaseElementType(Type).getNonReferenceType(); 17736 VarDecl *SrcVD = buildVarDecl(*this, ERange.getBegin(), 17737 Type.getUnqualifiedType(), ".lastprivate.src", 17738 D->hasAttrs() ? &D->getAttrs() : nullptr); 17739 DeclRefExpr *PseudoSrcExpr = 17740 buildDeclRefExpr(*this, SrcVD, Type.getUnqualifiedType(), ELoc); 17741 VarDecl *DstVD = 17742 buildVarDecl(*this, ERange.getBegin(), Type, ".lastprivate.dst", 17743 D->hasAttrs() ? &D->getAttrs() : nullptr); 17744 DeclRefExpr *PseudoDstExpr = buildDeclRefExpr(*this, DstVD, Type, ELoc); 17745 // For arrays generate assignment operation for single element and replace 17746 // it by the original array element in CodeGen. 17747 ExprResult AssignmentOp = BuildBinOp(/*S=*/nullptr, ELoc, BO_Assign, 17748 PseudoDstExpr, PseudoSrcExpr); 17749 if (AssignmentOp.isInvalid()) 17750 continue; 17751 AssignmentOp = 17752 ActOnFinishFullExpr(AssignmentOp.get(), ELoc, /*DiscardedValue*/ false); 17753 if (AssignmentOp.isInvalid()) 17754 continue; 17755 17756 DeclRefExpr *Ref = nullptr; 17757 if (!VD && !CurContext->isDependentContext()) { 17758 if (TopDVar.CKind == OMPC_firstprivate) { 17759 Ref = TopDVar.PrivateCopy; 17760 } else { 17761 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false); 17762 if (!isOpenMPCapturedDecl(D)) 17763 ExprCaptures.push_back(Ref->getDecl()); 17764 } 17765 if ((TopDVar.CKind == OMPC_firstprivate && !TopDVar.PrivateCopy) || 17766 (!isOpenMPCapturedDecl(D) && 17767 Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>())) { 17768 ExprResult RefRes = DefaultLvalueConversion(Ref); 17769 if (!RefRes.isUsable()) 17770 continue; 17771 ExprResult PostUpdateRes = 17772 BuildBinOp(DSAStack->getCurScope(), ELoc, BO_Assign, SimpleRefExpr, 17773 RefRes.get()); 17774 if (!PostUpdateRes.isUsable()) 17775 continue; 17776 ExprPostUpdates.push_back( 17777 IgnoredValueConversions(PostUpdateRes.get()).get()); 17778 } 17779 } 17780 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_lastprivate, Ref); 17781 Vars.push_back((VD || CurContext->isDependentContext()) 17782 ? RefExpr->IgnoreParens() 17783 : Ref); 17784 SrcExprs.push_back(PseudoSrcExpr); 17785 DstExprs.push_back(PseudoDstExpr); 17786 AssignmentOps.push_back(AssignmentOp.get()); 17787 } 17788 17789 if (Vars.empty()) 17790 return nullptr; 17791 17792 return OMPLastprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, 17793 Vars, SrcExprs, DstExprs, AssignmentOps, 17794 LPKind, LPKindLoc, ColonLoc, 17795 buildPreInits(Context, ExprCaptures), 17796 buildPostUpdate(*this, ExprPostUpdates)); 17797 } 17798 17799 OMPClause *Sema::ActOnOpenMPSharedClause(ArrayRef<Expr *> VarList, 17800 SourceLocation StartLoc, 17801 SourceLocation LParenLoc, 17802 SourceLocation EndLoc) { 17803 SmallVector<Expr *, 8> Vars; 17804 for (Expr *RefExpr : VarList) { 17805 assert(RefExpr && "NULL expr in OpenMP lastprivate clause."); 17806 SourceLocation ELoc; 17807 SourceRange ERange; 17808 Expr *SimpleRefExpr = RefExpr; 17809 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 17810 if (Res.second) { 17811 // It will be analyzed later. 17812 Vars.push_back(RefExpr); 17813 } 17814 ValueDecl *D = Res.first; 17815 if (!D) 17816 continue; 17817 17818 auto *VD = dyn_cast<VarDecl>(D); 17819 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 17820 // in a Construct] 17821 // Variables with the predetermined data-sharing attributes may not be 17822 // listed in data-sharing attributes clauses, except for the cases 17823 // listed below. For these exceptions only, listing a predetermined 17824 // variable in a data-sharing attribute clause is allowed and overrides 17825 // the variable's predetermined data-sharing attributes. 17826 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false); 17827 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_shared && 17828 DVar.RefExpr) { 17829 Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind) 17830 << getOpenMPClauseName(OMPC_shared); 17831 reportOriginalDsa(*this, DSAStack, D, DVar); 17832 continue; 17833 } 17834 17835 DeclRefExpr *Ref = nullptr; 17836 if (!VD && isOpenMPCapturedDecl(D) && !CurContext->isDependentContext()) 17837 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true); 17838 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_shared, Ref); 17839 Vars.push_back((VD || !Ref || CurContext->isDependentContext()) 17840 ? RefExpr->IgnoreParens() 17841 : Ref); 17842 } 17843 17844 if (Vars.empty()) 17845 return nullptr; 17846 17847 return OMPSharedClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars); 17848 } 17849 17850 namespace { 17851 class DSARefChecker : public StmtVisitor<DSARefChecker, bool> { 17852 DSAStackTy *Stack; 17853 17854 public: 17855 bool VisitDeclRefExpr(DeclRefExpr *E) { 17856 if (auto *VD = dyn_cast<VarDecl>(E->getDecl())) { 17857 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(VD, /*FromParent=*/false); 17858 if (DVar.CKind == OMPC_shared && !DVar.RefExpr) 17859 return false; 17860 if (DVar.CKind != OMPC_unknown) 17861 return true; 17862 DSAStackTy::DSAVarData DVarPrivate = Stack->hasDSA( 17863 VD, 17864 [](OpenMPClauseKind C, bool AppliedToPointee) { 17865 return isOpenMPPrivate(C) && !AppliedToPointee; 17866 }, 17867 [](OpenMPDirectiveKind) { return true; }, 17868 /*FromParent=*/true); 17869 return DVarPrivate.CKind != OMPC_unknown; 17870 } 17871 return false; 17872 } 17873 bool VisitStmt(Stmt *S) { 17874 for (Stmt *Child : S->children()) { 17875 if (Child && Visit(Child)) 17876 return true; 17877 } 17878 return false; 17879 } 17880 explicit DSARefChecker(DSAStackTy *S) : Stack(S) {} 17881 }; 17882 } // namespace 17883 17884 namespace { 17885 // Transform MemberExpression for specified FieldDecl of current class to 17886 // DeclRefExpr to specified OMPCapturedExprDecl. 17887 class TransformExprToCaptures : public TreeTransform<TransformExprToCaptures> { 17888 typedef TreeTransform<TransformExprToCaptures> BaseTransform; 17889 ValueDecl *Field = nullptr; 17890 DeclRefExpr *CapturedExpr = nullptr; 17891 17892 public: 17893 TransformExprToCaptures(Sema &SemaRef, ValueDecl *FieldDecl) 17894 : BaseTransform(SemaRef), Field(FieldDecl), CapturedExpr(nullptr) {} 17895 17896 ExprResult TransformMemberExpr(MemberExpr *E) { 17897 if (isa<CXXThisExpr>(E->getBase()->IgnoreParenImpCasts()) && 17898 E->getMemberDecl() == Field) { 17899 CapturedExpr = buildCapture(SemaRef, Field, E, /*WithInit=*/false); 17900 return CapturedExpr; 17901 } 17902 return BaseTransform::TransformMemberExpr(E); 17903 } 17904 DeclRefExpr *getCapturedExpr() { return CapturedExpr; } 17905 }; 17906 } // namespace 17907 17908 template <typename T, typename U> 17909 static T filterLookupForUDReductionAndMapper( 17910 SmallVectorImpl<U> &Lookups, const llvm::function_ref<T(ValueDecl *)> Gen) { 17911 for (U &Set : Lookups) { 17912 for (auto *D : Set) { 17913 if (T Res = Gen(cast<ValueDecl>(D))) 17914 return Res; 17915 } 17916 } 17917 return T(); 17918 } 17919 17920 static NamedDecl *findAcceptableDecl(Sema &SemaRef, NamedDecl *D) { 17921 assert(!LookupResult::isVisible(SemaRef, D) && "not in slow case"); 17922 17923 for (auto RD : D->redecls()) { 17924 // Don't bother with extra checks if we already know this one isn't visible. 17925 if (RD == D) 17926 continue; 17927 17928 auto ND = cast<NamedDecl>(RD); 17929 if (LookupResult::isVisible(SemaRef, ND)) 17930 return ND; 17931 } 17932 17933 return nullptr; 17934 } 17935 17936 static void 17937 argumentDependentLookup(Sema &SemaRef, const DeclarationNameInfo &Id, 17938 SourceLocation Loc, QualType Ty, 17939 SmallVectorImpl<UnresolvedSet<8>> &Lookups) { 17940 // Find all of the associated namespaces and classes based on the 17941 // arguments we have. 17942 Sema::AssociatedNamespaceSet AssociatedNamespaces; 17943 Sema::AssociatedClassSet AssociatedClasses; 17944 OpaqueValueExpr OVE(Loc, Ty, VK_LValue); 17945 SemaRef.FindAssociatedClassesAndNamespaces(Loc, &OVE, AssociatedNamespaces, 17946 AssociatedClasses); 17947 17948 // C++ [basic.lookup.argdep]p3: 17949 // Let X be the lookup set produced by unqualified lookup (3.4.1) 17950 // and let Y be the lookup set produced by argument dependent 17951 // lookup (defined as follows). If X contains [...] then Y is 17952 // empty. Otherwise Y is the set of declarations found in the 17953 // namespaces associated with the argument types as described 17954 // below. The set of declarations found by the lookup of the name 17955 // is the union of X and Y. 17956 // 17957 // Here, we compute Y and add its members to the overloaded 17958 // candidate set. 17959 for (auto *NS : AssociatedNamespaces) { 17960 // When considering an associated namespace, the lookup is the 17961 // same as the lookup performed when the associated namespace is 17962 // used as a qualifier (3.4.3.2) except that: 17963 // 17964 // -- Any using-directives in the associated namespace are 17965 // ignored. 17966 // 17967 // -- Any namespace-scope friend functions declared in 17968 // associated classes are visible within their respective 17969 // namespaces even if they are not visible during an ordinary 17970 // lookup (11.4). 17971 DeclContext::lookup_result R = NS->lookup(Id.getName()); 17972 for (auto *D : R) { 17973 auto *Underlying = D; 17974 if (auto *USD = dyn_cast<UsingShadowDecl>(D)) 17975 Underlying = USD->getTargetDecl(); 17976 17977 if (!isa<OMPDeclareReductionDecl>(Underlying) && 17978 !isa<OMPDeclareMapperDecl>(Underlying)) 17979 continue; 17980 17981 if (!SemaRef.isVisible(D)) { 17982 D = findAcceptableDecl(SemaRef, D); 17983 if (!D) 17984 continue; 17985 if (auto *USD = dyn_cast<UsingShadowDecl>(D)) 17986 Underlying = USD->getTargetDecl(); 17987 } 17988 Lookups.emplace_back(); 17989 Lookups.back().addDecl(Underlying); 17990 } 17991 } 17992 } 17993 17994 static ExprResult 17995 buildDeclareReductionRef(Sema &SemaRef, SourceLocation Loc, SourceRange Range, 17996 Scope *S, CXXScopeSpec &ReductionIdScopeSpec, 17997 const DeclarationNameInfo &ReductionId, QualType Ty, 17998 CXXCastPath &BasePath, Expr *UnresolvedReduction) { 17999 if (ReductionIdScopeSpec.isInvalid()) 18000 return ExprError(); 18001 SmallVector<UnresolvedSet<8>, 4> Lookups; 18002 if (S) { 18003 LookupResult Lookup(SemaRef, ReductionId, Sema::LookupOMPReductionName); 18004 Lookup.suppressDiagnostics(); 18005 while (S && SemaRef.LookupParsedName(Lookup, S, &ReductionIdScopeSpec)) { 18006 NamedDecl *D = Lookup.getRepresentativeDecl(); 18007 do { 18008 S = S->getParent(); 18009 } while (S && !S->isDeclScope(D)); 18010 if (S) 18011 S = S->getParent(); 18012 Lookups.emplace_back(); 18013 Lookups.back().append(Lookup.begin(), Lookup.end()); 18014 Lookup.clear(); 18015 } 18016 } else if (auto *ULE = 18017 cast_or_null<UnresolvedLookupExpr>(UnresolvedReduction)) { 18018 Lookups.push_back(UnresolvedSet<8>()); 18019 Decl *PrevD = nullptr; 18020 for (NamedDecl *D : ULE->decls()) { 18021 if (D == PrevD) 18022 Lookups.push_back(UnresolvedSet<8>()); 18023 else if (auto *DRD = dyn_cast<OMPDeclareReductionDecl>(D)) 18024 Lookups.back().addDecl(DRD); 18025 PrevD = D; 18026 } 18027 } 18028 if (SemaRef.CurContext->isDependentContext() || Ty->isDependentType() || 18029 Ty->isInstantiationDependentType() || 18030 Ty->containsUnexpandedParameterPack() || 18031 filterLookupForUDReductionAndMapper<bool>(Lookups, [](ValueDecl *D) { 18032 return !D->isInvalidDecl() && 18033 (D->getType()->isDependentType() || 18034 D->getType()->isInstantiationDependentType() || 18035 D->getType()->containsUnexpandedParameterPack()); 18036 })) { 18037 UnresolvedSet<8> ResSet; 18038 for (const UnresolvedSet<8> &Set : Lookups) { 18039 if (Set.empty()) 18040 continue; 18041 ResSet.append(Set.begin(), Set.end()); 18042 // The last item marks the end of all declarations at the specified scope. 18043 ResSet.addDecl(Set[Set.size() - 1]); 18044 } 18045 return UnresolvedLookupExpr::Create( 18046 SemaRef.Context, /*NamingClass=*/nullptr, 18047 ReductionIdScopeSpec.getWithLocInContext(SemaRef.Context), ReductionId, 18048 /*ADL=*/true, /*Overloaded=*/true, ResSet.begin(), ResSet.end()); 18049 } 18050 // Lookup inside the classes. 18051 // C++ [over.match.oper]p3: 18052 // For a unary operator @ with an operand of a type whose 18053 // cv-unqualified version is T1, and for a binary operator @ with 18054 // a left operand of a type whose cv-unqualified version is T1 and 18055 // a right operand of a type whose cv-unqualified version is T2, 18056 // three sets of candidate functions, designated member 18057 // candidates, non-member candidates and built-in candidates, are 18058 // constructed as follows: 18059 // -- If T1 is a complete class type or a class currently being 18060 // defined, the set of member candidates is the result of the 18061 // qualified lookup of T1::operator@ (13.3.1.1.1); otherwise, 18062 // the set of member candidates is empty. 18063 LookupResult Lookup(SemaRef, ReductionId, Sema::LookupOMPReductionName); 18064 Lookup.suppressDiagnostics(); 18065 if (const auto *TyRec = Ty->getAs<RecordType>()) { 18066 // Complete the type if it can be completed. 18067 // If the type is neither complete nor being defined, bail out now. 18068 if (SemaRef.isCompleteType(Loc, Ty) || TyRec->isBeingDefined() || 18069 TyRec->getDecl()->getDefinition()) { 18070 Lookup.clear(); 18071 SemaRef.LookupQualifiedName(Lookup, TyRec->getDecl()); 18072 if (Lookup.empty()) { 18073 Lookups.emplace_back(); 18074 Lookups.back().append(Lookup.begin(), Lookup.end()); 18075 } 18076 } 18077 } 18078 // Perform ADL. 18079 if (SemaRef.getLangOpts().CPlusPlus) 18080 argumentDependentLookup(SemaRef, ReductionId, Loc, Ty, Lookups); 18081 if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>( 18082 Lookups, [&SemaRef, Ty](ValueDecl *D) -> ValueDecl * { 18083 if (!D->isInvalidDecl() && 18084 SemaRef.Context.hasSameType(D->getType(), Ty)) 18085 return D; 18086 return nullptr; 18087 })) 18088 return SemaRef.BuildDeclRefExpr(VD, VD->getType().getNonReferenceType(), 18089 VK_LValue, Loc); 18090 if (SemaRef.getLangOpts().CPlusPlus) { 18091 if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>( 18092 Lookups, [&SemaRef, Ty, Loc](ValueDecl *D) -> ValueDecl * { 18093 if (!D->isInvalidDecl() && 18094 SemaRef.IsDerivedFrom(Loc, Ty, D->getType()) && 18095 !Ty.isMoreQualifiedThan(D->getType())) 18096 return D; 18097 return nullptr; 18098 })) { 18099 CXXBasePaths Paths(/*FindAmbiguities=*/true, /*RecordPaths=*/true, 18100 /*DetectVirtual=*/false); 18101 if (SemaRef.IsDerivedFrom(Loc, Ty, VD->getType(), Paths)) { 18102 if (!Paths.isAmbiguous(SemaRef.Context.getCanonicalType( 18103 VD->getType().getUnqualifiedType()))) { 18104 if (SemaRef.CheckBaseClassAccess( 18105 Loc, VD->getType(), Ty, Paths.front(), 18106 /*DiagID=*/0) != Sema::AR_inaccessible) { 18107 SemaRef.BuildBasePathArray(Paths, BasePath); 18108 return SemaRef.BuildDeclRefExpr( 18109 VD, VD->getType().getNonReferenceType(), VK_LValue, Loc); 18110 } 18111 } 18112 } 18113 } 18114 } 18115 if (ReductionIdScopeSpec.isSet()) { 18116 SemaRef.Diag(Loc, diag::err_omp_not_resolved_reduction_identifier) 18117 << Ty << Range; 18118 return ExprError(); 18119 } 18120 return ExprEmpty(); 18121 } 18122 18123 namespace { 18124 /// Data for the reduction-based clauses. 18125 struct ReductionData { 18126 /// List of original reduction items. 18127 SmallVector<Expr *, 8> Vars; 18128 /// List of private copies of the reduction items. 18129 SmallVector<Expr *, 8> Privates; 18130 /// LHS expressions for the reduction_op expressions. 18131 SmallVector<Expr *, 8> LHSs; 18132 /// RHS expressions for the reduction_op expressions. 18133 SmallVector<Expr *, 8> RHSs; 18134 /// Reduction operation expression. 18135 SmallVector<Expr *, 8> ReductionOps; 18136 /// inscan copy operation expressions. 18137 SmallVector<Expr *, 8> InscanCopyOps; 18138 /// inscan copy temp array expressions for prefix sums. 18139 SmallVector<Expr *, 8> InscanCopyArrayTemps; 18140 /// inscan copy temp array element expressions for prefix sums. 18141 SmallVector<Expr *, 8> InscanCopyArrayElems; 18142 /// Taskgroup descriptors for the corresponding reduction items in 18143 /// in_reduction clauses. 18144 SmallVector<Expr *, 8> TaskgroupDescriptors; 18145 /// List of captures for clause. 18146 SmallVector<Decl *, 4> ExprCaptures; 18147 /// List of postupdate expressions. 18148 SmallVector<Expr *, 4> ExprPostUpdates; 18149 /// Reduction modifier. 18150 unsigned RedModifier = 0; 18151 ReductionData() = delete; 18152 /// Reserves required memory for the reduction data. 18153 ReductionData(unsigned Size, unsigned Modifier = 0) : RedModifier(Modifier) { 18154 Vars.reserve(Size); 18155 Privates.reserve(Size); 18156 LHSs.reserve(Size); 18157 RHSs.reserve(Size); 18158 ReductionOps.reserve(Size); 18159 if (RedModifier == OMPC_REDUCTION_inscan) { 18160 InscanCopyOps.reserve(Size); 18161 InscanCopyArrayTemps.reserve(Size); 18162 InscanCopyArrayElems.reserve(Size); 18163 } 18164 TaskgroupDescriptors.reserve(Size); 18165 ExprCaptures.reserve(Size); 18166 ExprPostUpdates.reserve(Size); 18167 } 18168 /// Stores reduction item and reduction operation only (required for dependent 18169 /// reduction item). 18170 void push(Expr *Item, Expr *ReductionOp) { 18171 Vars.emplace_back(Item); 18172 Privates.emplace_back(nullptr); 18173 LHSs.emplace_back(nullptr); 18174 RHSs.emplace_back(nullptr); 18175 ReductionOps.emplace_back(ReductionOp); 18176 TaskgroupDescriptors.emplace_back(nullptr); 18177 if (RedModifier == OMPC_REDUCTION_inscan) { 18178 InscanCopyOps.push_back(nullptr); 18179 InscanCopyArrayTemps.push_back(nullptr); 18180 InscanCopyArrayElems.push_back(nullptr); 18181 } 18182 } 18183 /// Stores reduction data. 18184 void push(Expr *Item, Expr *Private, Expr *LHS, Expr *RHS, Expr *ReductionOp, 18185 Expr *TaskgroupDescriptor, Expr *CopyOp, Expr *CopyArrayTemp, 18186 Expr *CopyArrayElem) { 18187 Vars.emplace_back(Item); 18188 Privates.emplace_back(Private); 18189 LHSs.emplace_back(LHS); 18190 RHSs.emplace_back(RHS); 18191 ReductionOps.emplace_back(ReductionOp); 18192 TaskgroupDescriptors.emplace_back(TaskgroupDescriptor); 18193 if (RedModifier == OMPC_REDUCTION_inscan) { 18194 InscanCopyOps.push_back(CopyOp); 18195 InscanCopyArrayTemps.push_back(CopyArrayTemp); 18196 InscanCopyArrayElems.push_back(CopyArrayElem); 18197 } else { 18198 assert(CopyOp == nullptr && CopyArrayTemp == nullptr && 18199 CopyArrayElem == nullptr && 18200 "Copy operation must be used for inscan reductions only."); 18201 } 18202 } 18203 }; 18204 } // namespace 18205 18206 static bool checkOMPArraySectionConstantForReduction( 18207 ASTContext &Context, const OMPArraySectionExpr *OASE, bool &SingleElement, 18208 SmallVectorImpl<llvm::APSInt> &ArraySizes) { 18209 const Expr *Length = OASE->getLength(); 18210 if (Length == nullptr) { 18211 // For array sections of the form [1:] or [:], we would need to analyze 18212 // the lower bound... 18213 if (OASE->getColonLocFirst().isValid()) 18214 return false; 18215 18216 // This is an array subscript which has implicit length 1! 18217 SingleElement = true; 18218 ArraySizes.push_back(llvm::APSInt::get(1)); 18219 } else { 18220 Expr::EvalResult Result; 18221 if (!Length->EvaluateAsInt(Result, Context)) 18222 return false; 18223 18224 llvm::APSInt ConstantLengthValue = Result.Val.getInt(); 18225 SingleElement = (ConstantLengthValue.getSExtValue() == 1); 18226 ArraySizes.push_back(ConstantLengthValue); 18227 } 18228 18229 // Get the base of this array section and walk up from there. 18230 const Expr *Base = OASE->getBase()->IgnoreParenImpCasts(); 18231 18232 // We require length = 1 for all array sections except the right-most to 18233 // guarantee that the memory region is contiguous and has no holes in it. 18234 while (const auto *TempOASE = dyn_cast<OMPArraySectionExpr>(Base)) { 18235 Length = TempOASE->getLength(); 18236 if (Length == nullptr) { 18237 // For array sections of the form [1:] or [:], we would need to analyze 18238 // the lower bound... 18239 if (OASE->getColonLocFirst().isValid()) 18240 return false; 18241 18242 // This is an array subscript which has implicit length 1! 18243 ArraySizes.push_back(llvm::APSInt::get(1)); 18244 } else { 18245 Expr::EvalResult Result; 18246 if (!Length->EvaluateAsInt(Result, Context)) 18247 return false; 18248 18249 llvm::APSInt ConstantLengthValue = Result.Val.getInt(); 18250 if (ConstantLengthValue.getSExtValue() != 1) 18251 return false; 18252 18253 ArraySizes.push_back(ConstantLengthValue); 18254 } 18255 Base = TempOASE->getBase()->IgnoreParenImpCasts(); 18256 } 18257 18258 // If we have a single element, we don't need to add the implicit lengths. 18259 if (!SingleElement) { 18260 while (const auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base)) { 18261 // Has implicit length 1! 18262 ArraySizes.push_back(llvm::APSInt::get(1)); 18263 Base = TempASE->getBase()->IgnoreParenImpCasts(); 18264 } 18265 } 18266 18267 // This array section can be privatized as a single value or as a constant 18268 // sized array. 18269 return true; 18270 } 18271 18272 static BinaryOperatorKind 18273 getRelatedCompoundReductionOp(BinaryOperatorKind BOK) { 18274 if (BOK == BO_Add) 18275 return BO_AddAssign; 18276 if (BOK == BO_Mul) 18277 return BO_MulAssign; 18278 if (BOK == BO_And) 18279 return BO_AndAssign; 18280 if (BOK == BO_Or) 18281 return BO_OrAssign; 18282 if (BOK == BO_Xor) 18283 return BO_XorAssign; 18284 return BOK; 18285 } 18286 18287 static bool actOnOMPReductionKindClause( 18288 Sema &S, DSAStackTy *Stack, OpenMPClauseKind ClauseKind, 18289 ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, 18290 SourceLocation ColonLoc, SourceLocation EndLoc, 18291 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, 18292 ArrayRef<Expr *> UnresolvedReductions, ReductionData &RD) { 18293 DeclarationName DN = ReductionId.getName(); 18294 OverloadedOperatorKind OOK = DN.getCXXOverloadedOperator(); 18295 BinaryOperatorKind BOK = BO_Comma; 18296 18297 ASTContext &Context = S.Context; 18298 // OpenMP [2.14.3.6, reduction clause] 18299 // C 18300 // reduction-identifier is either an identifier or one of the following 18301 // operators: +, -, *, &, |, ^, && and || 18302 // C++ 18303 // reduction-identifier is either an id-expression or one of the following 18304 // operators: +, -, *, &, |, ^, && and || 18305 switch (OOK) { 18306 case OO_Plus: 18307 case OO_Minus: 18308 BOK = BO_Add; 18309 break; 18310 case OO_Star: 18311 BOK = BO_Mul; 18312 break; 18313 case OO_Amp: 18314 BOK = BO_And; 18315 break; 18316 case OO_Pipe: 18317 BOK = BO_Or; 18318 break; 18319 case OO_Caret: 18320 BOK = BO_Xor; 18321 break; 18322 case OO_AmpAmp: 18323 BOK = BO_LAnd; 18324 break; 18325 case OO_PipePipe: 18326 BOK = BO_LOr; 18327 break; 18328 case OO_New: 18329 case OO_Delete: 18330 case OO_Array_New: 18331 case OO_Array_Delete: 18332 case OO_Slash: 18333 case OO_Percent: 18334 case OO_Tilde: 18335 case OO_Exclaim: 18336 case OO_Equal: 18337 case OO_Less: 18338 case OO_Greater: 18339 case OO_LessEqual: 18340 case OO_GreaterEqual: 18341 case OO_PlusEqual: 18342 case OO_MinusEqual: 18343 case OO_StarEqual: 18344 case OO_SlashEqual: 18345 case OO_PercentEqual: 18346 case OO_CaretEqual: 18347 case OO_AmpEqual: 18348 case OO_PipeEqual: 18349 case OO_LessLess: 18350 case OO_GreaterGreater: 18351 case OO_LessLessEqual: 18352 case OO_GreaterGreaterEqual: 18353 case OO_EqualEqual: 18354 case OO_ExclaimEqual: 18355 case OO_Spaceship: 18356 case OO_PlusPlus: 18357 case OO_MinusMinus: 18358 case OO_Comma: 18359 case OO_ArrowStar: 18360 case OO_Arrow: 18361 case OO_Call: 18362 case OO_Subscript: 18363 case OO_Conditional: 18364 case OO_Coawait: 18365 case NUM_OVERLOADED_OPERATORS: 18366 llvm_unreachable("Unexpected reduction identifier"); 18367 case OO_None: 18368 if (IdentifierInfo *II = DN.getAsIdentifierInfo()) { 18369 if (II->isStr("max")) 18370 BOK = BO_GT; 18371 else if (II->isStr("min")) 18372 BOK = BO_LT; 18373 } 18374 break; 18375 } 18376 SourceRange ReductionIdRange; 18377 if (ReductionIdScopeSpec.isValid()) 18378 ReductionIdRange.setBegin(ReductionIdScopeSpec.getBeginLoc()); 18379 else 18380 ReductionIdRange.setBegin(ReductionId.getBeginLoc()); 18381 ReductionIdRange.setEnd(ReductionId.getEndLoc()); 18382 18383 auto IR = UnresolvedReductions.begin(), ER = UnresolvedReductions.end(); 18384 bool FirstIter = true; 18385 for (Expr *RefExpr : VarList) { 18386 assert(RefExpr && "nullptr expr in OpenMP reduction clause."); 18387 // OpenMP [2.1, C/C++] 18388 // A list item is a variable or array section, subject to the restrictions 18389 // specified in Section 2.4 on page 42 and in each of the sections 18390 // describing clauses and directives for which a list appears. 18391 // OpenMP [2.14.3.3, Restrictions, p.1] 18392 // A variable that is part of another variable (as an array or 18393 // structure element) cannot appear in a private clause. 18394 if (!FirstIter && IR != ER) 18395 ++IR; 18396 FirstIter = false; 18397 SourceLocation ELoc; 18398 SourceRange ERange; 18399 Expr *SimpleRefExpr = RefExpr; 18400 auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange, 18401 /*AllowArraySection=*/true); 18402 if (Res.second) { 18403 // Try to find 'declare reduction' corresponding construct before using 18404 // builtin/overloaded operators. 18405 QualType Type = Context.DependentTy; 18406 CXXCastPath BasePath; 18407 ExprResult DeclareReductionRef = buildDeclareReductionRef( 18408 S, ELoc, ERange, Stack->getCurScope(), ReductionIdScopeSpec, 18409 ReductionId, Type, BasePath, IR == ER ? nullptr : *IR); 18410 Expr *ReductionOp = nullptr; 18411 if (S.CurContext->isDependentContext() && 18412 (DeclareReductionRef.isUnset() || 18413 isa<UnresolvedLookupExpr>(DeclareReductionRef.get()))) 18414 ReductionOp = DeclareReductionRef.get(); 18415 // It will be analyzed later. 18416 RD.push(RefExpr, ReductionOp); 18417 } 18418 ValueDecl *D = Res.first; 18419 if (!D) 18420 continue; 18421 18422 Expr *TaskgroupDescriptor = nullptr; 18423 QualType Type; 18424 auto *ASE = dyn_cast<ArraySubscriptExpr>(RefExpr->IgnoreParens()); 18425 auto *OASE = dyn_cast<OMPArraySectionExpr>(RefExpr->IgnoreParens()); 18426 if (ASE) { 18427 Type = ASE->getType().getNonReferenceType(); 18428 } else if (OASE) { 18429 QualType BaseType = 18430 OMPArraySectionExpr::getBaseOriginalType(OASE->getBase()); 18431 if (const auto *ATy = BaseType->getAsArrayTypeUnsafe()) 18432 Type = ATy->getElementType(); 18433 else 18434 Type = BaseType->getPointeeType(); 18435 Type = Type.getNonReferenceType(); 18436 } else { 18437 Type = Context.getBaseElementType(D->getType().getNonReferenceType()); 18438 } 18439 auto *VD = dyn_cast<VarDecl>(D); 18440 18441 // OpenMP [2.9.3.3, Restrictions, C/C++, p.3] 18442 // A variable that appears in a private clause must not have an incomplete 18443 // type or a reference type. 18444 if (S.RequireCompleteType(ELoc, D->getType(), 18445 diag::err_omp_reduction_incomplete_type)) 18446 continue; 18447 // OpenMP [2.14.3.6, reduction clause, Restrictions] 18448 // A list item that appears in a reduction clause must not be 18449 // const-qualified. 18450 if (rejectConstNotMutableType(S, D, Type, ClauseKind, ELoc, 18451 /*AcceptIfMutable*/ false, ASE || OASE)) 18452 continue; 18453 18454 OpenMPDirectiveKind CurrDir = Stack->getCurrentDirective(); 18455 // OpenMP [2.9.3.6, Restrictions, C/C++, p.4] 18456 // If a list-item is a reference type then it must bind to the same object 18457 // for all threads of the team. 18458 if (!ASE && !OASE) { 18459 if (VD) { 18460 VarDecl *VDDef = VD->getDefinition(); 18461 if (VD->getType()->isReferenceType() && VDDef && VDDef->hasInit()) { 18462 DSARefChecker Check(Stack); 18463 if (Check.Visit(VDDef->getInit())) { 18464 S.Diag(ELoc, diag::err_omp_reduction_ref_type_arg) 18465 << getOpenMPClauseName(ClauseKind) << ERange; 18466 S.Diag(VDDef->getLocation(), diag::note_defined_here) << VDDef; 18467 continue; 18468 } 18469 } 18470 } 18471 18472 // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables Referenced 18473 // in a Construct] 18474 // Variables with the predetermined data-sharing attributes may not be 18475 // listed in data-sharing attributes clauses, except for the cases 18476 // listed below. For these exceptions only, listing a predetermined 18477 // variable in a data-sharing attribute clause is allowed and overrides 18478 // the variable's predetermined data-sharing attributes. 18479 // OpenMP [2.14.3.6, Restrictions, p.3] 18480 // Any number of reduction clauses can be specified on the directive, 18481 // but a list item can appear only once in the reduction clauses for that 18482 // directive. 18483 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(D, /*FromParent=*/false); 18484 if (DVar.CKind == OMPC_reduction) { 18485 S.Diag(ELoc, diag::err_omp_once_referenced) 18486 << getOpenMPClauseName(ClauseKind); 18487 if (DVar.RefExpr) 18488 S.Diag(DVar.RefExpr->getExprLoc(), diag::note_omp_referenced); 18489 continue; 18490 } 18491 if (DVar.CKind != OMPC_unknown) { 18492 S.Diag(ELoc, diag::err_omp_wrong_dsa) 18493 << getOpenMPClauseName(DVar.CKind) 18494 << getOpenMPClauseName(OMPC_reduction); 18495 reportOriginalDsa(S, Stack, D, DVar); 18496 continue; 18497 } 18498 18499 // OpenMP [2.14.3.6, Restrictions, p.1] 18500 // A list item that appears in a reduction clause of a worksharing 18501 // construct must be shared in the parallel regions to which any of the 18502 // worksharing regions arising from the worksharing construct bind. 18503 if (isOpenMPWorksharingDirective(CurrDir) && 18504 !isOpenMPParallelDirective(CurrDir) && 18505 !isOpenMPTeamsDirective(CurrDir)) { 18506 DVar = Stack->getImplicitDSA(D, true); 18507 if (DVar.CKind != OMPC_shared) { 18508 S.Diag(ELoc, diag::err_omp_required_access) 18509 << getOpenMPClauseName(OMPC_reduction) 18510 << getOpenMPClauseName(OMPC_shared); 18511 reportOriginalDsa(S, Stack, D, DVar); 18512 continue; 18513 } 18514 } 18515 } else { 18516 // Threadprivates cannot be shared between threads, so dignose if the base 18517 // is a threadprivate variable. 18518 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(D, /*FromParent=*/false); 18519 if (DVar.CKind == OMPC_threadprivate) { 18520 S.Diag(ELoc, diag::err_omp_wrong_dsa) 18521 << getOpenMPClauseName(DVar.CKind) 18522 << getOpenMPClauseName(OMPC_reduction); 18523 reportOriginalDsa(S, Stack, D, DVar); 18524 continue; 18525 } 18526 } 18527 18528 // Try to find 'declare reduction' corresponding construct before using 18529 // builtin/overloaded operators. 18530 CXXCastPath BasePath; 18531 ExprResult DeclareReductionRef = buildDeclareReductionRef( 18532 S, ELoc, ERange, Stack->getCurScope(), ReductionIdScopeSpec, 18533 ReductionId, Type, BasePath, IR == ER ? nullptr : *IR); 18534 if (DeclareReductionRef.isInvalid()) 18535 continue; 18536 if (S.CurContext->isDependentContext() && 18537 (DeclareReductionRef.isUnset() || 18538 isa<UnresolvedLookupExpr>(DeclareReductionRef.get()))) { 18539 RD.push(RefExpr, DeclareReductionRef.get()); 18540 continue; 18541 } 18542 if (BOK == BO_Comma && DeclareReductionRef.isUnset()) { 18543 // Not allowed reduction identifier is found. 18544 S.Diag(ReductionId.getBeginLoc(), 18545 diag::err_omp_unknown_reduction_identifier) 18546 << Type << ReductionIdRange; 18547 continue; 18548 } 18549 18550 // OpenMP [2.14.3.6, reduction clause, Restrictions] 18551 // The type of a list item that appears in a reduction clause must be valid 18552 // for the reduction-identifier. For a max or min reduction in C, the type 18553 // of the list item must be an allowed arithmetic data type: char, int, 18554 // float, double, or _Bool, possibly modified with long, short, signed, or 18555 // unsigned. For a max or min reduction in C++, the type of the list item 18556 // must be an allowed arithmetic data type: char, wchar_t, int, float, 18557 // double, or bool, possibly modified with long, short, signed, or unsigned. 18558 if (DeclareReductionRef.isUnset()) { 18559 if ((BOK == BO_GT || BOK == BO_LT) && 18560 !(Type->isScalarType() || 18561 (S.getLangOpts().CPlusPlus && Type->isArithmeticType()))) { 18562 S.Diag(ELoc, diag::err_omp_clause_not_arithmetic_type_arg) 18563 << getOpenMPClauseName(ClauseKind) << S.getLangOpts().CPlusPlus; 18564 if (!ASE && !OASE) { 18565 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) == 18566 VarDecl::DeclarationOnly; 18567 S.Diag(D->getLocation(), 18568 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 18569 << D; 18570 } 18571 continue; 18572 } 18573 if ((BOK == BO_OrAssign || BOK == BO_AndAssign || BOK == BO_XorAssign) && 18574 !S.getLangOpts().CPlusPlus && Type->isFloatingType()) { 18575 S.Diag(ELoc, diag::err_omp_clause_floating_type_arg) 18576 << getOpenMPClauseName(ClauseKind); 18577 if (!ASE && !OASE) { 18578 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) == 18579 VarDecl::DeclarationOnly; 18580 S.Diag(D->getLocation(), 18581 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 18582 << D; 18583 } 18584 continue; 18585 } 18586 } 18587 18588 Type = Type.getNonLValueExprType(Context).getUnqualifiedType(); 18589 VarDecl *LHSVD = buildVarDecl(S, ELoc, Type, ".reduction.lhs", 18590 D->hasAttrs() ? &D->getAttrs() : nullptr); 18591 VarDecl *RHSVD = buildVarDecl(S, ELoc, Type, D->getName(), 18592 D->hasAttrs() ? &D->getAttrs() : nullptr); 18593 QualType PrivateTy = Type; 18594 18595 // Try if we can determine constant lengths for all array sections and avoid 18596 // the VLA. 18597 bool ConstantLengthOASE = false; 18598 if (OASE) { 18599 bool SingleElement; 18600 llvm::SmallVector<llvm::APSInt, 4> ArraySizes; 18601 ConstantLengthOASE = checkOMPArraySectionConstantForReduction( 18602 Context, OASE, SingleElement, ArraySizes); 18603 18604 // If we don't have a single element, we must emit a constant array type. 18605 if (ConstantLengthOASE && !SingleElement) { 18606 for (llvm::APSInt &Size : ArraySizes) 18607 PrivateTy = Context.getConstantArrayType(PrivateTy, Size, nullptr, 18608 ArrayType::Normal, 18609 /*IndexTypeQuals=*/0); 18610 } 18611 } 18612 18613 if ((OASE && !ConstantLengthOASE) || 18614 (!OASE && !ASE && 18615 D->getType().getNonReferenceType()->isVariablyModifiedType())) { 18616 if (!Context.getTargetInfo().isVLASupported()) { 18617 if (isOpenMPTargetExecutionDirective(Stack->getCurrentDirective())) { 18618 S.Diag(ELoc, diag::err_omp_reduction_vla_unsupported) << !!OASE; 18619 S.Diag(ELoc, diag::note_vla_unsupported); 18620 continue; 18621 } else { 18622 S.targetDiag(ELoc, diag::err_omp_reduction_vla_unsupported) << !!OASE; 18623 S.targetDiag(ELoc, diag::note_vla_unsupported); 18624 } 18625 } 18626 // For arrays/array sections only: 18627 // Create pseudo array type for private copy. The size for this array will 18628 // be generated during codegen. 18629 // For array subscripts or single variables Private Ty is the same as Type 18630 // (type of the variable or single array element). 18631 PrivateTy = Context.getVariableArrayType( 18632 Type, 18633 new (Context) 18634 OpaqueValueExpr(ELoc, Context.getSizeType(), VK_PRValue), 18635 ArrayType::Normal, /*IndexTypeQuals=*/0, SourceRange()); 18636 } else if (!ASE && !OASE && 18637 Context.getAsArrayType(D->getType().getNonReferenceType())) { 18638 PrivateTy = D->getType().getNonReferenceType(); 18639 } 18640 // Private copy. 18641 VarDecl *PrivateVD = 18642 buildVarDecl(S, ELoc, PrivateTy, D->getName(), 18643 D->hasAttrs() ? &D->getAttrs() : nullptr, 18644 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr); 18645 // Add initializer for private variable. 18646 Expr *Init = nullptr; 18647 DeclRefExpr *LHSDRE = buildDeclRefExpr(S, LHSVD, Type, ELoc); 18648 DeclRefExpr *RHSDRE = buildDeclRefExpr(S, RHSVD, Type, ELoc); 18649 if (DeclareReductionRef.isUsable()) { 18650 auto *DRDRef = DeclareReductionRef.getAs<DeclRefExpr>(); 18651 auto *DRD = cast<OMPDeclareReductionDecl>(DRDRef->getDecl()); 18652 if (DRD->getInitializer()) { 18653 Init = DRDRef; 18654 RHSVD->setInit(DRDRef); 18655 RHSVD->setInitStyle(VarDecl::CallInit); 18656 } 18657 } else { 18658 switch (BOK) { 18659 case BO_Add: 18660 case BO_Xor: 18661 case BO_Or: 18662 case BO_LOr: 18663 // '+', '-', '^', '|', '||' reduction ops - initializer is '0'. 18664 if (Type->isScalarType() || Type->isAnyComplexType()) 18665 Init = S.ActOnIntegerConstant(ELoc, /*Val=*/0).get(); 18666 break; 18667 case BO_Mul: 18668 case BO_LAnd: 18669 if (Type->isScalarType() || Type->isAnyComplexType()) { 18670 // '*' and '&&' reduction ops - initializer is '1'. 18671 Init = S.ActOnIntegerConstant(ELoc, /*Val=*/1).get(); 18672 } 18673 break; 18674 case BO_And: { 18675 // '&' reduction op - initializer is '~0'. 18676 QualType OrigType = Type; 18677 if (auto *ComplexTy = OrigType->getAs<ComplexType>()) 18678 Type = ComplexTy->getElementType(); 18679 if (Type->isRealFloatingType()) { 18680 llvm::APFloat InitValue = llvm::APFloat::getAllOnesValue( 18681 Context.getFloatTypeSemantics(Type)); 18682 Init = FloatingLiteral::Create(Context, InitValue, /*isexact=*/true, 18683 Type, ELoc); 18684 } else if (Type->isScalarType()) { 18685 uint64_t Size = Context.getTypeSize(Type); 18686 QualType IntTy = Context.getIntTypeForBitwidth(Size, /*Signed=*/0); 18687 llvm::APInt InitValue = llvm::APInt::getAllOnes(Size); 18688 Init = IntegerLiteral::Create(Context, InitValue, IntTy, ELoc); 18689 } 18690 if (Init && OrigType->isAnyComplexType()) { 18691 // Init = 0xFFFF + 0xFFFFi; 18692 auto *Im = new (Context) ImaginaryLiteral(Init, OrigType); 18693 Init = S.CreateBuiltinBinOp(ELoc, BO_Add, Init, Im).get(); 18694 } 18695 Type = OrigType; 18696 break; 18697 } 18698 case BO_LT: 18699 case BO_GT: { 18700 // 'min' reduction op - initializer is 'Largest representable number in 18701 // the reduction list item type'. 18702 // 'max' reduction op - initializer is 'Least representable number in 18703 // the reduction list item type'. 18704 if (Type->isIntegerType() || Type->isPointerType()) { 18705 bool IsSigned = Type->hasSignedIntegerRepresentation(); 18706 uint64_t Size = Context.getTypeSize(Type); 18707 QualType IntTy = 18708 Context.getIntTypeForBitwidth(Size, /*Signed=*/IsSigned); 18709 llvm::APInt InitValue = 18710 (BOK != BO_LT) ? IsSigned ? llvm::APInt::getSignedMinValue(Size) 18711 : llvm::APInt::getMinValue(Size) 18712 : IsSigned ? llvm::APInt::getSignedMaxValue(Size) 18713 : llvm::APInt::getMaxValue(Size); 18714 Init = IntegerLiteral::Create(Context, InitValue, IntTy, ELoc); 18715 if (Type->isPointerType()) { 18716 // Cast to pointer type. 18717 ExprResult CastExpr = S.BuildCStyleCastExpr( 18718 ELoc, Context.getTrivialTypeSourceInfo(Type, ELoc), ELoc, Init); 18719 if (CastExpr.isInvalid()) 18720 continue; 18721 Init = CastExpr.get(); 18722 } 18723 } else if (Type->isRealFloatingType()) { 18724 llvm::APFloat InitValue = llvm::APFloat::getLargest( 18725 Context.getFloatTypeSemantics(Type), BOK != BO_LT); 18726 Init = FloatingLiteral::Create(Context, InitValue, /*isexact=*/true, 18727 Type, ELoc); 18728 } 18729 break; 18730 } 18731 case BO_PtrMemD: 18732 case BO_PtrMemI: 18733 case BO_MulAssign: 18734 case BO_Div: 18735 case BO_Rem: 18736 case BO_Sub: 18737 case BO_Shl: 18738 case BO_Shr: 18739 case BO_LE: 18740 case BO_GE: 18741 case BO_EQ: 18742 case BO_NE: 18743 case BO_Cmp: 18744 case BO_AndAssign: 18745 case BO_XorAssign: 18746 case BO_OrAssign: 18747 case BO_Assign: 18748 case BO_AddAssign: 18749 case BO_SubAssign: 18750 case BO_DivAssign: 18751 case BO_RemAssign: 18752 case BO_ShlAssign: 18753 case BO_ShrAssign: 18754 case BO_Comma: 18755 llvm_unreachable("Unexpected reduction operation"); 18756 } 18757 } 18758 if (Init && DeclareReductionRef.isUnset()) { 18759 S.AddInitializerToDecl(RHSVD, Init, /*DirectInit=*/false); 18760 // Store initializer for single element in private copy. Will be used 18761 // during codegen. 18762 PrivateVD->setInit(RHSVD->getInit()); 18763 PrivateVD->setInitStyle(RHSVD->getInitStyle()); 18764 } else if (!Init) { 18765 S.ActOnUninitializedDecl(RHSVD); 18766 // Store initializer for single element in private copy. Will be used 18767 // during codegen. 18768 PrivateVD->setInit(RHSVD->getInit()); 18769 PrivateVD->setInitStyle(RHSVD->getInitStyle()); 18770 } 18771 if (RHSVD->isInvalidDecl()) 18772 continue; 18773 if (!RHSVD->hasInit() && DeclareReductionRef.isUnset()) { 18774 S.Diag(ELoc, diag::err_omp_reduction_id_not_compatible) 18775 << Type << ReductionIdRange; 18776 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) == 18777 VarDecl::DeclarationOnly; 18778 S.Diag(D->getLocation(), 18779 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 18780 << D; 18781 continue; 18782 } 18783 DeclRefExpr *PrivateDRE = buildDeclRefExpr(S, PrivateVD, PrivateTy, ELoc); 18784 ExprResult ReductionOp; 18785 if (DeclareReductionRef.isUsable()) { 18786 QualType RedTy = DeclareReductionRef.get()->getType(); 18787 QualType PtrRedTy = Context.getPointerType(RedTy); 18788 ExprResult LHS = S.CreateBuiltinUnaryOp(ELoc, UO_AddrOf, LHSDRE); 18789 ExprResult RHS = S.CreateBuiltinUnaryOp(ELoc, UO_AddrOf, RHSDRE); 18790 if (!BasePath.empty()) { 18791 LHS = S.DefaultLvalueConversion(LHS.get()); 18792 RHS = S.DefaultLvalueConversion(RHS.get()); 18793 LHS = ImplicitCastExpr::Create( 18794 Context, PtrRedTy, CK_UncheckedDerivedToBase, LHS.get(), &BasePath, 18795 LHS.get()->getValueKind(), FPOptionsOverride()); 18796 RHS = ImplicitCastExpr::Create( 18797 Context, PtrRedTy, CK_UncheckedDerivedToBase, RHS.get(), &BasePath, 18798 RHS.get()->getValueKind(), FPOptionsOverride()); 18799 } 18800 FunctionProtoType::ExtProtoInfo EPI; 18801 QualType Params[] = {PtrRedTy, PtrRedTy}; 18802 QualType FnTy = Context.getFunctionType(Context.VoidTy, Params, EPI); 18803 auto *OVE = new (Context) OpaqueValueExpr( 18804 ELoc, Context.getPointerType(FnTy), VK_PRValue, OK_Ordinary, 18805 S.DefaultLvalueConversion(DeclareReductionRef.get()).get()); 18806 Expr *Args[] = {LHS.get(), RHS.get()}; 18807 ReductionOp = 18808 CallExpr::Create(Context, OVE, Args, Context.VoidTy, VK_PRValue, ELoc, 18809 S.CurFPFeatureOverrides()); 18810 } else { 18811 BinaryOperatorKind CombBOK = getRelatedCompoundReductionOp(BOK); 18812 if (Type->isRecordType() && CombBOK != BOK) { 18813 Sema::TentativeAnalysisScope Trap(S); 18814 ReductionOp = 18815 S.BuildBinOp(Stack->getCurScope(), ReductionId.getBeginLoc(), 18816 CombBOK, LHSDRE, RHSDRE); 18817 } 18818 if (!ReductionOp.isUsable()) { 18819 ReductionOp = 18820 S.BuildBinOp(Stack->getCurScope(), ReductionId.getBeginLoc(), BOK, 18821 LHSDRE, RHSDRE); 18822 if (ReductionOp.isUsable()) { 18823 if (BOK != BO_LT && BOK != BO_GT) { 18824 ReductionOp = 18825 S.BuildBinOp(Stack->getCurScope(), ReductionId.getBeginLoc(), 18826 BO_Assign, LHSDRE, ReductionOp.get()); 18827 } else { 18828 auto *ConditionalOp = new (Context) 18829 ConditionalOperator(ReductionOp.get(), ELoc, LHSDRE, ELoc, 18830 RHSDRE, Type, VK_LValue, OK_Ordinary); 18831 ReductionOp = 18832 S.BuildBinOp(Stack->getCurScope(), ReductionId.getBeginLoc(), 18833 BO_Assign, LHSDRE, ConditionalOp); 18834 } 18835 } 18836 } 18837 if (ReductionOp.isUsable()) 18838 ReductionOp = S.ActOnFinishFullExpr(ReductionOp.get(), 18839 /*DiscardedValue*/ false); 18840 if (!ReductionOp.isUsable()) 18841 continue; 18842 } 18843 18844 // Add copy operations for inscan reductions. 18845 // LHS = RHS; 18846 ExprResult CopyOpRes, TempArrayRes, TempArrayElem; 18847 if (ClauseKind == OMPC_reduction && 18848 RD.RedModifier == OMPC_REDUCTION_inscan) { 18849 ExprResult RHS = S.DefaultLvalueConversion(RHSDRE); 18850 CopyOpRes = S.BuildBinOp(Stack->getCurScope(), ELoc, BO_Assign, LHSDRE, 18851 RHS.get()); 18852 if (!CopyOpRes.isUsable()) 18853 continue; 18854 CopyOpRes = 18855 S.ActOnFinishFullExpr(CopyOpRes.get(), /*DiscardedValue=*/true); 18856 if (!CopyOpRes.isUsable()) 18857 continue; 18858 // For simd directive and simd-based directives in simd mode no need to 18859 // construct temp array, need just a single temp element. 18860 if (Stack->getCurrentDirective() == OMPD_simd || 18861 (S.getLangOpts().OpenMPSimd && 18862 isOpenMPSimdDirective(Stack->getCurrentDirective()))) { 18863 VarDecl *TempArrayVD = 18864 buildVarDecl(S, ELoc, PrivateTy, D->getName(), 18865 D->hasAttrs() ? &D->getAttrs() : nullptr); 18866 // Add a constructor to the temp decl. 18867 S.ActOnUninitializedDecl(TempArrayVD); 18868 TempArrayRes = buildDeclRefExpr(S, TempArrayVD, PrivateTy, ELoc); 18869 } else { 18870 // Build temp array for prefix sum. 18871 auto *Dim = new (S.Context) 18872 OpaqueValueExpr(ELoc, S.Context.getSizeType(), VK_PRValue); 18873 QualType ArrayTy = 18874 S.Context.getVariableArrayType(PrivateTy, Dim, ArrayType::Normal, 18875 /*IndexTypeQuals=*/0, {ELoc, ELoc}); 18876 VarDecl *TempArrayVD = 18877 buildVarDecl(S, ELoc, ArrayTy, D->getName(), 18878 D->hasAttrs() ? &D->getAttrs() : nullptr); 18879 // Add a constructor to the temp decl. 18880 S.ActOnUninitializedDecl(TempArrayVD); 18881 TempArrayRes = buildDeclRefExpr(S, TempArrayVD, ArrayTy, ELoc); 18882 TempArrayElem = 18883 S.DefaultFunctionArrayLvalueConversion(TempArrayRes.get()); 18884 auto *Idx = new (S.Context) 18885 OpaqueValueExpr(ELoc, S.Context.getSizeType(), VK_PRValue); 18886 TempArrayElem = S.CreateBuiltinArraySubscriptExpr(TempArrayElem.get(), 18887 ELoc, Idx, ELoc); 18888 } 18889 } 18890 18891 // OpenMP [2.15.4.6, Restrictions, p.2] 18892 // A list item that appears in an in_reduction clause of a task construct 18893 // must appear in a task_reduction clause of a construct associated with a 18894 // taskgroup region that includes the participating task in its taskgroup 18895 // set. The construct associated with the innermost region that meets this 18896 // condition must specify the same reduction-identifier as the in_reduction 18897 // clause. 18898 if (ClauseKind == OMPC_in_reduction) { 18899 SourceRange ParentSR; 18900 BinaryOperatorKind ParentBOK; 18901 const Expr *ParentReductionOp = nullptr; 18902 Expr *ParentBOKTD = nullptr, *ParentReductionOpTD = nullptr; 18903 DSAStackTy::DSAVarData ParentBOKDSA = 18904 Stack->getTopMostTaskgroupReductionData(D, ParentSR, ParentBOK, 18905 ParentBOKTD); 18906 DSAStackTy::DSAVarData ParentReductionOpDSA = 18907 Stack->getTopMostTaskgroupReductionData( 18908 D, ParentSR, ParentReductionOp, ParentReductionOpTD); 18909 bool IsParentBOK = ParentBOKDSA.DKind != OMPD_unknown; 18910 bool IsParentReductionOp = ParentReductionOpDSA.DKind != OMPD_unknown; 18911 if ((DeclareReductionRef.isUnset() && IsParentReductionOp) || 18912 (DeclareReductionRef.isUsable() && IsParentBOK) || 18913 (IsParentBOK && BOK != ParentBOK) || IsParentReductionOp) { 18914 bool EmitError = true; 18915 if (IsParentReductionOp && DeclareReductionRef.isUsable()) { 18916 llvm::FoldingSetNodeID RedId, ParentRedId; 18917 ParentReductionOp->Profile(ParentRedId, Context, /*Canonical=*/true); 18918 DeclareReductionRef.get()->Profile(RedId, Context, 18919 /*Canonical=*/true); 18920 EmitError = RedId != ParentRedId; 18921 } 18922 if (EmitError) { 18923 S.Diag(ReductionId.getBeginLoc(), 18924 diag::err_omp_reduction_identifier_mismatch) 18925 << ReductionIdRange << RefExpr->getSourceRange(); 18926 S.Diag(ParentSR.getBegin(), 18927 diag::note_omp_previous_reduction_identifier) 18928 << ParentSR 18929 << (IsParentBOK ? ParentBOKDSA.RefExpr 18930 : ParentReductionOpDSA.RefExpr) 18931 ->getSourceRange(); 18932 continue; 18933 } 18934 } 18935 TaskgroupDescriptor = IsParentBOK ? ParentBOKTD : ParentReductionOpTD; 18936 } 18937 18938 DeclRefExpr *Ref = nullptr; 18939 Expr *VarsExpr = RefExpr->IgnoreParens(); 18940 if (!VD && !S.CurContext->isDependentContext()) { 18941 if (ASE || OASE) { 18942 TransformExprToCaptures RebuildToCapture(S, D); 18943 VarsExpr = 18944 RebuildToCapture.TransformExpr(RefExpr->IgnoreParens()).get(); 18945 Ref = RebuildToCapture.getCapturedExpr(); 18946 } else { 18947 VarsExpr = Ref = buildCapture(S, D, SimpleRefExpr, /*WithInit=*/false); 18948 } 18949 if (!S.isOpenMPCapturedDecl(D)) { 18950 RD.ExprCaptures.emplace_back(Ref->getDecl()); 18951 if (Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>()) { 18952 ExprResult RefRes = S.DefaultLvalueConversion(Ref); 18953 if (!RefRes.isUsable()) 18954 continue; 18955 ExprResult PostUpdateRes = 18956 S.BuildBinOp(Stack->getCurScope(), ELoc, BO_Assign, SimpleRefExpr, 18957 RefRes.get()); 18958 if (!PostUpdateRes.isUsable()) 18959 continue; 18960 if (isOpenMPTaskingDirective(Stack->getCurrentDirective()) || 18961 Stack->getCurrentDirective() == OMPD_taskgroup) { 18962 S.Diag(RefExpr->getExprLoc(), 18963 diag::err_omp_reduction_non_addressable_expression) 18964 << RefExpr->getSourceRange(); 18965 continue; 18966 } 18967 RD.ExprPostUpdates.emplace_back( 18968 S.IgnoredValueConversions(PostUpdateRes.get()).get()); 18969 } 18970 } 18971 } 18972 // All reduction items are still marked as reduction (to do not increase 18973 // code base size). 18974 unsigned Modifier = RD.RedModifier; 18975 // Consider task_reductions as reductions with task modifier. Required for 18976 // correct analysis of in_reduction clauses. 18977 if (CurrDir == OMPD_taskgroup && ClauseKind == OMPC_task_reduction) 18978 Modifier = OMPC_REDUCTION_task; 18979 Stack->addDSA(D, RefExpr->IgnoreParens(), OMPC_reduction, Ref, Modifier, 18980 ASE || OASE); 18981 if (Modifier == OMPC_REDUCTION_task && 18982 (CurrDir == OMPD_taskgroup || 18983 ((isOpenMPParallelDirective(CurrDir) || 18984 isOpenMPWorksharingDirective(CurrDir)) && 18985 !isOpenMPSimdDirective(CurrDir)))) { 18986 if (DeclareReductionRef.isUsable()) 18987 Stack->addTaskgroupReductionData(D, ReductionIdRange, 18988 DeclareReductionRef.get()); 18989 else 18990 Stack->addTaskgroupReductionData(D, ReductionIdRange, BOK); 18991 } 18992 RD.push(VarsExpr, PrivateDRE, LHSDRE, RHSDRE, ReductionOp.get(), 18993 TaskgroupDescriptor, CopyOpRes.get(), TempArrayRes.get(), 18994 TempArrayElem.get()); 18995 } 18996 return RD.Vars.empty(); 18997 } 18998 18999 OMPClause *Sema::ActOnOpenMPReductionClause( 19000 ArrayRef<Expr *> VarList, OpenMPReductionClauseModifier Modifier, 19001 SourceLocation StartLoc, SourceLocation LParenLoc, 19002 SourceLocation ModifierLoc, SourceLocation ColonLoc, SourceLocation EndLoc, 19003 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, 19004 ArrayRef<Expr *> UnresolvedReductions) { 19005 if (ModifierLoc.isValid() && Modifier == OMPC_REDUCTION_unknown) { 19006 Diag(LParenLoc, diag::err_omp_unexpected_clause_value) 19007 << getListOfPossibleValues(OMPC_reduction, /*First=*/0, 19008 /*Last=*/OMPC_REDUCTION_unknown) 19009 << getOpenMPClauseName(OMPC_reduction); 19010 return nullptr; 19011 } 19012 // OpenMP 5.0, 2.19.5.4 reduction Clause, Restrictions 19013 // A reduction clause with the inscan reduction-modifier may only appear on a 19014 // worksharing-loop construct, a worksharing-loop SIMD construct, a simd 19015 // construct, a parallel worksharing-loop construct or a parallel 19016 // worksharing-loop SIMD construct. 19017 if (Modifier == OMPC_REDUCTION_inscan && 19018 (DSAStack->getCurrentDirective() != OMPD_for && 19019 DSAStack->getCurrentDirective() != OMPD_for_simd && 19020 DSAStack->getCurrentDirective() != OMPD_simd && 19021 DSAStack->getCurrentDirective() != OMPD_parallel_for && 19022 DSAStack->getCurrentDirective() != OMPD_parallel_for_simd)) { 19023 Diag(ModifierLoc, diag::err_omp_wrong_inscan_reduction); 19024 return nullptr; 19025 } 19026 19027 ReductionData RD(VarList.size(), Modifier); 19028 if (actOnOMPReductionKindClause(*this, DSAStack, OMPC_reduction, VarList, 19029 StartLoc, LParenLoc, ColonLoc, EndLoc, 19030 ReductionIdScopeSpec, ReductionId, 19031 UnresolvedReductions, RD)) 19032 return nullptr; 19033 19034 return OMPReductionClause::Create( 19035 Context, StartLoc, LParenLoc, ModifierLoc, ColonLoc, EndLoc, Modifier, 19036 RD.Vars, ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId, 19037 RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps, RD.InscanCopyOps, 19038 RD.InscanCopyArrayTemps, RD.InscanCopyArrayElems, 19039 buildPreInits(Context, RD.ExprCaptures), 19040 buildPostUpdate(*this, RD.ExprPostUpdates)); 19041 } 19042 19043 OMPClause *Sema::ActOnOpenMPTaskReductionClause( 19044 ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, 19045 SourceLocation ColonLoc, SourceLocation EndLoc, 19046 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, 19047 ArrayRef<Expr *> UnresolvedReductions) { 19048 ReductionData RD(VarList.size()); 19049 if (actOnOMPReductionKindClause(*this, DSAStack, OMPC_task_reduction, VarList, 19050 StartLoc, LParenLoc, ColonLoc, EndLoc, 19051 ReductionIdScopeSpec, ReductionId, 19052 UnresolvedReductions, RD)) 19053 return nullptr; 19054 19055 return OMPTaskReductionClause::Create( 19056 Context, StartLoc, LParenLoc, ColonLoc, EndLoc, RD.Vars, 19057 ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId, 19058 RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps, 19059 buildPreInits(Context, RD.ExprCaptures), 19060 buildPostUpdate(*this, RD.ExprPostUpdates)); 19061 } 19062 19063 OMPClause *Sema::ActOnOpenMPInReductionClause( 19064 ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, 19065 SourceLocation ColonLoc, SourceLocation EndLoc, 19066 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, 19067 ArrayRef<Expr *> UnresolvedReductions) { 19068 ReductionData RD(VarList.size()); 19069 if (actOnOMPReductionKindClause(*this, DSAStack, OMPC_in_reduction, VarList, 19070 StartLoc, LParenLoc, ColonLoc, EndLoc, 19071 ReductionIdScopeSpec, ReductionId, 19072 UnresolvedReductions, RD)) 19073 return nullptr; 19074 19075 return OMPInReductionClause::Create( 19076 Context, StartLoc, LParenLoc, ColonLoc, EndLoc, RD.Vars, 19077 ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId, 19078 RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps, RD.TaskgroupDescriptors, 19079 buildPreInits(Context, RD.ExprCaptures), 19080 buildPostUpdate(*this, RD.ExprPostUpdates)); 19081 } 19082 19083 bool Sema::CheckOpenMPLinearModifier(OpenMPLinearClauseKind LinKind, 19084 SourceLocation LinLoc) { 19085 if ((!LangOpts.CPlusPlus && LinKind != OMPC_LINEAR_val) || 19086 LinKind == OMPC_LINEAR_unknown) { 19087 Diag(LinLoc, diag::err_omp_wrong_linear_modifier) << LangOpts.CPlusPlus; 19088 return true; 19089 } 19090 return false; 19091 } 19092 19093 bool Sema::CheckOpenMPLinearDecl(const ValueDecl *D, SourceLocation ELoc, 19094 OpenMPLinearClauseKind LinKind, QualType Type, 19095 bool IsDeclareSimd) { 19096 const auto *VD = dyn_cast_or_null<VarDecl>(D); 19097 // A variable must not have an incomplete type or a reference type. 19098 if (RequireCompleteType(ELoc, Type, diag::err_omp_linear_incomplete_type)) 19099 return true; 19100 if ((LinKind == OMPC_LINEAR_uval || LinKind == OMPC_LINEAR_ref) && 19101 !Type->isReferenceType()) { 19102 Diag(ELoc, diag::err_omp_wrong_linear_modifier_non_reference) 19103 << Type << getOpenMPSimpleClauseTypeName(OMPC_linear, LinKind); 19104 return true; 19105 } 19106 Type = Type.getNonReferenceType(); 19107 19108 // OpenMP 5.0 [2.19.3, List Item Privatization, Restrictions] 19109 // A variable that is privatized must not have a const-qualified type 19110 // unless it is of class type with a mutable member. This restriction does 19111 // not apply to the firstprivate clause, nor to the linear clause on 19112 // declarative directives (like declare simd). 19113 if (!IsDeclareSimd && 19114 rejectConstNotMutableType(*this, D, Type, OMPC_linear, ELoc)) 19115 return true; 19116 19117 // A list item must be of integral or pointer type. 19118 Type = Type.getUnqualifiedType().getCanonicalType(); 19119 const auto *Ty = Type.getTypePtrOrNull(); 19120 if (!Ty || (LinKind != OMPC_LINEAR_ref && !Ty->isDependentType() && 19121 !Ty->isIntegralType(Context) && !Ty->isPointerType())) { 19122 Diag(ELoc, diag::err_omp_linear_expected_int_or_ptr) << Type; 19123 if (D) { 19124 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) == 19125 VarDecl::DeclarationOnly; 19126 Diag(D->getLocation(), 19127 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 19128 << D; 19129 } 19130 return true; 19131 } 19132 return false; 19133 } 19134 19135 OMPClause *Sema::ActOnOpenMPLinearClause( 19136 ArrayRef<Expr *> VarList, Expr *Step, SourceLocation StartLoc, 19137 SourceLocation LParenLoc, OpenMPLinearClauseKind LinKind, 19138 SourceLocation LinLoc, SourceLocation ColonLoc, SourceLocation EndLoc) { 19139 SmallVector<Expr *, 8> Vars; 19140 SmallVector<Expr *, 8> Privates; 19141 SmallVector<Expr *, 8> Inits; 19142 SmallVector<Decl *, 4> ExprCaptures; 19143 SmallVector<Expr *, 4> ExprPostUpdates; 19144 if (CheckOpenMPLinearModifier(LinKind, LinLoc)) 19145 LinKind = OMPC_LINEAR_val; 19146 for (Expr *RefExpr : VarList) { 19147 assert(RefExpr && "NULL expr in OpenMP linear clause."); 19148 SourceLocation ELoc; 19149 SourceRange ERange; 19150 Expr *SimpleRefExpr = RefExpr; 19151 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 19152 if (Res.second) { 19153 // It will be analyzed later. 19154 Vars.push_back(RefExpr); 19155 Privates.push_back(nullptr); 19156 Inits.push_back(nullptr); 19157 } 19158 ValueDecl *D = Res.first; 19159 if (!D) 19160 continue; 19161 19162 QualType Type = D->getType(); 19163 auto *VD = dyn_cast<VarDecl>(D); 19164 19165 // OpenMP [2.14.3.7, linear clause] 19166 // A list-item cannot appear in more than one linear clause. 19167 // A list-item that appears in a linear clause cannot appear in any 19168 // other data-sharing attribute clause. 19169 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false); 19170 if (DVar.RefExpr) { 19171 Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind) 19172 << getOpenMPClauseName(OMPC_linear); 19173 reportOriginalDsa(*this, DSAStack, D, DVar); 19174 continue; 19175 } 19176 19177 if (CheckOpenMPLinearDecl(D, ELoc, LinKind, Type)) 19178 continue; 19179 Type = Type.getNonReferenceType().getUnqualifiedType().getCanonicalType(); 19180 19181 // Build private copy of original var. 19182 VarDecl *Private = 19183 buildVarDecl(*this, ELoc, Type, D->getName(), 19184 D->hasAttrs() ? &D->getAttrs() : nullptr, 19185 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr); 19186 DeclRefExpr *PrivateRef = buildDeclRefExpr(*this, Private, Type, ELoc); 19187 // Build var to save initial value. 19188 VarDecl *Init = buildVarDecl(*this, ELoc, Type, ".linear.start"); 19189 Expr *InitExpr; 19190 DeclRefExpr *Ref = nullptr; 19191 if (!VD && !CurContext->isDependentContext()) { 19192 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false); 19193 if (!isOpenMPCapturedDecl(D)) { 19194 ExprCaptures.push_back(Ref->getDecl()); 19195 if (Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>()) { 19196 ExprResult RefRes = DefaultLvalueConversion(Ref); 19197 if (!RefRes.isUsable()) 19198 continue; 19199 ExprResult PostUpdateRes = 19200 BuildBinOp(DSAStack->getCurScope(), ELoc, BO_Assign, 19201 SimpleRefExpr, RefRes.get()); 19202 if (!PostUpdateRes.isUsable()) 19203 continue; 19204 ExprPostUpdates.push_back( 19205 IgnoredValueConversions(PostUpdateRes.get()).get()); 19206 } 19207 } 19208 } 19209 if (LinKind == OMPC_LINEAR_uval) 19210 InitExpr = VD ? VD->getInit() : SimpleRefExpr; 19211 else 19212 InitExpr = VD ? SimpleRefExpr : Ref; 19213 AddInitializerToDecl(Init, DefaultLvalueConversion(InitExpr).get(), 19214 /*DirectInit=*/false); 19215 DeclRefExpr *InitRef = buildDeclRefExpr(*this, Init, Type, ELoc); 19216 19217 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_linear, Ref); 19218 Vars.push_back((VD || CurContext->isDependentContext()) 19219 ? RefExpr->IgnoreParens() 19220 : Ref); 19221 Privates.push_back(PrivateRef); 19222 Inits.push_back(InitRef); 19223 } 19224 19225 if (Vars.empty()) 19226 return nullptr; 19227 19228 Expr *StepExpr = Step; 19229 Expr *CalcStepExpr = nullptr; 19230 if (Step && !Step->isValueDependent() && !Step->isTypeDependent() && 19231 !Step->isInstantiationDependent() && 19232 !Step->containsUnexpandedParameterPack()) { 19233 SourceLocation StepLoc = Step->getBeginLoc(); 19234 ExprResult Val = PerformOpenMPImplicitIntegerConversion(StepLoc, Step); 19235 if (Val.isInvalid()) 19236 return nullptr; 19237 StepExpr = Val.get(); 19238 19239 // Build var to save the step value. 19240 VarDecl *SaveVar = 19241 buildVarDecl(*this, StepLoc, StepExpr->getType(), ".linear.step"); 19242 ExprResult SaveRef = 19243 buildDeclRefExpr(*this, SaveVar, StepExpr->getType(), StepLoc); 19244 ExprResult CalcStep = 19245 BuildBinOp(CurScope, StepLoc, BO_Assign, SaveRef.get(), StepExpr); 19246 CalcStep = ActOnFinishFullExpr(CalcStep.get(), /*DiscardedValue*/ false); 19247 19248 // Warn about zero linear step (it would be probably better specified as 19249 // making corresponding variables 'const'). 19250 if (Optional<llvm::APSInt> Result = 19251 StepExpr->getIntegerConstantExpr(Context)) { 19252 if (!Result->isNegative() && !Result->isStrictlyPositive()) 19253 Diag(StepLoc, diag::warn_omp_linear_step_zero) 19254 << Vars[0] << (Vars.size() > 1); 19255 } else if (CalcStep.isUsable()) { 19256 // Calculate the step beforehand instead of doing this on each iteration. 19257 // (This is not used if the number of iterations may be kfold-ed). 19258 CalcStepExpr = CalcStep.get(); 19259 } 19260 } 19261 19262 return OMPLinearClause::Create(Context, StartLoc, LParenLoc, LinKind, LinLoc, 19263 ColonLoc, EndLoc, Vars, Privates, Inits, 19264 StepExpr, CalcStepExpr, 19265 buildPreInits(Context, ExprCaptures), 19266 buildPostUpdate(*this, ExprPostUpdates)); 19267 } 19268 19269 static bool FinishOpenMPLinearClause(OMPLinearClause &Clause, DeclRefExpr *IV, 19270 Expr *NumIterations, Sema &SemaRef, 19271 Scope *S, DSAStackTy *Stack) { 19272 // Walk the vars and build update/final expressions for the CodeGen. 19273 SmallVector<Expr *, 8> Updates; 19274 SmallVector<Expr *, 8> Finals; 19275 SmallVector<Expr *, 8> UsedExprs; 19276 Expr *Step = Clause.getStep(); 19277 Expr *CalcStep = Clause.getCalcStep(); 19278 // OpenMP [2.14.3.7, linear clause] 19279 // If linear-step is not specified it is assumed to be 1. 19280 if (!Step) 19281 Step = SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get(); 19282 else if (CalcStep) 19283 Step = cast<BinaryOperator>(CalcStep)->getLHS(); 19284 bool HasErrors = false; 19285 auto CurInit = Clause.inits().begin(); 19286 auto CurPrivate = Clause.privates().begin(); 19287 OpenMPLinearClauseKind LinKind = Clause.getModifier(); 19288 for (Expr *RefExpr : Clause.varlists()) { 19289 SourceLocation ELoc; 19290 SourceRange ERange; 19291 Expr *SimpleRefExpr = RefExpr; 19292 auto Res = getPrivateItem(SemaRef, SimpleRefExpr, ELoc, ERange); 19293 ValueDecl *D = Res.first; 19294 if (Res.second || !D) { 19295 Updates.push_back(nullptr); 19296 Finals.push_back(nullptr); 19297 HasErrors = true; 19298 continue; 19299 } 19300 auto &&Info = Stack->isLoopControlVariable(D); 19301 // OpenMP [2.15.11, distribute simd Construct] 19302 // A list item may not appear in a linear clause, unless it is the loop 19303 // iteration variable. 19304 if (isOpenMPDistributeDirective(Stack->getCurrentDirective()) && 19305 isOpenMPSimdDirective(Stack->getCurrentDirective()) && !Info.first) { 19306 SemaRef.Diag(ELoc, 19307 diag::err_omp_linear_distribute_var_non_loop_iteration); 19308 Updates.push_back(nullptr); 19309 Finals.push_back(nullptr); 19310 HasErrors = true; 19311 continue; 19312 } 19313 Expr *InitExpr = *CurInit; 19314 19315 // Build privatized reference to the current linear var. 19316 auto *DE = cast<DeclRefExpr>(SimpleRefExpr); 19317 Expr *CapturedRef; 19318 if (LinKind == OMPC_LINEAR_uval) 19319 CapturedRef = cast<VarDecl>(DE->getDecl())->getInit(); 19320 else 19321 CapturedRef = 19322 buildDeclRefExpr(SemaRef, cast<VarDecl>(DE->getDecl()), 19323 DE->getType().getUnqualifiedType(), DE->getExprLoc(), 19324 /*RefersToCapture=*/true); 19325 19326 // Build update: Var = InitExpr + IV * Step 19327 ExprResult Update; 19328 if (!Info.first) 19329 Update = buildCounterUpdate( 19330 SemaRef, S, RefExpr->getExprLoc(), *CurPrivate, InitExpr, IV, Step, 19331 /*Subtract=*/false, /*IsNonRectangularLB=*/false); 19332 else 19333 Update = *CurPrivate; 19334 Update = SemaRef.ActOnFinishFullExpr(Update.get(), DE->getBeginLoc(), 19335 /*DiscardedValue*/ false); 19336 19337 // Build final: Var = PrivCopy; 19338 ExprResult Final; 19339 if (!Info.first) 19340 Final = SemaRef.BuildBinOp( 19341 S, RefExpr->getExprLoc(), BO_Assign, CapturedRef, 19342 SemaRef.DefaultLvalueConversion(*CurPrivate).get()); 19343 else 19344 Final = *CurPrivate; 19345 Final = SemaRef.ActOnFinishFullExpr(Final.get(), DE->getBeginLoc(), 19346 /*DiscardedValue*/ false); 19347 19348 if (!Update.isUsable() || !Final.isUsable()) { 19349 Updates.push_back(nullptr); 19350 Finals.push_back(nullptr); 19351 UsedExprs.push_back(nullptr); 19352 HasErrors = true; 19353 } else { 19354 Updates.push_back(Update.get()); 19355 Finals.push_back(Final.get()); 19356 if (!Info.first) 19357 UsedExprs.push_back(SimpleRefExpr); 19358 } 19359 ++CurInit; 19360 ++CurPrivate; 19361 } 19362 if (Expr *S = Clause.getStep()) 19363 UsedExprs.push_back(S); 19364 // Fill the remaining part with the nullptr. 19365 UsedExprs.append(Clause.varlist_size() + 1 - UsedExprs.size(), nullptr); 19366 Clause.setUpdates(Updates); 19367 Clause.setFinals(Finals); 19368 Clause.setUsedExprs(UsedExprs); 19369 return HasErrors; 19370 } 19371 19372 OMPClause *Sema::ActOnOpenMPAlignedClause( 19373 ArrayRef<Expr *> VarList, Expr *Alignment, SourceLocation StartLoc, 19374 SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc) { 19375 SmallVector<Expr *, 8> Vars; 19376 for (Expr *RefExpr : VarList) { 19377 assert(RefExpr && "NULL expr in OpenMP linear clause."); 19378 SourceLocation ELoc; 19379 SourceRange ERange; 19380 Expr *SimpleRefExpr = RefExpr; 19381 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 19382 if (Res.second) { 19383 // It will be analyzed later. 19384 Vars.push_back(RefExpr); 19385 } 19386 ValueDecl *D = Res.first; 19387 if (!D) 19388 continue; 19389 19390 QualType QType = D->getType(); 19391 auto *VD = dyn_cast<VarDecl>(D); 19392 19393 // OpenMP [2.8.1, simd construct, Restrictions] 19394 // The type of list items appearing in the aligned clause must be 19395 // array, pointer, reference to array, or reference to pointer. 19396 QType = QType.getNonReferenceType().getUnqualifiedType().getCanonicalType(); 19397 const Type *Ty = QType.getTypePtrOrNull(); 19398 if (!Ty || (!Ty->isArrayType() && !Ty->isPointerType())) { 19399 Diag(ELoc, diag::err_omp_aligned_expected_array_or_ptr) 19400 << QType << getLangOpts().CPlusPlus << ERange; 19401 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) == 19402 VarDecl::DeclarationOnly; 19403 Diag(D->getLocation(), 19404 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 19405 << D; 19406 continue; 19407 } 19408 19409 // OpenMP [2.8.1, simd construct, Restrictions] 19410 // A list-item cannot appear in more than one aligned clause. 19411 if (const Expr *PrevRef = DSAStack->addUniqueAligned(D, SimpleRefExpr)) { 19412 Diag(ELoc, diag::err_omp_used_in_clause_twice) 19413 << 0 << getOpenMPClauseName(OMPC_aligned) << ERange; 19414 Diag(PrevRef->getExprLoc(), diag::note_omp_explicit_dsa) 19415 << getOpenMPClauseName(OMPC_aligned); 19416 continue; 19417 } 19418 19419 DeclRefExpr *Ref = nullptr; 19420 if (!VD && isOpenMPCapturedDecl(D)) 19421 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true); 19422 Vars.push_back(DefaultFunctionArrayConversion( 19423 (VD || !Ref) ? RefExpr->IgnoreParens() : Ref) 19424 .get()); 19425 } 19426 19427 // OpenMP [2.8.1, simd construct, Description] 19428 // The parameter of the aligned clause, alignment, must be a constant 19429 // positive integer expression. 19430 // If no optional parameter is specified, implementation-defined default 19431 // alignments for SIMD instructions on the target platforms are assumed. 19432 if (Alignment != nullptr) { 19433 ExprResult AlignResult = 19434 VerifyPositiveIntegerConstantInClause(Alignment, OMPC_aligned); 19435 if (AlignResult.isInvalid()) 19436 return nullptr; 19437 Alignment = AlignResult.get(); 19438 } 19439 if (Vars.empty()) 19440 return nullptr; 19441 19442 return OMPAlignedClause::Create(Context, StartLoc, LParenLoc, ColonLoc, 19443 EndLoc, Vars, Alignment); 19444 } 19445 19446 OMPClause *Sema::ActOnOpenMPCopyinClause(ArrayRef<Expr *> VarList, 19447 SourceLocation StartLoc, 19448 SourceLocation LParenLoc, 19449 SourceLocation EndLoc) { 19450 SmallVector<Expr *, 8> Vars; 19451 SmallVector<Expr *, 8> SrcExprs; 19452 SmallVector<Expr *, 8> DstExprs; 19453 SmallVector<Expr *, 8> AssignmentOps; 19454 for (Expr *RefExpr : VarList) { 19455 assert(RefExpr && "NULL expr in OpenMP copyin clause."); 19456 if (isa<DependentScopeDeclRefExpr>(RefExpr)) { 19457 // It will be analyzed later. 19458 Vars.push_back(RefExpr); 19459 SrcExprs.push_back(nullptr); 19460 DstExprs.push_back(nullptr); 19461 AssignmentOps.push_back(nullptr); 19462 continue; 19463 } 19464 19465 SourceLocation ELoc = RefExpr->getExprLoc(); 19466 // OpenMP [2.1, C/C++] 19467 // A list item is a variable name. 19468 // OpenMP [2.14.4.1, Restrictions, p.1] 19469 // A list item that appears in a copyin clause must be threadprivate. 19470 auto *DE = dyn_cast<DeclRefExpr>(RefExpr); 19471 if (!DE || !isa<VarDecl>(DE->getDecl())) { 19472 Diag(ELoc, diag::err_omp_expected_var_name_member_expr) 19473 << 0 << RefExpr->getSourceRange(); 19474 continue; 19475 } 19476 19477 Decl *D = DE->getDecl(); 19478 auto *VD = cast<VarDecl>(D); 19479 19480 QualType Type = VD->getType(); 19481 if (Type->isDependentType() || Type->isInstantiationDependentType()) { 19482 // It will be analyzed later. 19483 Vars.push_back(DE); 19484 SrcExprs.push_back(nullptr); 19485 DstExprs.push_back(nullptr); 19486 AssignmentOps.push_back(nullptr); 19487 continue; 19488 } 19489 19490 // OpenMP [2.14.4.1, Restrictions, C/C++, p.1] 19491 // A list item that appears in a copyin clause must be threadprivate. 19492 if (!DSAStack->isThreadPrivate(VD)) { 19493 Diag(ELoc, diag::err_omp_required_access) 19494 << getOpenMPClauseName(OMPC_copyin) 19495 << getOpenMPDirectiveName(OMPD_threadprivate); 19496 continue; 19497 } 19498 19499 // OpenMP [2.14.4.1, Restrictions, C/C++, p.2] 19500 // A variable of class type (or array thereof) that appears in a 19501 // copyin clause requires an accessible, unambiguous copy assignment 19502 // operator for the class type. 19503 QualType ElemType = Context.getBaseElementType(Type).getNonReferenceType(); 19504 VarDecl *SrcVD = 19505 buildVarDecl(*this, DE->getBeginLoc(), ElemType.getUnqualifiedType(), 19506 ".copyin.src", VD->hasAttrs() ? &VD->getAttrs() : nullptr); 19507 DeclRefExpr *PseudoSrcExpr = buildDeclRefExpr( 19508 *this, SrcVD, ElemType.getUnqualifiedType(), DE->getExprLoc()); 19509 VarDecl *DstVD = 19510 buildVarDecl(*this, DE->getBeginLoc(), ElemType, ".copyin.dst", 19511 VD->hasAttrs() ? &VD->getAttrs() : nullptr); 19512 DeclRefExpr *PseudoDstExpr = 19513 buildDeclRefExpr(*this, DstVD, ElemType, DE->getExprLoc()); 19514 // For arrays generate assignment operation for single element and replace 19515 // it by the original array element in CodeGen. 19516 ExprResult AssignmentOp = 19517 BuildBinOp(/*S=*/nullptr, DE->getExprLoc(), BO_Assign, PseudoDstExpr, 19518 PseudoSrcExpr); 19519 if (AssignmentOp.isInvalid()) 19520 continue; 19521 AssignmentOp = ActOnFinishFullExpr(AssignmentOp.get(), DE->getExprLoc(), 19522 /*DiscardedValue*/ false); 19523 if (AssignmentOp.isInvalid()) 19524 continue; 19525 19526 DSAStack->addDSA(VD, DE, OMPC_copyin); 19527 Vars.push_back(DE); 19528 SrcExprs.push_back(PseudoSrcExpr); 19529 DstExprs.push_back(PseudoDstExpr); 19530 AssignmentOps.push_back(AssignmentOp.get()); 19531 } 19532 19533 if (Vars.empty()) 19534 return nullptr; 19535 19536 return OMPCopyinClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars, 19537 SrcExprs, DstExprs, AssignmentOps); 19538 } 19539 19540 OMPClause *Sema::ActOnOpenMPCopyprivateClause(ArrayRef<Expr *> VarList, 19541 SourceLocation StartLoc, 19542 SourceLocation LParenLoc, 19543 SourceLocation EndLoc) { 19544 SmallVector<Expr *, 8> Vars; 19545 SmallVector<Expr *, 8> SrcExprs; 19546 SmallVector<Expr *, 8> DstExprs; 19547 SmallVector<Expr *, 8> AssignmentOps; 19548 for (Expr *RefExpr : VarList) { 19549 assert(RefExpr && "NULL expr in OpenMP linear clause."); 19550 SourceLocation ELoc; 19551 SourceRange ERange; 19552 Expr *SimpleRefExpr = RefExpr; 19553 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 19554 if (Res.second) { 19555 // It will be analyzed later. 19556 Vars.push_back(RefExpr); 19557 SrcExprs.push_back(nullptr); 19558 DstExprs.push_back(nullptr); 19559 AssignmentOps.push_back(nullptr); 19560 } 19561 ValueDecl *D = Res.first; 19562 if (!D) 19563 continue; 19564 19565 QualType Type = D->getType(); 19566 auto *VD = dyn_cast<VarDecl>(D); 19567 19568 // OpenMP [2.14.4.2, Restrictions, p.2] 19569 // A list item that appears in a copyprivate clause may not appear in a 19570 // private or firstprivate clause on the single construct. 19571 if (!VD || !DSAStack->isThreadPrivate(VD)) { 19572 DSAStackTy::DSAVarData DVar = 19573 DSAStack->getTopDSA(D, /*FromParent=*/false); 19574 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_copyprivate && 19575 DVar.RefExpr) { 19576 Diag(ELoc, diag::err_omp_wrong_dsa) 19577 << getOpenMPClauseName(DVar.CKind) 19578 << getOpenMPClauseName(OMPC_copyprivate); 19579 reportOriginalDsa(*this, DSAStack, D, DVar); 19580 continue; 19581 } 19582 19583 // OpenMP [2.11.4.2, Restrictions, p.1] 19584 // All list items that appear in a copyprivate clause must be either 19585 // threadprivate or private in the enclosing context. 19586 if (DVar.CKind == OMPC_unknown) { 19587 DVar = DSAStack->getImplicitDSA(D, false); 19588 if (DVar.CKind == OMPC_shared) { 19589 Diag(ELoc, diag::err_omp_required_access) 19590 << getOpenMPClauseName(OMPC_copyprivate) 19591 << "threadprivate or private in the enclosing context"; 19592 reportOriginalDsa(*this, DSAStack, D, DVar); 19593 continue; 19594 } 19595 } 19596 } 19597 19598 // Variably modified types are not supported. 19599 if (!Type->isAnyPointerType() && Type->isVariablyModifiedType()) { 19600 Diag(ELoc, diag::err_omp_variably_modified_type_not_supported) 19601 << getOpenMPClauseName(OMPC_copyprivate) << Type 19602 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 19603 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) == 19604 VarDecl::DeclarationOnly; 19605 Diag(D->getLocation(), 19606 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 19607 << D; 19608 continue; 19609 } 19610 19611 // OpenMP [2.14.4.1, Restrictions, C/C++, p.2] 19612 // A variable of class type (or array thereof) that appears in a 19613 // copyin clause requires an accessible, unambiguous copy assignment 19614 // operator for the class type. 19615 Type = Context.getBaseElementType(Type.getNonReferenceType()) 19616 .getUnqualifiedType(); 19617 VarDecl *SrcVD = 19618 buildVarDecl(*this, RefExpr->getBeginLoc(), Type, ".copyprivate.src", 19619 D->hasAttrs() ? &D->getAttrs() : nullptr); 19620 DeclRefExpr *PseudoSrcExpr = buildDeclRefExpr(*this, SrcVD, Type, ELoc); 19621 VarDecl *DstVD = 19622 buildVarDecl(*this, RefExpr->getBeginLoc(), Type, ".copyprivate.dst", 19623 D->hasAttrs() ? &D->getAttrs() : nullptr); 19624 DeclRefExpr *PseudoDstExpr = buildDeclRefExpr(*this, DstVD, Type, ELoc); 19625 ExprResult AssignmentOp = BuildBinOp( 19626 DSAStack->getCurScope(), ELoc, BO_Assign, PseudoDstExpr, PseudoSrcExpr); 19627 if (AssignmentOp.isInvalid()) 19628 continue; 19629 AssignmentOp = 19630 ActOnFinishFullExpr(AssignmentOp.get(), ELoc, /*DiscardedValue*/ false); 19631 if (AssignmentOp.isInvalid()) 19632 continue; 19633 19634 // No need to mark vars as copyprivate, they are already threadprivate or 19635 // implicitly private. 19636 assert(VD || isOpenMPCapturedDecl(D)); 19637 Vars.push_back( 19638 VD ? RefExpr->IgnoreParens() 19639 : buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false)); 19640 SrcExprs.push_back(PseudoSrcExpr); 19641 DstExprs.push_back(PseudoDstExpr); 19642 AssignmentOps.push_back(AssignmentOp.get()); 19643 } 19644 19645 if (Vars.empty()) 19646 return nullptr; 19647 19648 return OMPCopyprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, 19649 Vars, SrcExprs, DstExprs, AssignmentOps); 19650 } 19651 19652 OMPClause *Sema::ActOnOpenMPFlushClause(ArrayRef<Expr *> VarList, 19653 SourceLocation StartLoc, 19654 SourceLocation LParenLoc, 19655 SourceLocation EndLoc) { 19656 if (VarList.empty()) 19657 return nullptr; 19658 19659 return OMPFlushClause::Create(Context, StartLoc, LParenLoc, EndLoc, VarList); 19660 } 19661 19662 /// Tries to find omp_depend_t. type. 19663 static bool findOMPDependT(Sema &S, SourceLocation Loc, DSAStackTy *Stack, 19664 bool Diagnose = true) { 19665 QualType OMPDependT = Stack->getOMPDependT(); 19666 if (!OMPDependT.isNull()) 19667 return true; 19668 IdentifierInfo *II = &S.PP.getIdentifierTable().get("omp_depend_t"); 19669 ParsedType PT = S.getTypeName(*II, Loc, S.getCurScope()); 19670 if (!PT.getAsOpaquePtr() || PT.get().isNull()) { 19671 if (Diagnose) 19672 S.Diag(Loc, diag::err_omp_implied_type_not_found) << "omp_depend_t"; 19673 return false; 19674 } 19675 Stack->setOMPDependT(PT.get()); 19676 return true; 19677 } 19678 19679 OMPClause *Sema::ActOnOpenMPDepobjClause(Expr *Depobj, SourceLocation StartLoc, 19680 SourceLocation LParenLoc, 19681 SourceLocation EndLoc) { 19682 if (!Depobj) 19683 return nullptr; 19684 19685 bool OMPDependTFound = findOMPDependT(*this, StartLoc, DSAStack); 19686 19687 // OpenMP 5.0, 2.17.10.1 depobj Construct 19688 // depobj is an lvalue expression of type omp_depend_t. 19689 if (!Depobj->isTypeDependent() && !Depobj->isValueDependent() && 19690 !Depobj->isInstantiationDependent() && 19691 !Depobj->containsUnexpandedParameterPack() && 19692 (OMPDependTFound && 19693 !Context.typesAreCompatible(DSAStack->getOMPDependT(), Depobj->getType(), 19694 /*CompareUnqualified=*/true))) { 19695 Diag(Depobj->getExprLoc(), diag::err_omp_expected_omp_depend_t_lvalue) 19696 << 0 << Depobj->getType() << Depobj->getSourceRange(); 19697 } 19698 19699 if (!Depobj->isLValue()) { 19700 Diag(Depobj->getExprLoc(), diag::err_omp_expected_omp_depend_t_lvalue) 19701 << 1 << Depobj->getSourceRange(); 19702 } 19703 19704 return OMPDepobjClause::Create(Context, StartLoc, LParenLoc, EndLoc, Depobj); 19705 } 19706 19707 OMPClause * 19708 Sema::ActOnOpenMPDependClause(const OMPDependClause::DependDataTy &Data, 19709 Expr *DepModifier, ArrayRef<Expr *> VarList, 19710 SourceLocation StartLoc, SourceLocation LParenLoc, 19711 SourceLocation EndLoc) { 19712 OpenMPDependClauseKind DepKind = Data.DepKind; 19713 SourceLocation DepLoc = Data.DepLoc; 19714 if (DSAStack->getCurrentDirective() == OMPD_ordered && 19715 DepKind != OMPC_DEPEND_source && DepKind != OMPC_DEPEND_sink) { 19716 Diag(DepLoc, diag::err_omp_unexpected_clause_value) 19717 << "'source' or 'sink'" << getOpenMPClauseName(OMPC_depend); 19718 return nullptr; 19719 } 19720 if (DSAStack->getCurrentDirective() == OMPD_taskwait && 19721 DepKind == OMPC_DEPEND_mutexinoutset) { 19722 Diag(DepLoc, diag::err_omp_taskwait_depend_mutexinoutset_not_allowed); 19723 return nullptr; 19724 } 19725 if ((DSAStack->getCurrentDirective() != OMPD_ordered || 19726 DSAStack->getCurrentDirective() == OMPD_depobj) && 19727 (DepKind == OMPC_DEPEND_unknown || DepKind == OMPC_DEPEND_source || 19728 DepKind == OMPC_DEPEND_sink || 19729 ((LangOpts.OpenMP < 50 || 19730 DSAStack->getCurrentDirective() == OMPD_depobj) && 19731 DepKind == OMPC_DEPEND_depobj))) { 19732 SmallVector<unsigned, 6> Except = {OMPC_DEPEND_source, OMPC_DEPEND_sink, 19733 OMPC_DEPEND_outallmemory, 19734 OMPC_DEPEND_inoutallmemory}; 19735 if (LangOpts.OpenMP < 50 || DSAStack->getCurrentDirective() == OMPD_depobj) 19736 Except.push_back(OMPC_DEPEND_depobj); 19737 if (LangOpts.OpenMP < 51) 19738 Except.push_back(OMPC_DEPEND_inoutset); 19739 std::string Expected = (LangOpts.OpenMP >= 50 && !DepModifier) 19740 ? "depend modifier(iterator) or " 19741 : ""; 19742 Diag(DepLoc, diag::err_omp_unexpected_clause_value) 19743 << Expected + getListOfPossibleValues(OMPC_depend, /*First=*/0, 19744 /*Last=*/OMPC_DEPEND_unknown, 19745 Except) 19746 << getOpenMPClauseName(OMPC_depend); 19747 return nullptr; 19748 } 19749 if (DepModifier && 19750 (DepKind == OMPC_DEPEND_source || DepKind == OMPC_DEPEND_sink)) { 19751 Diag(DepModifier->getExprLoc(), 19752 diag::err_omp_depend_sink_source_with_modifier); 19753 return nullptr; 19754 } 19755 if (DepModifier && 19756 !DepModifier->getType()->isSpecificBuiltinType(BuiltinType::OMPIterator)) 19757 Diag(DepModifier->getExprLoc(), diag::err_omp_depend_modifier_not_iterator); 19758 19759 SmallVector<Expr *, 8> Vars; 19760 DSAStackTy::OperatorOffsetTy OpsOffs; 19761 llvm::APSInt DepCounter(/*BitWidth=*/32); 19762 llvm::APSInt TotalDepCount(/*BitWidth=*/32); 19763 if (DepKind == OMPC_DEPEND_sink || DepKind == OMPC_DEPEND_source) { 19764 if (const Expr *OrderedCountExpr = 19765 DSAStack->getParentOrderedRegionParam().first) { 19766 TotalDepCount = OrderedCountExpr->EvaluateKnownConstInt(Context); 19767 TotalDepCount.setIsUnsigned(/*Val=*/true); 19768 } 19769 } 19770 for (Expr *RefExpr : VarList) { 19771 assert(RefExpr && "NULL expr in OpenMP shared clause."); 19772 if (isa<DependentScopeDeclRefExpr>(RefExpr)) { 19773 // It will be analyzed later. 19774 Vars.push_back(RefExpr); 19775 continue; 19776 } 19777 19778 SourceLocation ELoc = RefExpr->getExprLoc(); 19779 Expr *SimpleExpr = RefExpr->IgnoreParenCasts(); 19780 if (DepKind == OMPC_DEPEND_sink) { 19781 if (DSAStack->getParentOrderedRegionParam().first && 19782 DepCounter >= TotalDepCount) { 19783 Diag(ELoc, diag::err_omp_depend_sink_unexpected_expr); 19784 continue; 19785 } 19786 ++DepCounter; 19787 // OpenMP [2.13.9, Summary] 19788 // depend(dependence-type : vec), where dependence-type is: 19789 // 'sink' and where vec is the iteration vector, which has the form: 19790 // x1 [+- d1], x2 [+- d2 ], . . . , xn [+- dn] 19791 // where n is the value specified by the ordered clause in the loop 19792 // directive, xi denotes the loop iteration variable of the i-th nested 19793 // loop associated with the loop directive, and di is a constant 19794 // non-negative integer. 19795 if (CurContext->isDependentContext()) { 19796 // It will be analyzed later. 19797 Vars.push_back(RefExpr); 19798 continue; 19799 } 19800 SimpleExpr = SimpleExpr->IgnoreImplicit(); 19801 OverloadedOperatorKind OOK = OO_None; 19802 SourceLocation OOLoc; 19803 Expr *LHS = SimpleExpr; 19804 Expr *RHS = nullptr; 19805 if (auto *BO = dyn_cast<BinaryOperator>(SimpleExpr)) { 19806 OOK = BinaryOperator::getOverloadedOperator(BO->getOpcode()); 19807 OOLoc = BO->getOperatorLoc(); 19808 LHS = BO->getLHS()->IgnoreParenImpCasts(); 19809 RHS = BO->getRHS()->IgnoreParenImpCasts(); 19810 } else if (auto *OCE = dyn_cast<CXXOperatorCallExpr>(SimpleExpr)) { 19811 OOK = OCE->getOperator(); 19812 OOLoc = OCE->getOperatorLoc(); 19813 LHS = OCE->getArg(/*Arg=*/0)->IgnoreParenImpCasts(); 19814 RHS = OCE->getArg(/*Arg=*/1)->IgnoreParenImpCasts(); 19815 } else if (auto *MCE = dyn_cast<CXXMemberCallExpr>(SimpleExpr)) { 19816 OOK = MCE->getMethodDecl() 19817 ->getNameInfo() 19818 .getName() 19819 .getCXXOverloadedOperator(); 19820 OOLoc = MCE->getCallee()->getExprLoc(); 19821 LHS = MCE->getImplicitObjectArgument()->IgnoreParenImpCasts(); 19822 RHS = MCE->getArg(/*Arg=*/0)->IgnoreParenImpCasts(); 19823 } 19824 SourceLocation ELoc; 19825 SourceRange ERange; 19826 auto Res = getPrivateItem(*this, LHS, ELoc, ERange); 19827 if (Res.second) { 19828 // It will be analyzed later. 19829 Vars.push_back(RefExpr); 19830 } 19831 ValueDecl *D = Res.first; 19832 if (!D) 19833 continue; 19834 19835 if (OOK != OO_Plus && OOK != OO_Minus && (RHS || OOK != OO_None)) { 19836 Diag(OOLoc, diag::err_omp_depend_sink_expected_plus_minus); 19837 continue; 19838 } 19839 if (RHS) { 19840 ExprResult RHSRes = VerifyPositiveIntegerConstantInClause( 19841 RHS, OMPC_depend, /*StrictlyPositive=*/false); 19842 if (RHSRes.isInvalid()) 19843 continue; 19844 } 19845 if (!CurContext->isDependentContext() && 19846 DSAStack->getParentOrderedRegionParam().first && 19847 DepCounter != DSAStack->isParentLoopControlVariable(D).first) { 19848 const ValueDecl *VD = 19849 DSAStack->getParentLoopControlVariable(DepCounter.getZExtValue()); 19850 if (VD) 19851 Diag(ELoc, diag::err_omp_depend_sink_expected_loop_iteration) 19852 << 1 << VD; 19853 else 19854 Diag(ELoc, diag::err_omp_depend_sink_expected_loop_iteration) << 0; 19855 continue; 19856 } 19857 OpsOffs.emplace_back(RHS, OOK); 19858 } else { 19859 bool OMPDependTFound = LangOpts.OpenMP >= 50; 19860 if (OMPDependTFound) 19861 OMPDependTFound = findOMPDependT(*this, StartLoc, DSAStack, 19862 DepKind == OMPC_DEPEND_depobj); 19863 if (DepKind == OMPC_DEPEND_depobj) { 19864 // OpenMP 5.0, 2.17.11 depend Clause, Restrictions, C/C++ 19865 // List items used in depend clauses with the depobj dependence type 19866 // must be expressions of the omp_depend_t type. 19867 if (!RefExpr->isValueDependent() && !RefExpr->isTypeDependent() && 19868 !RefExpr->isInstantiationDependent() && 19869 !RefExpr->containsUnexpandedParameterPack() && 19870 (OMPDependTFound && 19871 !Context.hasSameUnqualifiedType(DSAStack->getOMPDependT(), 19872 RefExpr->getType()))) { 19873 Diag(ELoc, diag::err_omp_expected_omp_depend_t_lvalue) 19874 << 0 << RefExpr->getType() << RefExpr->getSourceRange(); 19875 continue; 19876 } 19877 if (!RefExpr->isLValue()) { 19878 Diag(ELoc, diag::err_omp_expected_omp_depend_t_lvalue) 19879 << 1 << RefExpr->getType() << RefExpr->getSourceRange(); 19880 continue; 19881 } 19882 } else { 19883 // OpenMP 5.0 [2.17.11, Restrictions] 19884 // List items used in depend clauses cannot be zero-length array 19885 // sections. 19886 QualType ExprTy = RefExpr->getType().getNonReferenceType(); 19887 const auto *OASE = dyn_cast<OMPArraySectionExpr>(SimpleExpr); 19888 if (OASE) { 19889 QualType BaseType = 19890 OMPArraySectionExpr::getBaseOriginalType(OASE->getBase()); 19891 if (const auto *ATy = BaseType->getAsArrayTypeUnsafe()) 19892 ExprTy = ATy->getElementType(); 19893 else 19894 ExprTy = BaseType->getPointeeType(); 19895 ExprTy = ExprTy.getNonReferenceType(); 19896 const Expr *Length = OASE->getLength(); 19897 Expr::EvalResult Result; 19898 if (Length && !Length->isValueDependent() && 19899 Length->EvaluateAsInt(Result, Context) && 19900 Result.Val.getInt().isZero()) { 19901 Diag(ELoc, 19902 diag::err_omp_depend_zero_length_array_section_not_allowed) 19903 << SimpleExpr->getSourceRange(); 19904 continue; 19905 } 19906 } 19907 19908 // OpenMP 5.0, 2.17.11 depend Clause, Restrictions, C/C++ 19909 // List items used in depend clauses with the in, out, inout, 19910 // inoutset, or mutexinoutset dependence types cannot be 19911 // expressions of the omp_depend_t type. 19912 if (!RefExpr->isValueDependent() && !RefExpr->isTypeDependent() && 19913 !RefExpr->isInstantiationDependent() && 19914 !RefExpr->containsUnexpandedParameterPack() && 19915 (!RefExpr->IgnoreParenImpCasts()->isLValue() || 19916 (OMPDependTFound && 19917 DSAStack->getOMPDependT().getTypePtr() == ExprTy.getTypePtr()))) { 19918 Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item) 19919 << (LangOpts.OpenMP >= 50 ? 1 : 0) 19920 << (LangOpts.OpenMP >= 50 ? 1 : 0) << RefExpr->getSourceRange(); 19921 continue; 19922 } 19923 19924 auto *ASE = dyn_cast<ArraySubscriptExpr>(SimpleExpr); 19925 if (ASE && !ASE->getBase()->isTypeDependent() && 19926 !ASE->getBase()->getType().getNonReferenceType()->isPointerType() && 19927 !ASE->getBase()->getType().getNonReferenceType()->isArrayType()) { 19928 Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item) 19929 << (LangOpts.OpenMP >= 50 ? 1 : 0) 19930 << (LangOpts.OpenMP >= 50 ? 1 : 0) << RefExpr->getSourceRange(); 19931 continue; 19932 } 19933 19934 ExprResult Res; 19935 { 19936 Sema::TentativeAnalysisScope Trap(*this); 19937 Res = CreateBuiltinUnaryOp(ELoc, UO_AddrOf, 19938 RefExpr->IgnoreParenImpCasts()); 19939 } 19940 if (!Res.isUsable() && !isa<OMPArraySectionExpr>(SimpleExpr) && 19941 !isa<OMPArrayShapingExpr>(SimpleExpr)) { 19942 Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item) 19943 << (LangOpts.OpenMP >= 50 ? 1 : 0) 19944 << (LangOpts.OpenMP >= 50 ? 1 : 0) << RefExpr->getSourceRange(); 19945 continue; 19946 } 19947 } 19948 } 19949 Vars.push_back(RefExpr->IgnoreParenImpCasts()); 19950 } 19951 19952 if (!CurContext->isDependentContext() && DepKind == OMPC_DEPEND_sink && 19953 TotalDepCount > VarList.size() && 19954 DSAStack->getParentOrderedRegionParam().first && 19955 DSAStack->getParentLoopControlVariable(VarList.size() + 1)) { 19956 Diag(EndLoc, diag::err_omp_depend_sink_expected_loop_iteration) 19957 << 1 << DSAStack->getParentLoopControlVariable(VarList.size() + 1); 19958 } 19959 if (DepKind != OMPC_DEPEND_source && DepKind != OMPC_DEPEND_sink && 19960 DepKind != OMPC_DEPEND_outallmemory && 19961 DepKind != OMPC_DEPEND_inoutallmemory && Vars.empty()) 19962 return nullptr; 19963 19964 auto *C = OMPDependClause::Create( 19965 Context, StartLoc, LParenLoc, EndLoc, 19966 {DepKind, DepLoc, Data.ColonLoc, Data.OmpAllMemoryLoc}, DepModifier, Vars, 19967 TotalDepCount.getZExtValue()); 19968 if ((DepKind == OMPC_DEPEND_sink || DepKind == OMPC_DEPEND_source) && 19969 DSAStack->isParentOrderedRegion()) 19970 DSAStack->addDoacrossDependClause(C, OpsOffs); 19971 return C; 19972 } 19973 19974 OMPClause *Sema::ActOnOpenMPDeviceClause(OpenMPDeviceClauseModifier Modifier, 19975 Expr *Device, SourceLocation StartLoc, 19976 SourceLocation LParenLoc, 19977 SourceLocation ModifierLoc, 19978 SourceLocation EndLoc) { 19979 assert((ModifierLoc.isInvalid() || LangOpts.OpenMP >= 50) && 19980 "Unexpected device modifier in OpenMP < 50."); 19981 19982 bool ErrorFound = false; 19983 if (ModifierLoc.isValid() && Modifier == OMPC_DEVICE_unknown) { 19984 std::string Values = 19985 getListOfPossibleValues(OMPC_device, /*First=*/0, OMPC_DEVICE_unknown); 19986 Diag(ModifierLoc, diag::err_omp_unexpected_clause_value) 19987 << Values << getOpenMPClauseName(OMPC_device); 19988 ErrorFound = true; 19989 } 19990 19991 Expr *ValExpr = Device; 19992 Stmt *HelperValStmt = nullptr; 19993 19994 // OpenMP [2.9.1, Restrictions] 19995 // The device expression must evaluate to a non-negative integer value. 19996 ErrorFound = !isNonNegativeIntegerValue(ValExpr, *this, OMPC_device, 19997 /*StrictlyPositive=*/false) || 19998 ErrorFound; 19999 if (ErrorFound) 20000 return nullptr; 20001 20002 // OpenMP 5.0 [2.12.5, Restrictions] 20003 // In case of ancestor device-modifier, a requires directive with 20004 // the reverse_offload clause must be specified. 20005 if (Modifier == OMPC_DEVICE_ancestor) { 20006 if (!DSAStack->hasRequiresDeclWithClause<OMPReverseOffloadClause>()) { 20007 targetDiag( 20008 StartLoc, 20009 diag::err_omp_device_ancestor_without_requires_reverse_offload); 20010 ErrorFound = true; 20011 } 20012 } 20013 20014 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 20015 OpenMPDirectiveKind CaptureRegion = 20016 getOpenMPCaptureRegionForClause(DKind, OMPC_device, LangOpts.OpenMP); 20017 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 20018 ValExpr = MakeFullExpr(ValExpr).get(); 20019 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 20020 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 20021 HelperValStmt = buildPreInits(Context, Captures); 20022 } 20023 20024 return new (Context) 20025 OMPDeviceClause(Modifier, ValExpr, HelperValStmt, CaptureRegion, StartLoc, 20026 LParenLoc, ModifierLoc, EndLoc); 20027 } 20028 20029 static bool checkTypeMappable(SourceLocation SL, SourceRange SR, Sema &SemaRef, 20030 DSAStackTy *Stack, QualType QTy, 20031 bool FullCheck = true) { 20032 if (SemaRef.RequireCompleteType(SL, QTy, diag::err_incomplete_type)) 20033 return false; 20034 if (FullCheck && !SemaRef.CurContext->isDependentContext() && 20035 !QTy.isTriviallyCopyableType(SemaRef.Context)) 20036 SemaRef.Diag(SL, diag::warn_omp_non_trivial_type_mapped) << QTy << SR; 20037 return true; 20038 } 20039 20040 /// Return true if it can be proven that the provided array expression 20041 /// (array section or array subscript) does NOT specify the whole size of the 20042 /// array whose base type is \a BaseQTy. 20043 static bool checkArrayExpressionDoesNotReferToWholeSize(Sema &SemaRef, 20044 const Expr *E, 20045 QualType BaseQTy) { 20046 const auto *OASE = dyn_cast<OMPArraySectionExpr>(E); 20047 20048 // If this is an array subscript, it refers to the whole size if the size of 20049 // the dimension is constant and equals 1. Also, an array section assumes the 20050 // format of an array subscript if no colon is used. 20051 if (isa<ArraySubscriptExpr>(E) || 20052 (OASE && OASE->getColonLocFirst().isInvalid())) { 20053 if (const auto *ATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr())) 20054 return ATy->getSize().getSExtValue() != 1; 20055 // Size can't be evaluated statically. 20056 return false; 20057 } 20058 20059 assert(OASE && "Expecting array section if not an array subscript."); 20060 const Expr *LowerBound = OASE->getLowerBound(); 20061 const Expr *Length = OASE->getLength(); 20062 20063 // If there is a lower bound that does not evaluates to zero, we are not 20064 // covering the whole dimension. 20065 if (LowerBound) { 20066 Expr::EvalResult Result; 20067 if (!LowerBound->EvaluateAsInt(Result, SemaRef.getASTContext())) 20068 return false; // Can't get the integer value as a constant. 20069 20070 llvm::APSInt ConstLowerBound = Result.Val.getInt(); 20071 if (ConstLowerBound.getSExtValue()) 20072 return true; 20073 } 20074 20075 // If we don't have a length we covering the whole dimension. 20076 if (!Length) 20077 return false; 20078 20079 // If the base is a pointer, we don't have a way to get the size of the 20080 // pointee. 20081 if (BaseQTy->isPointerType()) 20082 return false; 20083 20084 // We can only check if the length is the same as the size of the dimension 20085 // if we have a constant array. 20086 const auto *CATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr()); 20087 if (!CATy) 20088 return false; 20089 20090 Expr::EvalResult Result; 20091 if (!Length->EvaluateAsInt(Result, SemaRef.getASTContext())) 20092 return false; // Can't get the integer value as a constant. 20093 20094 llvm::APSInt ConstLength = Result.Val.getInt(); 20095 return CATy->getSize().getSExtValue() != ConstLength.getSExtValue(); 20096 } 20097 20098 // Return true if it can be proven that the provided array expression (array 20099 // section or array subscript) does NOT specify a single element of the array 20100 // whose base type is \a BaseQTy. 20101 static bool checkArrayExpressionDoesNotReferToUnitySize(Sema &SemaRef, 20102 const Expr *E, 20103 QualType BaseQTy) { 20104 const auto *OASE = dyn_cast<OMPArraySectionExpr>(E); 20105 20106 // An array subscript always refer to a single element. Also, an array section 20107 // assumes the format of an array subscript if no colon is used. 20108 if (isa<ArraySubscriptExpr>(E) || 20109 (OASE && OASE->getColonLocFirst().isInvalid())) 20110 return false; 20111 20112 assert(OASE && "Expecting array section if not an array subscript."); 20113 const Expr *Length = OASE->getLength(); 20114 20115 // If we don't have a length we have to check if the array has unitary size 20116 // for this dimension. Also, we should always expect a length if the base type 20117 // is pointer. 20118 if (!Length) { 20119 if (const auto *ATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr())) 20120 return ATy->getSize().getSExtValue() != 1; 20121 // We cannot assume anything. 20122 return false; 20123 } 20124 20125 // Check if the length evaluates to 1. 20126 Expr::EvalResult Result; 20127 if (!Length->EvaluateAsInt(Result, SemaRef.getASTContext())) 20128 return false; // Can't get the integer value as a constant. 20129 20130 llvm::APSInt ConstLength = Result.Val.getInt(); 20131 return ConstLength.getSExtValue() != 1; 20132 } 20133 20134 // The base of elements of list in a map clause have to be either: 20135 // - a reference to variable or field. 20136 // - a member expression. 20137 // - an array expression. 20138 // 20139 // E.g. if we have the expression 'r.S.Arr[:12]', we want to retrieve the 20140 // reference to 'r'. 20141 // 20142 // If we have: 20143 // 20144 // struct SS { 20145 // Bla S; 20146 // foo() { 20147 // #pragma omp target map (S.Arr[:12]); 20148 // } 20149 // } 20150 // 20151 // We want to retrieve the member expression 'this->S'; 20152 20153 // OpenMP 5.0 [2.19.7.1, map Clause, Restrictions, p.2] 20154 // If a list item is an array section, it must specify contiguous storage. 20155 // 20156 // For this restriction it is sufficient that we make sure only references 20157 // to variables or fields and array expressions, and that no array sections 20158 // exist except in the rightmost expression (unless they cover the whole 20159 // dimension of the array). E.g. these would be invalid: 20160 // 20161 // r.ArrS[3:5].Arr[6:7] 20162 // 20163 // r.ArrS[3:5].x 20164 // 20165 // but these would be valid: 20166 // r.ArrS[3].Arr[6:7] 20167 // 20168 // r.ArrS[3].x 20169 namespace { 20170 class MapBaseChecker final : public StmtVisitor<MapBaseChecker, bool> { 20171 Sema &SemaRef; 20172 OpenMPClauseKind CKind = OMPC_unknown; 20173 OpenMPDirectiveKind DKind = OMPD_unknown; 20174 OMPClauseMappableExprCommon::MappableExprComponentList &Components; 20175 bool IsNonContiguous = false; 20176 bool NoDiagnose = false; 20177 const Expr *RelevantExpr = nullptr; 20178 bool AllowUnitySizeArraySection = true; 20179 bool AllowWholeSizeArraySection = true; 20180 bool AllowAnotherPtr = true; 20181 SourceLocation ELoc; 20182 SourceRange ERange; 20183 20184 void emitErrorMsg() { 20185 // If nothing else worked, this is not a valid map clause expression. 20186 if (SemaRef.getLangOpts().OpenMP < 50) { 20187 SemaRef.Diag(ELoc, 20188 diag::err_omp_expected_named_var_member_or_array_expression) 20189 << ERange; 20190 } else { 20191 SemaRef.Diag(ELoc, diag::err_omp_non_lvalue_in_map_or_motion_clauses) 20192 << getOpenMPClauseName(CKind) << ERange; 20193 } 20194 } 20195 20196 public: 20197 bool VisitDeclRefExpr(DeclRefExpr *DRE) { 20198 if (!isa<VarDecl>(DRE->getDecl())) { 20199 emitErrorMsg(); 20200 return false; 20201 } 20202 assert(!RelevantExpr && "RelevantExpr is expected to be nullptr"); 20203 RelevantExpr = DRE; 20204 // Record the component. 20205 Components.emplace_back(DRE, DRE->getDecl(), IsNonContiguous); 20206 return true; 20207 } 20208 20209 bool VisitMemberExpr(MemberExpr *ME) { 20210 Expr *E = ME; 20211 Expr *BaseE = ME->getBase()->IgnoreParenCasts(); 20212 20213 if (isa<CXXThisExpr>(BaseE)) { 20214 assert(!RelevantExpr && "RelevantExpr is expected to be nullptr"); 20215 // We found a base expression: this->Val. 20216 RelevantExpr = ME; 20217 } else { 20218 E = BaseE; 20219 } 20220 20221 if (!isa<FieldDecl>(ME->getMemberDecl())) { 20222 if (!NoDiagnose) { 20223 SemaRef.Diag(ELoc, diag::err_omp_expected_access_to_data_field) 20224 << ME->getSourceRange(); 20225 return false; 20226 } 20227 if (RelevantExpr) 20228 return false; 20229 return Visit(E); 20230 } 20231 20232 auto *FD = cast<FieldDecl>(ME->getMemberDecl()); 20233 20234 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.3] 20235 // A bit-field cannot appear in a map clause. 20236 // 20237 if (FD->isBitField()) { 20238 if (!NoDiagnose) { 20239 SemaRef.Diag(ELoc, diag::err_omp_bit_fields_forbidden_in_clause) 20240 << ME->getSourceRange() << getOpenMPClauseName(CKind); 20241 return false; 20242 } 20243 if (RelevantExpr) 20244 return false; 20245 return Visit(E); 20246 } 20247 20248 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1] 20249 // If the type of a list item is a reference to a type T then the type 20250 // will be considered to be T for all purposes of this clause. 20251 QualType CurType = BaseE->getType().getNonReferenceType(); 20252 20253 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.2] 20254 // A list item cannot be a variable that is a member of a structure with 20255 // a union type. 20256 // 20257 if (CurType->isUnionType()) { 20258 if (!NoDiagnose) { 20259 SemaRef.Diag(ELoc, diag::err_omp_union_type_not_allowed) 20260 << ME->getSourceRange(); 20261 return false; 20262 } 20263 return RelevantExpr || Visit(E); 20264 } 20265 20266 // If we got a member expression, we should not expect any array section 20267 // before that: 20268 // 20269 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.7] 20270 // If a list item is an element of a structure, only the rightmost symbol 20271 // of the variable reference can be an array section. 20272 // 20273 AllowUnitySizeArraySection = false; 20274 AllowWholeSizeArraySection = false; 20275 20276 // Record the component. 20277 Components.emplace_back(ME, FD, IsNonContiguous); 20278 return RelevantExpr || Visit(E); 20279 } 20280 20281 bool VisitArraySubscriptExpr(ArraySubscriptExpr *AE) { 20282 Expr *E = AE->getBase()->IgnoreParenImpCasts(); 20283 20284 if (!E->getType()->isAnyPointerType() && !E->getType()->isArrayType()) { 20285 if (!NoDiagnose) { 20286 SemaRef.Diag(ELoc, diag::err_omp_expected_base_var_name) 20287 << 0 << AE->getSourceRange(); 20288 return false; 20289 } 20290 return RelevantExpr || Visit(E); 20291 } 20292 20293 // If we got an array subscript that express the whole dimension we 20294 // can have any array expressions before. If it only expressing part of 20295 // the dimension, we can only have unitary-size array expressions. 20296 if (checkArrayExpressionDoesNotReferToWholeSize(SemaRef, AE, E->getType())) 20297 AllowWholeSizeArraySection = false; 20298 20299 if (const auto *TE = dyn_cast<CXXThisExpr>(E->IgnoreParenCasts())) { 20300 Expr::EvalResult Result; 20301 if (!AE->getIdx()->isValueDependent() && 20302 AE->getIdx()->EvaluateAsInt(Result, SemaRef.getASTContext()) && 20303 !Result.Val.getInt().isZero()) { 20304 SemaRef.Diag(AE->getIdx()->getExprLoc(), 20305 diag::err_omp_invalid_map_this_expr); 20306 SemaRef.Diag(AE->getIdx()->getExprLoc(), 20307 diag::note_omp_invalid_subscript_on_this_ptr_map); 20308 } 20309 assert(!RelevantExpr && "RelevantExpr is expected to be nullptr"); 20310 RelevantExpr = TE; 20311 } 20312 20313 // Record the component - we don't have any declaration associated. 20314 Components.emplace_back(AE, nullptr, IsNonContiguous); 20315 20316 return RelevantExpr || Visit(E); 20317 } 20318 20319 bool VisitOMPArraySectionExpr(OMPArraySectionExpr *OASE) { 20320 // After OMP 5.0 Array section in reduction clause will be implicitly 20321 // mapped 20322 assert(!(SemaRef.getLangOpts().OpenMP < 50 && NoDiagnose) && 20323 "Array sections cannot be implicitly mapped."); 20324 Expr *E = OASE->getBase()->IgnoreParenImpCasts(); 20325 QualType CurType = 20326 OMPArraySectionExpr::getBaseOriginalType(E).getCanonicalType(); 20327 20328 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1] 20329 // If the type of a list item is a reference to a type T then the type 20330 // will be considered to be T for all purposes of this clause. 20331 if (CurType->isReferenceType()) 20332 CurType = CurType->getPointeeType(); 20333 20334 bool IsPointer = CurType->isAnyPointerType(); 20335 20336 if (!IsPointer && !CurType->isArrayType()) { 20337 SemaRef.Diag(ELoc, diag::err_omp_expected_base_var_name) 20338 << 0 << OASE->getSourceRange(); 20339 return false; 20340 } 20341 20342 bool NotWhole = 20343 checkArrayExpressionDoesNotReferToWholeSize(SemaRef, OASE, CurType); 20344 bool NotUnity = 20345 checkArrayExpressionDoesNotReferToUnitySize(SemaRef, OASE, CurType); 20346 20347 if (AllowWholeSizeArraySection) { 20348 // Any array section is currently allowed. Allowing a whole size array 20349 // section implies allowing a unity array section as well. 20350 // 20351 // If this array section refers to the whole dimension we can still 20352 // accept other array sections before this one, except if the base is a 20353 // pointer. Otherwise, only unitary sections are accepted. 20354 if (NotWhole || IsPointer) 20355 AllowWholeSizeArraySection = false; 20356 } else if (DKind == OMPD_target_update && 20357 SemaRef.getLangOpts().OpenMP >= 50) { 20358 if (IsPointer && !AllowAnotherPtr) 20359 SemaRef.Diag(ELoc, diag::err_omp_section_length_undefined) 20360 << /*array of unknown bound */ 1; 20361 else 20362 IsNonContiguous = true; 20363 } else if (AllowUnitySizeArraySection && NotUnity) { 20364 // A unity or whole array section is not allowed and that is not 20365 // compatible with the properties of the current array section. 20366 if (NoDiagnose) 20367 return false; 20368 SemaRef.Diag(ELoc, 20369 diag::err_array_section_does_not_specify_contiguous_storage) 20370 << OASE->getSourceRange(); 20371 return false; 20372 } 20373 20374 if (IsPointer) 20375 AllowAnotherPtr = false; 20376 20377 if (const auto *TE = dyn_cast<CXXThisExpr>(E)) { 20378 Expr::EvalResult ResultR; 20379 Expr::EvalResult ResultL; 20380 if (!OASE->getLength()->isValueDependent() && 20381 OASE->getLength()->EvaluateAsInt(ResultR, SemaRef.getASTContext()) && 20382 !ResultR.Val.getInt().isOne()) { 20383 SemaRef.Diag(OASE->getLength()->getExprLoc(), 20384 diag::err_omp_invalid_map_this_expr); 20385 SemaRef.Diag(OASE->getLength()->getExprLoc(), 20386 diag::note_omp_invalid_length_on_this_ptr_mapping); 20387 } 20388 if (OASE->getLowerBound() && !OASE->getLowerBound()->isValueDependent() && 20389 OASE->getLowerBound()->EvaluateAsInt(ResultL, 20390 SemaRef.getASTContext()) && 20391 !ResultL.Val.getInt().isZero()) { 20392 SemaRef.Diag(OASE->getLowerBound()->getExprLoc(), 20393 diag::err_omp_invalid_map_this_expr); 20394 SemaRef.Diag(OASE->getLowerBound()->getExprLoc(), 20395 diag::note_omp_invalid_lower_bound_on_this_ptr_mapping); 20396 } 20397 assert(!RelevantExpr && "RelevantExpr is expected to be nullptr"); 20398 RelevantExpr = TE; 20399 } 20400 20401 // Record the component - we don't have any declaration associated. 20402 Components.emplace_back(OASE, nullptr, /*IsNonContiguous=*/false); 20403 return RelevantExpr || Visit(E); 20404 } 20405 bool VisitOMPArrayShapingExpr(OMPArrayShapingExpr *E) { 20406 Expr *Base = E->getBase(); 20407 20408 // Record the component - we don't have any declaration associated. 20409 Components.emplace_back(E, nullptr, IsNonContiguous); 20410 20411 return Visit(Base->IgnoreParenImpCasts()); 20412 } 20413 20414 bool VisitUnaryOperator(UnaryOperator *UO) { 20415 if (SemaRef.getLangOpts().OpenMP < 50 || !UO->isLValue() || 20416 UO->getOpcode() != UO_Deref) { 20417 emitErrorMsg(); 20418 return false; 20419 } 20420 if (!RelevantExpr) { 20421 // Record the component if haven't found base decl. 20422 Components.emplace_back(UO, nullptr, /*IsNonContiguous=*/false); 20423 } 20424 return RelevantExpr || Visit(UO->getSubExpr()->IgnoreParenImpCasts()); 20425 } 20426 bool VisitBinaryOperator(BinaryOperator *BO) { 20427 if (SemaRef.getLangOpts().OpenMP < 50 || !BO->getType()->isPointerType()) { 20428 emitErrorMsg(); 20429 return false; 20430 } 20431 20432 // Pointer arithmetic is the only thing we expect to happen here so after we 20433 // make sure the binary operator is a pointer type, the we only thing need 20434 // to to is to visit the subtree that has the same type as root (so that we 20435 // know the other subtree is just an offset) 20436 Expr *LE = BO->getLHS()->IgnoreParenImpCasts(); 20437 Expr *RE = BO->getRHS()->IgnoreParenImpCasts(); 20438 Components.emplace_back(BO, nullptr, false); 20439 assert((LE->getType().getTypePtr() == BO->getType().getTypePtr() || 20440 RE->getType().getTypePtr() == BO->getType().getTypePtr()) && 20441 "Either LHS or RHS have base decl inside"); 20442 if (BO->getType().getTypePtr() == LE->getType().getTypePtr()) 20443 return RelevantExpr || Visit(LE); 20444 return RelevantExpr || Visit(RE); 20445 } 20446 bool VisitCXXThisExpr(CXXThisExpr *CTE) { 20447 assert(!RelevantExpr && "RelevantExpr is expected to be nullptr"); 20448 RelevantExpr = CTE; 20449 Components.emplace_back(CTE, nullptr, IsNonContiguous); 20450 return true; 20451 } 20452 bool VisitCXXOperatorCallExpr(CXXOperatorCallExpr *COCE) { 20453 assert(!RelevantExpr && "RelevantExpr is expected to be nullptr"); 20454 Components.emplace_back(COCE, nullptr, IsNonContiguous); 20455 return true; 20456 } 20457 bool VisitOpaqueValueExpr(OpaqueValueExpr *E) { 20458 Expr *Source = E->getSourceExpr(); 20459 if (!Source) { 20460 emitErrorMsg(); 20461 return false; 20462 } 20463 return Visit(Source); 20464 } 20465 bool VisitStmt(Stmt *) { 20466 emitErrorMsg(); 20467 return false; 20468 } 20469 const Expr *getFoundBase() const { return RelevantExpr; } 20470 explicit MapBaseChecker( 20471 Sema &SemaRef, OpenMPClauseKind CKind, OpenMPDirectiveKind DKind, 20472 OMPClauseMappableExprCommon::MappableExprComponentList &Components, 20473 bool NoDiagnose, SourceLocation &ELoc, SourceRange &ERange) 20474 : SemaRef(SemaRef), CKind(CKind), DKind(DKind), Components(Components), 20475 NoDiagnose(NoDiagnose), ELoc(ELoc), ERange(ERange) {} 20476 }; 20477 } // namespace 20478 20479 /// Return the expression of the base of the mappable expression or null if it 20480 /// cannot be determined and do all the necessary checks to see if the 20481 /// expression is valid as a standalone mappable expression. In the process, 20482 /// record all the components of the expression. 20483 static const Expr *checkMapClauseExpressionBase( 20484 Sema &SemaRef, Expr *E, 20485 OMPClauseMappableExprCommon::MappableExprComponentList &CurComponents, 20486 OpenMPClauseKind CKind, OpenMPDirectiveKind DKind, bool NoDiagnose) { 20487 SourceLocation ELoc = E->getExprLoc(); 20488 SourceRange ERange = E->getSourceRange(); 20489 MapBaseChecker Checker(SemaRef, CKind, DKind, CurComponents, NoDiagnose, ELoc, 20490 ERange); 20491 if (Checker.Visit(E->IgnoreParens())) { 20492 // Check if the highest dimension array section has length specified 20493 if (SemaRef.getLangOpts().OpenMP >= 50 && !CurComponents.empty() && 20494 (CKind == OMPC_to || CKind == OMPC_from)) { 20495 auto CI = CurComponents.rbegin(); 20496 auto CE = CurComponents.rend(); 20497 for (; CI != CE; ++CI) { 20498 const auto *OASE = 20499 dyn_cast<OMPArraySectionExpr>(CI->getAssociatedExpression()); 20500 if (!OASE) 20501 continue; 20502 if (OASE && OASE->getLength()) 20503 break; 20504 SemaRef.Diag(ELoc, diag::err_array_section_does_not_specify_length) 20505 << ERange; 20506 } 20507 } 20508 return Checker.getFoundBase(); 20509 } 20510 return nullptr; 20511 } 20512 20513 // Return true if expression E associated with value VD has conflicts with other 20514 // map information. 20515 static bool checkMapConflicts( 20516 Sema &SemaRef, DSAStackTy *DSAS, const ValueDecl *VD, const Expr *E, 20517 bool CurrentRegionOnly, 20518 OMPClauseMappableExprCommon::MappableExprComponentListRef CurComponents, 20519 OpenMPClauseKind CKind) { 20520 assert(VD && E); 20521 SourceLocation ELoc = E->getExprLoc(); 20522 SourceRange ERange = E->getSourceRange(); 20523 20524 // In order to easily check the conflicts we need to match each component of 20525 // the expression under test with the components of the expressions that are 20526 // already in the stack. 20527 20528 assert(!CurComponents.empty() && "Map clause expression with no components!"); 20529 assert(CurComponents.back().getAssociatedDeclaration() == VD && 20530 "Map clause expression with unexpected base!"); 20531 20532 // Variables to help detecting enclosing problems in data environment nests. 20533 bool IsEnclosedByDataEnvironmentExpr = false; 20534 const Expr *EnclosingExpr = nullptr; 20535 20536 bool FoundError = DSAS->checkMappableExprComponentListsForDecl( 20537 VD, CurrentRegionOnly, 20538 [&IsEnclosedByDataEnvironmentExpr, &SemaRef, VD, CurrentRegionOnly, ELoc, 20539 ERange, CKind, &EnclosingExpr, 20540 CurComponents](OMPClauseMappableExprCommon::MappableExprComponentListRef 20541 StackComponents, 20542 OpenMPClauseKind Kind) { 20543 if (CKind == Kind && SemaRef.LangOpts.OpenMP >= 50) 20544 return false; 20545 assert(!StackComponents.empty() && 20546 "Map clause expression with no components!"); 20547 assert(StackComponents.back().getAssociatedDeclaration() == VD && 20548 "Map clause expression with unexpected base!"); 20549 (void)VD; 20550 20551 // The whole expression in the stack. 20552 const Expr *RE = StackComponents.front().getAssociatedExpression(); 20553 20554 // Expressions must start from the same base. Here we detect at which 20555 // point both expressions diverge from each other and see if we can 20556 // detect if the memory referred to both expressions is contiguous and 20557 // do not overlap. 20558 auto CI = CurComponents.rbegin(); 20559 auto CE = CurComponents.rend(); 20560 auto SI = StackComponents.rbegin(); 20561 auto SE = StackComponents.rend(); 20562 for (; CI != CE && SI != SE; ++CI, ++SI) { 20563 20564 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.3] 20565 // At most one list item can be an array item derived from a given 20566 // variable in map clauses of the same construct. 20567 if (CurrentRegionOnly && 20568 (isa<ArraySubscriptExpr>(CI->getAssociatedExpression()) || 20569 isa<OMPArraySectionExpr>(CI->getAssociatedExpression()) || 20570 isa<OMPArrayShapingExpr>(CI->getAssociatedExpression())) && 20571 (isa<ArraySubscriptExpr>(SI->getAssociatedExpression()) || 20572 isa<OMPArraySectionExpr>(SI->getAssociatedExpression()) || 20573 isa<OMPArrayShapingExpr>(SI->getAssociatedExpression()))) { 20574 SemaRef.Diag(CI->getAssociatedExpression()->getExprLoc(), 20575 diag::err_omp_multiple_array_items_in_map_clause) 20576 << CI->getAssociatedExpression()->getSourceRange(); 20577 SemaRef.Diag(SI->getAssociatedExpression()->getExprLoc(), 20578 diag::note_used_here) 20579 << SI->getAssociatedExpression()->getSourceRange(); 20580 return true; 20581 } 20582 20583 // Do both expressions have the same kind? 20584 if (CI->getAssociatedExpression()->getStmtClass() != 20585 SI->getAssociatedExpression()->getStmtClass()) 20586 break; 20587 20588 // Are we dealing with different variables/fields? 20589 if (CI->getAssociatedDeclaration() != SI->getAssociatedDeclaration()) 20590 break; 20591 } 20592 // Check if the extra components of the expressions in the enclosing 20593 // data environment are redundant for the current base declaration. 20594 // If they are, the maps completely overlap, which is legal. 20595 for (; SI != SE; ++SI) { 20596 QualType Type; 20597 if (const auto *ASE = 20598 dyn_cast<ArraySubscriptExpr>(SI->getAssociatedExpression())) { 20599 Type = ASE->getBase()->IgnoreParenImpCasts()->getType(); 20600 } else if (const auto *OASE = dyn_cast<OMPArraySectionExpr>( 20601 SI->getAssociatedExpression())) { 20602 const Expr *E = OASE->getBase()->IgnoreParenImpCasts(); 20603 Type = 20604 OMPArraySectionExpr::getBaseOriginalType(E).getCanonicalType(); 20605 } else if (const auto *OASE = dyn_cast<OMPArrayShapingExpr>( 20606 SI->getAssociatedExpression())) { 20607 Type = OASE->getBase()->getType()->getPointeeType(); 20608 } 20609 if (Type.isNull() || Type->isAnyPointerType() || 20610 checkArrayExpressionDoesNotReferToWholeSize( 20611 SemaRef, SI->getAssociatedExpression(), Type)) 20612 break; 20613 } 20614 20615 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.4] 20616 // List items of map clauses in the same construct must not share 20617 // original storage. 20618 // 20619 // If the expressions are exactly the same or one is a subset of the 20620 // other, it means they are sharing storage. 20621 if (CI == CE && SI == SE) { 20622 if (CurrentRegionOnly) { 20623 if (CKind == OMPC_map) { 20624 SemaRef.Diag(ELoc, diag::err_omp_map_shared_storage) << ERange; 20625 } else { 20626 assert(CKind == OMPC_to || CKind == OMPC_from); 20627 SemaRef.Diag(ELoc, diag::err_omp_once_referenced_in_target_update) 20628 << ERange; 20629 } 20630 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here) 20631 << RE->getSourceRange(); 20632 return true; 20633 } 20634 // If we find the same expression in the enclosing data environment, 20635 // that is legal. 20636 IsEnclosedByDataEnvironmentExpr = true; 20637 return false; 20638 } 20639 20640 QualType DerivedType = 20641 std::prev(CI)->getAssociatedDeclaration()->getType(); 20642 SourceLocation DerivedLoc = 20643 std::prev(CI)->getAssociatedExpression()->getExprLoc(); 20644 20645 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1] 20646 // If the type of a list item is a reference to a type T then the type 20647 // will be considered to be T for all purposes of this clause. 20648 DerivedType = DerivedType.getNonReferenceType(); 20649 20650 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.1] 20651 // A variable for which the type is pointer and an array section 20652 // derived from that variable must not appear as list items of map 20653 // clauses of the same construct. 20654 // 20655 // Also, cover one of the cases in: 20656 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.5] 20657 // If any part of the original storage of a list item has corresponding 20658 // storage in the device data environment, all of the original storage 20659 // must have corresponding storage in the device data environment. 20660 // 20661 if (DerivedType->isAnyPointerType()) { 20662 if (CI == CE || SI == SE) { 20663 SemaRef.Diag( 20664 DerivedLoc, 20665 diag::err_omp_pointer_mapped_along_with_derived_section) 20666 << DerivedLoc; 20667 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here) 20668 << RE->getSourceRange(); 20669 return true; 20670 } 20671 if (CI->getAssociatedExpression()->getStmtClass() != 20672 SI->getAssociatedExpression()->getStmtClass() || 20673 CI->getAssociatedDeclaration()->getCanonicalDecl() == 20674 SI->getAssociatedDeclaration()->getCanonicalDecl()) { 20675 assert(CI != CE && SI != SE); 20676 SemaRef.Diag(DerivedLoc, diag::err_omp_same_pointer_dereferenced) 20677 << DerivedLoc; 20678 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here) 20679 << RE->getSourceRange(); 20680 return true; 20681 } 20682 } 20683 20684 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.4] 20685 // List items of map clauses in the same construct must not share 20686 // original storage. 20687 // 20688 // An expression is a subset of the other. 20689 if (CurrentRegionOnly && (CI == CE || SI == SE)) { 20690 if (CKind == OMPC_map) { 20691 if (CI != CE || SI != SE) { 20692 // Allow constructs like this: map(s, s.ptr[0:1]), where s.ptr is 20693 // a pointer. 20694 auto Begin = 20695 CI != CE ? CurComponents.begin() : StackComponents.begin(); 20696 auto End = CI != CE ? CurComponents.end() : StackComponents.end(); 20697 auto It = Begin; 20698 while (It != End && !It->getAssociatedDeclaration()) 20699 std::advance(It, 1); 20700 assert(It != End && 20701 "Expected at least one component with the declaration."); 20702 if (It != Begin && It->getAssociatedDeclaration() 20703 ->getType() 20704 .getCanonicalType() 20705 ->isAnyPointerType()) { 20706 IsEnclosedByDataEnvironmentExpr = false; 20707 EnclosingExpr = nullptr; 20708 return false; 20709 } 20710 } 20711 SemaRef.Diag(ELoc, diag::err_omp_map_shared_storage) << ERange; 20712 } else { 20713 assert(CKind == OMPC_to || CKind == OMPC_from); 20714 SemaRef.Diag(ELoc, diag::err_omp_once_referenced_in_target_update) 20715 << ERange; 20716 } 20717 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here) 20718 << RE->getSourceRange(); 20719 return true; 20720 } 20721 20722 // The current expression uses the same base as other expression in the 20723 // data environment but does not contain it completely. 20724 if (!CurrentRegionOnly && SI != SE) 20725 EnclosingExpr = RE; 20726 20727 // The current expression is a subset of the expression in the data 20728 // environment. 20729 IsEnclosedByDataEnvironmentExpr |= 20730 (!CurrentRegionOnly && CI != CE && SI == SE); 20731 20732 return false; 20733 }); 20734 20735 if (CurrentRegionOnly) 20736 return FoundError; 20737 20738 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.5] 20739 // If any part of the original storage of a list item has corresponding 20740 // storage in the device data environment, all of the original storage must 20741 // have corresponding storage in the device data environment. 20742 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.6] 20743 // If a list item is an element of a structure, and a different element of 20744 // the structure has a corresponding list item in the device data environment 20745 // prior to a task encountering the construct associated with the map clause, 20746 // then the list item must also have a corresponding list item in the device 20747 // data environment prior to the task encountering the construct. 20748 // 20749 if (EnclosingExpr && !IsEnclosedByDataEnvironmentExpr) { 20750 SemaRef.Diag(ELoc, 20751 diag::err_omp_original_storage_is_shared_and_does_not_contain) 20752 << ERange; 20753 SemaRef.Diag(EnclosingExpr->getExprLoc(), diag::note_used_here) 20754 << EnclosingExpr->getSourceRange(); 20755 return true; 20756 } 20757 20758 return FoundError; 20759 } 20760 20761 // Look up the user-defined mapper given the mapper name and mapped type, and 20762 // build a reference to it. 20763 static ExprResult buildUserDefinedMapperRef(Sema &SemaRef, Scope *S, 20764 CXXScopeSpec &MapperIdScopeSpec, 20765 const DeclarationNameInfo &MapperId, 20766 QualType Type, 20767 Expr *UnresolvedMapper) { 20768 if (MapperIdScopeSpec.isInvalid()) 20769 return ExprError(); 20770 // Get the actual type for the array type. 20771 if (Type->isArrayType()) { 20772 assert(Type->getAsArrayTypeUnsafe() && "Expect to get a valid array type"); 20773 Type = Type->getAsArrayTypeUnsafe()->getElementType().getCanonicalType(); 20774 } 20775 // Find all user-defined mappers with the given MapperId. 20776 SmallVector<UnresolvedSet<8>, 4> Lookups; 20777 LookupResult Lookup(SemaRef, MapperId, Sema::LookupOMPMapperName); 20778 Lookup.suppressDiagnostics(); 20779 if (S) { 20780 while (S && SemaRef.LookupParsedName(Lookup, S, &MapperIdScopeSpec)) { 20781 NamedDecl *D = Lookup.getRepresentativeDecl(); 20782 while (S && !S->isDeclScope(D)) 20783 S = S->getParent(); 20784 if (S) 20785 S = S->getParent(); 20786 Lookups.emplace_back(); 20787 Lookups.back().append(Lookup.begin(), Lookup.end()); 20788 Lookup.clear(); 20789 } 20790 } else if (auto *ULE = cast_or_null<UnresolvedLookupExpr>(UnresolvedMapper)) { 20791 // Extract the user-defined mappers with the given MapperId. 20792 Lookups.push_back(UnresolvedSet<8>()); 20793 for (NamedDecl *D : ULE->decls()) { 20794 auto *DMD = cast<OMPDeclareMapperDecl>(D); 20795 assert(DMD && "Expect valid OMPDeclareMapperDecl during instantiation."); 20796 Lookups.back().addDecl(DMD); 20797 } 20798 } 20799 // Defer the lookup for dependent types. The results will be passed through 20800 // UnresolvedMapper on instantiation. 20801 if (SemaRef.CurContext->isDependentContext() || Type->isDependentType() || 20802 Type->isInstantiationDependentType() || 20803 Type->containsUnexpandedParameterPack() || 20804 filterLookupForUDReductionAndMapper<bool>(Lookups, [](ValueDecl *D) { 20805 return !D->isInvalidDecl() && 20806 (D->getType()->isDependentType() || 20807 D->getType()->isInstantiationDependentType() || 20808 D->getType()->containsUnexpandedParameterPack()); 20809 })) { 20810 UnresolvedSet<8> URS; 20811 for (const UnresolvedSet<8> &Set : Lookups) { 20812 if (Set.empty()) 20813 continue; 20814 URS.append(Set.begin(), Set.end()); 20815 } 20816 return UnresolvedLookupExpr::Create( 20817 SemaRef.Context, /*NamingClass=*/nullptr, 20818 MapperIdScopeSpec.getWithLocInContext(SemaRef.Context), MapperId, 20819 /*ADL=*/false, /*Overloaded=*/true, URS.begin(), URS.end()); 20820 } 20821 SourceLocation Loc = MapperId.getLoc(); 20822 // [OpenMP 5.0], 2.19.7.3 declare mapper Directive, Restrictions 20823 // The type must be of struct, union or class type in C and C++ 20824 if (!Type->isStructureOrClassType() && !Type->isUnionType() && 20825 (MapperIdScopeSpec.isSet() || MapperId.getAsString() != "default")) { 20826 SemaRef.Diag(Loc, diag::err_omp_mapper_wrong_type); 20827 return ExprError(); 20828 } 20829 // Perform argument dependent lookup. 20830 if (SemaRef.getLangOpts().CPlusPlus && !MapperIdScopeSpec.isSet()) 20831 argumentDependentLookup(SemaRef, MapperId, Loc, Type, Lookups); 20832 // Return the first user-defined mapper with the desired type. 20833 if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>( 20834 Lookups, [&SemaRef, Type](ValueDecl *D) -> ValueDecl * { 20835 if (!D->isInvalidDecl() && 20836 SemaRef.Context.hasSameType(D->getType(), Type)) 20837 return D; 20838 return nullptr; 20839 })) 20840 return SemaRef.BuildDeclRefExpr(VD, Type, VK_LValue, Loc); 20841 // Find the first user-defined mapper with a type derived from the desired 20842 // type. 20843 if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>( 20844 Lookups, [&SemaRef, Type, Loc](ValueDecl *D) -> ValueDecl * { 20845 if (!D->isInvalidDecl() && 20846 SemaRef.IsDerivedFrom(Loc, Type, D->getType()) && 20847 !Type.isMoreQualifiedThan(D->getType())) 20848 return D; 20849 return nullptr; 20850 })) { 20851 CXXBasePaths Paths(/*FindAmbiguities=*/true, /*RecordPaths=*/true, 20852 /*DetectVirtual=*/false); 20853 if (SemaRef.IsDerivedFrom(Loc, Type, VD->getType(), Paths)) { 20854 if (!Paths.isAmbiguous(SemaRef.Context.getCanonicalType( 20855 VD->getType().getUnqualifiedType()))) { 20856 if (SemaRef.CheckBaseClassAccess( 20857 Loc, VD->getType(), Type, Paths.front(), 20858 /*DiagID=*/0) != Sema::AR_inaccessible) { 20859 return SemaRef.BuildDeclRefExpr(VD, Type, VK_LValue, Loc); 20860 } 20861 } 20862 } 20863 } 20864 // Report error if a mapper is specified, but cannot be found. 20865 if (MapperIdScopeSpec.isSet() || MapperId.getAsString() != "default") { 20866 SemaRef.Diag(Loc, diag::err_omp_invalid_mapper) 20867 << Type << MapperId.getName(); 20868 return ExprError(); 20869 } 20870 return ExprEmpty(); 20871 } 20872 20873 namespace { 20874 // Utility struct that gathers all the related lists associated with a mappable 20875 // expression. 20876 struct MappableVarListInfo { 20877 // The list of expressions. 20878 ArrayRef<Expr *> VarList; 20879 // The list of processed expressions. 20880 SmallVector<Expr *, 16> ProcessedVarList; 20881 // The mappble components for each expression. 20882 OMPClauseMappableExprCommon::MappableExprComponentLists VarComponents; 20883 // The base declaration of the variable. 20884 SmallVector<ValueDecl *, 16> VarBaseDeclarations; 20885 // The reference to the user-defined mapper associated with every expression. 20886 SmallVector<Expr *, 16> UDMapperList; 20887 20888 MappableVarListInfo(ArrayRef<Expr *> VarList) : VarList(VarList) { 20889 // We have a list of components and base declarations for each entry in the 20890 // variable list. 20891 VarComponents.reserve(VarList.size()); 20892 VarBaseDeclarations.reserve(VarList.size()); 20893 } 20894 }; 20895 } // namespace 20896 20897 // Check the validity of the provided variable list for the provided clause kind 20898 // \a CKind. In the check process the valid expressions, mappable expression 20899 // components, variables, and user-defined mappers are extracted and used to 20900 // fill \a ProcessedVarList, \a VarComponents, \a VarBaseDeclarations, and \a 20901 // UDMapperList in MVLI. \a MapType, \a IsMapTypeImplicit, \a MapperIdScopeSpec, 20902 // and \a MapperId are expected to be valid if the clause kind is 'map'. 20903 static void checkMappableExpressionList( 20904 Sema &SemaRef, DSAStackTy *DSAS, OpenMPClauseKind CKind, 20905 MappableVarListInfo &MVLI, SourceLocation StartLoc, 20906 CXXScopeSpec &MapperIdScopeSpec, DeclarationNameInfo MapperId, 20907 ArrayRef<Expr *> UnresolvedMappers, 20908 OpenMPMapClauseKind MapType = OMPC_MAP_unknown, 20909 ArrayRef<OpenMPMapModifierKind> Modifiers = None, 20910 bool IsMapTypeImplicit = false, bool NoDiagnose = false) { 20911 // We only expect mappable expressions in 'to', 'from', and 'map' clauses. 20912 assert((CKind == OMPC_map || CKind == OMPC_to || CKind == OMPC_from) && 20913 "Unexpected clause kind with mappable expressions!"); 20914 20915 // If the identifier of user-defined mapper is not specified, it is "default". 20916 // We do not change the actual name in this clause to distinguish whether a 20917 // mapper is specified explicitly, i.e., it is not explicitly specified when 20918 // MapperId.getName() is empty. 20919 if (!MapperId.getName() || MapperId.getName().isEmpty()) { 20920 auto &DeclNames = SemaRef.getASTContext().DeclarationNames; 20921 MapperId.setName(DeclNames.getIdentifier( 20922 &SemaRef.getASTContext().Idents.get("default"))); 20923 MapperId.setLoc(StartLoc); 20924 } 20925 20926 // Iterators to find the current unresolved mapper expression. 20927 auto UMIt = UnresolvedMappers.begin(), UMEnd = UnresolvedMappers.end(); 20928 bool UpdateUMIt = false; 20929 Expr *UnresolvedMapper = nullptr; 20930 20931 bool HasHoldModifier = 20932 llvm::is_contained(Modifiers, OMPC_MAP_MODIFIER_ompx_hold); 20933 20934 // Keep track of the mappable components and base declarations in this clause. 20935 // Each entry in the list is going to have a list of components associated. We 20936 // record each set of the components so that we can build the clause later on. 20937 // In the end we should have the same amount of declarations and component 20938 // lists. 20939 20940 for (Expr *RE : MVLI.VarList) { 20941 assert(RE && "Null expr in omp to/from/map clause"); 20942 SourceLocation ELoc = RE->getExprLoc(); 20943 20944 // Find the current unresolved mapper expression. 20945 if (UpdateUMIt && UMIt != UMEnd) { 20946 UMIt++; 20947 assert( 20948 UMIt != UMEnd && 20949 "Expect the size of UnresolvedMappers to match with that of VarList"); 20950 } 20951 UpdateUMIt = true; 20952 if (UMIt != UMEnd) 20953 UnresolvedMapper = *UMIt; 20954 20955 const Expr *VE = RE->IgnoreParenLValueCasts(); 20956 20957 if (VE->isValueDependent() || VE->isTypeDependent() || 20958 VE->isInstantiationDependent() || 20959 VE->containsUnexpandedParameterPack()) { 20960 // Try to find the associated user-defined mapper. 20961 ExprResult ER = buildUserDefinedMapperRef( 20962 SemaRef, DSAS->getCurScope(), MapperIdScopeSpec, MapperId, 20963 VE->getType().getCanonicalType(), UnresolvedMapper); 20964 if (ER.isInvalid()) 20965 continue; 20966 MVLI.UDMapperList.push_back(ER.get()); 20967 // We can only analyze this information once the missing information is 20968 // resolved. 20969 MVLI.ProcessedVarList.push_back(RE); 20970 continue; 20971 } 20972 20973 Expr *SimpleExpr = RE->IgnoreParenCasts(); 20974 20975 if (!RE->isLValue()) { 20976 if (SemaRef.getLangOpts().OpenMP < 50) { 20977 SemaRef.Diag( 20978 ELoc, diag::err_omp_expected_named_var_member_or_array_expression) 20979 << RE->getSourceRange(); 20980 } else { 20981 SemaRef.Diag(ELoc, diag::err_omp_non_lvalue_in_map_or_motion_clauses) 20982 << getOpenMPClauseName(CKind) << RE->getSourceRange(); 20983 } 20984 continue; 20985 } 20986 20987 OMPClauseMappableExprCommon::MappableExprComponentList CurComponents; 20988 ValueDecl *CurDeclaration = nullptr; 20989 20990 // Obtain the array or member expression bases if required. Also, fill the 20991 // components array with all the components identified in the process. 20992 const Expr *BE = 20993 checkMapClauseExpressionBase(SemaRef, SimpleExpr, CurComponents, CKind, 20994 DSAS->getCurrentDirective(), NoDiagnose); 20995 if (!BE) 20996 continue; 20997 20998 assert(!CurComponents.empty() && 20999 "Invalid mappable expression information."); 21000 21001 if (const auto *TE = dyn_cast<CXXThisExpr>(BE)) { 21002 // Add store "this" pointer to class in DSAStackTy for future checking 21003 DSAS->addMappedClassesQualTypes(TE->getType()); 21004 // Try to find the associated user-defined mapper. 21005 ExprResult ER = buildUserDefinedMapperRef( 21006 SemaRef, DSAS->getCurScope(), MapperIdScopeSpec, MapperId, 21007 VE->getType().getCanonicalType(), UnresolvedMapper); 21008 if (ER.isInvalid()) 21009 continue; 21010 MVLI.UDMapperList.push_back(ER.get()); 21011 // Skip restriction checking for variable or field declarations 21012 MVLI.ProcessedVarList.push_back(RE); 21013 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1); 21014 MVLI.VarComponents.back().append(CurComponents.begin(), 21015 CurComponents.end()); 21016 MVLI.VarBaseDeclarations.push_back(nullptr); 21017 continue; 21018 } 21019 21020 // For the following checks, we rely on the base declaration which is 21021 // expected to be associated with the last component. The declaration is 21022 // expected to be a variable or a field (if 'this' is being mapped). 21023 CurDeclaration = CurComponents.back().getAssociatedDeclaration(); 21024 assert(CurDeclaration && "Null decl on map clause."); 21025 assert( 21026 CurDeclaration->isCanonicalDecl() && 21027 "Expecting components to have associated only canonical declarations."); 21028 21029 auto *VD = dyn_cast<VarDecl>(CurDeclaration); 21030 const auto *FD = dyn_cast<FieldDecl>(CurDeclaration); 21031 21032 assert((VD || FD) && "Only variables or fields are expected here!"); 21033 (void)FD; 21034 21035 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.10] 21036 // threadprivate variables cannot appear in a map clause. 21037 // OpenMP 4.5 [2.10.5, target update Construct] 21038 // threadprivate variables cannot appear in a from clause. 21039 if (VD && DSAS->isThreadPrivate(VD)) { 21040 if (NoDiagnose) 21041 continue; 21042 DSAStackTy::DSAVarData DVar = DSAS->getTopDSA(VD, /*FromParent=*/false); 21043 SemaRef.Diag(ELoc, diag::err_omp_threadprivate_in_clause) 21044 << getOpenMPClauseName(CKind); 21045 reportOriginalDsa(SemaRef, DSAS, VD, DVar); 21046 continue; 21047 } 21048 21049 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.9] 21050 // A list item cannot appear in both a map clause and a data-sharing 21051 // attribute clause on the same construct. 21052 21053 // Check conflicts with other map clause expressions. We check the conflicts 21054 // with the current construct separately from the enclosing data 21055 // environment, because the restrictions are different. We only have to 21056 // check conflicts across regions for the map clauses. 21057 if (checkMapConflicts(SemaRef, DSAS, CurDeclaration, SimpleExpr, 21058 /*CurrentRegionOnly=*/true, CurComponents, CKind)) 21059 break; 21060 if (CKind == OMPC_map && 21061 (SemaRef.getLangOpts().OpenMP <= 45 || StartLoc.isValid()) && 21062 checkMapConflicts(SemaRef, DSAS, CurDeclaration, SimpleExpr, 21063 /*CurrentRegionOnly=*/false, CurComponents, CKind)) 21064 break; 21065 21066 // OpenMP 4.5 [2.10.5, target update Construct] 21067 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1] 21068 // If the type of a list item is a reference to a type T then the type will 21069 // be considered to be T for all purposes of this clause. 21070 auto I = llvm::find_if( 21071 CurComponents, 21072 [](const OMPClauseMappableExprCommon::MappableComponent &MC) { 21073 return MC.getAssociatedDeclaration(); 21074 }); 21075 assert(I != CurComponents.end() && "Null decl on map clause."); 21076 (void)I; 21077 QualType Type; 21078 auto *ASE = dyn_cast<ArraySubscriptExpr>(VE->IgnoreParens()); 21079 auto *OASE = dyn_cast<OMPArraySectionExpr>(VE->IgnoreParens()); 21080 auto *OAShE = dyn_cast<OMPArrayShapingExpr>(VE->IgnoreParens()); 21081 if (ASE) { 21082 Type = ASE->getType().getNonReferenceType(); 21083 } else if (OASE) { 21084 QualType BaseType = 21085 OMPArraySectionExpr::getBaseOriginalType(OASE->getBase()); 21086 if (const auto *ATy = BaseType->getAsArrayTypeUnsafe()) 21087 Type = ATy->getElementType(); 21088 else 21089 Type = BaseType->getPointeeType(); 21090 Type = Type.getNonReferenceType(); 21091 } else if (OAShE) { 21092 Type = OAShE->getBase()->getType()->getPointeeType(); 21093 } else { 21094 Type = VE->getType(); 21095 } 21096 21097 // OpenMP 4.5 [2.10.5, target update Construct, Restrictions, p.4] 21098 // A list item in a to or from clause must have a mappable type. 21099 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.9] 21100 // A list item must have a mappable type. 21101 if (!checkTypeMappable(VE->getExprLoc(), VE->getSourceRange(), SemaRef, 21102 DSAS, Type, /*FullCheck=*/true)) 21103 continue; 21104 21105 if (CKind == OMPC_map) { 21106 // target enter data 21107 // OpenMP [2.10.2, Restrictions, p. 99] 21108 // A map-type must be specified in all map clauses and must be either 21109 // to or alloc. 21110 OpenMPDirectiveKind DKind = DSAS->getCurrentDirective(); 21111 if (DKind == OMPD_target_enter_data && 21112 !(MapType == OMPC_MAP_to || MapType == OMPC_MAP_alloc)) { 21113 SemaRef.Diag(StartLoc, diag::err_omp_invalid_map_type_for_directive) 21114 << (IsMapTypeImplicit ? 1 : 0) 21115 << getOpenMPSimpleClauseTypeName(OMPC_map, MapType) 21116 << getOpenMPDirectiveName(DKind); 21117 continue; 21118 } 21119 21120 // target exit_data 21121 // OpenMP [2.10.3, Restrictions, p. 102] 21122 // A map-type must be specified in all map clauses and must be either 21123 // from, release, or delete. 21124 if (DKind == OMPD_target_exit_data && 21125 !(MapType == OMPC_MAP_from || MapType == OMPC_MAP_release || 21126 MapType == OMPC_MAP_delete)) { 21127 SemaRef.Diag(StartLoc, diag::err_omp_invalid_map_type_for_directive) 21128 << (IsMapTypeImplicit ? 1 : 0) 21129 << getOpenMPSimpleClauseTypeName(OMPC_map, MapType) 21130 << getOpenMPDirectiveName(DKind); 21131 continue; 21132 } 21133 21134 // The 'ompx_hold' modifier is specifically intended to be used on a 21135 // 'target' or 'target data' directive to prevent data from being unmapped 21136 // during the associated statement. It is not permitted on a 'target 21137 // enter data' or 'target exit data' directive, which have no associated 21138 // statement. 21139 if ((DKind == OMPD_target_enter_data || DKind == OMPD_target_exit_data) && 21140 HasHoldModifier) { 21141 SemaRef.Diag(StartLoc, 21142 diag::err_omp_invalid_map_type_modifier_for_directive) 21143 << getOpenMPSimpleClauseTypeName(OMPC_map, 21144 OMPC_MAP_MODIFIER_ompx_hold) 21145 << getOpenMPDirectiveName(DKind); 21146 continue; 21147 } 21148 21149 // target, target data 21150 // OpenMP 5.0 [2.12.2, Restrictions, p. 163] 21151 // OpenMP 5.0 [2.12.5, Restrictions, p. 174] 21152 // A map-type in a map clause must be to, from, tofrom or alloc 21153 if ((DKind == OMPD_target_data || 21154 isOpenMPTargetExecutionDirective(DKind)) && 21155 !(MapType == OMPC_MAP_to || MapType == OMPC_MAP_from || 21156 MapType == OMPC_MAP_tofrom || MapType == OMPC_MAP_alloc)) { 21157 SemaRef.Diag(StartLoc, diag::err_omp_invalid_map_type_for_directive) 21158 << (IsMapTypeImplicit ? 1 : 0) 21159 << getOpenMPSimpleClauseTypeName(OMPC_map, MapType) 21160 << getOpenMPDirectiveName(DKind); 21161 continue; 21162 } 21163 21164 // OpenMP 4.5 [2.15.5.1, Restrictions, p.3] 21165 // A list item cannot appear in both a map clause and a data-sharing 21166 // attribute clause on the same construct 21167 // 21168 // OpenMP 5.0 [2.19.7.1, Restrictions, p.7] 21169 // A list item cannot appear in both a map clause and a data-sharing 21170 // attribute clause on the same construct unless the construct is a 21171 // combined construct. 21172 if (VD && ((SemaRef.LangOpts.OpenMP <= 45 && 21173 isOpenMPTargetExecutionDirective(DKind)) || 21174 DKind == OMPD_target)) { 21175 DSAStackTy::DSAVarData DVar = DSAS->getTopDSA(VD, /*FromParent=*/false); 21176 if (isOpenMPPrivate(DVar.CKind)) { 21177 SemaRef.Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa) 21178 << getOpenMPClauseName(DVar.CKind) 21179 << getOpenMPClauseName(OMPC_map) 21180 << getOpenMPDirectiveName(DSAS->getCurrentDirective()); 21181 reportOriginalDsa(SemaRef, DSAS, CurDeclaration, DVar); 21182 continue; 21183 } 21184 } 21185 } 21186 21187 // Try to find the associated user-defined mapper. 21188 ExprResult ER = buildUserDefinedMapperRef( 21189 SemaRef, DSAS->getCurScope(), MapperIdScopeSpec, MapperId, 21190 Type.getCanonicalType(), UnresolvedMapper); 21191 if (ER.isInvalid()) 21192 continue; 21193 MVLI.UDMapperList.push_back(ER.get()); 21194 21195 // Save the current expression. 21196 MVLI.ProcessedVarList.push_back(RE); 21197 21198 // Store the components in the stack so that they can be used to check 21199 // against other clauses later on. 21200 DSAS->addMappableExpressionComponents(CurDeclaration, CurComponents, 21201 /*WhereFoundClauseKind=*/OMPC_map); 21202 21203 // Save the components and declaration to create the clause. For purposes of 21204 // the clause creation, any component list that has has base 'this' uses 21205 // null as base declaration. 21206 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1); 21207 MVLI.VarComponents.back().append(CurComponents.begin(), 21208 CurComponents.end()); 21209 MVLI.VarBaseDeclarations.push_back(isa<MemberExpr>(BE) ? nullptr 21210 : CurDeclaration); 21211 } 21212 } 21213 21214 OMPClause *Sema::ActOnOpenMPMapClause( 21215 ArrayRef<OpenMPMapModifierKind> MapTypeModifiers, 21216 ArrayRef<SourceLocation> MapTypeModifiersLoc, 21217 CXXScopeSpec &MapperIdScopeSpec, DeclarationNameInfo &MapperId, 21218 OpenMPMapClauseKind MapType, bool IsMapTypeImplicit, SourceLocation MapLoc, 21219 SourceLocation ColonLoc, ArrayRef<Expr *> VarList, 21220 const OMPVarListLocTy &Locs, bool NoDiagnose, 21221 ArrayRef<Expr *> UnresolvedMappers) { 21222 OpenMPMapModifierKind Modifiers[] = { 21223 OMPC_MAP_MODIFIER_unknown, OMPC_MAP_MODIFIER_unknown, 21224 OMPC_MAP_MODIFIER_unknown, OMPC_MAP_MODIFIER_unknown, 21225 OMPC_MAP_MODIFIER_unknown}; 21226 SourceLocation ModifiersLoc[NumberOfOMPMapClauseModifiers]; 21227 21228 // Process map-type-modifiers, flag errors for duplicate modifiers. 21229 unsigned Count = 0; 21230 for (unsigned I = 0, E = MapTypeModifiers.size(); I < E; ++I) { 21231 if (MapTypeModifiers[I] != OMPC_MAP_MODIFIER_unknown && 21232 llvm::is_contained(Modifiers, MapTypeModifiers[I])) { 21233 Diag(MapTypeModifiersLoc[I], diag::err_omp_duplicate_map_type_modifier); 21234 continue; 21235 } 21236 assert(Count < NumberOfOMPMapClauseModifiers && 21237 "Modifiers exceed the allowed number of map type modifiers"); 21238 Modifiers[Count] = MapTypeModifiers[I]; 21239 ModifiersLoc[Count] = MapTypeModifiersLoc[I]; 21240 ++Count; 21241 } 21242 21243 MappableVarListInfo MVLI(VarList); 21244 checkMappableExpressionList(*this, DSAStack, OMPC_map, MVLI, Locs.StartLoc, 21245 MapperIdScopeSpec, MapperId, UnresolvedMappers, 21246 MapType, Modifiers, IsMapTypeImplicit, 21247 NoDiagnose); 21248 21249 // We need to produce a map clause even if we don't have variables so that 21250 // other diagnostics related with non-existing map clauses are accurate. 21251 return OMPMapClause::Create(Context, Locs, MVLI.ProcessedVarList, 21252 MVLI.VarBaseDeclarations, MVLI.VarComponents, 21253 MVLI.UDMapperList, Modifiers, ModifiersLoc, 21254 MapperIdScopeSpec.getWithLocInContext(Context), 21255 MapperId, MapType, IsMapTypeImplicit, MapLoc); 21256 } 21257 21258 QualType Sema::ActOnOpenMPDeclareReductionType(SourceLocation TyLoc, 21259 TypeResult ParsedType) { 21260 assert(ParsedType.isUsable()); 21261 21262 QualType ReductionType = GetTypeFromParser(ParsedType.get()); 21263 if (ReductionType.isNull()) 21264 return QualType(); 21265 21266 // [OpenMP 4.0], 2.15 declare reduction Directive, Restrictions, C\C++ 21267 // A type name in a declare reduction directive cannot be a function type, an 21268 // array type, a reference type, or a type qualified with const, volatile or 21269 // restrict. 21270 if (ReductionType.hasQualifiers()) { 21271 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 0; 21272 return QualType(); 21273 } 21274 21275 if (ReductionType->isFunctionType()) { 21276 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 1; 21277 return QualType(); 21278 } 21279 if (ReductionType->isReferenceType()) { 21280 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 2; 21281 return QualType(); 21282 } 21283 if (ReductionType->isArrayType()) { 21284 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 3; 21285 return QualType(); 21286 } 21287 return ReductionType; 21288 } 21289 21290 Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareReductionDirectiveStart( 21291 Scope *S, DeclContext *DC, DeclarationName Name, 21292 ArrayRef<std::pair<QualType, SourceLocation>> ReductionTypes, 21293 AccessSpecifier AS, Decl *PrevDeclInScope) { 21294 SmallVector<Decl *, 8> Decls; 21295 Decls.reserve(ReductionTypes.size()); 21296 21297 LookupResult Lookup(*this, Name, SourceLocation(), LookupOMPReductionName, 21298 forRedeclarationInCurContext()); 21299 // [OpenMP 4.0], 2.15 declare reduction Directive, Restrictions 21300 // A reduction-identifier may not be re-declared in the current scope for the 21301 // same type or for a type that is compatible according to the base language 21302 // rules. 21303 llvm::DenseMap<QualType, SourceLocation> PreviousRedeclTypes; 21304 OMPDeclareReductionDecl *PrevDRD = nullptr; 21305 bool InCompoundScope = true; 21306 if (S != nullptr) { 21307 // Find previous declaration with the same name not referenced in other 21308 // declarations. 21309 FunctionScopeInfo *ParentFn = getEnclosingFunction(); 21310 InCompoundScope = 21311 (ParentFn != nullptr) && !ParentFn->CompoundScopes.empty(); 21312 LookupName(Lookup, S); 21313 FilterLookupForScope(Lookup, DC, S, /*ConsiderLinkage=*/false, 21314 /*AllowInlineNamespace=*/false); 21315 llvm::DenseMap<OMPDeclareReductionDecl *, bool> UsedAsPrevious; 21316 LookupResult::Filter Filter = Lookup.makeFilter(); 21317 while (Filter.hasNext()) { 21318 auto *PrevDecl = cast<OMPDeclareReductionDecl>(Filter.next()); 21319 if (InCompoundScope) { 21320 auto I = UsedAsPrevious.find(PrevDecl); 21321 if (I == UsedAsPrevious.end()) 21322 UsedAsPrevious[PrevDecl] = false; 21323 if (OMPDeclareReductionDecl *D = PrevDecl->getPrevDeclInScope()) 21324 UsedAsPrevious[D] = true; 21325 } 21326 PreviousRedeclTypes[PrevDecl->getType().getCanonicalType()] = 21327 PrevDecl->getLocation(); 21328 } 21329 Filter.done(); 21330 if (InCompoundScope) { 21331 for (const auto &PrevData : UsedAsPrevious) { 21332 if (!PrevData.second) { 21333 PrevDRD = PrevData.first; 21334 break; 21335 } 21336 } 21337 } 21338 } else if (PrevDeclInScope != nullptr) { 21339 auto *PrevDRDInScope = PrevDRD = 21340 cast<OMPDeclareReductionDecl>(PrevDeclInScope); 21341 do { 21342 PreviousRedeclTypes[PrevDRDInScope->getType().getCanonicalType()] = 21343 PrevDRDInScope->getLocation(); 21344 PrevDRDInScope = PrevDRDInScope->getPrevDeclInScope(); 21345 } while (PrevDRDInScope != nullptr); 21346 } 21347 for (const auto &TyData : ReductionTypes) { 21348 const auto I = PreviousRedeclTypes.find(TyData.first.getCanonicalType()); 21349 bool Invalid = false; 21350 if (I != PreviousRedeclTypes.end()) { 21351 Diag(TyData.second, diag::err_omp_declare_reduction_redefinition) 21352 << TyData.first; 21353 Diag(I->second, diag::note_previous_definition); 21354 Invalid = true; 21355 } 21356 PreviousRedeclTypes[TyData.first.getCanonicalType()] = TyData.second; 21357 auto *DRD = OMPDeclareReductionDecl::Create(Context, DC, TyData.second, 21358 Name, TyData.first, PrevDRD); 21359 DC->addDecl(DRD); 21360 DRD->setAccess(AS); 21361 Decls.push_back(DRD); 21362 if (Invalid) 21363 DRD->setInvalidDecl(); 21364 else 21365 PrevDRD = DRD; 21366 } 21367 21368 return DeclGroupPtrTy::make( 21369 DeclGroupRef::Create(Context, Decls.begin(), Decls.size())); 21370 } 21371 21372 void Sema::ActOnOpenMPDeclareReductionCombinerStart(Scope *S, Decl *D) { 21373 auto *DRD = cast<OMPDeclareReductionDecl>(D); 21374 21375 // Enter new function scope. 21376 PushFunctionScope(); 21377 setFunctionHasBranchProtectedScope(); 21378 getCurFunction()->setHasOMPDeclareReductionCombiner(); 21379 21380 if (S != nullptr) 21381 PushDeclContext(S, DRD); 21382 else 21383 CurContext = DRD; 21384 21385 PushExpressionEvaluationContext( 21386 ExpressionEvaluationContext::PotentiallyEvaluated); 21387 21388 QualType ReductionType = DRD->getType(); 21389 // Create 'T* omp_parm;T omp_in;'. All references to 'omp_in' will 21390 // be replaced by '*omp_parm' during codegen. This required because 'omp_in' 21391 // uses semantics of argument handles by value, but it should be passed by 21392 // reference. C lang does not support references, so pass all parameters as 21393 // pointers. 21394 // Create 'T omp_in;' variable. 21395 VarDecl *OmpInParm = 21396 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_in"); 21397 // Create 'T* omp_parm;T omp_out;'. All references to 'omp_out' will 21398 // be replaced by '*omp_parm' during codegen. This required because 'omp_out' 21399 // uses semantics of argument handles by value, but it should be passed by 21400 // reference. C lang does not support references, so pass all parameters as 21401 // pointers. 21402 // Create 'T omp_out;' variable. 21403 VarDecl *OmpOutParm = 21404 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_out"); 21405 if (S != nullptr) { 21406 PushOnScopeChains(OmpInParm, S); 21407 PushOnScopeChains(OmpOutParm, S); 21408 } else { 21409 DRD->addDecl(OmpInParm); 21410 DRD->addDecl(OmpOutParm); 21411 } 21412 Expr *InE = 21413 ::buildDeclRefExpr(*this, OmpInParm, ReductionType, D->getLocation()); 21414 Expr *OutE = 21415 ::buildDeclRefExpr(*this, OmpOutParm, ReductionType, D->getLocation()); 21416 DRD->setCombinerData(InE, OutE); 21417 } 21418 21419 void Sema::ActOnOpenMPDeclareReductionCombinerEnd(Decl *D, Expr *Combiner) { 21420 auto *DRD = cast<OMPDeclareReductionDecl>(D); 21421 DiscardCleanupsInEvaluationContext(); 21422 PopExpressionEvaluationContext(); 21423 21424 PopDeclContext(); 21425 PopFunctionScopeInfo(); 21426 21427 if (Combiner != nullptr) 21428 DRD->setCombiner(Combiner); 21429 else 21430 DRD->setInvalidDecl(); 21431 } 21432 21433 VarDecl *Sema::ActOnOpenMPDeclareReductionInitializerStart(Scope *S, Decl *D) { 21434 auto *DRD = cast<OMPDeclareReductionDecl>(D); 21435 21436 // Enter new function scope. 21437 PushFunctionScope(); 21438 setFunctionHasBranchProtectedScope(); 21439 21440 if (S != nullptr) 21441 PushDeclContext(S, DRD); 21442 else 21443 CurContext = DRD; 21444 21445 PushExpressionEvaluationContext( 21446 ExpressionEvaluationContext::PotentiallyEvaluated); 21447 21448 QualType ReductionType = DRD->getType(); 21449 // Create 'T* omp_parm;T omp_priv;'. All references to 'omp_priv' will 21450 // be replaced by '*omp_parm' during codegen. This required because 'omp_priv' 21451 // uses semantics of argument handles by value, but it should be passed by 21452 // reference. C lang does not support references, so pass all parameters as 21453 // pointers. 21454 // Create 'T omp_priv;' variable. 21455 VarDecl *OmpPrivParm = 21456 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_priv"); 21457 // Create 'T* omp_parm;T omp_orig;'. All references to 'omp_orig' will 21458 // be replaced by '*omp_parm' during codegen. This required because 'omp_orig' 21459 // uses semantics of argument handles by value, but it should be passed by 21460 // reference. C lang does not support references, so pass all parameters as 21461 // pointers. 21462 // Create 'T omp_orig;' variable. 21463 VarDecl *OmpOrigParm = 21464 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_orig"); 21465 if (S != nullptr) { 21466 PushOnScopeChains(OmpPrivParm, S); 21467 PushOnScopeChains(OmpOrigParm, S); 21468 } else { 21469 DRD->addDecl(OmpPrivParm); 21470 DRD->addDecl(OmpOrigParm); 21471 } 21472 Expr *OrigE = 21473 ::buildDeclRefExpr(*this, OmpOrigParm, ReductionType, D->getLocation()); 21474 Expr *PrivE = 21475 ::buildDeclRefExpr(*this, OmpPrivParm, ReductionType, D->getLocation()); 21476 DRD->setInitializerData(OrigE, PrivE); 21477 return OmpPrivParm; 21478 } 21479 21480 void Sema::ActOnOpenMPDeclareReductionInitializerEnd(Decl *D, Expr *Initializer, 21481 VarDecl *OmpPrivParm) { 21482 auto *DRD = cast<OMPDeclareReductionDecl>(D); 21483 DiscardCleanupsInEvaluationContext(); 21484 PopExpressionEvaluationContext(); 21485 21486 PopDeclContext(); 21487 PopFunctionScopeInfo(); 21488 21489 if (Initializer != nullptr) { 21490 DRD->setInitializer(Initializer, OMPDeclareReductionDecl::CallInit); 21491 } else if (OmpPrivParm->hasInit()) { 21492 DRD->setInitializer(OmpPrivParm->getInit(), 21493 OmpPrivParm->isDirectInit() 21494 ? OMPDeclareReductionDecl::DirectInit 21495 : OMPDeclareReductionDecl::CopyInit); 21496 } else { 21497 DRD->setInvalidDecl(); 21498 } 21499 } 21500 21501 Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareReductionDirectiveEnd( 21502 Scope *S, DeclGroupPtrTy DeclReductions, bool IsValid) { 21503 for (Decl *D : DeclReductions.get()) { 21504 if (IsValid) { 21505 if (S) 21506 PushOnScopeChains(cast<OMPDeclareReductionDecl>(D), S, 21507 /*AddToContext=*/false); 21508 } else { 21509 D->setInvalidDecl(); 21510 } 21511 } 21512 return DeclReductions; 21513 } 21514 21515 TypeResult Sema::ActOnOpenMPDeclareMapperVarDecl(Scope *S, Declarator &D) { 21516 TypeSourceInfo *TInfo = GetTypeForDeclarator(D, S); 21517 QualType T = TInfo->getType(); 21518 if (D.isInvalidType()) 21519 return true; 21520 21521 if (getLangOpts().CPlusPlus) { 21522 // Check that there are no default arguments (C++ only). 21523 CheckExtraCXXDefaultArguments(D); 21524 } 21525 21526 return CreateParsedType(T, TInfo); 21527 } 21528 21529 QualType Sema::ActOnOpenMPDeclareMapperType(SourceLocation TyLoc, 21530 TypeResult ParsedType) { 21531 assert(ParsedType.isUsable() && "Expect usable parsed mapper type"); 21532 21533 QualType MapperType = GetTypeFromParser(ParsedType.get()); 21534 assert(!MapperType.isNull() && "Expect valid mapper type"); 21535 21536 // [OpenMP 5.0], 2.19.7.3 declare mapper Directive, Restrictions 21537 // The type must be of struct, union or class type in C and C++ 21538 if (!MapperType->isStructureOrClassType() && !MapperType->isUnionType()) { 21539 Diag(TyLoc, diag::err_omp_mapper_wrong_type); 21540 return QualType(); 21541 } 21542 return MapperType; 21543 } 21544 21545 Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareMapperDirective( 21546 Scope *S, DeclContext *DC, DeclarationName Name, QualType MapperType, 21547 SourceLocation StartLoc, DeclarationName VN, AccessSpecifier AS, 21548 Expr *MapperVarRef, ArrayRef<OMPClause *> Clauses, Decl *PrevDeclInScope) { 21549 LookupResult Lookup(*this, Name, SourceLocation(), LookupOMPMapperName, 21550 forRedeclarationInCurContext()); 21551 // [OpenMP 5.0], 2.19.7.3 declare mapper Directive, Restrictions 21552 // A mapper-identifier may not be redeclared in the current scope for the 21553 // same type or for a type that is compatible according to the base language 21554 // rules. 21555 llvm::DenseMap<QualType, SourceLocation> PreviousRedeclTypes; 21556 OMPDeclareMapperDecl *PrevDMD = nullptr; 21557 bool InCompoundScope = true; 21558 if (S != nullptr) { 21559 // Find previous declaration with the same name not referenced in other 21560 // declarations. 21561 FunctionScopeInfo *ParentFn = getEnclosingFunction(); 21562 InCompoundScope = 21563 (ParentFn != nullptr) && !ParentFn->CompoundScopes.empty(); 21564 LookupName(Lookup, S); 21565 FilterLookupForScope(Lookup, DC, S, /*ConsiderLinkage=*/false, 21566 /*AllowInlineNamespace=*/false); 21567 llvm::DenseMap<OMPDeclareMapperDecl *, bool> UsedAsPrevious; 21568 LookupResult::Filter Filter = Lookup.makeFilter(); 21569 while (Filter.hasNext()) { 21570 auto *PrevDecl = cast<OMPDeclareMapperDecl>(Filter.next()); 21571 if (InCompoundScope) { 21572 auto I = UsedAsPrevious.find(PrevDecl); 21573 if (I == UsedAsPrevious.end()) 21574 UsedAsPrevious[PrevDecl] = false; 21575 if (OMPDeclareMapperDecl *D = PrevDecl->getPrevDeclInScope()) 21576 UsedAsPrevious[D] = true; 21577 } 21578 PreviousRedeclTypes[PrevDecl->getType().getCanonicalType()] = 21579 PrevDecl->getLocation(); 21580 } 21581 Filter.done(); 21582 if (InCompoundScope) { 21583 for (const auto &PrevData : UsedAsPrevious) { 21584 if (!PrevData.second) { 21585 PrevDMD = PrevData.first; 21586 break; 21587 } 21588 } 21589 } 21590 } else if (PrevDeclInScope) { 21591 auto *PrevDMDInScope = PrevDMD = 21592 cast<OMPDeclareMapperDecl>(PrevDeclInScope); 21593 do { 21594 PreviousRedeclTypes[PrevDMDInScope->getType().getCanonicalType()] = 21595 PrevDMDInScope->getLocation(); 21596 PrevDMDInScope = PrevDMDInScope->getPrevDeclInScope(); 21597 } while (PrevDMDInScope != nullptr); 21598 } 21599 const auto I = PreviousRedeclTypes.find(MapperType.getCanonicalType()); 21600 bool Invalid = false; 21601 if (I != PreviousRedeclTypes.end()) { 21602 Diag(StartLoc, diag::err_omp_declare_mapper_redefinition) 21603 << MapperType << Name; 21604 Diag(I->second, diag::note_previous_definition); 21605 Invalid = true; 21606 } 21607 // Build expressions for implicit maps of data members with 'default' 21608 // mappers. 21609 SmallVector<OMPClause *, 4> ClausesWithImplicit(Clauses.begin(), 21610 Clauses.end()); 21611 if (LangOpts.OpenMP >= 50) 21612 processImplicitMapsWithDefaultMappers(*this, DSAStack, ClausesWithImplicit); 21613 auto *DMD = 21614 OMPDeclareMapperDecl::Create(Context, DC, StartLoc, Name, MapperType, VN, 21615 ClausesWithImplicit, PrevDMD); 21616 if (S) 21617 PushOnScopeChains(DMD, S); 21618 else 21619 DC->addDecl(DMD); 21620 DMD->setAccess(AS); 21621 if (Invalid) 21622 DMD->setInvalidDecl(); 21623 21624 auto *VD = cast<DeclRefExpr>(MapperVarRef)->getDecl(); 21625 VD->setDeclContext(DMD); 21626 VD->setLexicalDeclContext(DMD); 21627 DMD->addDecl(VD); 21628 DMD->setMapperVarRef(MapperVarRef); 21629 21630 return DeclGroupPtrTy::make(DeclGroupRef(DMD)); 21631 } 21632 21633 ExprResult 21634 Sema::ActOnOpenMPDeclareMapperDirectiveVarDecl(Scope *S, QualType MapperType, 21635 SourceLocation StartLoc, 21636 DeclarationName VN) { 21637 TypeSourceInfo *TInfo = 21638 Context.getTrivialTypeSourceInfo(MapperType, StartLoc); 21639 auto *VD = VarDecl::Create(Context, Context.getTranslationUnitDecl(), 21640 StartLoc, StartLoc, VN.getAsIdentifierInfo(), 21641 MapperType, TInfo, SC_None); 21642 if (S) 21643 PushOnScopeChains(VD, S, /*AddToContext=*/false); 21644 Expr *E = buildDeclRefExpr(*this, VD, MapperType, StartLoc); 21645 DSAStack->addDeclareMapperVarRef(E); 21646 return E; 21647 } 21648 21649 bool Sema::isOpenMPDeclareMapperVarDeclAllowed(const VarDecl *VD) const { 21650 assert(LangOpts.OpenMP && "Expected OpenMP mode."); 21651 const Expr *Ref = DSAStack->getDeclareMapperVarRef(); 21652 if (const auto *DRE = cast_or_null<DeclRefExpr>(Ref)) { 21653 if (VD->getCanonicalDecl() == DRE->getDecl()->getCanonicalDecl()) 21654 return true; 21655 if (VD->isUsableInConstantExpressions(Context)) 21656 return true; 21657 return false; 21658 } 21659 return true; 21660 } 21661 21662 const ValueDecl *Sema::getOpenMPDeclareMapperVarName() const { 21663 assert(LangOpts.OpenMP && "Expected OpenMP mode."); 21664 return cast<DeclRefExpr>(DSAStack->getDeclareMapperVarRef())->getDecl(); 21665 } 21666 21667 OMPClause *Sema::ActOnOpenMPNumTeamsClause(Expr *NumTeams, 21668 SourceLocation StartLoc, 21669 SourceLocation LParenLoc, 21670 SourceLocation EndLoc) { 21671 Expr *ValExpr = NumTeams; 21672 Stmt *HelperValStmt = nullptr; 21673 21674 // OpenMP [teams Constrcut, Restrictions] 21675 // The num_teams expression must evaluate to a positive integer value. 21676 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_num_teams, 21677 /*StrictlyPositive=*/true)) 21678 return nullptr; 21679 21680 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 21681 OpenMPDirectiveKind CaptureRegion = 21682 getOpenMPCaptureRegionForClause(DKind, OMPC_num_teams, LangOpts.OpenMP); 21683 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 21684 ValExpr = MakeFullExpr(ValExpr).get(); 21685 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 21686 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 21687 HelperValStmt = buildPreInits(Context, Captures); 21688 } 21689 21690 return new (Context) OMPNumTeamsClause(ValExpr, HelperValStmt, CaptureRegion, 21691 StartLoc, LParenLoc, EndLoc); 21692 } 21693 21694 OMPClause *Sema::ActOnOpenMPThreadLimitClause(Expr *ThreadLimit, 21695 SourceLocation StartLoc, 21696 SourceLocation LParenLoc, 21697 SourceLocation EndLoc) { 21698 Expr *ValExpr = ThreadLimit; 21699 Stmt *HelperValStmt = nullptr; 21700 21701 // OpenMP [teams Constrcut, Restrictions] 21702 // The thread_limit expression must evaluate to a positive integer value. 21703 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_thread_limit, 21704 /*StrictlyPositive=*/true)) 21705 return nullptr; 21706 21707 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 21708 OpenMPDirectiveKind CaptureRegion = getOpenMPCaptureRegionForClause( 21709 DKind, OMPC_thread_limit, LangOpts.OpenMP); 21710 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 21711 ValExpr = MakeFullExpr(ValExpr).get(); 21712 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 21713 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 21714 HelperValStmt = buildPreInits(Context, Captures); 21715 } 21716 21717 return new (Context) OMPThreadLimitClause( 21718 ValExpr, HelperValStmt, CaptureRegion, StartLoc, LParenLoc, EndLoc); 21719 } 21720 21721 OMPClause *Sema::ActOnOpenMPPriorityClause(Expr *Priority, 21722 SourceLocation StartLoc, 21723 SourceLocation LParenLoc, 21724 SourceLocation EndLoc) { 21725 Expr *ValExpr = Priority; 21726 Stmt *HelperValStmt = nullptr; 21727 OpenMPDirectiveKind CaptureRegion = OMPD_unknown; 21728 21729 // OpenMP [2.9.1, task Constrcut] 21730 // The priority-value is a non-negative numerical scalar expression. 21731 if (!isNonNegativeIntegerValue( 21732 ValExpr, *this, OMPC_priority, 21733 /*StrictlyPositive=*/false, /*BuildCapture=*/true, 21734 DSAStack->getCurrentDirective(), &CaptureRegion, &HelperValStmt)) 21735 return nullptr; 21736 21737 return new (Context) OMPPriorityClause(ValExpr, HelperValStmt, CaptureRegion, 21738 StartLoc, LParenLoc, EndLoc); 21739 } 21740 21741 OMPClause *Sema::ActOnOpenMPGrainsizeClause(Expr *Grainsize, 21742 SourceLocation StartLoc, 21743 SourceLocation LParenLoc, 21744 SourceLocation EndLoc) { 21745 Expr *ValExpr = Grainsize; 21746 Stmt *HelperValStmt = nullptr; 21747 OpenMPDirectiveKind CaptureRegion = OMPD_unknown; 21748 21749 // OpenMP [2.9.2, taskloop Constrcut] 21750 // The parameter of the grainsize clause must be a positive integer 21751 // expression. 21752 if (!isNonNegativeIntegerValue( 21753 ValExpr, *this, OMPC_grainsize, 21754 /*StrictlyPositive=*/true, /*BuildCapture=*/true, 21755 DSAStack->getCurrentDirective(), &CaptureRegion, &HelperValStmt)) 21756 return nullptr; 21757 21758 return new (Context) OMPGrainsizeClause(ValExpr, HelperValStmt, CaptureRegion, 21759 StartLoc, LParenLoc, EndLoc); 21760 } 21761 21762 OMPClause *Sema::ActOnOpenMPNumTasksClause(Expr *NumTasks, 21763 SourceLocation StartLoc, 21764 SourceLocation LParenLoc, 21765 SourceLocation EndLoc) { 21766 Expr *ValExpr = NumTasks; 21767 Stmt *HelperValStmt = nullptr; 21768 OpenMPDirectiveKind CaptureRegion = OMPD_unknown; 21769 21770 // OpenMP [2.9.2, taskloop Constrcut] 21771 // The parameter of the num_tasks clause must be a positive integer 21772 // expression. 21773 if (!isNonNegativeIntegerValue( 21774 ValExpr, *this, OMPC_num_tasks, 21775 /*StrictlyPositive=*/true, /*BuildCapture=*/true, 21776 DSAStack->getCurrentDirective(), &CaptureRegion, &HelperValStmt)) 21777 return nullptr; 21778 21779 return new (Context) OMPNumTasksClause(ValExpr, HelperValStmt, CaptureRegion, 21780 StartLoc, LParenLoc, EndLoc); 21781 } 21782 21783 OMPClause *Sema::ActOnOpenMPHintClause(Expr *Hint, SourceLocation StartLoc, 21784 SourceLocation LParenLoc, 21785 SourceLocation EndLoc) { 21786 // OpenMP [2.13.2, critical construct, Description] 21787 // ... where hint-expression is an integer constant expression that evaluates 21788 // to a valid lock hint. 21789 ExprResult HintExpr = 21790 VerifyPositiveIntegerConstantInClause(Hint, OMPC_hint, false); 21791 if (HintExpr.isInvalid()) 21792 return nullptr; 21793 return new (Context) 21794 OMPHintClause(HintExpr.get(), StartLoc, LParenLoc, EndLoc); 21795 } 21796 21797 /// Tries to find omp_event_handle_t type. 21798 static bool findOMPEventHandleT(Sema &S, SourceLocation Loc, 21799 DSAStackTy *Stack) { 21800 QualType OMPEventHandleT = Stack->getOMPEventHandleT(); 21801 if (!OMPEventHandleT.isNull()) 21802 return true; 21803 IdentifierInfo *II = &S.PP.getIdentifierTable().get("omp_event_handle_t"); 21804 ParsedType PT = S.getTypeName(*II, Loc, S.getCurScope()); 21805 if (!PT.getAsOpaquePtr() || PT.get().isNull()) { 21806 S.Diag(Loc, diag::err_omp_implied_type_not_found) << "omp_event_handle_t"; 21807 return false; 21808 } 21809 Stack->setOMPEventHandleT(PT.get()); 21810 return true; 21811 } 21812 21813 OMPClause *Sema::ActOnOpenMPDetachClause(Expr *Evt, SourceLocation StartLoc, 21814 SourceLocation LParenLoc, 21815 SourceLocation EndLoc) { 21816 if (!Evt->isValueDependent() && !Evt->isTypeDependent() && 21817 !Evt->isInstantiationDependent() && 21818 !Evt->containsUnexpandedParameterPack()) { 21819 if (!findOMPEventHandleT(*this, Evt->getExprLoc(), DSAStack)) 21820 return nullptr; 21821 // OpenMP 5.0, 2.10.1 task Construct. 21822 // event-handle is a variable of the omp_event_handle_t type. 21823 auto *Ref = dyn_cast<DeclRefExpr>(Evt->IgnoreParenImpCasts()); 21824 if (!Ref) { 21825 Diag(Evt->getExprLoc(), diag::err_omp_var_expected) 21826 << "omp_event_handle_t" << 0 << Evt->getSourceRange(); 21827 return nullptr; 21828 } 21829 auto *VD = dyn_cast_or_null<VarDecl>(Ref->getDecl()); 21830 if (!VD) { 21831 Diag(Evt->getExprLoc(), diag::err_omp_var_expected) 21832 << "omp_event_handle_t" << 0 << Evt->getSourceRange(); 21833 return nullptr; 21834 } 21835 if (!Context.hasSameUnqualifiedType(DSAStack->getOMPEventHandleT(), 21836 VD->getType()) || 21837 VD->getType().isConstant(Context)) { 21838 Diag(Evt->getExprLoc(), diag::err_omp_var_expected) 21839 << "omp_event_handle_t" << 1 << VD->getType() 21840 << Evt->getSourceRange(); 21841 return nullptr; 21842 } 21843 // OpenMP 5.0, 2.10.1 task Construct 21844 // [detach clause]... The event-handle will be considered as if it was 21845 // specified on a firstprivate clause. 21846 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(VD, /*FromParent=*/false); 21847 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_firstprivate && 21848 DVar.RefExpr) { 21849 Diag(Evt->getExprLoc(), diag::err_omp_wrong_dsa) 21850 << getOpenMPClauseName(DVar.CKind) 21851 << getOpenMPClauseName(OMPC_firstprivate); 21852 reportOriginalDsa(*this, DSAStack, VD, DVar); 21853 return nullptr; 21854 } 21855 } 21856 21857 return new (Context) OMPDetachClause(Evt, StartLoc, LParenLoc, EndLoc); 21858 } 21859 21860 OMPClause *Sema::ActOnOpenMPDistScheduleClause( 21861 OpenMPDistScheduleClauseKind Kind, Expr *ChunkSize, SourceLocation StartLoc, 21862 SourceLocation LParenLoc, SourceLocation KindLoc, SourceLocation CommaLoc, 21863 SourceLocation EndLoc) { 21864 if (Kind == OMPC_DIST_SCHEDULE_unknown) { 21865 std::string Values; 21866 Values += "'"; 21867 Values += getOpenMPSimpleClauseTypeName(OMPC_dist_schedule, 0); 21868 Values += "'"; 21869 Diag(KindLoc, diag::err_omp_unexpected_clause_value) 21870 << Values << getOpenMPClauseName(OMPC_dist_schedule); 21871 return nullptr; 21872 } 21873 Expr *ValExpr = ChunkSize; 21874 Stmt *HelperValStmt = nullptr; 21875 if (ChunkSize) { 21876 if (!ChunkSize->isValueDependent() && !ChunkSize->isTypeDependent() && 21877 !ChunkSize->isInstantiationDependent() && 21878 !ChunkSize->containsUnexpandedParameterPack()) { 21879 SourceLocation ChunkSizeLoc = ChunkSize->getBeginLoc(); 21880 ExprResult Val = 21881 PerformOpenMPImplicitIntegerConversion(ChunkSizeLoc, ChunkSize); 21882 if (Val.isInvalid()) 21883 return nullptr; 21884 21885 ValExpr = Val.get(); 21886 21887 // OpenMP [2.7.1, Restrictions] 21888 // chunk_size must be a loop invariant integer expression with a positive 21889 // value. 21890 if (Optional<llvm::APSInt> Result = 21891 ValExpr->getIntegerConstantExpr(Context)) { 21892 if (Result->isSigned() && !Result->isStrictlyPositive()) { 21893 Diag(ChunkSizeLoc, diag::err_omp_negative_expression_in_clause) 21894 << "dist_schedule" << ChunkSize->getSourceRange(); 21895 return nullptr; 21896 } 21897 } else if (getOpenMPCaptureRegionForClause( 21898 DSAStack->getCurrentDirective(), OMPC_dist_schedule, 21899 LangOpts.OpenMP) != OMPD_unknown && 21900 !CurContext->isDependentContext()) { 21901 ValExpr = MakeFullExpr(ValExpr).get(); 21902 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 21903 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 21904 HelperValStmt = buildPreInits(Context, Captures); 21905 } 21906 } 21907 } 21908 21909 return new (Context) 21910 OMPDistScheduleClause(StartLoc, LParenLoc, KindLoc, CommaLoc, EndLoc, 21911 Kind, ValExpr, HelperValStmt); 21912 } 21913 21914 OMPClause *Sema::ActOnOpenMPDefaultmapClause( 21915 OpenMPDefaultmapClauseModifier M, OpenMPDefaultmapClauseKind Kind, 21916 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation MLoc, 21917 SourceLocation KindLoc, SourceLocation EndLoc) { 21918 if (getLangOpts().OpenMP < 50) { 21919 if (M != OMPC_DEFAULTMAP_MODIFIER_tofrom || 21920 Kind != OMPC_DEFAULTMAP_scalar) { 21921 std::string Value; 21922 SourceLocation Loc; 21923 Value += "'"; 21924 if (M != OMPC_DEFAULTMAP_MODIFIER_tofrom) { 21925 Value += getOpenMPSimpleClauseTypeName(OMPC_defaultmap, 21926 OMPC_DEFAULTMAP_MODIFIER_tofrom); 21927 Loc = MLoc; 21928 } else { 21929 Value += getOpenMPSimpleClauseTypeName(OMPC_defaultmap, 21930 OMPC_DEFAULTMAP_scalar); 21931 Loc = KindLoc; 21932 } 21933 Value += "'"; 21934 Diag(Loc, diag::err_omp_unexpected_clause_value) 21935 << Value << getOpenMPClauseName(OMPC_defaultmap); 21936 return nullptr; 21937 } 21938 } else { 21939 bool isDefaultmapModifier = (M != OMPC_DEFAULTMAP_MODIFIER_unknown); 21940 bool isDefaultmapKind = (Kind != OMPC_DEFAULTMAP_unknown) || 21941 (LangOpts.OpenMP >= 50 && KindLoc.isInvalid()); 21942 if (!isDefaultmapKind || !isDefaultmapModifier) { 21943 StringRef KindValue = "'scalar', 'aggregate', 'pointer'"; 21944 if (LangOpts.OpenMP == 50) { 21945 StringRef ModifierValue = "'alloc', 'from', 'to', 'tofrom', " 21946 "'firstprivate', 'none', 'default'"; 21947 if (!isDefaultmapKind && isDefaultmapModifier) { 21948 Diag(KindLoc, diag::err_omp_unexpected_clause_value) 21949 << KindValue << getOpenMPClauseName(OMPC_defaultmap); 21950 } else if (isDefaultmapKind && !isDefaultmapModifier) { 21951 Diag(MLoc, diag::err_omp_unexpected_clause_value) 21952 << ModifierValue << getOpenMPClauseName(OMPC_defaultmap); 21953 } else { 21954 Diag(MLoc, diag::err_omp_unexpected_clause_value) 21955 << ModifierValue << getOpenMPClauseName(OMPC_defaultmap); 21956 Diag(KindLoc, diag::err_omp_unexpected_clause_value) 21957 << KindValue << getOpenMPClauseName(OMPC_defaultmap); 21958 } 21959 } else { 21960 StringRef ModifierValue = 21961 "'alloc', 'from', 'to', 'tofrom', " 21962 "'firstprivate', 'none', 'default', 'present'"; 21963 if (!isDefaultmapKind && isDefaultmapModifier) { 21964 Diag(KindLoc, diag::err_omp_unexpected_clause_value) 21965 << KindValue << getOpenMPClauseName(OMPC_defaultmap); 21966 } else if (isDefaultmapKind && !isDefaultmapModifier) { 21967 Diag(MLoc, diag::err_omp_unexpected_clause_value) 21968 << ModifierValue << getOpenMPClauseName(OMPC_defaultmap); 21969 } else { 21970 Diag(MLoc, diag::err_omp_unexpected_clause_value) 21971 << ModifierValue << getOpenMPClauseName(OMPC_defaultmap); 21972 Diag(KindLoc, diag::err_omp_unexpected_clause_value) 21973 << KindValue << getOpenMPClauseName(OMPC_defaultmap); 21974 } 21975 } 21976 return nullptr; 21977 } 21978 21979 // OpenMP [5.0, 2.12.5, Restrictions, p. 174] 21980 // At most one defaultmap clause for each category can appear on the 21981 // directive. 21982 if (DSAStack->checkDefaultmapCategory(Kind)) { 21983 Diag(StartLoc, diag::err_omp_one_defaultmap_each_category); 21984 return nullptr; 21985 } 21986 } 21987 if (Kind == OMPC_DEFAULTMAP_unknown) { 21988 // Variable category is not specified - mark all categories. 21989 DSAStack->setDefaultDMAAttr(M, OMPC_DEFAULTMAP_aggregate, StartLoc); 21990 DSAStack->setDefaultDMAAttr(M, OMPC_DEFAULTMAP_scalar, StartLoc); 21991 DSAStack->setDefaultDMAAttr(M, OMPC_DEFAULTMAP_pointer, StartLoc); 21992 } else { 21993 DSAStack->setDefaultDMAAttr(M, Kind, StartLoc); 21994 } 21995 21996 return new (Context) 21997 OMPDefaultmapClause(StartLoc, LParenLoc, MLoc, KindLoc, EndLoc, Kind, M); 21998 } 21999 22000 bool Sema::ActOnStartOpenMPDeclareTargetContext( 22001 DeclareTargetContextInfo &DTCI) { 22002 DeclContext *CurLexicalContext = getCurLexicalContext(); 22003 if (!CurLexicalContext->isFileContext() && 22004 !CurLexicalContext->isExternCContext() && 22005 !CurLexicalContext->isExternCXXContext() && 22006 !isa<CXXRecordDecl>(CurLexicalContext) && 22007 !isa<ClassTemplateDecl>(CurLexicalContext) && 22008 !isa<ClassTemplatePartialSpecializationDecl>(CurLexicalContext) && 22009 !isa<ClassTemplateSpecializationDecl>(CurLexicalContext)) { 22010 Diag(DTCI.Loc, diag::err_omp_region_not_file_context); 22011 return false; 22012 } 22013 DeclareTargetNesting.push_back(DTCI); 22014 return true; 22015 } 22016 22017 const Sema::DeclareTargetContextInfo 22018 Sema::ActOnOpenMPEndDeclareTargetDirective() { 22019 assert(!DeclareTargetNesting.empty() && 22020 "check isInOpenMPDeclareTargetContext() first!"); 22021 return DeclareTargetNesting.pop_back_val(); 22022 } 22023 22024 void Sema::ActOnFinishedOpenMPDeclareTargetContext( 22025 DeclareTargetContextInfo &DTCI) { 22026 for (auto &It : DTCI.ExplicitlyMapped) 22027 ActOnOpenMPDeclareTargetName(It.first, It.second.Loc, It.second.MT, DTCI); 22028 } 22029 22030 void Sema::DiagnoseUnterminatedOpenMPDeclareTarget() { 22031 if (DeclareTargetNesting.empty()) 22032 return; 22033 DeclareTargetContextInfo &DTCI = DeclareTargetNesting.back(); 22034 Diag(DTCI.Loc, diag::warn_omp_unterminated_declare_target) 22035 << getOpenMPDirectiveName(DTCI.Kind); 22036 } 22037 22038 NamedDecl *Sema::lookupOpenMPDeclareTargetName(Scope *CurScope, 22039 CXXScopeSpec &ScopeSpec, 22040 const DeclarationNameInfo &Id) { 22041 LookupResult Lookup(*this, Id, LookupOrdinaryName); 22042 LookupParsedName(Lookup, CurScope, &ScopeSpec, true); 22043 22044 if (Lookup.isAmbiguous()) 22045 return nullptr; 22046 Lookup.suppressDiagnostics(); 22047 22048 if (!Lookup.isSingleResult()) { 22049 VarOrFuncDeclFilterCCC CCC(*this); 22050 if (TypoCorrection Corrected = 22051 CorrectTypo(Id, LookupOrdinaryName, CurScope, nullptr, CCC, 22052 CTK_ErrorRecovery)) { 22053 diagnoseTypo(Corrected, PDiag(diag::err_undeclared_var_use_suggest) 22054 << Id.getName()); 22055 checkDeclIsAllowedInOpenMPTarget(nullptr, Corrected.getCorrectionDecl()); 22056 return nullptr; 22057 } 22058 22059 Diag(Id.getLoc(), diag::err_undeclared_var_use) << Id.getName(); 22060 return nullptr; 22061 } 22062 22063 NamedDecl *ND = Lookup.getAsSingle<NamedDecl>(); 22064 if (!isa<VarDecl>(ND) && !isa<FunctionDecl>(ND) && 22065 !isa<FunctionTemplateDecl>(ND)) { 22066 Diag(Id.getLoc(), diag::err_omp_invalid_target_decl) << Id.getName(); 22067 return nullptr; 22068 } 22069 return ND; 22070 } 22071 22072 void Sema::ActOnOpenMPDeclareTargetName(NamedDecl *ND, SourceLocation Loc, 22073 OMPDeclareTargetDeclAttr::MapTypeTy MT, 22074 DeclareTargetContextInfo &DTCI) { 22075 assert((isa<VarDecl>(ND) || isa<FunctionDecl>(ND) || 22076 isa<FunctionTemplateDecl>(ND)) && 22077 "Expected variable, function or function template."); 22078 22079 // Diagnose marking after use as it may lead to incorrect diagnosis and 22080 // codegen. 22081 if (LangOpts.OpenMP >= 50 && 22082 (ND->isUsed(/*CheckUsedAttr=*/false) || ND->isReferenced())) 22083 Diag(Loc, diag::warn_omp_declare_target_after_first_use); 22084 22085 // Explicit declare target lists have precedence. 22086 const unsigned Level = -1; 22087 22088 auto *VD = cast<ValueDecl>(ND); 22089 llvm::Optional<OMPDeclareTargetDeclAttr *> ActiveAttr = 22090 OMPDeclareTargetDeclAttr::getActiveAttr(VD); 22091 if (ActiveAttr.hasValue() && ActiveAttr.getValue()->getDevType() != DTCI.DT && 22092 ActiveAttr.getValue()->getLevel() == Level) { 22093 Diag(Loc, diag::err_omp_device_type_mismatch) 22094 << OMPDeclareTargetDeclAttr::ConvertDevTypeTyToStr(DTCI.DT) 22095 << OMPDeclareTargetDeclAttr::ConvertDevTypeTyToStr( 22096 ActiveAttr.getValue()->getDevType()); 22097 return; 22098 } 22099 if (ActiveAttr.hasValue() && ActiveAttr.getValue()->getMapType() != MT && 22100 ActiveAttr.getValue()->getLevel() == Level) { 22101 Diag(Loc, diag::err_omp_declare_target_to_and_link) << ND; 22102 return; 22103 } 22104 22105 if (ActiveAttr.hasValue() && ActiveAttr.getValue()->getLevel() == Level) 22106 return; 22107 22108 Expr *IndirectE = nullptr; 22109 bool IsIndirect = false; 22110 if (DTCI.Indirect.hasValue()) { 22111 IndirectE = DTCI.Indirect.getValue(); 22112 if (!IndirectE) 22113 IsIndirect = true; 22114 } 22115 auto *A = OMPDeclareTargetDeclAttr::CreateImplicit( 22116 Context, MT, DTCI.DT, IndirectE, IsIndirect, Level, 22117 SourceRange(Loc, Loc)); 22118 ND->addAttr(A); 22119 if (ASTMutationListener *ML = Context.getASTMutationListener()) 22120 ML->DeclarationMarkedOpenMPDeclareTarget(ND, A); 22121 checkDeclIsAllowedInOpenMPTarget(nullptr, ND, Loc); 22122 } 22123 22124 static void checkDeclInTargetContext(SourceLocation SL, SourceRange SR, 22125 Sema &SemaRef, Decl *D) { 22126 if (!D || !isa<VarDecl>(D)) 22127 return; 22128 auto *VD = cast<VarDecl>(D); 22129 Optional<OMPDeclareTargetDeclAttr::MapTypeTy> MapTy = 22130 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD); 22131 if (SemaRef.LangOpts.OpenMP >= 50 && 22132 (SemaRef.getCurLambda(/*IgnoreNonLambdaCapturingScope=*/true) || 22133 SemaRef.getCurBlock() || SemaRef.getCurCapturedRegion()) && 22134 VD->hasGlobalStorage()) { 22135 if (!MapTy || *MapTy != OMPDeclareTargetDeclAttr::MT_To) { 22136 // OpenMP 5.0, 2.12.7 declare target Directive, Restrictions 22137 // If a lambda declaration and definition appears between a 22138 // declare target directive and the matching end declare target 22139 // directive, all variables that are captured by the lambda 22140 // expression must also appear in a to clause. 22141 SemaRef.Diag(VD->getLocation(), 22142 diag::err_omp_lambda_capture_in_declare_target_not_to); 22143 SemaRef.Diag(SL, diag::note_var_explicitly_captured_here) 22144 << VD << 0 << SR; 22145 return; 22146 } 22147 } 22148 if (MapTy.hasValue()) 22149 return; 22150 SemaRef.Diag(VD->getLocation(), diag::warn_omp_not_in_target_context); 22151 SemaRef.Diag(SL, diag::note_used_here) << SR; 22152 } 22153 22154 static bool checkValueDeclInTarget(SourceLocation SL, SourceRange SR, 22155 Sema &SemaRef, DSAStackTy *Stack, 22156 ValueDecl *VD) { 22157 return OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD) || 22158 checkTypeMappable(SL, SR, SemaRef, Stack, VD->getType(), 22159 /*FullCheck=*/false); 22160 } 22161 22162 void Sema::checkDeclIsAllowedInOpenMPTarget(Expr *E, Decl *D, 22163 SourceLocation IdLoc) { 22164 if (!D || D->isInvalidDecl()) 22165 return; 22166 SourceRange SR = E ? E->getSourceRange() : D->getSourceRange(); 22167 SourceLocation SL = E ? E->getBeginLoc() : D->getLocation(); 22168 if (auto *VD = dyn_cast<VarDecl>(D)) { 22169 // Only global variables can be marked as declare target. 22170 if (!VD->isFileVarDecl() && !VD->isStaticLocal() && 22171 !VD->isStaticDataMember()) 22172 return; 22173 // 2.10.6: threadprivate variable cannot appear in a declare target 22174 // directive. 22175 if (DSAStack->isThreadPrivate(VD)) { 22176 Diag(SL, diag::err_omp_threadprivate_in_target); 22177 reportOriginalDsa(*this, DSAStack, VD, DSAStack->getTopDSA(VD, false)); 22178 return; 22179 } 22180 } 22181 if (const auto *FTD = dyn_cast<FunctionTemplateDecl>(D)) 22182 D = FTD->getTemplatedDecl(); 22183 if (auto *FD = dyn_cast<FunctionDecl>(D)) { 22184 llvm::Optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res = 22185 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(FD); 22186 if (IdLoc.isValid() && Res && *Res == OMPDeclareTargetDeclAttr::MT_Link) { 22187 Diag(IdLoc, diag::err_omp_function_in_link_clause); 22188 Diag(FD->getLocation(), diag::note_defined_here) << FD; 22189 return; 22190 } 22191 } 22192 if (auto *VD = dyn_cast<ValueDecl>(D)) { 22193 // Problem if any with var declared with incomplete type will be reported 22194 // as normal, so no need to check it here. 22195 if ((E || !VD->getType()->isIncompleteType()) && 22196 !checkValueDeclInTarget(SL, SR, *this, DSAStack, VD)) 22197 return; 22198 if (!E && isInOpenMPDeclareTargetContext()) { 22199 // Checking declaration inside declare target region. 22200 if (isa<VarDecl>(D) || isa<FunctionDecl>(D) || 22201 isa<FunctionTemplateDecl>(D)) { 22202 llvm::Optional<OMPDeclareTargetDeclAttr *> ActiveAttr = 22203 OMPDeclareTargetDeclAttr::getActiveAttr(VD); 22204 unsigned Level = DeclareTargetNesting.size(); 22205 if (ActiveAttr.hasValue() && ActiveAttr.getValue()->getLevel() >= Level) 22206 return; 22207 DeclareTargetContextInfo &DTCI = DeclareTargetNesting.back(); 22208 Expr *IndirectE = nullptr; 22209 bool IsIndirect = false; 22210 if (DTCI.Indirect.hasValue()) { 22211 IndirectE = DTCI.Indirect.getValue(); 22212 if (!IndirectE) 22213 IsIndirect = true; 22214 } 22215 auto *A = OMPDeclareTargetDeclAttr::CreateImplicit( 22216 Context, OMPDeclareTargetDeclAttr::MT_To, DTCI.DT, IndirectE, 22217 IsIndirect, Level, SourceRange(DTCI.Loc, DTCI.Loc)); 22218 D->addAttr(A); 22219 if (ASTMutationListener *ML = Context.getASTMutationListener()) 22220 ML->DeclarationMarkedOpenMPDeclareTarget(D, A); 22221 } 22222 return; 22223 } 22224 } 22225 if (!E) 22226 return; 22227 checkDeclInTargetContext(E->getExprLoc(), E->getSourceRange(), *this, D); 22228 } 22229 22230 OMPClause *Sema::ActOnOpenMPToClause( 22231 ArrayRef<OpenMPMotionModifierKind> MotionModifiers, 22232 ArrayRef<SourceLocation> MotionModifiersLoc, 22233 CXXScopeSpec &MapperIdScopeSpec, DeclarationNameInfo &MapperId, 22234 SourceLocation ColonLoc, ArrayRef<Expr *> VarList, 22235 const OMPVarListLocTy &Locs, ArrayRef<Expr *> UnresolvedMappers) { 22236 OpenMPMotionModifierKind Modifiers[] = {OMPC_MOTION_MODIFIER_unknown, 22237 OMPC_MOTION_MODIFIER_unknown}; 22238 SourceLocation ModifiersLoc[NumberOfOMPMotionModifiers]; 22239 22240 // Process motion-modifiers, flag errors for duplicate modifiers. 22241 unsigned Count = 0; 22242 for (unsigned I = 0, E = MotionModifiers.size(); I < E; ++I) { 22243 if (MotionModifiers[I] != OMPC_MOTION_MODIFIER_unknown && 22244 llvm::is_contained(Modifiers, MotionModifiers[I])) { 22245 Diag(MotionModifiersLoc[I], diag::err_omp_duplicate_motion_modifier); 22246 continue; 22247 } 22248 assert(Count < NumberOfOMPMotionModifiers && 22249 "Modifiers exceed the allowed number of motion modifiers"); 22250 Modifiers[Count] = MotionModifiers[I]; 22251 ModifiersLoc[Count] = MotionModifiersLoc[I]; 22252 ++Count; 22253 } 22254 22255 MappableVarListInfo MVLI(VarList); 22256 checkMappableExpressionList(*this, DSAStack, OMPC_to, MVLI, Locs.StartLoc, 22257 MapperIdScopeSpec, MapperId, UnresolvedMappers); 22258 if (MVLI.ProcessedVarList.empty()) 22259 return nullptr; 22260 22261 return OMPToClause::Create( 22262 Context, Locs, MVLI.ProcessedVarList, MVLI.VarBaseDeclarations, 22263 MVLI.VarComponents, MVLI.UDMapperList, Modifiers, ModifiersLoc, 22264 MapperIdScopeSpec.getWithLocInContext(Context), MapperId); 22265 } 22266 22267 OMPClause *Sema::ActOnOpenMPFromClause( 22268 ArrayRef<OpenMPMotionModifierKind> MotionModifiers, 22269 ArrayRef<SourceLocation> MotionModifiersLoc, 22270 CXXScopeSpec &MapperIdScopeSpec, DeclarationNameInfo &MapperId, 22271 SourceLocation ColonLoc, ArrayRef<Expr *> VarList, 22272 const OMPVarListLocTy &Locs, ArrayRef<Expr *> UnresolvedMappers) { 22273 OpenMPMotionModifierKind Modifiers[] = {OMPC_MOTION_MODIFIER_unknown, 22274 OMPC_MOTION_MODIFIER_unknown}; 22275 SourceLocation ModifiersLoc[NumberOfOMPMotionModifiers]; 22276 22277 // Process motion-modifiers, flag errors for duplicate modifiers. 22278 unsigned Count = 0; 22279 for (unsigned I = 0, E = MotionModifiers.size(); I < E; ++I) { 22280 if (MotionModifiers[I] != OMPC_MOTION_MODIFIER_unknown && 22281 llvm::is_contained(Modifiers, MotionModifiers[I])) { 22282 Diag(MotionModifiersLoc[I], diag::err_omp_duplicate_motion_modifier); 22283 continue; 22284 } 22285 assert(Count < NumberOfOMPMotionModifiers && 22286 "Modifiers exceed the allowed number of motion modifiers"); 22287 Modifiers[Count] = MotionModifiers[I]; 22288 ModifiersLoc[Count] = MotionModifiersLoc[I]; 22289 ++Count; 22290 } 22291 22292 MappableVarListInfo MVLI(VarList); 22293 checkMappableExpressionList(*this, DSAStack, OMPC_from, MVLI, Locs.StartLoc, 22294 MapperIdScopeSpec, MapperId, UnresolvedMappers); 22295 if (MVLI.ProcessedVarList.empty()) 22296 return nullptr; 22297 22298 return OMPFromClause::Create( 22299 Context, Locs, MVLI.ProcessedVarList, MVLI.VarBaseDeclarations, 22300 MVLI.VarComponents, MVLI.UDMapperList, Modifiers, ModifiersLoc, 22301 MapperIdScopeSpec.getWithLocInContext(Context), MapperId); 22302 } 22303 22304 OMPClause *Sema::ActOnOpenMPUseDevicePtrClause(ArrayRef<Expr *> VarList, 22305 const OMPVarListLocTy &Locs) { 22306 MappableVarListInfo MVLI(VarList); 22307 SmallVector<Expr *, 8> PrivateCopies; 22308 SmallVector<Expr *, 8> Inits; 22309 22310 for (Expr *RefExpr : VarList) { 22311 assert(RefExpr && "NULL expr in OpenMP use_device_ptr clause."); 22312 SourceLocation ELoc; 22313 SourceRange ERange; 22314 Expr *SimpleRefExpr = RefExpr; 22315 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 22316 if (Res.second) { 22317 // It will be analyzed later. 22318 MVLI.ProcessedVarList.push_back(RefExpr); 22319 PrivateCopies.push_back(nullptr); 22320 Inits.push_back(nullptr); 22321 } 22322 ValueDecl *D = Res.first; 22323 if (!D) 22324 continue; 22325 22326 QualType Type = D->getType(); 22327 Type = Type.getNonReferenceType().getUnqualifiedType(); 22328 22329 auto *VD = dyn_cast<VarDecl>(D); 22330 22331 // Item should be a pointer or reference to pointer. 22332 if (!Type->isPointerType()) { 22333 Diag(ELoc, diag::err_omp_usedeviceptr_not_a_pointer) 22334 << 0 << RefExpr->getSourceRange(); 22335 continue; 22336 } 22337 22338 // Build the private variable and the expression that refers to it. 22339 auto VDPrivate = 22340 buildVarDecl(*this, ELoc, Type, D->getName(), 22341 D->hasAttrs() ? &D->getAttrs() : nullptr, 22342 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr); 22343 if (VDPrivate->isInvalidDecl()) 22344 continue; 22345 22346 CurContext->addDecl(VDPrivate); 22347 DeclRefExpr *VDPrivateRefExpr = buildDeclRefExpr( 22348 *this, VDPrivate, RefExpr->getType().getUnqualifiedType(), ELoc); 22349 22350 // Add temporary variable to initialize the private copy of the pointer. 22351 VarDecl *VDInit = 22352 buildVarDecl(*this, RefExpr->getExprLoc(), Type, ".devptr.temp"); 22353 DeclRefExpr *VDInitRefExpr = buildDeclRefExpr( 22354 *this, VDInit, RefExpr->getType(), RefExpr->getExprLoc()); 22355 AddInitializerToDecl(VDPrivate, 22356 DefaultLvalueConversion(VDInitRefExpr).get(), 22357 /*DirectInit=*/false); 22358 22359 // If required, build a capture to implement the privatization initialized 22360 // with the current list item value. 22361 DeclRefExpr *Ref = nullptr; 22362 if (!VD) 22363 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true); 22364 MVLI.ProcessedVarList.push_back(VD ? RefExpr->IgnoreParens() : Ref); 22365 PrivateCopies.push_back(VDPrivateRefExpr); 22366 Inits.push_back(VDInitRefExpr); 22367 22368 // We need to add a data sharing attribute for this variable to make sure it 22369 // is correctly captured. A variable that shows up in a use_device_ptr has 22370 // similar properties of a first private variable. 22371 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_firstprivate, Ref); 22372 22373 // Create a mappable component for the list item. List items in this clause 22374 // only need a component. 22375 MVLI.VarBaseDeclarations.push_back(D); 22376 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1); 22377 MVLI.VarComponents.back().emplace_back(SimpleRefExpr, D, 22378 /*IsNonContiguous=*/false); 22379 } 22380 22381 if (MVLI.ProcessedVarList.empty()) 22382 return nullptr; 22383 22384 return OMPUseDevicePtrClause::Create( 22385 Context, Locs, MVLI.ProcessedVarList, PrivateCopies, Inits, 22386 MVLI.VarBaseDeclarations, MVLI.VarComponents); 22387 } 22388 22389 OMPClause *Sema::ActOnOpenMPUseDeviceAddrClause(ArrayRef<Expr *> VarList, 22390 const OMPVarListLocTy &Locs) { 22391 MappableVarListInfo MVLI(VarList); 22392 22393 for (Expr *RefExpr : VarList) { 22394 assert(RefExpr && "NULL expr in OpenMP use_device_addr clause."); 22395 SourceLocation ELoc; 22396 SourceRange ERange; 22397 Expr *SimpleRefExpr = RefExpr; 22398 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange, 22399 /*AllowArraySection=*/true); 22400 if (Res.second) { 22401 // It will be analyzed later. 22402 MVLI.ProcessedVarList.push_back(RefExpr); 22403 } 22404 ValueDecl *D = Res.first; 22405 if (!D) 22406 continue; 22407 auto *VD = dyn_cast<VarDecl>(D); 22408 22409 // If required, build a capture to implement the privatization initialized 22410 // with the current list item value. 22411 DeclRefExpr *Ref = nullptr; 22412 if (!VD) 22413 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true); 22414 MVLI.ProcessedVarList.push_back(VD ? RefExpr->IgnoreParens() : Ref); 22415 22416 // We need to add a data sharing attribute for this variable to make sure it 22417 // is correctly captured. A variable that shows up in a use_device_addr has 22418 // similar properties of a first private variable. 22419 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_firstprivate, Ref); 22420 22421 // Create a mappable component for the list item. List items in this clause 22422 // only need a component. 22423 MVLI.VarBaseDeclarations.push_back(D); 22424 MVLI.VarComponents.emplace_back(); 22425 Expr *Component = SimpleRefExpr; 22426 if (VD && (isa<OMPArraySectionExpr>(RefExpr->IgnoreParenImpCasts()) || 22427 isa<ArraySubscriptExpr>(RefExpr->IgnoreParenImpCasts()))) 22428 Component = DefaultFunctionArrayLvalueConversion(SimpleRefExpr).get(); 22429 MVLI.VarComponents.back().emplace_back(Component, D, 22430 /*IsNonContiguous=*/false); 22431 } 22432 22433 if (MVLI.ProcessedVarList.empty()) 22434 return nullptr; 22435 22436 return OMPUseDeviceAddrClause::Create(Context, Locs, MVLI.ProcessedVarList, 22437 MVLI.VarBaseDeclarations, 22438 MVLI.VarComponents); 22439 } 22440 22441 OMPClause *Sema::ActOnOpenMPIsDevicePtrClause(ArrayRef<Expr *> VarList, 22442 const OMPVarListLocTy &Locs) { 22443 MappableVarListInfo MVLI(VarList); 22444 for (Expr *RefExpr : VarList) { 22445 assert(RefExpr && "NULL expr in OpenMP is_device_ptr clause."); 22446 SourceLocation ELoc; 22447 SourceRange ERange; 22448 Expr *SimpleRefExpr = RefExpr; 22449 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 22450 if (Res.second) { 22451 // It will be analyzed later. 22452 MVLI.ProcessedVarList.push_back(RefExpr); 22453 } 22454 ValueDecl *D = Res.first; 22455 if (!D) 22456 continue; 22457 22458 QualType Type = D->getType(); 22459 // item should be a pointer or array or reference to pointer or array 22460 if (!Type.getNonReferenceType()->isPointerType() && 22461 !Type.getNonReferenceType()->isArrayType()) { 22462 Diag(ELoc, diag::err_omp_argument_type_isdeviceptr) 22463 << 0 << RefExpr->getSourceRange(); 22464 continue; 22465 } 22466 22467 // Check if the declaration in the clause does not show up in any data 22468 // sharing attribute. 22469 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false); 22470 if (isOpenMPPrivate(DVar.CKind)) { 22471 Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa) 22472 << getOpenMPClauseName(DVar.CKind) 22473 << getOpenMPClauseName(OMPC_is_device_ptr) 22474 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 22475 reportOriginalDsa(*this, DSAStack, D, DVar); 22476 continue; 22477 } 22478 22479 const Expr *ConflictExpr; 22480 if (DSAStack->checkMappableExprComponentListsForDecl( 22481 D, /*CurrentRegionOnly=*/true, 22482 [&ConflictExpr]( 22483 OMPClauseMappableExprCommon::MappableExprComponentListRef R, 22484 OpenMPClauseKind) -> bool { 22485 ConflictExpr = R.front().getAssociatedExpression(); 22486 return true; 22487 })) { 22488 Diag(ELoc, diag::err_omp_map_shared_storage) << RefExpr->getSourceRange(); 22489 Diag(ConflictExpr->getExprLoc(), diag::note_used_here) 22490 << ConflictExpr->getSourceRange(); 22491 continue; 22492 } 22493 22494 // Store the components in the stack so that they can be used to check 22495 // against other clauses later on. 22496 OMPClauseMappableExprCommon::MappableComponent MC( 22497 SimpleRefExpr, D, /*IsNonContiguous=*/false); 22498 DSAStack->addMappableExpressionComponents( 22499 D, MC, /*WhereFoundClauseKind=*/OMPC_is_device_ptr); 22500 22501 // Record the expression we've just processed. 22502 MVLI.ProcessedVarList.push_back(SimpleRefExpr); 22503 22504 // Create a mappable component for the list item. List items in this clause 22505 // only need a component. We use a null declaration to signal fields in 22506 // 'this'. 22507 assert((isa<DeclRefExpr>(SimpleRefExpr) || 22508 isa<CXXThisExpr>(cast<MemberExpr>(SimpleRefExpr)->getBase())) && 22509 "Unexpected device pointer expression!"); 22510 MVLI.VarBaseDeclarations.push_back( 22511 isa<DeclRefExpr>(SimpleRefExpr) ? D : nullptr); 22512 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1); 22513 MVLI.VarComponents.back().push_back(MC); 22514 } 22515 22516 if (MVLI.ProcessedVarList.empty()) 22517 return nullptr; 22518 22519 return OMPIsDevicePtrClause::Create(Context, Locs, MVLI.ProcessedVarList, 22520 MVLI.VarBaseDeclarations, 22521 MVLI.VarComponents); 22522 } 22523 22524 OMPClause *Sema::ActOnOpenMPHasDeviceAddrClause(ArrayRef<Expr *> VarList, 22525 const OMPVarListLocTy &Locs) { 22526 MappableVarListInfo MVLI(VarList); 22527 for (Expr *RefExpr : VarList) { 22528 assert(RefExpr && "NULL expr in OpenMP has_device_addr clause."); 22529 SourceLocation ELoc; 22530 SourceRange ERange; 22531 Expr *SimpleRefExpr = RefExpr; 22532 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange, 22533 /*AllowArraySection=*/true); 22534 if (Res.second) { 22535 // It will be analyzed later. 22536 MVLI.ProcessedVarList.push_back(RefExpr); 22537 } 22538 ValueDecl *D = Res.first; 22539 if (!D) 22540 continue; 22541 22542 // Check if the declaration in the clause does not show up in any data 22543 // sharing attribute. 22544 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false); 22545 if (isOpenMPPrivate(DVar.CKind)) { 22546 Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa) 22547 << getOpenMPClauseName(DVar.CKind) 22548 << getOpenMPClauseName(OMPC_has_device_addr) 22549 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 22550 reportOriginalDsa(*this, DSAStack, D, DVar); 22551 continue; 22552 } 22553 22554 const Expr *ConflictExpr; 22555 if (DSAStack->checkMappableExprComponentListsForDecl( 22556 D, /*CurrentRegionOnly=*/true, 22557 [&ConflictExpr]( 22558 OMPClauseMappableExprCommon::MappableExprComponentListRef R, 22559 OpenMPClauseKind) -> bool { 22560 ConflictExpr = R.front().getAssociatedExpression(); 22561 return true; 22562 })) { 22563 Diag(ELoc, diag::err_omp_map_shared_storage) << RefExpr->getSourceRange(); 22564 Diag(ConflictExpr->getExprLoc(), diag::note_used_here) 22565 << ConflictExpr->getSourceRange(); 22566 continue; 22567 } 22568 22569 // Store the components in the stack so that they can be used to check 22570 // against other clauses later on. 22571 OMPClauseMappableExprCommon::MappableComponent MC( 22572 SimpleRefExpr, D, /*IsNonContiguous=*/false); 22573 DSAStack->addMappableExpressionComponents( 22574 D, MC, /*WhereFoundClauseKind=*/OMPC_has_device_addr); 22575 22576 // Record the expression we've just processed. 22577 auto *VD = dyn_cast<VarDecl>(D); 22578 if (!VD && !CurContext->isDependentContext()) { 22579 DeclRefExpr *Ref = 22580 buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true); 22581 assert(Ref && "has_device_addr capture failed"); 22582 MVLI.ProcessedVarList.push_back(Ref); 22583 } else 22584 MVLI.ProcessedVarList.push_back(RefExpr->IgnoreParens()); 22585 22586 // Create a mappable component for the list item. List items in this clause 22587 // only need a component. We use a null declaration to signal fields in 22588 // 'this'. 22589 assert((isa<DeclRefExpr>(SimpleRefExpr) || 22590 isa<CXXThisExpr>(cast<MemberExpr>(SimpleRefExpr)->getBase())) && 22591 "Unexpected device pointer expression!"); 22592 MVLI.VarBaseDeclarations.push_back( 22593 isa<DeclRefExpr>(SimpleRefExpr) ? D : nullptr); 22594 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1); 22595 MVLI.VarComponents.back().push_back(MC); 22596 } 22597 22598 if (MVLI.ProcessedVarList.empty()) 22599 return nullptr; 22600 22601 return OMPHasDeviceAddrClause::Create(Context, Locs, MVLI.ProcessedVarList, 22602 MVLI.VarBaseDeclarations, 22603 MVLI.VarComponents); 22604 } 22605 22606 OMPClause *Sema::ActOnOpenMPAllocateClause( 22607 Expr *Allocator, ArrayRef<Expr *> VarList, SourceLocation StartLoc, 22608 SourceLocation ColonLoc, SourceLocation LParenLoc, SourceLocation EndLoc) { 22609 if (Allocator) { 22610 // OpenMP [2.11.4 allocate Clause, Description] 22611 // allocator is an expression of omp_allocator_handle_t type. 22612 if (!findOMPAllocatorHandleT(*this, Allocator->getExprLoc(), DSAStack)) 22613 return nullptr; 22614 22615 ExprResult AllocatorRes = DefaultLvalueConversion(Allocator); 22616 if (AllocatorRes.isInvalid()) 22617 return nullptr; 22618 AllocatorRes = PerformImplicitConversion(AllocatorRes.get(), 22619 DSAStack->getOMPAllocatorHandleT(), 22620 Sema::AA_Initializing, 22621 /*AllowExplicit=*/true); 22622 if (AllocatorRes.isInvalid()) 22623 return nullptr; 22624 Allocator = AllocatorRes.get(); 22625 } else { 22626 // OpenMP 5.0, 2.11.4 allocate Clause, Restrictions. 22627 // allocate clauses that appear on a target construct or on constructs in a 22628 // target region must specify an allocator expression unless a requires 22629 // directive with the dynamic_allocators clause is present in the same 22630 // compilation unit. 22631 if (LangOpts.OpenMPIsDevice && 22632 !DSAStack->hasRequiresDeclWithClause<OMPDynamicAllocatorsClause>()) 22633 targetDiag(StartLoc, diag::err_expected_allocator_expression); 22634 } 22635 // Analyze and build list of variables. 22636 SmallVector<Expr *, 8> Vars; 22637 for (Expr *RefExpr : VarList) { 22638 assert(RefExpr && "NULL expr in OpenMP private clause."); 22639 SourceLocation ELoc; 22640 SourceRange ERange; 22641 Expr *SimpleRefExpr = RefExpr; 22642 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 22643 if (Res.second) { 22644 // It will be analyzed later. 22645 Vars.push_back(RefExpr); 22646 } 22647 ValueDecl *D = Res.first; 22648 if (!D) 22649 continue; 22650 22651 auto *VD = dyn_cast<VarDecl>(D); 22652 DeclRefExpr *Ref = nullptr; 22653 if (!VD && !CurContext->isDependentContext()) 22654 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false); 22655 Vars.push_back((VD || CurContext->isDependentContext()) 22656 ? RefExpr->IgnoreParens() 22657 : Ref); 22658 } 22659 22660 if (Vars.empty()) 22661 return nullptr; 22662 22663 if (Allocator) 22664 DSAStack->addInnerAllocatorExpr(Allocator); 22665 return OMPAllocateClause::Create(Context, StartLoc, LParenLoc, Allocator, 22666 ColonLoc, EndLoc, Vars); 22667 } 22668 22669 OMPClause *Sema::ActOnOpenMPNontemporalClause(ArrayRef<Expr *> VarList, 22670 SourceLocation StartLoc, 22671 SourceLocation LParenLoc, 22672 SourceLocation EndLoc) { 22673 SmallVector<Expr *, 8> Vars; 22674 for (Expr *RefExpr : VarList) { 22675 assert(RefExpr && "NULL expr in OpenMP nontemporal clause."); 22676 SourceLocation ELoc; 22677 SourceRange ERange; 22678 Expr *SimpleRefExpr = RefExpr; 22679 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 22680 if (Res.second) 22681 // It will be analyzed later. 22682 Vars.push_back(RefExpr); 22683 ValueDecl *D = Res.first; 22684 if (!D) 22685 continue; 22686 22687 // OpenMP 5.0, 2.9.3.1 simd Construct, Restrictions. 22688 // A list-item cannot appear in more than one nontemporal clause. 22689 if (const Expr *PrevRef = 22690 DSAStack->addUniqueNontemporal(D, SimpleRefExpr)) { 22691 Diag(ELoc, diag::err_omp_used_in_clause_twice) 22692 << 0 << getOpenMPClauseName(OMPC_nontemporal) << ERange; 22693 Diag(PrevRef->getExprLoc(), diag::note_omp_explicit_dsa) 22694 << getOpenMPClauseName(OMPC_nontemporal); 22695 continue; 22696 } 22697 22698 Vars.push_back(RefExpr); 22699 } 22700 22701 if (Vars.empty()) 22702 return nullptr; 22703 22704 return OMPNontemporalClause::Create(Context, StartLoc, LParenLoc, EndLoc, 22705 Vars); 22706 } 22707 22708 OMPClause *Sema::ActOnOpenMPInclusiveClause(ArrayRef<Expr *> VarList, 22709 SourceLocation StartLoc, 22710 SourceLocation LParenLoc, 22711 SourceLocation EndLoc) { 22712 SmallVector<Expr *, 8> Vars; 22713 for (Expr *RefExpr : VarList) { 22714 assert(RefExpr && "NULL expr in OpenMP nontemporal clause."); 22715 SourceLocation ELoc; 22716 SourceRange ERange; 22717 Expr *SimpleRefExpr = RefExpr; 22718 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange, 22719 /*AllowArraySection=*/true); 22720 if (Res.second) 22721 // It will be analyzed later. 22722 Vars.push_back(RefExpr); 22723 ValueDecl *D = Res.first; 22724 if (!D) 22725 continue; 22726 22727 const DSAStackTy::DSAVarData DVar = 22728 DSAStack->getTopDSA(D, /*FromParent=*/true); 22729 // OpenMP 5.0, 2.9.6, scan Directive, Restrictions. 22730 // A list item that appears in the inclusive or exclusive clause must appear 22731 // in a reduction clause with the inscan modifier on the enclosing 22732 // worksharing-loop, worksharing-loop SIMD, or simd construct. 22733 if (DVar.CKind != OMPC_reduction || DVar.Modifier != OMPC_REDUCTION_inscan) 22734 Diag(ELoc, diag::err_omp_inclusive_exclusive_not_reduction) 22735 << RefExpr->getSourceRange(); 22736 22737 if (DSAStack->getParentDirective() != OMPD_unknown) 22738 DSAStack->markDeclAsUsedInScanDirective(D); 22739 Vars.push_back(RefExpr); 22740 } 22741 22742 if (Vars.empty()) 22743 return nullptr; 22744 22745 return OMPInclusiveClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars); 22746 } 22747 22748 OMPClause *Sema::ActOnOpenMPExclusiveClause(ArrayRef<Expr *> VarList, 22749 SourceLocation StartLoc, 22750 SourceLocation LParenLoc, 22751 SourceLocation EndLoc) { 22752 SmallVector<Expr *, 8> Vars; 22753 for (Expr *RefExpr : VarList) { 22754 assert(RefExpr && "NULL expr in OpenMP nontemporal clause."); 22755 SourceLocation ELoc; 22756 SourceRange ERange; 22757 Expr *SimpleRefExpr = RefExpr; 22758 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange, 22759 /*AllowArraySection=*/true); 22760 if (Res.second) 22761 // It will be analyzed later. 22762 Vars.push_back(RefExpr); 22763 ValueDecl *D = Res.first; 22764 if (!D) 22765 continue; 22766 22767 OpenMPDirectiveKind ParentDirective = DSAStack->getParentDirective(); 22768 DSAStackTy::DSAVarData DVar; 22769 if (ParentDirective != OMPD_unknown) 22770 DVar = DSAStack->getTopDSA(D, /*FromParent=*/true); 22771 // OpenMP 5.0, 2.9.6, scan Directive, Restrictions. 22772 // A list item that appears in the inclusive or exclusive clause must appear 22773 // in a reduction clause with the inscan modifier on the enclosing 22774 // worksharing-loop, worksharing-loop SIMD, or simd construct. 22775 if (ParentDirective == OMPD_unknown || DVar.CKind != OMPC_reduction || 22776 DVar.Modifier != OMPC_REDUCTION_inscan) { 22777 Diag(ELoc, diag::err_omp_inclusive_exclusive_not_reduction) 22778 << RefExpr->getSourceRange(); 22779 } else { 22780 DSAStack->markDeclAsUsedInScanDirective(D); 22781 } 22782 Vars.push_back(RefExpr); 22783 } 22784 22785 if (Vars.empty()) 22786 return nullptr; 22787 22788 return OMPExclusiveClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars); 22789 } 22790 22791 /// Tries to find omp_alloctrait_t type. 22792 static bool findOMPAlloctraitT(Sema &S, SourceLocation Loc, DSAStackTy *Stack) { 22793 QualType OMPAlloctraitT = Stack->getOMPAlloctraitT(); 22794 if (!OMPAlloctraitT.isNull()) 22795 return true; 22796 IdentifierInfo &II = S.PP.getIdentifierTable().get("omp_alloctrait_t"); 22797 ParsedType PT = S.getTypeName(II, Loc, S.getCurScope()); 22798 if (!PT.getAsOpaquePtr() || PT.get().isNull()) { 22799 S.Diag(Loc, diag::err_omp_implied_type_not_found) << "omp_alloctrait_t"; 22800 return false; 22801 } 22802 Stack->setOMPAlloctraitT(PT.get()); 22803 return true; 22804 } 22805 22806 OMPClause *Sema::ActOnOpenMPUsesAllocatorClause( 22807 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc, 22808 ArrayRef<UsesAllocatorsData> Data) { 22809 // OpenMP [2.12.5, target Construct] 22810 // allocator is an identifier of omp_allocator_handle_t type. 22811 if (!findOMPAllocatorHandleT(*this, StartLoc, DSAStack)) 22812 return nullptr; 22813 // OpenMP [2.12.5, target Construct] 22814 // allocator-traits-array is an identifier of const omp_alloctrait_t * type. 22815 if (llvm::any_of( 22816 Data, 22817 [](const UsesAllocatorsData &D) { return D.AllocatorTraits; }) && 22818 !findOMPAlloctraitT(*this, StartLoc, DSAStack)) 22819 return nullptr; 22820 llvm::SmallPtrSet<CanonicalDeclPtr<Decl>, 4> PredefinedAllocators; 22821 for (int I = 0; I < OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; ++I) { 22822 auto AllocatorKind = static_cast<OMPAllocateDeclAttr::AllocatorTypeTy>(I); 22823 StringRef Allocator = 22824 OMPAllocateDeclAttr::ConvertAllocatorTypeTyToStr(AllocatorKind); 22825 DeclarationName AllocatorName = &Context.Idents.get(Allocator); 22826 PredefinedAllocators.insert(LookupSingleName( 22827 TUScope, AllocatorName, StartLoc, Sema::LookupAnyName)); 22828 } 22829 22830 SmallVector<OMPUsesAllocatorsClause::Data, 4> NewData; 22831 for (const UsesAllocatorsData &D : Data) { 22832 Expr *AllocatorExpr = nullptr; 22833 // Check allocator expression. 22834 if (D.Allocator->isTypeDependent()) { 22835 AllocatorExpr = D.Allocator; 22836 } else { 22837 // Traits were specified - need to assign new allocator to the specified 22838 // allocator, so it must be an lvalue. 22839 AllocatorExpr = D.Allocator->IgnoreParenImpCasts(); 22840 auto *DRE = dyn_cast<DeclRefExpr>(AllocatorExpr); 22841 bool IsPredefinedAllocator = false; 22842 if (DRE) 22843 IsPredefinedAllocator = PredefinedAllocators.count(DRE->getDecl()); 22844 if (!DRE || 22845 !(Context.hasSameUnqualifiedType( 22846 AllocatorExpr->getType(), DSAStack->getOMPAllocatorHandleT()) || 22847 Context.typesAreCompatible(AllocatorExpr->getType(), 22848 DSAStack->getOMPAllocatorHandleT(), 22849 /*CompareUnqualified=*/true)) || 22850 (!IsPredefinedAllocator && 22851 (AllocatorExpr->getType().isConstant(Context) || 22852 !AllocatorExpr->isLValue()))) { 22853 Diag(D.Allocator->getExprLoc(), diag::err_omp_var_expected) 22854 << "omp_allocator_handle_t" << (DRE ? 1 : 0) 22855 << AllocatorExpr->getType() << D.Allocator->getSourceRange(); 22856 continue; 22857 } 22858 // OpenMP [2.12.5, target Construct] 22859 // Predefined allocators appearing in a uses_allocators clause cannot have 22860 // traits specified. 22861 if (IsPredefinedAllocator && D.AllocatorTraits) { 22862 Diag(D.AllocatorTraits->getExprLoc(), 22863 diag::err_omp_predefined_allocator_with_traits) 22864 << D.AllocatorTraits->getSourceRange(); 22865 Diag(D.Allocator->getExprLoc(), diag::note_omp_predefined_allocator) 22866 << cast<NamedDecl>(DRE->getDecl())->getName() 22867 << D.Allocator->getSourceRange(); 22868 continue; 22869 } 22870 // OpenMP [2.12.5, target Construct] 22871 // Non-predefined allocators appearing in a uses_allocators clause must 22872 // have traits specified. 22873 if (!IsPredefinedAllocator && !D.AllocatorTraits) { 22874 Diag(D.Allocator->getExprLoc(), 22875 diag::err_omp_nonpredefined_allocator_without_traits); 22876 continue; 22877 } 22878 // No allocator traits - just convert it to rvalue. 22879 if (!D.AllocatorTraits) 22880 AllocatorExpr = DefaultLvalueConversion(AllocatorExpr).get(); 22881 DSAStack->addUsesAllocatorsDecl( 22882 DRE->getDecl(), 22883 IsPredefinedAllocator 22884 ? DSAStackTy::UsesAllocatorsDeclKind::PredefinedAllocator 22885 : DSAStackTy::UsesAllocatorsDeclKind::UserDefinedAllocator); 22886 } 22887 Expr *AllocatorTraitsExpr = nullptr; 22888 if (D.AllocatorTraits) { 22889 if (D.AllocatorTraits->isTypeDependent()) { 22890 AllocatorTraitsExpr = D.AllocatorTraits; 22891 } else { 22892 // OpenMP [2.12.5, target Construct] 22893 // Arrays that contain allocator traits that appear in a uses_allocators 22894 // clause must be constant arrays, have constant values and be defined 22895 // in the same scope as the construct in which the clause appears. 22896 AllocatorTraitsExpr = D.AllocatorTraits->IgnoreParenImpCasts(); 22897 // Check that traits expr is a constant array. 22898 QualType TraitTy; 22899 if (const ArrayType *Ty = 22900 AllocatorTraitsExpr->getType()->getAsArrayTypeUnsafe()) 22901 if (const auto *ConstArrayTy = dyn_cast<ConstantArrayType>(Ty)) 22902 TraitTy = ConstArrayTy->getElementType(); 22903 if (TraitTy.isNull() || 22904 !(Context.hasSameUnqualifiedType(TraitTy, 22905 DSAStack->getOMPAlloctraitT()) || 22906 Context.typesAreCompatible(TraitTy, DSAStack->getOMPAlloctraitT(), 22907 /*CompareUnqualified=*/true))) { 22908 Diag(D.AllocatorTraits->getExprLoc(), 22909 diag::err_omp_expected_array_alloctraits) 22910 << AllocatorTraitsExpr->getType(); 22911 continue; 22912 } 22913 // Do not map by default allocator traits if it is a standalone 22914 // variable. 22915 if (auto *DRE = dyn_cast<DeclRefExpr>(AllocatorTraitsExpr)) 22916 DSAStack->addUsesAllocatorsDecl( 22917 DRE->getDecl(), 22918 DSAStackTy::UsesAllocatorsDeclKind::AllocatorTrait); 22919 } 22920 } 22921 OMPUsesAllocatorsClause::Data &NewD = NewData.emplace_back(); 22922 NewD.Allocator = AllocatorExpr; 22923 NewD.AllocatorTraits = AllocatorTraitsExpr; 22924 NewD.LParenLoc = D.LParenLoc; 22925 NewD.RParenLoc = D.RParenLoc; 22926 } 22927 return OMPUsesAllocatorsClause::Create(Context, StartLoc, LParenLoc, EndLoc, 22928 NewData); 22929 } 22930 22931 OMPClause *Sema::ActOnOpenMPAffinityClause( 22932 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation ColonLoc, 22933 SourceLocation EndLoc, Expr *Modifier, ArrayRef<Expr *> Locators) { 22934 SmallVector<Expr *, 8> Vars; 22935 for (Expr *RefExpr : Locators) { 22936 assert(RefExpr && "NULL expr in OpenMP shared clause."); 22937 if (isa<DependentScopeDeclRefExpr>(RefExpr) || RefExpr->isTypeDependent()) { 22938 // It will be analyzed later. 22939 Vars.push_back(RefExpr); 22940 continue; 22941 } 22942 22943 SourceLocation ELoc = RefExpr->getExprLoc(); 22944 Expr *SimpleExpr = RefExpr->IgnoreParenImpCasts(); 22945 22946 if (!SimpleExpr->isLValue()) { 22947 Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item) 22948 << 1 << 0 << RefExpr->getSourceRange(); 22949 continue; 22950 } 22951 22952 ExprResult Res; 22953 { 22954 Sema::TentativeAnalysisScope Trap(*this); 22955 Res = CreateBuiltinUnaryOp(ELoc, UO_AddrOf, SimpleExpr); 22956 } 22957 if (!Res.isUsable() && !isa<OMPArraySectionExpr>(SimpleExpr) && 22958 !isa<OMPArrayShapingExpr>(SimpleExpr)) { 22959 Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item) 22960 << 1 << 0 << RefExpr->getSourceRange(); 22961 continue; 22962 } 22963 Vars.push_back(SimpleExpr); 22964 } 22965 22966 return OMPAffinityClause::Create(Context, StartLoc, LParenLoc, ColonLoc, 22967 EndLoc, Modifier, Vars); 22968 } 22969 22970 OMPClause *Sema::ActOnOpenMPBindClause(OpenMPBindClauseKind Kind, 22971 SourceLocation KindLoc, 22972 SourceLocation StartLoc, 22973 SourceLocation LParenLoc, 22974 SourceLocation EndLoc) { 22975 if (Kind == OMPC_BIND_unknown) { 22976 Diag(KindLoc, diag::err_omp_unexpected_clause_value) 22977 << getListOfPossibleValues(OMPC_bind, /*First=*/0, 22978 /*Last=*/unsigned(OMPC_BIND_unknown)) 22979 << getOpenMPClauseName(OMPC_bind); 22980 return nullptr; 22981 } 22982 22983 return OMPBindClause::Create(Context, Kind, KindLoc, StartLoc, LParenLoc, 22984 EndLoc); 22985 } 22986