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).value_or( 2399 DSAStackTy::UsesAllocatorsDeclKind::AllocatorTrait) == 2400 DSAStackTy::UsesAllocatorsDeclKind::UserDefinedAllocator) 2401 return OMPC_private; 2402 return (DSAStack->hasExplicitDSA( 2403 D, [](OpenMPClauseKind K, bool) { return K == OMPC_private; }, 2404 Level) || 2405 (DSAStack->isClauseParsingMode() && 2406 DSAStack->getClauseParsingMode() == OMPC_private) || 2407 // Consider taskgroup reduction descriptor variable a private 2408 // to avoid possible capture in the region. 2409 (DSAStack->hasExplicitDirective( 2410 [](OpenMPDirectiveKind K) { 2411 return K == OMPD_taskgroup || 2412 ((isOpenMPParallelDirective(K) || 2413 isOpenMPWorksharingDirective(K)) && 2414 !isOpenMPSimdDirective(K)); 2415 }, 2416 Level) && 2417 DSAStack->isTaskgroupReductionRef(D, Level))) 2418 ? OMPC_private 2419 : OMPC_unknown; 2420 } 2421 2422 void Sema::setOpenMPCaptureKind(FieldDecl *FD, const ValueDecl *D, 2423 unsigned Level) { 2424 assert(LangOpts.OpenMP && "OpenMP is not allowed"); 2425 D = getCanonicalDecl(D); 2426 OpenMPClauseKind OMPC = OMPC_unknown; 2427 for (unsigned I = DSAStack->getNestingLevel() + 1; I > Level; --I) { 2428 const unsigned NewLevel = I - 1; 2429 if (DSAStack->hasExplicitDSA( 2430 D, 2431 [&OMPC](const OpenMPClauseKind K, bool AppliedToPointee) { 2432 if (isOpenMPPrivate(K) && !AppliedToPointee) { 2433 OMPC = K; 2434 return true; 2435 } 2436 return false; 2437 }, 2438 NewLevel)) 2439 break; 2440 if (DSAStack->checkMappableExprComponentListsForDeclAtLevel( 2441 D, NewLevel, 2442 [](OMPClauseMappableExprCommon::MappableExprComponentListRef, 2443 OpenMPClauseKind) { return true; })) { 2444 OMPC = OMPC_map; 2445 break; 2446 } 2447 if (DSAStack->hasExplicitDirective(isOpenMPTargetExecutionDirective, 2448 NewLevel)) { 2449 OMPC = OMPC_map; 2450 if (DSAStack->mustBeFirstprivateAtLevel( 2451 NewLevel, getVariableCategoryFromDecl(LangOpts, D))) 2452 OMPC = OMPC_firstprivate; 2453 break; 2454 } 2455 } 2456 if (OMPC != OMPC_unknown) 2457 FD->addAttr(OMPCaptureKindAttr::CreateImplicit(Context, unsigned(OMPC))); 2458 } 2459 2460 bool Sema::isOpenMPTargetCapturedDecl(const ValueDecl *D, unsigned Level, 2461 unsigned CaptureLevel) const { 2462 assert(LangOpts.OpenMP && "OpenMP is not allowed"); 2463 // Return true if the current level is no longer enclosed in a target region. 2464 2465 SmallVector<OpenMPDirectiveKind, 4> Regions; 2466 getOpenMPCaptureRegions(Regions, DSAStack->getDirective(Level)); 2467 const auto *VD = dyn_cast<VarDecl>(D); 2468 return VD && !VD->hasLocalStorage() && 2469 DSAStack->hasExplicitDirective(isOpenMPTargetExecutionDirective, 2470 Level) && 2471 Regions[CaptureLevel] != OMPD_task; 2472 } 2473 2474 bool Sema::isOpenMPGlobalCapturedDecl(ValueDecl *D, unsigned Level, 2475 unsigned CaptureLevel) const { 2476 assert(LangOpts.OpenMP && "OpenMP is not allowed"); 2477 // Return true if the current level is no longer enclosed in a target region. 2478 2479 if (const auto *VD = dyn_cast<VarDecl>(D)) { 2480 if (!VD->hasLocalStorage()) { 2481 if (isInOpenMPTargetExecutionDirective()) 2482 return true; 2483 DSAStackTy::DSAVarData TopDVar = 2484 DSAStack->getTopDSA(D, /*FromParent=*/false); 2485 unsigned NumLevels = 2486 getOpenMPCaptureLevels(DSAStack->getDirective(Level)); 2487 if (Level == 0) 2488 // non-file scope static variale with default(firstprivate) 2489 // should be gloabal captured. 2490 return (NumLevels == CaptureLevel + 1 && 2491 (TopDVar.CKind != OMPC_shared || 2492 DSAStack->getDefaultDSA() == DSA_firstprivate)); 2493 do { 2494 --Level; 2495 DSAStackTy::DSAVarData DVar = DSAStack->getImplicitDSA(D, Level); 2496 if (DVar.CKind != OMPC_shared) 2497 return true; 2498 } while (Level > 0); 2499 } 2500 } 2501 return true; 2502 } 2503 2504 void Sema::DestroyDataSharingAttributesStack() { delete DSAStack; } 2505 2506 void Sema::ActOnOpenMPBeginDeclareVariant(SourceLocation Loc, 2507 OMPTraitInfo &TI) { 2508 OMPDeclareVariantScopes.push_back(OMPDeclareVariantScope(TI)); 2509 } 2510 2511 void Sema::ActOnOpenMPEndDeclareVariant() { 2512 assert(isInOpenMPDeclareVariantScope() && 2513 "Not in OpenMP declare variant scope!"); 2514 2515 OMPDeclareVariantScopes.pop_back(); 2516 } 2517 2518 void Sema::finalizeOpenMPDelayedAnalysis(const FunctionDecl *Caller, 2519 const FunctionDecl *Callee, 2520 SourceLocation Loc) { 2521 assert(LangOpts.OpenMP && "Expected OpenMP compilation mode."); 2522 Optional<OMPDeclareTargetDeclAttr::DevTypeTy> DevTy = 2523 OMPDeclareTargetDeclAttr::getDeviceType(Caller->getMostRecentDecl()); 2524 // Ignore host functions during device analyzis. 2525 if (LangOpts.OpenMPIsDevice && 2526 (!DevTy || *DevTy == OMPDeclareTargetDeclAttr::DT_Host)) 2527 return; 2528 // Ignore nohost functions during host analyzis. 2529 if (!LangOpts.OpenMPIsDevice && DevTy && 2530 *DevTy == OMPDeclareTargetDeclAttr::DT_NoHost) 2531 return; 2532 const FunctionDecl *FD = Callee->getMostRecentDecl(); 2533 DevTy = OMPDeclareTargetDeclAttr::getDeviceType(FD); 2534 if (LangOpts.OpenMPIsDevice && DevTy && 2535 *DevTy == OMPDeclareTargetDeclAttr::DT_Host) { 2536 // Diagnose host function called during device codegen. 2537 StringRef HostDevTy = 2538 getOpenMPSimpleClauseTypeName(OMPC_device_type, OMPC_DEVICE_TYPE_host); 2539 Diag(Loc, diag::err_omp_wrong_device_function_call) << HostDevTy << 0; 2540 Diag(*OMPDeclareTargetDeclAttr::getLocation(FD), 2541 diag::note_omp_marked_device_type_here) 2542 << HostDevTy; 2543 return; 2544 } 2545 if (!LangOpts.OpenMPIsDevice && !LangOpts.OpenMPOffloadMandatory && DevTy && 2546 *DevTy == OMPDeclareTargetDeclAttr::DT_NoHost) { 2547 // Diagnose nohost function called during host codegen. 2548 StringRef NoHostDevTy = getOpenMPSimpleClauseTypeName( 2549 OMPC_device_type, OMPC_DEVICE_TYPE_nohost); 2550 Diag(Loc, diag::err_omp_wrong_device_function_call) << NoHostDevTy << 1; 2551 Diag(*OMPDeclareTargetDeclAttr::getLocation(FD), 2552 diag::note_omp_marked_device_type_here) 2553 << NoHostDevTy; 2554 } 2555 } 2556 2557 void Sema::StartOpenMPDSABlock(OpenMPDirectiveKind DKind, 2558 const DeclarationNameInfo &DirName, 2559 Scope *CurScope, SourceLocation Loc) { 2560 DSAStack->push(DKind, DirName, CurScope, Loc); 2561 PushExpressionEvaluationContext( 2562 ExpressionEvaluationContext::PotentiallyEvaluated); 2563 } 2564 2565 void Sema::StartOpenMPClause(OpenMPClauseKind K) { 2566 DSAStack->setClauseParsingMode(K); 2567 } 2568 2569 void Sema::EndOpenMPClause() { 2570 DSAStack->setClauseParsingMode(/*K=*/OMPC_unknown); 2571 CleanupVarDeclMarking(); 2572 } 2573 2574 static std::pair<ValueDecl *, bool> 2575 getPrivateItem(Sema &S, Expr *&RefExpr, SourceLocation &ELoc, 2576 SourceRange &ERange, bool AllowArraySection = false); 2577 2578 /// Check consistency of the reduction clauses. 2579 static void checkReductionClauses(Sema &S, DSAStackTy *Stack, 2580 ArrayRef<OMPClause *> Clauses) { 2581 bool InscanFound = false; 2582 SourceLocation InscanLoc; 2583 // OpenMP 5.0, 2.19.5.4 reduction Clause, Restrictions. 2584 // A reduction clause without the inscan reduction-modifier may not appear on 2585 // a construct on which a reduction clause with the inscan reduction-modifier 2586 // appears. 2587 for (OMPClause *C : Clauses) { 2588 if (C->getClauseKind() != OMPC_reduction) 2589 continue; 2590 auto *RC = cast<OMPReductionClause>(C); 2591 if (RC->getModifier() == OMPC_REDUCTION_inscan) { 2592 InscanFound = true; 2593 InscanLoc = RC->getModifierLoc(); 2594 continue; 2595 } 2596 if (RC->getModifier() == OMPC_REDUCTION_task) { 2597 // OpenMP 5.0, 2.19.5.4 reduction Clause. 2598 // A reduction clause with the task reduction-modifier may only appear on 2599 // a parallel construct, a worksharing construct or a combined or 2600 // composite construct for which any of the aforementioned constructs is a 2601 // constituent construct and simd or loop are not constituent constructs. 2602 OpenMPDirectiveKind CurDir = Stack->getCurrentDirective(); 2603 if (!(isOpenMPParallelDirective(CurDir) || 2604 isOpenMPWorksharingDirective(CurDir)) || 2605 isOpenMPSimdDirective(CurDir)) 2606 S.Diag(RC->getModifierLoc(), 2607 diag::err_omp_reduction_task_not_parallel_or_worksharing); 2608 continue; 2609 } 2610 } 2611 if (InscanFound) { 2612 for (OMPClause *C : Clauses) { 2613 if (C->getClauseKind() != OMPC_reduction) 2614 continue; 2615 auto *RC = cast<OMPReductionClause>(C); 2616 if (RC->getModifier() != OMPC_REDUCTION_inscan) { 2617 S.Diag(RC->getModifier() == OMPC_REDUCTION_unknown 2618 ? RC->getBeginLoc() 2619 : RC->getModifierLoc(), 2620 diag::err_omp_inscan_reduction_expected); 2621 S.Diag(InscanLoc, diag::note_omp_previous_inscan_reduction); 2622 continue; 2623 } 2624 for (Expr *Ref : RC->varlists()) { 2625 assert(Ref && "NULL expr in OpenMP nontemporal clause."); 2626 SourceLocation ELoc; 2627 SourceRange ERange; 2628 Expr *SimpleRefExpr = Ref; 2629 auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange, 2630 /*AllowArraySection=*/true); 2631 ValueDecl *D = Res.first; 2632 if (!D) 2633 continue; 2634 if (!Stack->isUsedInScanDirective(getCanonicalDecl(D))) { 2635 S.Diag(Ref->getExprLoc(), 2636 diag::err_omp_reduction_not_inclusive_exclusive) 2637 << Ref->getSourceRange(); 2638 } 2639 } 2640 } 2641 } 2642 } 2643 2644 static void checkAllocateClauses(Sema &S, DSAStackTy *Stack, 2645 ArrayRef<OMPClause *> Clauses); 2646 static DeclRefExpr *buildCapture(Sema &S, ValueDecl *D, Expr *CaptureExpr, 2647 bool WithInit); 2648 2649 static void reportOriginalDsa(Sema &SemaRef, const DSAStackTy *Stack, 2650 const ValueDecl *D, 2651 const DSAStackTy::DSAVarData &DVar, 2652 bool IsLoopIterVar = false); 2653 2654 void Sema::EndOpenMPDSABlock(Stmt *CurDirective) { 2655 // OpenMP [2.14.3.5, Restrictions, C/C++, p.1] 2656 // A variable of class type (or array thereof) that appears in a lastprivate 2657 // clause requires an accessible, unambiguous default constructor for the 2658 // class type, unless the list item is also specified in a firstprivate 2659 // clause. 2660 if (const auto *D = dyn_cast_or_null<OMPExecutableDirective>(CurDirective)) { 2661 for (OMPClause *C : D->clauses()) { 2662 if (auto *Clause = dyn_cast<OMPLastprivateClause>(C)) { 2663 SmallVector<Expr *, 8> PrivateCopies; 2664 for (Expr *DE : Clause->varlists()) { 2665 if (DE->isValueDependent() || DE->isTypeDependent()) { 2666 PrivateCopies.push_back(nullptr); 2667 continue; 2668 } 2669 auto *DRE = cast<DeclRefExpr>(DE->IgnoreParens()); 2670 auto *VD = cast<VarDecl>(DRE->getDecl()); 2671 QualType Type = VD->getType().getNonReferenceType(); 2672 const DSAStackTy::DSAVarData DVar = 2673 DSAStack->getTopDSA(VD, /*FromParent=*/false); 2674 if (DVar.CKind == OMPC_lastprivate) { 2675 // Generate helper private variable and initialize it with the 2676 // default value. The address of the original variable is replaced 2677 // by the address of the new private variable in CodeGen. This new 2678 // variable is not added to IdResolver, so the code in the OpenMP 2679 // region uses original variable for proper diagnostics. 2680 VarDecl *VDPrivate = buildVarDecl( 2681 *this, DE->getExprLoc(), Type.getUnqualifiedType(), 2682 VD->getName(), VD->hasAttrs() ? &VD->getAttrs() : nullptr, DRE); 2683 ActOnUninitializedDecl(VDPrivate); 2684 if (VDPrivate->isInvalidDecl()) { 2685 PrivateCopies.push_back(nullptr); 2686 continue; 2687 } 2688 PrivateCopies.push_back(buildDeclRefExpr( 2689 *this, VDPrivate, DE->getType(), DE->getExprLoc())); 2690 } else { 2691 // The variable is also a firstprivate, so initialization sequence 2692 // for private copy is generated already. 2693 PrivateCopies.push_back(nullptr); 2694 } 2695 } 2696 Clause->setPrivateCopies(PrivateCopies); 2697 continue; 2698 } 2699 // Finalize nontemporal clause by handling private copies, if any. 2700 if (auto *Clause = dyn_cast<OMPNontemporalClause>(C)) { 2701 SmallVector<Expr *, 8> PrivateRefs; 2702 for (Expr *RefExpr : Clause->varlists()) { 2703 assert(RefExpr && "NULL expr in OpenMP nontemporal clause."); 2704 SourceLocation ELoc; 2705 SourceRange ERange; 2706 Expr *SimpleRefExpr = RefExpr; 2707 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 2708 if (Res.second) 2709 // It will be analyzed later. 2710 PrivateRefs.push_back(RefExpr); 2711 ValueDecl *D = Res.first; 2712 if (!D) 2713 continue; 2714 2715 const DSAStackTy::DSAVarData DVar = 2716 DSAStack->getTopDSA(D, /*FromParent=*/false); 2717 PrivateRefs.push_back(DVar.PrivateCopy ? DVar.PrivateCopy 2718 : SimpleRefExpr); 2719 } 2720 Clause->setPrivateRefs(PrivateRefs); 2721 continue; 2722 } 2723 if (auto *Clause = dyn_cast<OMPUsesAllocatorsClause>(C)) { 2724 for (unsigned I = 0, E = Clause->getNumberOfAllocators(); I < E; ++I) { 2725 OMPUsesAllocatorsClause::Data D = Clause->getAllocatorData(I); 2726 auto *DRE = dyn_cast<DeclRefExpr>(D.Allocator->IgnoreParenImpCasts()); 2727 if (!DRE) 2728 continue; 2729 ValueDecl *VD = DRE->getDecl(); 2730 if (!VD || !isa<VarDecl>(VD)) 2731 continue; 2732 DSAStackTy::DSAVarData DVar = 2733 DSAStack->getTopDSA(VD, /*FromParent=*/false); 2734 // OpenMP [2.12.5, target Construct] 2735 // Memory allocators that appear in a uses_allocators clause cannot 2736 // appear in other data-sharing attribute clauses or data-mapping 2737 // attribute clauses in the same construct. 2738 Expr *MapExpr = nullptr; 2739 if (DVar.RefExpr || 2740 DSAStack->checkMappableExprComponentListsForDecl( 2741 VD, /*CurrentRegionOnly=*/true, 2742 [VD, &MapExpr]( 2743 OMPClauseMappableExprCommon::MappableExprComponentListRef 2744 MapExprComponents, 2745 OpenMPClauseKind C) { 2746 auto MI = MapExprComponents.rbegin(); 2747 auto ME = MapExprComponents.rend(); 2748 if (MI != ME && 2749 MI->getAssociatedDeclaration()->getCanonicalDecl() == 2750 VD->getCanonicalDecl()) { 2751 MapExpr = MI->getAssociatedExpression(); 2752 return true; 2753 } 2754 return false; 2755 })) { 2756 Diag(D.Allocator->getExprLoc(), 2757 diag::err_omp_allocator_used_in_clauses) 2758 << D.Allocator->getSourceRange(); 2759 if (DVar.RefExpr) 2760 reportOriginalDsa(*this, DSAStack, VD, DVar); 2761 else 2762 Diag(MapExpr->getExprLoc(), diag::note_used_here) 2763 << MapExpr->getSourceRange(); 2764 } 2765 } 2766 continue; 2767 } 2768 } 2769 // Check allocate clauses. 2770 if (!CurContext->isDependentContext()) 2771 checkAllocateClauses(*this, DSAStack, D->clauses()); 2772 checkReductionClauses(*this, DSAStack, D->clauses()); 2773 } 2774 2775 DSAStack->pop(); 2776 DiscardCleanupsInEvaluationContext(); 2777 PopExpressionEvaluationContext(); 2778 } 2779 2780 static bool FinishOpenMPLinearClause(OMPLinearClause &Clause, DeclRefExpr *IV, 2781 Expr *NumIterations, Sema &SemaRef, 2782 Scope *S, DSAStackTy *Stack); 2783 2784 namespace { 2785 2786 class VarDeclFilterCCC final : public CorrectionCandidateCallback { 2787 private: 2788 Sema &SemaRef; 2789 2790 public: 2791 explicit VarDeclFilterCCC(Sema &S) : SemaRef(S) {} 2792 bool ValidateCandidate(const TypoCorrection &Candidate) override { 2793 NamedDecl *ND = Candidate.getCorrectionDecl(); 2794 if (const auto *VD = dyn_cast_or_null<VarDecl>(ND)) { 2795 return VD->hasGlobalStorage() && 2796 SemaRef.isDeclInScope(ND, SemaRef.getCurLexicalContext(), 2797 SemaRef.getCurScope()); 2798 } 2799 return false; 2800 } 2801 2802 std::unique_ptr<CorrectionCandidateCallback> clone() override { 2803 return std::make_unique<VarDeclFilterCCC>(*this); 2804 } 2805 }; 2806 2807 class VarOrFuncDeclFilterCCC final : public CorrectionCandidateCallback { 2808 private: 2809 Sema &SemaRef; 2810 2811 public: 2812 explicit VarOrFuncDeclFilterCCC(Sema &S) : SemaRef(S) {} 2813 bool ValidateCandidate(const TypoCorrection &Candidate) override { 2814 NamedDecl *ND = Candidate.getCorrectionDecl(); 2815 if (ND && ((isa<VarDecl>(ND) && ND->getKind() == Decl::Var) || 2816 isa<FunctionDecl>(ND))) { 2817 return SemaRef.isDeclInScope(ND, SemaRef.getCurLexicalContext(), 2818 SemaRef.getCurScope()); 2819 } 2820 return false; 2821 } 2822 2823 std::unique_ptr<CorrectionCandidateCallback> clone() override { 2824 return std::make_unique<VarOrFuncDeclFilterCCC>(*this); 2825 } 2826 }; 2827 2828 } // namespace 2829 2830 ExprResult Sema::ActOnOpenMPIdExpression(Scope *CurScope, 2831 CXXScopeSpec &ScopeSpec, 2832 const DeclarationNameInfo &Id, 2833 OpenMPDirectiveKind Kind) { 2834 LookupResult Lookup(*this, Id, LookupOrdinaryName); 2835 LookupParsedName(Lookup, CurScope, &ScopeSpec, true); 2836 2837 if (Lookup.isAmbiguous()) 2838 return ExprError(); 2839 2840 VarDecl *VD; 2841 if (!Lookup.isSingleResult()) { 2842 VarDeclFilterCCC CCC(*this); 2843 if (TypoCorrection Corrected = 2844 CorrectTypo(Id, LookupOrdinaryName, CurScope, nullptr, CCC, 2845 CTK_ErrorRecovery)) { 2846 diagnoseTypo(Corrected, 2847 PDiag(Lookup.empty() 2848 ? diag::err_undeclared_var_use_suggest 2849 : diag::err_omp_expected_var_arg_suggest) 2850 << Id.getName()); 2851 VD = Corrected.getCorrectionDeclAs<VarDecl>(); 2852 } else { 2853 Diag(Id.getLoc(), Lookup.empty() ? diag::err_undeclared_var_use 2854 : diag::err_omp_expected_var_arg) 2855 << Id.getName(); 2856 return ExprError(); 2857 } 2858 } else if (!(VD = Lookup.getAsSingle<VarDecl>())) { 2859 Diag(Id.getLoc(), diag::err_omp_expected_var_arg) << Id.getName(); 2860 Diag(Lookup.getFoundDecl()->getLocation(), diag::note_declared_at); 2861 return ExprError(); 2862 } 2863 Lookup.suppressDiagnostics(); 2864 2865 // OpenMP [2.9.2, Syntax, C/C++] 2866 // Variables must be file-scope, namespace-scope, or static block-scope. 2867 if (Kind == OMPD_threadprivate && !VD->hasGlobalStorage()) { 2868 Diag(Id.getLoc(), diag::err_omp_global_var_arg) 2869 << getOpenMPDirectiveName(Kind) << !VD->isStaticLocal(); 2870 bool IsDecl = 2871 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 2872 Diag(VD->getLocation(), 2873 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 2874 << VD; 2875 return ExprError(); 2876 } 2877 2878 VarDecl *CanonicalVD = VD->getCanonicalDecl(); 2879 NamedDecl *ND = CanonicalVD; 2880 // OpenMP [2.9.2, Restrictions, C/C++, p.2] 2881 // A threadprivate directive for file-scope variables must appear outside 2882 // any definition or declaration. 2883 if (CanonicalVD->getDeclContext()->isTranslationUnit() && 2884 !getCurLexicalContext()->isTranslationUnit()) { 2885 Diag(Id.getLoc(), diag::err_omp_var_scope) 2886 << getOpenMPDirectiveName(Kind) << VD; 2887 bool IsDecl = 2888 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 2889 Diag(VD->getLocation(), 2890 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 2891 << VD; 2892 return ExprError(); 2893 } 2894 // OpenMP [2.9.2, Restrictions, C/C++, p.3] 2895 // A threadprivate directive for static class member variables must appear 2896 // in the class definition, in the same scope in which the member 2897 // variables are declared. 2898 if (CanonicalVD->isStaticDataMember() && 2899 !CanonicalVD->getDeclContext()->Equals(getCurLexicalContext())) { 2900 Diag(Id.getLoc(), diag::err_omp_var_scope) 2901 << getOpenMPDirectiveName(Kind) << VD; 2902 bool IsDecl = 2903 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 2904 Diag(VD->getLocation(), 2905 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 2906 << VD; 2907 return ExprError(); 2908 } 2909 // OpenMP [2.9.2, Restrictions, C/C++, p.4] 2910 // A threadprivate directive for namespace-scope variables must appear 2911 // outside any definition or declaration other than the namespace 2912 // definition itself. 2913 if (CanonicalVD->getDeclContext()->isNamespace() && 2914 (!getCurLexicalContext()->isFileContext() || 2915 !getCurLexicalContext()->Encloses(CanonicalVD->getDeclContext()))) { 2916 Diag(Id.getLoc(), diag::err_omp_var_scope) 2917 << getOpenMPDirectiveName(Kind) << VD; 2918 bool IsDecl = 2919 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 2920 Diag(VD->getLocation(), 2921 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 2922 << VD; 2923 return ExprError(); 2924 } 2925 // OpenMP [2.9.2, Restrictions, C/C++, p.6] 2926 // A threadprivate directive for static block-scope variables must appear 2927 // in the scope of the variable and not in a nested scope. 2928 if (CanonicalVD->isLocalVarDecl() && CurScope && 2929 !isDeclInScope(ND, getCurLexicalContext(), CurScope)) { 2930 Diag(Id.getLoc(), diag::err_omp_var_scope) 2931 << getOpenMPDirectiveName(Kind) << VD; 2932 bool IsDecl = 2933 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 2934 Diag(VD->getLocation(), 2935 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 2936 << VD; 2937 return ExprError(); 2938 } 2939 2940 // OpenMP [2.9.2, Restrictions, C/C++, p.2-6] 2941 // A threadprivate directive must lexically precede all references to any 2942 // of the variables in its list. 2943 if (Kind == OMPD_threadprivate && VD->isUsed() && 2944 !DSAStack->isThreadPrivate(VD)) { 2945 Diag(Id.getLoc(), diag::err_omp_var_used) 2946 << getOpenMPDirectiveName(Kind) << VD; 2947 return ExprError(); 2948 } 2949 2950 QualType ExprType = VD->getType().getNonReferenceType(); 2951 return DeclRefExpr::Create(Context, NestedNameSpecifierLoc(), 2952 SourceLocation(), VD, 2953 /*RefersToEnclosingVariableOrCapture=*/false, 2954 Id.getLoc(), ExprType, VK_LValue); 2955 } 2956 2957 Sema::DeclGroupPtrTy 2958 Sema::ActOnOpenMPThreadprivateDirective(SourceLocation Loc, 2959 ArrayRef<Expr *> VarList) { 2960 if (OMPThreadPrivateDecl *D = CheckOMPThreadPrivateDecl(Loc, VarList)) { 2961 CurContext->addDecl(D); 2962 return DeclGroupPtrTy::make(DeclGroupRef(D)); 2963 } 2964 return nullptr; 2965 } 2966 2967 namespace { 2968 class LocalVarRefChecker final 2969 : public ConstStmtVisitor<LocalVarRefChecker, bool> { 2970 Sema &SemaRef; 2971 2972 public: 2973 bool VisitDeclRefExpr(const DeclRefExpr *E) { 2974 if (const auto *VD = dyn_cast<VarDecl>(E->getDecl())) { 2975 if (VD->hasLocalStorage()) { 2976 SemaRef.Diag(E->getBeginLoc(), 2977 diag::err_omp_local_var_in_threadprivate_init) 2978 << E->getSourceRange(); 2979 SemaRef.Diag(VD->getLocation(), diag::note_defined_here) 2980 << VD << VD->getSourceRange(); 2981 return true; 2982 } 2983 } 2984 return false; 2985 } 2986 bool VisitStmt(const Stmt *S) { 2987 for (const Stmt *Child : S->children()) { 2988 if (Child && Visit(Child)) 2989 return true; 2990 } 2991 return false; 2992 } 2993 explicit LocalVarRefChecker(Sema &SemaRef) : SemaRef(SemaRef) {} 2994 }; 2995 } // namespace 2996 2997 OMPThreadPrivateDecl * 2998 Sema::CheckOMPThreadPrivateDecl(SourceLocation Loc, ArrayRef<Expr *> VarList) { 2999 SmallVector<Expr *, 8> Vars; 3000 for (Expr *RefExpr : VarList) { 3001 auto *DE = cast<DeclRefExpr>(RefExpr); 3002 auto *VD = cast<VarDecl>(DE->getDecl()); 3003 SourceLocation ILoc = DE->getExprLoc(); 3004 3005 // Mark variable as used. 3006 VD->setReferenced(); 3007 VD->markUsed(Context); 3008 3009 QualType QType = VD->getType(); 3010 if (QType->isDependentType() || QType->isInstantiationDependentType()) { 3011 // It will be analyzed later. 3012 Vars.push_back(DE); 3013 continue; 3014 } 3015 3016 // OpenMP [2.9.2, Restrictions, C/C++, p.10] 3017 // A threadprivate variable must not have an incomplete type. 3018 if (RequireCompleteType(ILoc, VD->getType(), 3019 diag::err_omp_threadprivate_incomplete_type)) { 3020 continue; 3021 } 3022 3023 // OpenMP [2.9.2, Restrictions, C/C++, p.10] 3024 // A threadprivate variable must not have a reference type. 3025 if (VD->getType()->isReferenceType()) { 3026 Diag(ILoc, diag::err_omp_ref_type_arg) 3027 << getOpenMPDirectiveName(OMPD_threadprivate) << VD->getType(); 3028 bool IsDecl = 3029 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 3030 Diag(VD->getLocation(), 3031 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 3032 << VD; 3033 continue; 3034 } 3035 3036 // Check if this is a TLS variable. If TLS is not being supported, produce 3037 // the corresponding diagnostic. 3038 if ((VD->getTLSKind() != VarDecl::TLS_None && 3039 !(VD->hasAttr<OMPThreadPrivateDeclAttr>() && 3040 getLangOpts().OpenMPUseTLS && 3041 getASTContext().getTargetInfo().isTLSSupported())) || 3042 (VD->getStorageClass() == SC_Register && VD->hasAttr<AsmLabelAttr>() && 3043 !VD->isLocalVarDecl())) { 3044 Diag(ILoc, diag::err_omp_var_thread_local) 3045 << VD << ((VD->getTLSKind() != VarDecl::TLS_None) ? 0 : 1); 3046 bool IsDecl = 3047 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 3048 Diag(VD->getLocation(), 3049 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 3050 << VD; 3051 continue; 3052 } 3053 3054 // Check if initial value of threadprivate variable reference variable with 3055 // local storage (it is not supported by runtime). 3056 if (const Expr *Init = VD->getAnyInitializer()) { 3057 LocalVarRefChecker Checker(*this); 3058 if (Checker.Visit(Init)) 3059 continue; 3060 } 3061 3062 Vars.push_back(RefExpr); 3063 DSAStack->addDSA(VD, DE, OMPC_threadprivate); 3064 VD->addAttr(OMPThreadPrivateDeclAttr::CreateImplicit( 3065 Context, SourceRange(Loc, Loc))); 3066 if (ASTMutationListener *ML = Context.getASTMutationListener()) 3067 ML->DeclarationMarkedOpenMPThreadPrivate(VD); 3068 } 3069 OMPThreadPrivateDecl *D = nullptr; 3070 if (!Vars.empty()) { 3071 D = OMPThreadPrivateDecl::Create(Context, getCurLexicalContext(), Loc, 3072 Vars); 3073 D->setAccess(AS_public); 3074 } 3075 return D; 3076 } 3077 3078 static OMPAllocateDeclAttr::AllocatorTypeTy 3079 getAllocatorKind(Sema &S, DSAStackTy *Stack, Expr *Allocator) { 3080 if (!Allocator) 3081 return OMPAllocateDeclAttr::OMPNullMemAlloc; 3082 if (Allocator->isTypeDependent() || Allocator->isValueDependent() || 3083 Allocator->isInstantiationDependent() || 3084 Allocator->containsUnexpandedParameterPack()) 3085 return OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; 3086 auto AllocatorKindRes = OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; 3087 const Expr *AE = Allocator->IgnoreParenImpCasts(); 3088 for (int I = 0; I < OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; ++I) { 3089 auto AllocatorKind = static_cast<OMPAllocateDeclAttr::AllocatorTypeTy>(I); 3090 const Expr *DefAllocator = Stack->getAllocator(AllocatorKind); 3091 llvm::FoldingSetNodeID AEId, DAEId; 3092 AE->Profile(AEId, S.getASTContext(), /*Canonical=*/true); 3093 DefAllocator->Profile(DAEId, S.getASTContext(), /*Canonical=*/true); 3094 if (AEId == DAEId) { 3095 AllocatorKindRes = AllocatorKind; 3096 break; 3097 } 3098 } 3099 return AllocatorKindRes; 3100 } 3101 3102 static bool checkPreviousOMPAllocateAttribute( 3103 Sema &S, DSAStackTy *Stack, Expr *RefExpr, VarDecl *VD, 3104 OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind, Expr *Allocator) { 3105 if (!VD->hasAttr<OMPAllocateDeclAttr>()) 3106 return false; 3107 const auto *A = VD->getAttr<OMPAllocateDeclAttr>(); 3108 Expr *PrevAllocator = A->getAllocator(); 3109 OMPAllocateDeclAttr::AllocatorTypeTy PrevAllocatorKind = 3110 getAllocatorKind(S, Stack, PrevAllocator); 3111 bool AllocatorsMatch = AllocatorKind == PrevAllocatorKind; 3112 if (AllocatorsMatch && 3113 AllocatorKind == OMPAllocateDeclAttr::OMPUserDefinedMemAlloc && 3114 Allocator && PrevAllocator) { 3115 const Expr *AE = Allocator->IgnoreParenImpCasts(); 3116 const Expr *PAE = PrevAllocator->IgnoreParenImpCasts(); 3117 llvm::FoldingSetNodeID AEId, PAEId; 3118 AE->Profile(AEId, S.Context, /*Canonical=*/true); 3119 PAE->Profile(PAEId, S.Context, /*Canonical=*/true); 3120 AllocatorsMatch = AEId == PAEId; 3121 } 3122 if (!AllocatorsMatch) { 3123 SmallString<256> AllocatorBuffer; 3124 llvm::raw_svector_ostream AllocatorStream(AllocatorBuffer); 3125 if (Allocator) 3126 Allocator->printPretty(AllocatorStream, nullptr, S.getPrintingPolicy()); 3127 SmallString<256> PrevAllocatorBuffer; 3128 llvm::raw_svector_ostream PrevAllocatorStream(PrevAllocatorBuffer); 3129 if (PrevAllocator) 3130 PrevAllocator->printPretty(PrevAllocatorStream, nullptr, 3131 S.getPrintingPolicy()); 3132 3133 SourceLocation AllocatorLoc = 3134 Allocator ? Allocator->getExprLoc() : RefExpr->getExprLoc(); 3135 SourceRange AllocatorRange = 3136 Allocator ? Allocator->getSourceRange() : RefExpr->getSourceRange(); 3137 SourceLocation PrevAllocatorLoc = 3138 PrevAllocator ? PrevAllocator->getExprLoc() : A->getLocation(); 3139 SourceRange PrevAllocatorRange = 3140 PrevAllocator ? PrevAllocator->getSourceRange() : A->getRange(); 3141 S.Diag(AllocatorLoc, diag::warn_omp_used_different_allocator) 3142 << (Allocator ? 1 : 0) << AllocatorStream.str() 3143 << (PrevAllocator ? 1 : 0) << PrevAllocatorStream.str() 3144 << AllocatorRange; 3145 S.Diag(PrevAllocatorLoc, diag::note_omp_previous_allocator) 3146 << PrevAllocatorRange; 3147 return true; 3148 } 3149 return false; 3150 } 3151 3152 static void 3153 applyOMPAllocateAttribute(Sema &S, VarDecl *VD, 3154 OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind, 3155 Expr *Allocator, Expr *Alignment, SourceRange SR) { 3156 if (VD->hasAttr<OMPAllocateDeclAttr>()) 3157 return; 3158 if (Alignment && 3159 (Alignment->isTypeDependent() || Alignment->isValueDependent() || 3160 Alignment->isInstantiationDependent() || 3161 Alignment->containsUnexpandedParameterPack())) 3162 // Apply later when we have a usable value. 3163 return; 3164 if (Allocator && 3165 (Allocator->isTypeDependent() || Allocator->isValueDependent() || 3166 Allocator->isInstantiationDependent() || 3167 Allocator->containsUnexpandedParameterPack())) 3168 return; 3169 auto *A = OMPAllocateDeclAttr::CreateImplicit(S.Context, AllocatorKind, 3170 Allocator, Alignment, SR); 3171 VD->addAttr(A); 3172 if (ASTMutationListener *ML = S.Context.getASTMutationListener()) 3173 ML->DeclarationMarkedOpenMPAllocate(VD, A); 3174 } 3175 3176 Sema::DeclGroupPtrTy 3177 Sema::ActOnOpenMPAllocateDirective(SourceLocation Loc, ArrayRef<Expr *> VarList, 3178 ArrayRef<OMPClause *> Clauses, 3179 DeclContext *Owner) { 3180 assert(Clauses.size() <= 2 && "Expected at most two clauses."); 3181 Expr *Alignment = nullptr; 3182 Expr *Allocator = nullptr; 3183 if (Clauses.empty()) { 3184 // OpenMP 5.0, 2.11.3 allocate Directive, Restrictions. 3185 // allocate directives that appear in a target region must specify an 3186 // allocator clause unless a requires directive with the dynamic_allocators 3187 // clause is present in the same compilation unit. 3188 if (LangOpts.OpenMPIsDevice && 3189 !DSAStack->hasRequiresDeclWithClause<OMPDynamicAllocatorsClause>()) 3190 targetDiag(Loc, diag::err_expected_allocator_clause); 3191 } else { 3192 for (const OMPClause *C : Clauses) 3193 if (const auto *AC = dyn_cast<OMPAllocatorClause>(C)) 3194 Allocator = AC->getAllocator(); 3195 else if (const auto *AC = dyn_cast<OMPAlignClause>(C)) 3196 Alignment = AC->getAlignment(); 3197 else 3198 llvm_unreachable("Unexpected clause on allocate directive"); 3199 } 3200 OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind = 3201 getAllocatorKind(*this, DSAStack, Allocator); 3202 SmallVector<Expr *, 8> Vars; 3203 for (Expr *RefExpr : VarList) { 3204 auto *DE = cast<DeclRefExpr>(RefExpr); 3205 auto *VD = cast<VarDecl>(DE->getDecl()); 3206 3207 // Check if this is a TLS variable or global register. 3208 if (VD->getTLSKind() != VarDecl::TLS_None || 3209 VD->hasAttr<OMPThreadPrivateDeclAttr>() || 3210 (VD->getStorageClass() == SC_Register && VD->hasAttr<AsmLabelAttr>() && 3211 !VD->isLocalVarDecl())) 3212 continue; 3213 3214 // If the used several times in the allocate directive, the same allocator 3215 // must be used. 3216 if (checkPreviousOMPAllocateAttribute(*this, DSAStack, RefExpr, VD, 3217 AllocatorKind, Allocator)) 3218 continue; 3219 3220 // OpenMP, 2.11.3 allocate Directive, Restrictions, C / C++ 3221 // If a list item has a static storage type, the allocator expression in the 3222 // allocator clause must be a constant expression that evaluates to one of 3223 // the predefined memory allocator values. 3224 if (Allocator && VD->hasGlobalStorage()) { 3225 if (AllocatorKind == OMPAllocateDeclAttr::OMPUserDefinedMemAlloc) { 3226 Diag(Allocator->getExprLoc(), 3227 diag::err_omp_expected_predefined_allocator) 3228 << Allocator->getSourceRange(); 3229 bool IsDecl = VD->isThisDeclarationADefinition(Context) == 3230 VarDecl::DeclarationOnly; 3231 Diag(VD->getLocation(), 3232 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 3233 << VD; 3234 continue; 3235 } 3236 } 3237 3238 Vars.push_back(RefExpr); 3239 applyOMPAllocateAttribute(*this, VD, AllocatorKind, Allocator, Alignment, 3240 DE->getSourceRange()); 3241 } 3242 if (Vars.empty()) 3243 return nullptr; 3244 if (!Owner) 3245 Owner = getCurLexicalContext(); 3246 auto *D = OMPAllocateDecl::Create(Context, Owner, Loc, Vars, Clauses); 3247 D->setAccess(AS_public); 3248 Owner->addDecl(D); 3249 return DeclGroupPtrTy::make(DeclGroupRef(D)); 3250 } 3251 3252 Sema::DeclGroupPtrTy 3253 Sema::ActOnOpenMPRequiresDirective(SourceLocation Loc, 3254 ArrayRef<OMPClause *> ClauseList) { 3255 OMPRequiresDecl *D = nullptr; 3256 if (!CurContext->isFileContext()) { 3257 Diag(Loc, diag::err_omp_invalid_scope) << "requires"; 3258 } else { 3259 D = CheckOMPRequiresDecl(Loc, ClauseList); 3260 if (D) { 3261 CurContext->addDecl(D); 3262 DSAStack->addRequiresDecl(D); 3263 } 3264 } 3265 return DeclGroupPtrTy::make(DeclGroupRef(D)); 3266 } 3267 3268 void Sema::ActOnOpenMPAssumesDirective(SourceLocation Loc, 3269 OpenMPDirectiveKind DKind, 3270 ArrayRef<std::string> Assumptions, 3271 bool SkippedClauses) { 3272 if (!SkippedClauses && Assumptions.empty()) 3273 Diag(Loc, diag::err_omp_no_clause_for_directive) 3274 << llvm::omp::getAllAssumeClauseOptions() 3275 << llvm::omp::getOpenMPDirectiveName(DKind); 3276 3277 auto *AA = AssumptionAttr::Create(Context, llvm::join(Assumptions, ","), Loc); 3278 if (DKind == llvm::omp::Directive::OMPD_begin_assumes) { 3279 OMPAssumeScoped.push_back(AA); 3280 return; 3281 } 3282 3283 // Global assumes without assumption clauses are ignored. 3284 if (Assumptions.empty()) 3285 return; 3286 3287 assert(DKind == llvm::omp::Directive::OMPD_assumes && 3288 "Unexpected omp assumption directive!"); 3289 OMPAssumeGlobal.push_back(AA); 3290 3291 // The OMPAssumeGlobal scope above will take care of new declarations but 3292 // we also want to apply the assumption to existing ones, e.g., to 3293 // declarations in included headers. To this end, we traverse all existing 3294 // declaration contexts and annotate function declarations here. 3295 SmallVector<DeclContext *, 8> DeclContexts; 3296 auto *Ctx = CurContext; 3297 while (Ctx->getLexicalParent()) 3298 Ctx = Ctx->getLexicalParent(); 3299 DeclContexts.push_back(Ctx); 3300 while (!DeclContexts.empty()) { 3301 DeclContext *DC = DeclContexts.pop_back_val(); 3302 for (auto *SubDC : DC->decls()) { 3303 if (SubDC->isInvalidDecl()) 3304 continue; 3305 if (auto *CTD = dyn_cast<ClassTemplateDecl>(SubDC)) { 3306 DeclContexts.push_back(CTD->getTemplatedDecl()); 3307 llvm::append_range(DeclContexts, CTD->specializations()); 3308 continue; 3309 } 3310 if (auto *DC = dyn_cast<DeclContext>(SubDC)) 3311 DeclContexts.push_back(DC); 3312 if (auto *F = dyn_cast<FunctionDecl>(SubDC)) { 3313 F->addAttr(AA); 3314 continue; 3315 } 3316 } 3317 } 3318 } 3319 3320 void Sema::ActOnOpenMPEndAssumesDirective() { 3321 assert(isInOpenMPAssumeScope() && "Not in OpenMP assumes scope!"); 3322 OMPAssumeScoped.pop_back(); 3323 } 3324 3325 OMPRequiresDecl *Sema::CheckOMPRequiresDecl(SourceLocation Loc, 3326 ArrayRef<OMPClause *> ClauseList) { 3327 /// For target specific clauses, the requires directive cannot be 3328 /// specified after the handling of any of the target regions in the 3329 /// current compilation unit. 3330 ArrayRef<SourceLocation> TargetLocations = 3331 DSAStack->getEncounteredTargetLocs(); 3332 SourceLocation AtomicLoc = DSAStack->getAtomicDirectiveLoc(); 3333 if (!TargetLocations.empty() || !AtomicLoc.isInvalid()) { 3334 for (const OMPClause *CNew : ClauseList) { 3335 // Check if any of the requires clauses affect target regions. 3336 if (isa<OMPUnifiedSharedMemoryClause>(CNew) || 3337 isa<OMPUnifiedAddressClause>(CNew) || 3338 isa<OMPReverseOffloadClause>(CNew) || 3339 isa<OMPDynamicAllocatorsClause>(CNew)) { 3340 Diag(Loc, diag::err_omp_directive_before_requires) 3341 << "target" << getOpenMPClauseName(CNew->getClauseKind()); 3342 for (SourceLocation TargetLoc : TargetLocations) { 3343 Diag(TargetLoc, diag::note_omp_requires_encountered_directive) 3344 << "target"; 3345 } 3346 } else if (!AtomicLoc.isInvalid() && 3347 isa<OMPAtomicDefaultMemOrderClause>(CNew)) { 3348 Diag(Loc, diag::err_omp_directive_before_requires) 3349 << "atomic" << getOpenMPClauseName(CNew->getClauseKind()); 3350 Diag(AtomicLoc, diag::note_omp_requires_encountered_directive) 3351 << "atomic"; 3352 } 3353 } 3354 } 3355 3356 if (!DSAStack->hasDuplicateRequiresClause(ClauseList)) 3357 return OMPRequiresDecl::Create(Context, getCurLexicalContext(), Loc, 3358 ClauseList); 3359 return nullptr; 3360 } 3361 3362 static void reportOriginalDsa(Sema &SemaRef, const DSAStackTy *Stack, 3363 const ValueDecl *D, 3364 const DSAStackTy::DSAVarData &DVar, 3365 bool IsLoopIterVar) { 3366 if (DVar.RefExpr) { 3367 SemaRef.Diag(DVar.RefExpr->getExprLoc(), diag::note_omp_explicit_dsa) 3368 << getOpenMPClauseName(DVar.CKind); 3369 return; 3370 } 3371 enum { 3372 PDSA_StaticMemberShared, 3373 PDSA_StaticLocalVarShared, 3374 PDSA_LoopIterVarPrivate, 3375 PDSA_LoopIterVarLinear, 3376 PDSA_LoopIterVarLastprivate, 3377 PDSA_ConstVarShared, 3378 PDSA_GlobalVarShared, 3379 PDSA_TaskVarFirstprivate, 3380 PDSA_LocalVarPrivate, 3381 PDSA_Implicit 3382 } Reason = PDSA_Implicit; 3383 bool ReportHint = false; 3384 auto ReportLoc = D->getLocation(); 3385 auto *VD = dyn_cast<VarDecl>(D); 3386 if (IsLoopIterVar) { 3387 if (DVar.CKind == OMPC_private) 3388 Reason = PDSA_LoopIterVarPrivate; 3389 else if (DVar.CKind == OMPC_lastprivate) 3390 Reason = PDSA_LoopIterVarLastprivate; 3391 else 3392 Reason = PDSA_LoopIterVarLinear; 3393 } else if (isOpenMPTaskingDirective(DVar.DKind) && 3394 DVar.CKind == OMPC_firstprivate) { 3395 Reason = PDSA_TaskVarFirstprivate; 3396 ReportLoc = DVar.ImplicitDSALoc; 3397 } else if (VD && VD->isStaticLocal()) 3398 Reason = PDSA_StaticLocalVarShared; 3399 else if (VD && VD->isStaticDataMember()) 3400 Reason = PDSA_StaticMemberShared; 3401 else if (VD && VD->isFileVarDecl()) 3402 Reason = PDSA_GlobalVarShared; 3403 else if (D->getType().isConstant(SemaRef.getASTContext())) 3404 Reason = PDSA_ConstVarShared; 3405 else if (VD && VD->isLocalVarDecl() && DVar.CKind == OMPC_private) { 3406 ReportHint = true; 3407 Reason = PDSA_LocalVarPrivate; 3408 } 3409 if (Reason != PDSA_Implicit) { 3410 SemaRef.Diag(ReportLoc, diag::note_omp_predetermined_dsa) 3411 << Reason << ReportHint 3412 << getOpenMPDirectiveName(Stack->getCurrentDirective()); 3413 } else if (DVar.ImplicitDSALoc.isValid()) { 3414 SemaRef.Diag(DVar.ImplicitDSALoc, diag::note_omp_implicit_dsa) 3415 << getOpenMPClauseName(DVar.CKind); 3416 } 3417 } 3418 3419 static OpenMPMapClauseKind 3420 getMapClauseKindFromModifier(OpenMPDefaultmapClauseModifier M, 3421 bool IsAggregateOrDeclareTarget) { 3422 OpenMPMapClauseKind Kind = OMPC_MAP_unknown; 3423 switch (M) { 3424 case OMPC_DEFAULTMAP_MODIFIER_alloc: 3425 Kind = OMPC_MAP_alloc; 3426 break; 3427 case OMPC_DEFAULTMAP_MODIFIER_to: 3428 Kind = OMPC_MAP_to; 3429 break; 3430 case OMPC_DEFAULTMAP_MODIFIER_from: 3431 Kind = OMPC_MAP_from; 3432 break; 3433 case OMPC_DEFAULTMAP_MODIFIER_tofrom: 3434 Kind = OMPC_MAP_tofrom; 3435 break; 3436 case OMPC_DEFAULTMAP_MODIFIER_present: 3437 // OpenMP 5.1 [2.21.7.3] defaultmap clause, Description] 3438 // If implicit-behavior is present, each variable referenced in the 3439 // construct in the category specified by variable-category is treated as if 3440 // it had been listed in a map clause with the map-type of alloc and 3441 // map-type-modifier of present. 3442 Kind = OMPC_MAP_alloc; 3443 break; 3444 case OMPC_DEFAULTMAP_MODIFIER_firstprivate: 3445 case OMPC_DEFAULTMAP_MODIFIER_last: 3446 llvm_unreachable("Unexpected defaultmap implicit behavior"); 3447 case OMPC_DEFAULTMAP_MODIFIER_none: 3448 case OMPC_DEFAULTMAP_MODIFIER_default: 3449 case OMPC_DEFAULTMAP_MODIFIER_unknown: 3450 // IsAggregateOrDeclareTarget could be true if: 3451 // 1. the implicit behavior for aggregate is tofrom 3452 // 2. it's a declare target link 3453 if (IsAggregateOrDeclareTarget) { 3454 Kind = OMPC_MAP_tofrom; 3455 break; 3456 } 3457 llvm_unreachable("Unexpected defaultmap implicit behavior"); 3458 } 3459 assert(Kind != OMPC_MAP_unknown && "Expect map kind to be known"); 3460 return Kind; 3461 } 3462 3463 namespace { 3464 class DSAAttrChecker final : public StmtVisitor<DSAAttrChecker, void> { 3465 DSAStackTy *Stack; 3466 Sema &SemaRef; 3467 bool ErrorFound = false; 3468 bool TryCaptureCXXThisMembers = false; 3469 CapturedStmt *CS = nullptr; 3470 const static unsigned DefaultmapKindNum = OMPC_DEFAULTMAP_pointer + 1; 3471 llvm::SmallVector<Expr *, 4> ImplicitFirstprivate; 3472 llvm::SmallVector<Expr *, 4> ImplicitPrivate; 3473 llvm::SmallVector<Expr *, 4> ImplicitMap[DefaultmapKindNum][OMPC_MAP_delete]; 3474 llvm::SmallVector<OpenMPMapModifierKind, NumberOfOMPMapClauseModifiers> 3475 ImplicitMapModifier[DefaultmapKindNum]; 3476 Sema::VarsWithInheritedDSAType VarsWithInheritedDSA; 3477 llvm::SmallDenseSet<const ValueDecl *, 4> ImplicitDeclarations; 3478 3479 void VisitSubCaptures(OMPExecutableDirective *S) { 3480 // Check implicitly captured variables. 3481 if (!S->hasAssociatedStmt() || !S->getAssociatedStmt()) 3482 return; 3483 if (S->getDirectiveKind() == OMPD_atomic || 3484 S->getDirectiveKind() == OMPD_critical || 3485 S->getDirectiveKind() == OMPD_section || 3486 S->getDirectiveKind() == OMPD_master || 3487 S->getDirectiveKind() == OMPD_masked || 3488 isOpenMPLoopTransformationDirective(S->getDirectiveKind())) { 3489 Visit(S->getAssociatedStmt()); 3490 return; 3491 } 3492 visitSubCaptures(S->getInnermostCapturedStmt()); 3493 // Try to capture inner this->member references to generate correct mappings 3494 // and diagnostics. 3495 if (TryCaptureCXXThisMembers || 3496 (isOpenMPTargetExecutionDirective(Stack->getCurrentDirective()) && 3497 llvm::any_of(S->getInnermostCapturedStmt()->captures(), 3498 [](const CapturedStmt::Capture &C) { 3499 return C.capturesThis(); 3500 }))) { 3501 bool SavedTryCaptureCXXThisMembers = TryCaptureCXXThisMembers; 3502 TryCaptureCXXThisMembers = true; 3503 Visit(S->getInnermostCapturedStmt()->getCapturedStmt()); 3504 TryCaptureCXXThisMembers = SavedTryCaptureCXXThisMembers; 3505 } 3506 // In tasks firstprivates are not captured anymore, need to analyze them 3507 // explicitly. 3508 if (isOpenMPTaskingDirective(S->getDirectiveKind()) && 3509 !isOpenMPTaskLoopDirective(S->getDirectiveKind())) { 3510 for (OMPClause *C : S->clauses()) 3511 if (auto *FC = dyn_cast<OMPFirstprivateClause>(C)) { 3512 for (Expr *Ref : FC->varlists()) 3513 Visit(Ref); 3514 } 3515 } 3516 } 3517 3518 public: 3519 void VisitDeclRefExpr(DeclRefExpr *E) { 3520 if (TryCaptureCXXThisMembers || E->isTypeDependent() || 3521 E->isValueDependent() || E->containsUnexpandedParameterPack() || 3522 E->isInstantiationDependent()) 3523 return; 3524 if (auto *VD = dyn_cast<VarDecl>(E->getDecl())) { 3525 // Check the datasharing rules for the expressions in the clauses. 3526 if (!CS || (isa<OMPCapturedExprDecl>(VD) && !CS->capturesVariable(VD) && 3527 !Stack->getTopDSA(VD, /*FromParent=*/false).RefExpr)) { 3528 if (auto *CED = dyn_cast<OMPCapturedExprDecl>(VD)) 3529 if (!CED->hasAttr<OMPCaptureNoInitAttr>()) { 3530 Visit(CED->getInit()); 3531 return; 3532 } 3533 } else if (VD->isImplicit() || isa<OMPCapturedExprDecl>(VD)) 3534 // Do not analyze internal variables and do not enclose them into 3535 // implicit clauses. 3536 return; 3537 VD = VD->getCanonicalDecl(); 3538 // Skip internally declared variables. 3539 if (VD->hasLocalStorage() && CS && !CS->capturesVariable(VD) && 3540 !Stack->isImplicitTaskFirstprivate(VD)) 3541 return; 3542 // Skip allocators in uses_allocators clauses. 3543 if (Stack->isUsesAllocatorsDecl(VD)) 3544 return; 3545 3546 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(VD, /*FromParent=*/false); 3547 // Check if the variable has explicit DSA set and stop analysis if it so. 3548 if (DVar.RefExpr || !ImplicitDeclarations.insert(VD).second) 3549 return; 3550 3551 // Skip internally declared static variables. 3552 llvm::Optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res = 3553 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD); 3554 if (VD->hasGlobalStorage() && CS && !CS->capturesVariable(VD) && 3555 (Stack->hasRequiresDeclWithClause<OMPUnifiedSharedMemoryClause>() || 3556 !Res || *Res != OMPDeclareTargetDeclAttr::MT_Link) && 3557 !Stack->isImplicitTaskFirstprivate(VD)) 3558 return; 3559 3560 SourceLocation ELoc = E->getExprLoc(); 3561 OpenMPDirectiveKind DKind = Stack->getCurrentDirective(); 3562 // The default(none) clause requires that each variable that is referenced 3563 // in the construct, and does not have a predetermined data-sharing 3564 // attribute, must have its data-sharing attribute explicitly determined 3565 // by being listed in a data-sharing attribute clause. 3566 if (DVar.CKind == OMPC_unknown && 3567 (Stack->getDefaultDSA() == DSA_none || 3568 Stack->getDefaultDSA() == DSA_private || 3569 Stack->getDefaultDSA() == DSA_firstprivate) && 3570 isImplicitOrExplicitTaskingRegion(DKind) && 3571 VarsWithInheritedDSA.count(VD) == 0) { 3572 bool InheritedDSA = Stack->getDefaultDSA() == DSA_none; 3573 if (!InheritedDSA && (Stack->getDefaultDSA() == DSA_firstprivate || 3574 Stack->getDefaultDSA() == DSA_private)) { 3575 DSAStackTy::DSAVarData DVar = 3576 Stack->getImplicitDSA(VD, /*FromParent=*/false); 3577 InheritedDSA = DVar.CKind == OMPC_unknown; 3578 } 3579 if (InheritedDSA) 3580 VarsWithInheritedDSA[VD] = E; 3581 if (Stack->getDefaultDSA() == DSA_none) 3582 return; 3583 } 3584 3585 // OpenMP 5.0 [2.19.7.2, defaultmap clause, Description] 3586 // If implicit-behavior is none, each variable referenced in the 3587 // construct that does not have a predetermined data-sharing attribute 3588 // and does not appear in a to or link clause on a declare target 3589 // directive must be listed in a data-mapping attribute clause, a 3590 // data-sharing attribute clause (including a data-sharing attribute 3591 // clause on a combined construct where target. is one of the 3592 // constituent constructs), or an is_device_ptr clause. 3593 OpenMPDefaultmapClauseKind ClauseKind = 3594 getVariableCategoryFromDecl(SemaRef.getLangOpts(), VD); 3595 if (SemaRef.getLangOpts().OpenMP >= 50) { 3596 bool IsModifierNone = Stack->getDefaultmapModifier(ClauseKind) == 3597 OMPC_DEFAULTMAP_MODIFIER_none; 3598 if (DVar.CKind == OMPC_unknown && IsModifierNone && 3599 VarsWithInheritedDSA.count(VD) == 0 && !Res) { 3600 // Only check for data-mapping attribute and is_device_ptr here 3601 // since we have already make sure that the declaration does not 3602 // have a data-sharing attribute above 3603 if (!Stack->checkMappableExprComponentListsForDecl( 3604 VD, /*CurrentRegionOnly=*/true, 3605 [VD](OMPClauseMappableExprCommon::MappableExprComponentListRef 3606 MapExprComponents, 3607 OpenMPClauseKind) { 3608 auto MI = MapExprComponents.rbegin(); 3609 auto ME = MapExprComponents.rend(); 3610 return MI != ME && MI->getAssociatedDeclaration() == VD; 3611 })) { 3612 VarsWithInheritedDSA[VD] = E; 3613 return; 3614 } 3615 } 3616 } 3617 if (SemaRef.getLangOpts().OpenMP > 50) { 3618 bool IsModifierPresent = Stack->getDefaultmapModifier(ClauseKind) == 3619 OMPC_DEFAULTMAP_MODIFIER_present; 3620 if (IsModifierPresent) { 3621 if (llvm::find(ImplicitMapModifier[ClauseKind], 3622 OMPC_MAP_MODIFIER_present) == 3623 std::end(ImplicitMapModifier[ClauseKind])) { 3624 ImplicitMapModifier[ClauseKind].push_back( 3625 OMPC_MAP_MODIFIER_present); 3626 } 3627 } 3628 } 3629 3630 if (isOpenMPTargetExecutionDirective(DKind) && 3631 !Stack->isLoopControlVariable(VD).first) { 3632 if (!Stack->checkMappableExprComponentListsForDecl( 3633 VD, /*CurrentRegionOnly=*/true, 3634 [this](OMPClauseMappableExprCommon::MappableExprComponentListRef 3635 StackComponents, 3636 OpenMPClauseKind) { 3637 if (SemaRef.LangOpts.OpenMP >= 50) 3638 return !StackComponents.empty(); 3639 // Variable is used if it has been marked as an array, array 3640 // section, array shaping or the variable iself. 3641 return StackComponents.size() == 1 || 3642 std::all_of( 3643 std::next(StackComponents.rbegin()), 3644 StackComponents.rend(), 3645 [](const OMPClauseMappableExprCommon:: 3646 MappableComponent &MC) { 3647 return MC.getAssociatedDeclaration() == 3648 nullptr && 3649 (isa<OMPArraySectionExpr>( 3650 MC.getAssociatedExpression()) || 3651 isa<OMPArrayShapingExpr>( 3652 MC.getAssociatedExpression()) || 3653 isa<ArraySubscriptExpr>( 3654 MC.getAssociatedExpression())); 3655 }); 3656 })) { 3657 bool IsFirstprivate = false; 3658 // By default lambdas are captured as firstprivates. 3659 if (const auto *RD = 3660 VD->getType().getNonReferenceType()->getAsCXXRecordDecl()) 3661 IsFirstprivate = RD->isLambda(); 3662 IsFirstprivate = 3663 IsFirstprivate || (Stack->mustBeFirstprivate(ClauseKind) && !Res); 3664 if (IsFirstprivate) { 3665 ImplicitFirstprivate.emplace_back(E); 3666 } else { 3667 OpenMPDefaultmapClauseModifier M = 3668 Stack->getDefaultmapModifier(ClauseKind); 3669 OpenMPMapClauseKind Kind = getMapClauseKindFromModifier( 3670 M, ClauseKind == OMPC_DEFAULTMAP_aggregate || Res); 3671 ImplicitMap[ClauseKind][Kind].emplace_back(E); 3672 } 3673 return; 3674 } 3675 } 3676 3677 // OpenMP [2.9.3.6, Restrictions, p.2] 3678 // A list item that appears in a reduction clause of the innermost 3679 // enclosing worksharing or parallel construct may not be accessed in an 3680 // explicit task. 3681 DVar = Stack->hasInnermostDSA( 3682 VD, 3683 [](OpenMPClauseKind C, bool AppliedToPointee) { 3684 return C == OMPC_reduction && !AppliedToPointee; 3685 }, 3686 [](OpenMPDirectiveKind K) { 3687 return isOpenMPParallelDirective(K) || 3688 isOpenMPWorksharingDirective(K) || isOpenMPTeamsDirective(K); 3689 }, 3690 /*FromParent=*/true); 3691 if (isOpenMPTaskingDirective(DKind) && DVar.CKind == OMPC_reduction) { 3692 ErrorFound = true; 3693 SemaRef.Diag(ELoc, diag::err_omp_reduction_in_task); 3694 reportOriginalDsa(SemaRef, Stack, VD, DVar); 3695 return; 3696 } 3697 3698 // Define implicit data-sharing attributes for task. 3699 DVar = Stack->getImplicitDSA(VD, /*FromParent=*/false); 3700 if (((isOpenMPTaskingDirective(DKind) && DVar.CKind != OMPC_shared) || 3701 (((Stack->getDefaultDSA() == DSA_firstprivate && 3702 DVar.CKind == OMPC_firstprivate) || 3703 (Stack->getDefaultDSA() == DSA_private && 3704 DVar.CKind == OMPC_private)) && 3705 !DVar.RefExpr)) && 3706 !Stack->isLoopControlVariable(VD).first) { 3707 if (Stack->getDefaultDSA() == DSA_private) 3708 ImplicitPrivate.push_back(E); 3709 else 3710 ImplicitFirstprivate.push_back(E); 3711 return; 3712 } 3713 3714 // Store implicitly used globals with declare target link for parent 3715 // target. 3716 if (!isOpenMPTargetExecutionDirective(DKind) && Res && 3717 *Res == OMPDeclareTargetDeclAttr::MT_Link) { 3718 Stack->addToParentTargetRegionLinkGlobals(E); 3719 return; 3720 } 3721 } 3722 } 3723 void VisitMemberExpr(MemberExpr *E) { 3724 if (E->isTypeDependent() || E->isValueDependent() || 3725 E->containsUnexpandedParameterPack() || E->isInstantiationDependent()) 3726 return; 3727 auto *FD = dyn_cast<FieldDecl>(E->getMemberDecl()); 3728 OpenMPDirectiveKind DKind = Stack->getCurrentDirective(); 3729 if (auto *TE = dyn_cast<CXXThisExpr>(E->getBase()->IgnoreParenCasts())) { 3730 if (!FD) 3731 return; 3732 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(FD, /*FromParent=*/false); 3733 // Check if the variable has explicit DSA set and stop analysis if it 3734 // so. 3735 if (DVar.RefExpr || !ImplicitDeclarations.insert(FD).second) 3736 return; 3737 3738 if (isOpenMPTargetExecutionDirective(DKind) && 3739 !Stack->isLoopControlVariable(FD).first && 3740 !Stack->checkMappableExprComponentListsForDecl( 3741 FD, /*CurrentRegionOnly=*/true, 3742 [](OMPClauseMappableExprCommon::MappableExprComponentListRef 3743 StackComponents, 3744 OpenMPClauseKind) { 3745 return isa<CXXThisExpr>( 3746 cast<MemberExpr>( 3747 StackComponents.back().getAssociatedExpression()) 3748 ->getBase() 3749 ->IgnoreParens()); 3750 })) { 3751 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.3] 3752 // A bit-field cannot appear in a map clause. 3753 // 3754 if (FD->isBitField()) 3755 return; 3756 3757 // Check to see if the member expression is referencing a class that 3758 // has already been explicitly mapped 3759 if (Stack->isClassPreviouslyMapped(TE->getType())) 3760 return; 3761 3762 OpenMPDefaultmapClauseModifier Modifier = 3763 Stack->getDefaultmapModifier(OMPC_DEFAULTMAP_aggregate); 3764 OpenMPDefaultmapClauseKind ClauseKind = 3765 getVariableCategoryFromDecl(SemaRef.getLangOpts(), FD); 3766 OpenMPMapClauseKind Kind = getMapClauseKindFromModifier( 3767 Modifier, /*IsAggregateOrDeclareTarget*/ true); 3768 ImplicitMap[ClauseKind][Kind].emplace_back(E); 3769 return; 3770 } 3771 3772 SourceLocation ELoc = E->getExprLoc(); 3773 // OpenMP [2.9.3.6, Restrictions, p.2] 3774 // A list item that appears in a reduction clause of the innermost 3775 // enclosing worksharing or parallel construct may not be accessed in 3776 // an explicit task. 3777 DVar = Stack->hasInnermostDSA( 3778 FD, 3779 [](OpenMPClauseKind C, bool AppliedToPointee) { 3780 return C == OMPC_reduction && !AppliedToPointee; 3781 }, 3782 [](OpenMPDirectiveKind K) { 3783 return isOpenMPParallelDirective(K) || 3784 isOpenMPWorksharingDirective(K) || isOpenMPTeamsDirective(K); 3785 }, 3786 /*FromParent=*/true); 3787 if (isOpenMPTaskingDirective(DKind) && DVar.CKind == OMPC_reduction) { 3788 ErrorFound = true; 3789 SemaRef.Diag(ELoc, diag::err_omp_reduction_in_task); 3790 reportOriginalDsa(SemaRef, Stack, FD, DVar); 3791 return; 3792 } 3793 3794 // Define implicit data-sharing attributes for task. 3795 DVar = Stack->getImplicitDSA(FD, /*FromParent=*/false); 3796 if (isOpenMPTaskingDirective(DKind) && DVar.CKind != OMPC_shared && 3797 !Stack->isLoopControlVariable(FD).first) { 3798 // Check if there is a captured expression for the current field in the 3799 // region. Do not mark it as firstprivate unless there is no captured 3800 // expression. 3801 // TODO: try to make it firstprivate. 3802 if (DVar.CKind != OMPC_unknown) 3803 ImplicitFirstprivate.push_back(E); 3804 } 3805 return; 3806 } 3807 if (isOpenMPTargetExecutionDirective(DKind)) { 3808 OMPClauseMappableExprCommon::MappableExprComponentList CurComponents; 3809 if (!checkMapClauseExpressionBase(SemaRef, E, CurComponents, OMPC_map, 3810 Stack->getCurrentDirective(), 3811 /*NoDiagnose=*/true)) 3812 return; 3813 const auto *VD = cast<ValueDecl>( 3814 CurComponents.back().getAssociatedDeclaration()->getCanonicalDecl()); 3815 if (!Stack->checkMappableExprComponentListsForDecl( 3816 VD, /*CurrentRegionOnly=*/true, 3817 [&CurComponents]( 3818 OMPClauseMappableExprCommon::MappableExprComponentListRef 3819 StackComponents, 3820 OpenMPClauseKind) { 3821 auto CCI = CurComponents.rbegin(); 3822 auto CCE = CurComponents.rend(); 3823 for (const auto &SC : llvm::reverse(StackComponents)) { 3824 // Do both expressions have the same kind? 3825 if (CCI->getAssociatedExpression()->getStmtClass() != 3826 SC.getAssociatedExpression()->getStmtClass()) 3827 if (!((isa<OMPArraySectionExpr>( 3828 SC.getAssociatedExpression()) || 3829 isa<OMPArrayShapingExpr>( 3830 SC.getAssociatedExpression())) && 3831 isa<ArraySubscriptExpr>( 3832 CCI->getAssociatedExpression()))) 3833 return false; 3834 3835 const Decl *CCD = CCI->getAssociatedDeclaration(); 3836 const Decl *SCD = SC.getAssociatedDeclaration(); 3837 CCD = CCD ? CCD->getCanonicalDecl() : nullptr; 3838 SCD = SCD ? SCD->getCanonicalDecl() : nullptr; 3839 if (SCD != CCD) 3840 return false; 3841 std::advance(CCI, 1); 3842 if (CCI == CCE) 3843 break; 3844 } 3845 return true; 3846 })) { 3847 Visit(E->getBase()); 3848 } 3849 } else if (!TryCaptureCXXThisMembers) { 3850 Visit(E->getBase()); 3851 } 3852 } 3853 void VisitOMPExecutableDirective(OMPExecutableDirective *S) { 3854 for (OMPClause *C : S->clauses()) { 3855 // Skip analysis of arguments of private clauses for task|target 3856 // directives. 3857 if (isa_and_nonnull<OMPPrivateClause>(C)) 3858 continue; 3859 // Skip analysis of arguments of implicitly defined firstprivate clause 3860 // for task|target directives. 3861 // Skip analysis of arguments of implicitly defined map clause for target 3862 // directives. 3863 if (C && !((isa<OMPFirstprivateClause>(C) || isa<OMPMapClause>(C)) && 3864 C->isImplicit() && 3865 !isOpenMPTaskingDirective(Stack->getCurrentDirective()))) { 3866 for (Stmt *CC : C->children()) { 3867 if (CC) 3868 Visit(CC); 3869 } 3870 } 3871 } 3872 // Check implicitly captured variables. 3873 VisitSubCaptures(S); 3874 } 3875 3876 void VisitOMPLoopTransformationDirective(OMPLoopTransformationDirective *S) { 3877 // Loop transformation directives do not introduce data sharing 3878 VisitStmt(S); 3879 } 3880 3881 void VisitCallExpr(CallExpr *S) { 3882 for (Stmt *C : S->arguments()) { 3883 if (C) { 3884 // Check implicitly captured variables in the task-based directives to 3885 // check if they must be firstprivatized. 3886 Visit(C); 3887 } 3888 } 3889 if (Expr *Callee = S->getCallee()) 3890 if (auto *CE = dyn_cast<MemberExpr>(Callee->IgnoreParenImpCasts())) 3891 Visit(CE->getBase()); 3892 } 3893 void VisitStmt(Stmt *S) { 3894 for (Stmt *C : S->children()) { 3895 if (C) { 3896 // Check implicitly captured variables in the task-based directives to 3897 // check if they must be firstprivatized. 3898 Visit(C); 3899 } 3900 } 3901 } 3902 3903 void visitSubCaptures(CapturedStmt *S) { 3904 for (const CapturedStmt::Capture &Cap : S->captures()) { 3905 if (!Cap.capturesVariable() && !Cap.capturesVariableByCopy()) 3906 continue; 3907 VarDecl *VD = Cap.getCapturedVar(); 3908 // Do not try to map the variable if it or its sub-component was mapped 3909 // already. 3910 if (isOpenMPTargetExecutionDirective(Stack->getCurrentDirective()) && 3911 Stack->checkMappableExprComponentListsForDecl( 3912 VD, /*CurrentRegionOnly=*/true, 3913 [](OMPClauseMappableExprCommon::MappableExprComponentListRef, 3914 OpenMPClauseKind) { return true; })) 3915 continue; 3916 DeclRefExpr *DRE = buildDeclRefExpr( 3917 SemaRef, VD, VD->getType().getNonLValueExprType(SemaRef.Context), 3918 Cap.getLocation(), /*RefersToCapture=*/true); 3919 Visit(DRE); 3920 } 3921 } 3922 bool isErrorFound() const { return ErrorFound; } 3923 ArrayRef<Expr *> getImplicitFirstprivate() const { 3924 return ImplicitFirstprivate; 3925 } 3926 ArrayRef<Expr *> getImplicitPrivate() const { return ImplicitPrivate; } 3927 ArrayRef<Expr *> getImplicitMap(OpenMPDefaultmapClauseKind DK, 3928 OpenMPMapClauseKind MK) const { 3929 return ImplicitMap[DK][MK]; 3930 } 3931 ArrayRef<OpenMPMapModifierKind> 3932 getImplicitMapModifier(OpenMPDefaultmapClauseKind Kind) const { 3933 return ImplicitMapModifier[Kind]; 3934 } 3935 const Sema::VarsWithInheritedDSAType &getVarsWithInheritedDSA() const { 3936 return VarsWithInheritedDSA; 3937 } 3938 3939 DSAAttrChecker(DSAStackTy *S, Sema &SemaRef, CapturedStmt *CS) 3940 : Stack(S), SemaRef(SemaRef), ErrorFound(false), CS(CS) { 3941 // Process declare target link variables for the target directives. 3942 if (isOpenMPTargetExecutionDirective(S->getCurrentDirective())) { 3943 for (DeclRefExpr *E : Stack->getLinkGlobals()) 3944 Visit(E); 3945 } 3946 } 3947 }; 3948 } // namespace 3949 3950 static void handleDeclareVariantConstructTrait(DSAStackTy *Stack, 3951 OpenMPDirectiveKind DKind, 3952 bool ScopeEntry) { 3953 SmallVector<llvm::omp::TraitProperty, 8> Traits; 3954 if (isOpenMPTargetExecutionDirective(DKind)) 3955 Traits.emplace_back(llvm::omp::TraitProperty::construct_target_target); 3956 if (isOpenMPTeamsDirective(DKind)) 3957 Traits.emplace_back(llvm::omp::TraitProperty::construct_teams_teams); 3958 if (isOpenMPParallelDirective(DKind)) 3959 Traits.emplace_back(llvm::omp::TraitProperty::construct_parallel_parallel); 3960 if (isOpenMPWorksharingDirective(DKind)) 3961 Traits.emplace_back(llvm::omp::TraitProperty::construct_for_for); 3962 if (isOpenMPSimdDirective(DKind)) 3963 Traits.emplace_back(llvm::omp::TraitProperty::construct_simd_simd); 3964 Stack->handleConstructTrait(Traits, ScopeEntry); 3965 } 3966 3967 void Sema::ActOnOpenMPRegionStart(OpenMPDirectiveKind DKind, Scope *CurScope) { 3968 switch (DKind) { 3969 case OMPD_parallel: 3970 case OMPD_parallel_for: 3971 case OMPD_parallel_for_simd: 3972 case OMPD_parallel_sections: 3973 case OMPD_parallel_master: 3974 case OMPD_parallel_masked: 3975 case OMPD_parallel_loop: 3976 case OMPD_teams: 3977 case OMPD_teams_distribute: 3978 case OMPD_teams_distribute_simd: { 3979 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 3980 QualType KmpInt32PtrTy = 3981 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3982 Sema::CapturedParamNameType Params[] = { 3983 std::make_pair(".global_tid.", KmpInt32PtrTy), 3984 std::make_pair(".bound_tid.", KmpInt32PtrTy), 3985 std::make_pair(StringRef(), QualType()) // __context with shared vars 3986 }; 3987 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3988 Params); 3989 break; 3990 } 3991 case OMPD_target_teams: 3992 case OMPD_target_parallel: 3993 case OMPD_target_parallel_for: 3994 case OMPD_target_parallel_for_simd: 3995 case OMPD_target_teams_loop: 3996 case OMPD_target_parallel_loop: 3997 case OMPD_target_teams_distribute: 3998 case OMPD_target_teams_distribute_simd: { 3999 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 4000 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 4001 QualType KmpInt32PtrTy = 4002 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 4003 QualType Args[] = {VoidPtrTy}; 4004 FunctionProtoType::ExtProtoInfo EPI; 4005 EPI.Variadic = true; 4006 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 4007 Sema::CapturedParamNameType Params[] = { 4008 std::make_pair(".global_tid.", KmpInt32Ty), 4009 std::make_pair(".part_id.", KmpInt32PtrTy), 4010 std::make_pair(".privates.", VoidPtrTy), 4011 std::make_pair( 4012 ".copy_fn.", 4013 Context.getPointerType(CopyFnType).withConst().withRestrict()), 4014 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 4015 std::make_pair(StringRef(), QualType()) // __context with shared vars 4016 }; 4017 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 4018 Params, /*OpenMPCaptureLevel=*/0); 4019 // Mark this captured region as inlined, because we don't use outlined 4020 // function directly. 4021 getCurCapturedRegion()->TheCapturedDecl->addAttr( 4022 AlwaysInlineAttr::CreateImplicit( 4023 Context, {}, AttributeCommonInfo::AS_Keyword, 4024 AlwaysInlineAttr::Keyword_forceinline)); 4025 Sema::CapturedParamNameType ParamsTarget[] = { 4026 std::make_pair(StringRef(), QualType()) // __context with shared vars 4027 }; 4028 // Start a captured region for 'target' with no implicit parameters. 4029 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 4030 ParamsTarget, /*OpenMPCaptureLevel=*/1); 4031 Sema::CapturedParamNameType ParamsTeamsOrParallel[] = { 4032 std::make_pair(".global_tid.", KmpInt32PtrTy), 4033 std::make_pair(".bound_tid.", KmpInt32PtrTy), 4034 std::make_pair(StringRef(), QualType()) // __context with shared vars 4035 }; 4036 // Start a captured region for 'teams' or 'parallel'. Both regions have 4037 // the same implicit parameters. 4038 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 4039 ParamsTeamsOrParallel, /*OpenMPCaptureLevel=*/2); 4040 break; 4041 } 4042 case OMPD_target: 4043 case OMPD_target_simd: { 4044 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 4045 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 4046 QualType KmpInt32PtrTy = 4047 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 4048 QualType Args[] = {VoidPtrTy}; 4049 FunctionProtoType::ExtProtoInfo EPI; 4050 EPI.Variadic = true; 4051 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 4052 Sema::CapturedParamNameType Params[] = { 4053 std::make_pair(".global_tid.", KmpInt32Ty), 4054 std::make_pair(".part_id.", KmpInt32PtrTy), 4055 std::make_pair(".privates.", VoidPtrTy), 4056 std::make_pair( 4057 ".copy_fn.", 4058 Context.getPointerType(CopyFnType).withConst().withRestrict()), 4059 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 4060 std::make_pair(StringRef(), QualType()) // __context with shared vars 4061 }; 4062 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 4063 Params, /*OpenMPCaptureLevel=*/0); 4064 // Mark this captured region as inlined, because we don't use outlined 4065 // function directly. 4066 getCurCapturedRegion()->TheCapturedDecl->addAttr( 4067 AlwaysInlineAttr::CreateImplicit( 4068 Context, {}, AttributeCommonInfo::AS_Keyword, 4069 AlwaysInlineAttr::Keyword_forceinline)); 4070 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 4071 std::make_pair(StringRef(), QualType()), 4072 /*OpenMPCaptureLevel=*/1); 4073 break; 4074 } 4075 case OMPD_atomic: 4076 case OMPD_critical: 4077 case OMPD_section: 4078 case OMPD_master: 4079 case OMPD_masked: 4080 case OMPD_tile: 4081 case OMPD_unroll: 4082 break; 4083 case OMPD_loop: 4084 // TODO: 'loop' may require additional parameters depending on the binding. 4085 // Treat similar to OMPD_simd/OMPD_for for now. 4086 case OMPD_simd: 4087 case OMPD_for: 4088 case OMPD_for_simd: 4089 case OMPD_sections: 4090 case OMPD_single: 4091 case OMPD_taskgroup: 4092 case OMPD_distribute: 4093 case OMPD_distribute_simd: 4094 case OMPD_ordered: 4095 case OMPD_target_data: 4096 case OMPD_dispatch: { 4097 Sema::CapturedParamNameType Params[] = { 4098 std::make_pair(StringRef(), QualType()) // __context with shared vars 4099 }; 4100 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 4101 Params); 4102 break; 4103 } 4104 case OMPD_task: { 4105 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 4106 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 4107 QualType KmpInt32PtrTy = 4108 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 4109 QualType Args[] = {VoidPtrTy}; 4110 FunctionProtoType::ExtProtoInfo EPI; 4111 EPI.Variadic = true; 4112 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 4113 Sema::CapturedParamNameType Params[] = { 4114 std::make_pair(".global_tid.", KmpInt32Ty), 4115 std::make_pair(".part_id.", KmpInt32PtrTy), 4116 std::make_pair(".privates.", VoidPtrTy), 4117 std::make_pair( 4118 ".copy_fn.", 4119 Context.getPointerType(CopyFnType).withConst().withRestrict()), 4120 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 4121 std::make_pair(StringRef(), QualType()) // __context with shared vars 4122 }; 4123 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 4124 Params); 4125 // Mark this captured region as inlined, because we don't use outlined 4126 // function directly. 4127 getCurCapturedRegion()->TheCapturedDecl->addAttr( 4128 AlwaysInlineAttr::CreateImplicit( 4129 Context, {}, AttributeCommonInfo::AS_Keyword, 4130 AlwaysInlineAttr::Keyword_forceinline)); 4131 break; 4132 } 4133 case OMPD_taskloop: 4134 case OMPD_taskloop_simd: 4135 case OMPD_master_taskloop: 4136 case OMPD_master_taskloop_simd: { 4137 QualType KmpInt32Ty = 4138 Context.getIntTypeForBitwidth(/*DestWidth=*/32, /*Signed=*/1) 4139 .withConst(); 4140 QualType KmpUInt64Ty = 4141 Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/0) 4142 .withConst(); 4143 QualType KmpInt64Ty = 4144 Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/1) 4145 .withConst(); 4146 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 4147 QualType KmpInt32PtrTy = 4148 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 4149 QualType Args[] = {VoidPtrTy}; 4150 FunctionProtoType::ExtProtoInfo EPI; 4151 EPI.Variadic = true; 4152 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 4153 Sema::CapturedParamNameType Params[] = { 4154 std::make_pair(".global_tid.", KmpInt32Ty), 4155 std::make_pair(".part_id.", KmpInt32PtrTy), 4156 std::make_pair(".privates.", VoidPtrTy), 4157 std::make_pair( 4158 ".copy_fn.", 4159 Context.getPointerType(CopyFnType).withConst().withRestrict()), 4160 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 4161 std::make_pair(".lb.", KmpUInt64Ty), 4162 std::make_pair(".ub.", KmpUInt64Ty), 4163 std::make_pair(".st.", KmpInt64Ty), 4164 std::make_pair(".liter.", KmpInt32Ty), 4165 std::make_pair(".reductions.", VoidPtrTy), 4166 std::make_pair(StringRef(), QualType()) // __context with shared vars 4167 }; 4168 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 4169 Params); 4170 // Mark this captured region as inlined, because we don't use outlined 4171 // function directly. 4172 getCurCapturedRegion()->TheCapturedDecl->addAttr( 4173 AlwaysInlineAttr::CreateImplicit( 4174 Context, {}, AttributeCommonInfo::AS_Keyword, 4175 AlwaysInlineAttr::Keyword_forceinline)); 4176 break; 4177 } 4178 case OMPD_parallel_master_taskloop: 4179 case OMPD_parallel_master_taskloop_simd: { 4180 QualType KmpInt32Ty = 4181 Context.getIntTypeForBitwidth(/*DestWidth=*/32, /*Signed=*/1) 4182 .withConst(); 4183 QualType KmpUInt64Ty = 4184 Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/0) 4185 .withConst(); 4186 QualType KmpInt64Ty = 4187 Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/1) 4188 .withConst(); 4189 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 4190 QualType KmpInt32PtrTy = 4191 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 4192 Sema::CapturedParamNameType ParamsParallel[] = { 4193 std::make_pair(".global_tid.", KmpInt32PtrTy), 4194 std::make_pair(".bound_tid.", KmpInt32PtrTy), 4195 std::make_pair(StringRef(), QualType()) // __context with shared vars 4196 }; 4197 // Start a captured region for 'parallel'. 4198 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 4199 ParamsParallel, /*OpenMPCaptureLevel=*/0); 4200 QualType Args[] = {VoidPtrTy}; 4201 FunctionProtoType::ExtProtoInfo EPI; 4202 EPI.Variadic = true; 4203 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 4204 Sema::CapturedParamNameType Params[] = { 4205 std::make_pair(".global_tid.", KmpInt32Ty), 4206 std::make_pair(".part_id.", KmpInt32PtrTy), 4207 std::make_pair(".privates.", VoidPtrTy), 4208 std::make_pair( 4209 ".copy_fn.", 4210 Context.getPointerType(CopyFnType).withConst().withRestrict()), 4211 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 4212 std::make_pair(".lb.", KmpUInt64Ty), 4213 std::make_pair(".ub.", KmpUInt64Ty), 4214 std::make_pair(".st.", KmpInt64Ty), 4215 std::make_pair(".liter.", KmpInt32Ty), 4216 std::make_pair(".reductions.", VoidPtrTy), 4217 std::make_pair(StringRef(), QualType()) // __context with shared vars 4218 }; 4219 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 4220 Params, /*OpenMPCaptureLevel=*/1); 4221 // Mark this captured region as inlined, because we don't use outlined 4222 // function directly. 4223 getCurCapturedRegion()->TheCapturedDecl->addAttr( 4224 AlwaysInlineAttr::CreateImplicit( 4225 Context, {}, AttributeCommonInfo::AS_Keyword, 4226 AlwaysInlineAttr::Keyword_forceinline)); 4227 break; 4228 } 4229 case OMPD_distribute_parallel_for_simd: 4230 case OMPD_distribute_parallel_for: { 4231 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 4232 QualType KmpInt32PtrTy = 4233 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 4234 Sema::CapturedParamNameType Params[] = { 4235 std::make_pair(".global_tid.", KmpInt32PtrTy), 4236 std::make_pair(".bound_tid.", KmpInt32PtrTy), 4237 std::make_pair(".previous.lb.", Context.getSizeType().withConst()), 4238 std::make_pair(".previous.ub.", Context.getSizeType().withConst()), 4239 std::make_pair(StringRef(), QualType()) // __context with shared vars 4240 }; 4241 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 4242 Params); 4243 break; 4244 } 4245 case OMPD_target_teams_distribute_parallel_for: 4246 case OMPD_target_teams_distribute_parallel_for_simd: { 4247 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 4248 QualType KmpInt32PtrTy = 4249 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 4250 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 4251 4252 QualType Args[] = {VoidPtrTy}; 4253 FunctionProtoType::ExtProtoInfo EPI; 4254 EPI.Variadic = true; 4255 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 4256 Sema::CapturedParamNameType Params[] = { 4257 std::make_pair(".global_tid.", KmpInt32Ty), 4258 std::make_pair(".part_id.", KmpInt32PtrTy), 4259 std::make_pair(".privates.", VoidPtrTy), 4260 std::make_pair( 4261 ".copy_fn.", 4262 Context.getPointerType(CopyFnType).withConst().withRestrict()), 4263 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 4264 std::make_pair(StringRef(), QualType()) // __context with shared vars 4265 }; 4266 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 4267 Params, /*OpenMPCaptureLevel=*/0); 4268 // Mark this captured region as inlined, because we don't use outlined 4269 // function directly. 4270 getCurCapturedRegion()->TheCapturedDecl->addAttr( 4271 AlwaysInlineAttr::CreateImplicit( 4272 Context, {}, AttributeCommonInfo::AS_Keyword, 4273 AlwaysInlineAttr::Keyword_forceinline)); 4274 Sema::CapturedParamNameType ParamsTarget[] = { 4275 std::make_pair(StringRef(), QualType()) // __context with shared vars 4276 }; 4277 // Start a captured region for 'target' with no implicit parameters. 4278 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 4279 ParamsTarget, /*OpenMPCaptureLevel=*/1); 4280 4281 Sema::CapturedParamNameType ParamsTeams[] = { 4282 std::make_pair(".global_tid.", KmpInt32PtrTy), 4283 std::make_pair(".bound_tid.", KmpInt32PtrTy), 4284 std::make_pair(StringRef(), QualType()) // __context with shared vars 4285 }; 4286 // Start a captured region for 'target' with no implicit parameters. 4287 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 4288 ParamsTeams, /*OpenMPCaptureLevel=*/2); 4289 4290 Sema::CapturedParamNameType ParamsParallel[] = { 4291 std::make_pair(".global_tid.", KmpInt32PtrTy), 4292 std::make_pair(".bound_tid.", KmpInt32PtrTy), 4293 std::make_pair(".previous.lb.", Context.getSizeType().withConst()), 4294 std::make_pair(".previous.ub.", Context.getSizeType().withConst()), 4295 std::make_pair(StringRef(), QualType()) // __context with shared vars 4296 }; 4297 // Start a captured region for 'teams' or 'parallel'. Both regions have 4298 // the same implicit parameters. 4299 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 4300 ParamsParallel, /*OpenMPCaptureLevel=*/3); 4301 break; 4302 } 4303 4304 case OMPD_teams_loop: { 4305 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 4306 QualType KmpInt32PtrTy = 4307 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 4308 4309 Sema::CapturedParamNameType ParamsTeams[] = { 4310 std::make_pair(".global_tid.", KmpInt32PtrTy), 4311 std::make_pair(".bound_tid.", KmpInt32PtrTy), 4312 std::make_pair(StringRef(), QualType()) // __context with shared vars 4313 }; 4314 // Start a captured region for 'teams'. 4315 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 4316 ParamsTeams, /*OpenMPCaptureLevel=*/0); 4317 break; 4318 } 4319 4320 case OMPD_teams_distribute_parallel_for: 4321 case OMPD_teams_distribute_parallel_for_simd: { 4322 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 4323 QualType KmpInt32PtrTy = 4324 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 4325 4326 Sema::CapturedParamNameType ParamsTeams[] = { 4327 std::make_pair(".global_tid.", KmpInt32PtrTy), 4328 std::make_pair(".bound_tid.", KmpInt32PtrTy), 4329 std::make_pair(StringRef(), QualType()) // __context with shared vars 4330 }; 4331 // Start a captured region for 'target' with no implicit parameters. 4332 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 4333 ParamsTeams, /*OpenMPCaptureLevel=*/0); 4334 4335 Sema::CapturedParamNameType ParamsParallel[] = { 4336 std::make_pair(".global_tid.", KmpInt32PtrTy), 4337 std::make_pair(".bound_tid.", KmpInt32PtrTy), 4338 std::make_pair(".previous.lb.", Context.getSizeType().withConst()), 4339 std::make_pair(".previous.ub.", Context.getSizeType().withConst()), 4340 std::make_pair(StringRef(), QualType()) // __context with shared vars 4341 }; 4342 // Start a captured region for 'teams' or 'parallel'. Both regions have 4343 // the same implicit parameters. 4344 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 4345 ParamsParallel, /*OpenMPCaptureLevel=*/1); 4346 break; 4347 } 4348 case OMPD_target_update: 4349 case OMPD_target_enter_data: 4350 case OMPD_target_exit_data: { 4351 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 4352 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 4353 QualType KmpInt32PtrTy = 4354 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 4355 QualType Args[] = {VoidPtrTy}; 4356 FunctionProtoType::ExtProtoInfo EPI; 4357 EPI.Variadic = true; 4358 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 4359 Sema::CapturedParamNameType Params[] = { 4360 std::make_pair(".global_tid.", KmpInt32Ty), 4361 std::make_pair(".part_id.", KmpInt32PtrTy), 4362 std::make_pair(".privates.", VoidPtrTy), 4363 std::make_pair( 4364 ".copy_fn.", 4365 Context.getPointerType(CopyFnType).withConst().withRestrict()), 4366 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 4367 std::make_pair(StringRef(), QualType()) // __context with shared vars 4368 }; 4369 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 4370 Params); 4371 // Mark this captured region as inlined, because we don't use outlined 4372 // function directly. 4373 getCurCapturedRegion()->TheCapturedDecl->addAttr( 4374 AlwaysInlineAttr::CreateImplicit( 4375 Context, {}, AttributeCommonInfo::AS_Keyword, 4376 AlwaysInlineAttr::Keyword_forceinline)); 4377 break; 4378 } 4379 case OMPD_threadprivate: 4380 case OMPD_allocate: 4381 case OMPD_taskyield: 4382 case OMPD_barrier: 4383 case OMPD_taskwait: 4384 case OMPD_cancellation_point: 4385 case OMPD_cancel: 4386 case OMPD_flush: 4387 case OMPD_depobj: 4388 case OMPD_scan: 4389 case OMPD_declare_reduction: 4390 case OMPD_declare_mapper: 4391 case OMPD_declare_simd: 4392 case OMPD_declare_target: 4393 case OMPD_end_declare_target: 4394 case OMPD_requires: 4395 case OMPD_declare_variant: 4396 case OMPD_begin_declare_variant: 4397 case OMPD_end_declare_variant: 4398 case OMPD_metadirective: 4399 llvm_unreachable("OpenMP Directive is not allowed"); 4400 case OMPD_unknown: 4401 default: 4402 llvm_unreachable("Unknown OpenMP directive"); 4403 } 4404 DSAStack->setContext(CurContext); 4405 handleDeclareVariantConstructTrait(DSAStack, DKind, /* ScopeEntry */ true); 4406 } 4407 4408 int Sema::getNumberOfConstructScopes(unsigned Level) const { 4409 return getOpenMPCaptureLevels(DSAStack->getDirective(Level)); 4410 } 4411 4412 int Sema::getOpenMPCaptureLevels(OpenMPDirectiveKind DKind) { 4413 SmallVector<OpenMPDirectiveKind, 4> CaptureRegions; 4414 getOpenMPCaptureRegions(CaptureRegions, DKind); 4415 return CaptureRegions.size(); 4416 } 4417 4418 static OMPCapturedExprDecl *buildCaptureDecl(Sema &S, IdentifierInfo *Id, 4419 Expr *CaptureExpr, bool WithInit, 4420 bool AsExpression) { 4421 assert(CaptureExpr); 4422 ASTContext &C = S.getASTContext(); 4423 Expr *Init = AsExpression ? CaptureExpr : CaptureExpr->IgnoreImpCasts(); 4424 QualType Ty = Init->getType(); 4425 if (CaptureExpr->getObjectKind() == OK_Ordinary && CaptureExpr->isGLValue()) { 4426 if (S.getLangOpts().CPlusPlus) { 4427 Ty = C.getLValueReferenceType(Ty); 4428 } else { 4429 Ty = C.getPointerType(Ty); 4430 ExprResult Res = 4431 S.CreateBuiltinUnaryOp(CaptureExpr->getExprLoc(), UO_AddrOf, Init); 4432 if (!Res.isUsable()) 4433 return nullptr; 4434 Init = Res.get(); 4435 } 4436 WithInit = true; 4437 } 4438 auto *CED = OMPCapturedExprDecl::Create(C, S.CurContext, Id, Ty, 4439 CaptureExpr->getBeginLoc()); 4440 if (!WithInit) 4441 CED->addAttr(OMPCaptureNoInitAttr::CreateImplicit(C)); 4442 S.CurContext->addHiddenDecl(CED); 4443 Sema::TentativeAnalysisScope Trap(S); 4444 S.AddInitializerToDecl(CED, Init, /*DirectInit=*/false); 4445 return CED; 4446 } 4447 4448 static DeclRefExpr *buildCapture(Sema &S, ValueDecl *D, Expr *CaptureExpr, 4449 bool WithInit) { 4450 OMPCapturedExprDecl *CD; 4451 if (VarDecl *VD = S.isOpenMPCapturedDecl(D)) 4452 CD = cast<OMPCapturedExprDecl>(VD); 4453 else 4454 CD = buildCaptureDecl(S, D->getIdentifier(), CaptureExpr, WithInit, 4455 /*AsExpression=*/false); 4456 return buildDeclRefExpr(S, CD, CD->getType().getNonReferenceType(), 4457 CaptureExpr->getExprLoc()); 4458 } 4459 4460 static ExprResult buildCapture(Sema &S, Expr *CaptureExpr, DeclRefExpr *&Ref) { 4461 CaptureExpr = S.DefaultLvalueConversion(CaptureExpr).get(); 4462 if (!Ref) { 4463 OMPCapturedExprDecl *CD = buildCaptureDecl( 4464 S, &S.getASTContext().Idents.get(".capture_expr."), CaptureExpr, 4465 /*WithInit=*/true, /*AsExpression=*/true); 4466 Ref = buildDeclRefExpr(S, CD, CD->getType().getNonReferenceType(), 4467 CaptureExpr->getExprLoc()); 4468 } 4469 ExprResult Res = Ref; 4470 if (!S.getLangOpts().CPlusPlus && 4471 CaptureExpr->getObjectKind() == OK_Ordinary && CaptureExpr->isGLValue() && 4472 Ref->getType()->isPointerType()) { 4473 Res = S.CreateBuiltinUnaryOp(CaptureExpr->getExprLoc(), UO_Deref, Ref); 4474 if (!Res.isUsable()) 4475 return ExprError(); 4476 } 4477 return S.DefaultLvalueConversion(Res.get()); 4478 } 4479 4480 namespace { 4481 // OpenMP directives parsed in this section are represented as a 4482 // CapturedStatement with an associated statement. If a syntax error 4483 // is detected during the parsing of the associated statement, the 4484 // compiler must abort processing and close the CapturedStatement. 4485 // 4486 // Combined directives such as 'target parallel' have more than one 4487 // nested CapturedStatements. This RAII ensures that we unwind out 4488 // of all the nested CapturedStatements when an error is found. 4489 class CaptureRegionUnwinderRAII { 4490 private: 4491 Sema &S; 4492 bool &ErrorFound; 4493 OpenMPDirectiveKind DKind = OMPD_unknown; 4494 4495 public: 4496 CaptureRegionUnwinderRAII(Sema &S, bool &ErrorFound, 4497 OpenMPDirectiveKind DKind) 4498 : S(S), ErrorFound(ErrorFound), DKind(DKind) {} 4499 ~CaptureRegionUnwinderRAII() { 4500 if (ErrorFound) { 4501 int ThisCaptureLevel = S.getOpenMPCaptureLevels(DKind); 4502 while (--ThisCaptureLevel >= 0) 4503 S.ActOnCapturedRegionError(); 4504 } 4505 } 4506 }; 4507 } // namespace 4508 4509 void Sema::tryCaptureOpenMPLambdas(ValueDecl *V) { 4510 // Capture variables captured by reference in lambdas for target-based 4511 // directives. 4512 if (!CurContext->isDependentContext() && 4513 (isOpenMPTargetExecutionDirective(DSAStack->getCurrentDirective()) || 4514 isOpenMPTargetDataManagementDirective( 4515 DSAStack->getCurrentDirective()))) { 4516 QualType Type = V->getType(); 4517 if (const auto *RD = Type.getCanonicalType() 4518 .getNonReferenceType() 4519 ->getAsCXXRecordDecl()) { 4520 bool SavedForceCaptureByReferenceInTargetExecutable = 4521 DSAStack->isForceCaptureByReferenceInTargetExecutable(); 4522 DSAStack->setForceCaptureByReferenceInTargetExecutable( 4523 /*V=*/true); 4524 if (RD->isLambda()) { 4525 llvm::DenseMap<const VarDecl *, FieldDecl *> Captures; 4526 FieldDecl *ThisCapture; 4527 RD->getCaptureFields(Captures, ThisCapture); 4528 for (const LambdaCapture &LC : RD->captures()) { 4529 if (LC.getCaptureKind() == LCK_ByRef) { 4530 VarDecl *VD = LC.getCapturedVar(); 4531 DeclContext *VDC = VD->getDeclContext(); 4532 if (!VDC->Encloses(CurContext)) 4533 continue; 4534 MarkVariableReferenced(LC.getLocation(), VD); 4535 } else if (LC.getCaptureKind() == LCK_This) { 4536 QualType ThisTy = getCurrentThisType(); 4537 if (!ThisTy.isNull() && 4538 Context.typesAreCompatible(ThisTy, ThisCapture->getType())) 4539 CheckCXXThisCapture(LC.getLocation()); 4540 } 4541 } 4542 } 4543 DSAStack->setForceCaptureByReferenceInTargetExecutable( 4544 SavedForceCaptureByReferenceInTargetExecutable); 4545 } 4546 } 4547 } 4548 4549 static bool checkOrderedOrderSpecified(Sema &S, 4550 const ArrayRef<OMPClause *> Clauses) { 4551 const OMPOrderedClause *Ordered = nullptr; 4552 const OMPOrderClause *Order = nullptr; 4553 4554 for (const OMPClause *Clause : Clauses) { 4555 if (Clause->getClauseKind() == OMPC_ordered) 4556 Ordered = cast<OMPOrderedClause>(Clause); 4557 else if (Clause->getClauseKind() == OMPC_order) { 4558 Order = cast<OMPOrderClause>(Clause); 4559 if (Order->getKind() != OMPC_ORDER_concurrent) 4560 Order = nullptr; 4561 } 4562 if (Ordered && Order) 4563 break; 4564 } 4565 4566 if (Ordered && Order) { 4567 S.Diag(Order->getKindKwLoc(), 4568 diag::err_omp_simple_clause_incompatible_with_ordered) 4569 << getOpenMPClauseName(OMPC_order) 4570 << getOpenMPSimpleClauseTypeName(OMPC_order, OMPC_ORDER_concurrent) 4571 << SourceRange(Order->getBeginLoc(), Order->getEndLoc()); 4572 S.Diag(Ordered->getBeginLoc(), diag::note_omp_ordered_param) 4573 << 0 << SourceRange(Ordered->getBeginLoc(), Ordered->getEndLoc()); 4574 return true; 4575 } 4576 return false; 4577 } 4578 4579 StmtResult Sema::ActOnOpenMPRegionEnd(StmtResult S, 4580 ArrayRef<OMPClause *> Clauses) { 4581 handleDeclareVariantConstructTrait(DSAStack, DSAStack->getCurrentDirective(), 4582 /* ScopeEntry */ false); 4583 if (DSAStack->getCurrentDirective() == OMPD_atomic || 4584 DSAStack->getCurrentDirective() == OMPD_critical || 4585 DSAStack->getCurrentDirective() == OMPD_section || 4586 DSAStack->getCurrentDirective() == OMPD_master || 4587 DSAStack->getCurrentDirective() == OMPD_masked) 4588 return S; 4589 4590 bool ErrorFound = false; 4591 CaptureRegionUnwinderRAII CaptureRegionUnwinder( 4592 *this, ErrorFound, DSAStack->getCurrentDirective()); 4593 if (!S.isUsable()) { 4594 ErrorFound = true; 4595 return StmtError(); 4596 } 4597 4598 SmallVector<OpenMPDirectiveKind, 4> CaptureRegions; 4599 getOpenMPCaptureRegions(CaptureRegions, DSAStack->getCurrentDirective()); 4600 OMPOrderedClause *OC = nullptr; 4601 OMPScheduleClause *SC = nullptr; 4602 SmallVector<const OMPLinearClause *, 4> LCs; 4603 SmallVector<const OMPClauseWithPreInit *, 4> PICs; 4604 // This is required for proper codegen. 4605 for (OMPClause *Clause : Clauses) { 4606 if (!LangOpts.OpenMPSimd && 4607 isOpenMPTaskingDirective(DSAStack->getCurrentDirective()) && 4608 Clause->getClauseKind() == OMPC_in_reduction) { 4609 // Capture taskgroup task_reduction descriptors inside the tasking regions 4610 // with the corresponding in_reduction items. 4611 auto *IRC = cast<OMPInReductionClause>(Clause); 4612 for (Expr *E : IRC->taskgroup_descriptors()) 4613 if (E) 4614 MarkDeclarationsReferencedInExpr(E); 4615 } 4616 if (isOpenMPPrivate(Clause->getClauseKind()) || 4617 Clause->getClauseKind() == OMPC_copyprivate || 4618 (getLangOpts().OpenMPUseTLS && 4619 getASTContext().getTargetInfo().isTLSSupported() && 4620 Clause->getClauseKind() == OMPC_copyin)) { 4621 DSAStack->setForceVarCapturing(Clause->getClauseKind() == OMPC_copyin); 4622 // Mark all variables in private list clauses as used in inner region. 4623 for (Stmt *VarRef : Clause->children()) { 4624 if (auto *E = cast_or_null<Expr>(VarRef)) { 4625 MarkDeclarationsReferencedInExpr(E); 4626 } 4627 } 4628 DSAStack->setForceVarCapturing(/*V=*/false); 4629 } else if (isOpenMPLoopTransformationDirective( 4630 DSAStack->getCurrentDirective())) { 4631 assert(CaptureRegions.empty() && 4632 "No captured regions in loop transformation directives."); 4633 } else if (CaptureRegions.size() > 1 || 4634 CaptureRegions.back() != OMPD_unknown) { 4635 if (auto *C = OMPClauseWithPreInit::get(Clause)) 4636 PICs.push_back(C); 4637 if (auto *C = OMPClauseWithPostUpdate::get(Clause)) { 4638 if (Expr *E = C->getPostUpdateExpr()) 4639 MarkDeclarationsReferencedInExpr(E); 4640 } 4641 } 4642 if (Clause->getClauseKind() == OMPC_schedule) 4643 SC = cast<OMPScheduleClause>(Clause); 4644 else if (Clause->getClauseKind() == OMPC_ordered) 4645 OC = cast<OMPOrderedClause>(Clause); 4646 else if (Clause->getClauseKind() == OMPC_linear) 4647 LCs.push_back(cast<OMPLinearClause>(Clause)); 4648 } 4649 // Capture allocator expressions if used. 4650 for (Expr *E : DSAStack->getInnerAllocators()) 4651 MarkDeclarationsReferencedInExpr(E); 4652 // OpenMP, 2.7.1 Loop Construct, Restrictions 4653 // The nonmonotonic modifier cannot be specified if an ordered clause is 4654 // specified. 4655 if (SC && 4656 (SC->getFirstScheduleModifier() == OMPC_SCHEDULE_MODIFIER_nonmonotonic || 4657 SC->getSecondScheduleModifier() == 4658 OMPC_SCHEDULE_MODIFIER_nonmonotonic) && 4659 OC) { 4660 Diag(SC->getFirstScheduleModifier() == OMPC_SCHEDULE_MODIFIER_nonmonotonic 4661 ? SC->getFirstScheduleModifierLoc() 4662 : SC->getSecondScheduleModifierLoc(), 4663 diag::err_omp_simple_clause_incompatible_with_ordered) 4664 << getOpenMPClauseName(OMPC_schedule) 4665 << getOpenMPSimpleClauseTypeName(OMPC_schedule, 4666 OMPC_SCHEDULE_MODIFIER_nonmonotonic) 4667 << SourceRange(OC->getBeginLoc(), OC->getEndLoc()); 4668 ErrorFound = true; 4669 } 4670 // OpenMP 5.0, 2.9.2 Worksharing-Loop Construct, Restrictions. 4671 // If an order(concurrent) clause is present, an ordered clause may not appear 4672 // on the same directive. 4673 if (checkOrderedOrderSpecified(*this, Clauses)) 4674 ErrorFound = true; 4675 if (!LCs.empty() && OC && OC->getNumForLoops()) { 4676 for (const OMPLinearClause *C : LCs) { 4677 Diag(C->getBeginLoc(), diag::err_omp_linear_ordered) 4678 << SourceRange(OC->getBeginLoc(), OC->getEndLoc()); 4679 } 4680 ErrorFound = true; 4681 } 4682 if (isOpenMPWorksharingDirective(DSAStack->getCurrentDirective()) && 4683 isOpenMPSimdDirective(DSAStack->getCurrentDirective()) && OC && 4684 OC->getNumForLoops()) { 4685 Diag(OC->getBeginLoc(), diag::err_omp_ordered_simd) 4686 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 4687 ErrorFound = true; 4688 } 4689 if (ErrorFound) { 4690 return StmtError(); 4691 } 4692 StmtResult SR = S; 4693 unsigned CompletedRegions = 0; 4694 for (OpenMPDirectiveKind ThisCaptureRegion : llvm::reverse(CaptureRegions)) { 4695 // Mark all variables in private list clauses as used in inner region. 4696 // Required for proper codegen of combined directives. 4697 // TODO: add processing for other clauses. 4698 if (ThisCaptureRegion != OMPD_unknown) { 4699 for (const clang::OMPClauseWithPreInit *C : PICs) { 4700 OpenMPDirectiveKind CaptureRegion = C->getCaptureRegion(); 4701 // Find the particular capture region for the clause if the 4702 // directive is a combined one with multiple capture regions. 4703 // If the directive is not a combined one, the capture region 4704 // associated with the clause is OMPD_unknown and is generated 4705 // only once. 4706 if (CaptureRegion == ThisCaptureRegion || 4707 CaptureRegion == OMPD_unknown) { 4708 if (auto *DS = cast_or_null<DeclStmt>(C->getPreInitStmt())) { 4709 for (Decl *D : DS->decls()) 4710 MarkVariableReferenced(D->getLocation(), cast<VarDecl>(D)); 4711 } 4712 } 4713 } 4714 } 4715 if (ThisCaptureRegion == OMPD_target) { 4716 // Capture allocator traits in the target region. They are used implicitly 4717 // and, thus, are not captured by default. 4718 for (OMPClause *C : Clauses) { 4719 if (const auto *UAC = dyn_cast<OMPUsesAllocatorsClause>(C)) { 4720 for (unsigned I = 0, End = UAC->getNumberOfAllocators(); I < End; 4721 ++I) { 4722 OMPUsesAllocatorsClause::Data D = UAC->getAllocatorData(I); 4723 if (Expr *E = D.AllocatorTraits) 4724 MarkDeclarationsReferencedInExpr(E); 4725 } 4726 continue; 4727 } 4728 } 4729 } 4730 if (ThisCaptureRegion == OMPD_parallel) { 4731 // Capture temp arrays for inscan reductions and locals in aligned 4732 // clauses. 4733 for (OMPClause *C : Clauses) { 4734 if (auto *RC = dyn_cast<OMPReductionClause>(C)) { 4735 if (RC->getModifier() != OMPC_REDUCTION_inscan) 4736 continue; 4737 for (Expr *E : RC->copy_array_temps()) 4738 MarkDeclarationsReferencedInExpr(E); 4739 } 4740 if (auto *AC = dyn_cast<OMPAlignedClause>(C)) { 4741 for (Expr *E : AC->varlists()) 4742 MarkDeclarationsReferencedInExpr(E); 4743 } 4744 } 4745 } 4746 if (++CompletedRegions == CaptureRegions.size()) 4747 DSAStack->setBodyComplete(); 4748 SR = ActOnCapturedRegionEnd(SR.get()); 4749 } 4750 return SR; 4751 } 4752 4753 static bool checkCancelRegion(Sema &SemaRef, OpenMPDirectiveKind CurrentRegion, 4754 OpenMPDirectiveKind CancelRegion, 4755 SourceLocation StartLoc) { 4756 // CancelRegion is only needed for cancel and cancellation_point. 4757 if (CurrentRegion != OMPD_cancel && CurrentRegion != OMPD_cancellation_point) 4758 return false; 4759 4760 if (CancelRegion == OMPD_parallel || CancelRegion == OMPD_for || 4761 CancelRegion == OMPD_sections || CancelRegion == OMPD_taskgroup) 4762 return false; 4763 4764 SemaRef.Diag(StartLoc, diag::err_omp_wrong_cancel_region) 4765 << getOpenMPDirectiveName(CancelRegion); 4766 return true; 4767 } 4768 4769 static bool checkNestingOfRegions(Sema &SemaRef, const DSAStackTy *Stack, 4770 OpenMPDirectiveKind CurrentRegion, 4771 const DeclarationNameInfo &CurrentName, 4772 OpenMPDirectiveKind CancelRegion, 4773 OpenMPBindClauseKind BindKind, 4774 SourceLocation StartLoc) { 4775 if (Stack->getCurScope()) { 4776 OpenMPDirectiveKind ParentRegion = Stack->getParentDirective(); 4777 OpenMPDirectiveKind OffendingRegion = ParentRegion; 4778 bool NestingProhibited = false; 4779 bool CloseNesting = true; 4780 bool OrphanSeen = false; 4781 enum { 4782 NoRecommend, 4783 ShouldBeInParallelRegion, 4784 ShouldBeInOrderedRegion, 4785 ShouldBeInTargetRegion, 4786 ShouldBeInTeamsRegion, 4787 ShouldBeInLoopSimdRegion, 4788 } Recommend = NoRecommend; 4789 if (isOpenMPSimdDirective(ParentRegion) && 4790 ((SemaRef.LangOpts.OpenMP <= 45 && CurrentRegion != OMPD_ordered) || 4791 (SemaRef.LangOpts.OpenMP >= 50 && CurrentRegion != OMPD_ordered && 4792 CurrentRegion != OMPD_simd && CurrentRegion != OMPD_atomic && 4793 CurrentRegion != OMPD_scan))) { 4794 // OpenMP [2.16, Nesting of Regions] 4795 // OpenMP constructs may not be nested inside a simd region. 4796 // OpenMP [2.8.1,simd Construct, Restrictions] 4797 // An ordered construct with the simd clause is the only OpenMP 4798 // construct that can appear in the simd region. 4799 // Allowing a SIMD construct nested in another SIMD construct is an 4800 // extension. The OpenMP 4.5 spec does not allow it. Issue a warning 4801 // message. 4802 // OpenMP 5.0 [2.9.3.1, simd Construct, Restrictions] 4803 // The only OpenMP constructs that can be encountered during execution of 4804 // a simd region are the atomic construct, the loop construct, the simd 4805 // construct and the ordered construct with the simd clause. 4806 SemaRef.Diag(StartLoc, (CurrentRegion != OMPD_simd) 4807 ? diag::err_omp_prohibited_region_simd 4808 : diag::warn_omp_nesting_simd) 4809 << (SemaRef.LangOpts.OpenMP >= 50 ? 1 : 0); 4810 return CurrentRegion != OMPD_simd; 4811 } 4812 if (ParentRegion == OMPD_atomic) { 4813 // OpenMP [2.16, Nesting of Regions] 4814 // OpenMP constructs may not be nested inside an atomic region. 4815 SemaRef.Diag(StartLoc, diag::err_omp_prohibited_region_atomic); 4816 return true; 4817 } 4818 if (CurrentRegion == OMPD_section) { 4819 // OpenMP [2.7.2, sections Construct, Restrictions] 4820 // Orphaned section directives are prohibited. That is, the section 4821 // directives must appear within the sections construct and must not be 4822 // encountered elsewhere in the sections region. 4823 if (ParentRegion != OMPD_sections && 4824 ParentRegion != OMPD_parallel_sections) { 4825 SemaRef.Diag(StartLoc, diag::err_omp_orphaned_section_directive) 4826 << (ParentRegion != OMPD_unknown) 4827 << getOpenMPDirectiveName(ParentRegion); 4828 return true; 4829 } 4830 return false; 4831 } 4832 // Allow some constructs (except teams and cancellation constructs) to be 4833 // orphaned (they could be used in functions, called from OpenMP regions 4834 // with the required preconditions). 4835 if (ParentRegion == OMPD_unknown && 4836 !isOpenMPNestingTeamsDirective(CurrentRegion) && 4837 CurrentRegion != OMPD_cancellation_point && 4838 CurrentRegion != OMPD_cancel && CurrentRegion != OMPD_scan) 4839 return false; 4840 if (CurrentRegion == OMPD_cancellation_point || 4841 CurrentRegion == OMPD_cancel) { 4842 // OpenMP [2.16, Nesting of Regions] 4843 // A cancellation point construct for which construct-type-clause is 4844 // taskgroup must be nested inside a task construct. A cancellation 4845 // point construct for which construct-type-clause is not taskgroup must 4846 // be closely nested inside an OpenMP construct that matches the type 4847 // specified in construct-type-clause. 4848 // A cancel construct for which construct-type-clause is taskgroup must be 4849 // nested inside a task construct. A cancel construct for which 4850 // construct-type-clause is not taskgroup must be closely nested inside an 4851 // OpenMP construct that matches the type specified in 4852 // construct-type-clause. 4853 NestingProhibited = 4854 !((CancelRegion == OMPD_parallel && 4855 (ParentRegion == OMPD_parallel || 4856 ParentRegion == OMPD_target_parallel)) || 4857 (CancelRegion == OMPD_for && 4858 (ParentRegion == OMPD_for || ParentRegion == OMPD_parallel_for || 4859 ParentRegion == OMPD_target_parallel_for || 4860 ParentRegion == OMPD_distribute_parallel_for || 4861 ParentRegion == OMPD_teams_distribute_parallel_for || 4862 ParentRegion == OMPD_target_teams_distribute_parallel_for)) || 4863 (CancelRegion == OMPD_taskgroup && 4864 (ParentRegion == OMPD_task || 4865 (SemaRef.getLangOpts().OpenMP >= 50 && 4866 (ParentRegion == OMPD_taskloop || 4867 ParentRegion == OMPD_master_taskloop || 4868 ParentRegion == OMPD_parallel_master_taskloop)))) || 4869 (CancelRegion == OMPD_sections && 4870 (ParentRegion == OMPD_section || ParentRegion == OMPD_sections || 4871 ParentRegion == OMPD_parallel_sections))); 4872 OrphanSeen = ParentRegion == OMPD_unknown; 4873 } else if (CurrentRegion == OMPD_master || CurrentRegion == OMPD_masked) { 4874 // OpenMP 5.1 [2.22, Nesting of Regions] 4875 // A masked region may not be closely nested inside a worksharing, loop, 4876 // atomic, task, or taskloop region. 4877 NestingProhibited = isOpenMPWorksharingDirective(ParentRegion) || 4878 isOpenMPGenericLoopDirective(ParentRegion) || 4879 isOpenMPTaskingDirective(ParentRegion); 4880 } else if (CurrentRegion == OMPD_critical && CurrentName.getName()) { 4881 // OpenMP [2.16, Nesting of Regions] 4882 // A critical region may not be nested (closely or otherwise) inside a 4883 // critical region with the same name. Note that this restriction is not 4884 // sufficient to prevent deadlock. 4885 SourceLocation PreviousCriticalLoc; 4886 bool DeadLock = Stack->hasDirective( 4887 [CurrentName, &PreviousCriticalLoc](OpenMPDirectiveKind K, 4888 const DeclarationNameInfo &DNI, 4889 SourceLocation Loc) { 4890 if (K == OMPD_critical && DNI.getName() == CurrentName.getName()) { 4891 PreviousCriticalLoc = Loc; 4892 return true; 4893 } 4894 return false; 4895 }, 4896 false /* skip top directive */); 4897 if (DeadLock) { 4898 SemaRef.Diag(StartLoc, 4899 diag::err_omp_prohibited_region_critical_same_name) 4900 << CurrentName.getName(); 4901 if (PreviousCriticalLoc.isValid()) 4902 SemaRef.Diag(PreviousCriticalLoc, 4903 diag::note_omp_previous_critical_region); 4904 return true; 4905 } 4906 } else if (CurrentRegion == OMPD_barrier) { 4907 // OpenMP 5.1 [2.22, Nesting of Regions] 4908 // A barrier region may not be closely nested inside a worksharing, loop, 4909 // task, taskloop, critical, ordered, atomic, or masked region. 4910 NestingProhibited = 4911 isOpenMPWorksharingDirective(ParentRegion) || 4912 isOpenMPGenericLoopDirective(ParentRegion) || 4913 isOpenMPTaskingDirective(ParentRegion) || 4914 ParentRegion == OMPD_master || ParentRegion == OMPD_masked || 4915 ParentRegion == OMPD_parallel_master || 4916 ParentRegion == OMPD_parallel_masked || 4917 ParentRegion == OMPD_critical || ParentRegion == OMPD_ordered; 4918 } else if (isOpenMPWorksharingDirective(CurrentRegion) && 4919 !isOpenMPParallelDirective(CurrentRegion) && 4920 !isOpenMPTeamsDirective(CurrentRegion)) { 4921 // OpenMP 5.1 [2.22, Nesting of Regions] 4922 // A loop region that binds to a parallel region or a worksharing region 4923 // may not be closely nested inside a worksharing, loop, task, taskloop, 4924 // critical, ordered, atomic, or masked region. 4925 NestingProhibited = 4926 isOpenMPWorksharingDirective(ParentRegion) || 4927 isOpenMPGenericLoopDirective(ParentRegion) || 4928 isOpenMPTaskingDirective(ParentRegion) || 4929 ParentRegion == OMPD_master || ParentRegion == OMPD_masked || 4930 ParentRegion == OMPD_parallel_master || 4931 ParentRegion == OMPD_parallel_masked || 4932 ParentRegion == OMPD_critical || ParentRegion == OMPD_ordered; 4933 Recommend = ShouldBeInParallelRegion; 4934 } else if (CurrentRegion == OMPD_ordered) { 4935 // OpenMP [2.16, Nesting of Regions] 4936 // An ordered region may not be closely nested inside a critical, 4937 // atomic, or explicit task region. 4938 // An ordered region must be closely nested inside a loop region (or 4939 // parallel loop region) with an ordered clause. 4940 // OpenMP [2.8.1,simd Construct, Restrictions] 4941 // An ordered construct with the simd clause is the only OpenMP construct 4942 // that can appear in the simd region. 4943 NestingProhibited = ParentRegion == OMPD_critical || 4944 isOpenMPTaskingDirective(ParentRegion) || 4945 !(isOpenMPSimdDirective(ParentRegion) || 4946 Stack->isParentOrderedRegion()); 4947 Recommend = ShouldBeInOrderedRegion; 4948 } else if (isOpenMPNestingTeamsDirective(CurrentRegion)) { 4949 // OpenMP [2.16, Nesting of Regions] 4950 // If specified, a teams construct must be contained within a target 4951 // construct. 4952 NestingProhibited = 4953 (SemaRef.LangOpts.OpenMP <= 45 && ParentRegion != OMPD_target) || 4954 (SemaRef.LangOpts.OpenMP >= 50 && ParentRegion != OMPD_unknown && 4955 ParentRegion != OMPD_target); 4956 OrphanSeen = ParentRegion == OMPD_unknown; 4957 Recommend = ShouldBeInTargetRegion; 4958 } else if (CurrentRegion == OMPD_scan) { 4959 // OpenMP [2.16, Nesting of Regions] 4960 // If specified, a teams construct must be contained within a target 4961 // construct. 4962 NestingProhibited = 4963 SemaRef.LangOpts.OpenMP < 50 || 4964 (ParentRegion != OMPD_simd && ParentRegion != OMPD_for && 4965 ParentRegion != OMPD_for_simd && ParentRegion != OMPD_parallel_for && 4966 ParentRegion != OMPD_parallel_for_simd); 4967 OrphanSeen = ParentRegion == OMPD_unknown; 4968 Recommend = ShouldBeInLoopSimdRegion; 4969 } 4970 if (!NestingProhibited && 4971 !isOpenMPTargetExecutionDirective(CurrentRegion) && 4972 !isOpenMPTargetDataManagementDirective(CurrentRegion) && 4973 (ParentRegion == OMPD_teams || ParentRegion == OMPD_target_teams)) { 4974 // OpenMP [5.1, 2.22, Nesting of Regions] 4975 // distribute, distribute simd, distribute parallel worksharing-loop, 4976 // distribute parallel worksharing-loop SIMD, loop, parallel regions, 4977 // including any parallel regions arising from combined constructs, 4978 // omp_get_num_teams() regions, and omp_get_team_num() regions are the 4979 // only OpenMP regions that may be strictly nested inside the teams 4980 // region. 4981 // 4982 // As an extension, we permit atomic within teams as well. 4983 NestingProhibited = !isOpenMPParallelDirective(CurrentRegion) && 4984 !isOpenMPDistributeDirective(CurrentRegion) && 4985 CurrentRegion != OMPD_loop && 4986 !(SemaRef.getLangOpts().OpenMPExtensions && 4987 CurrentRegion == OMPD_atomic); 4988 Recommend = ShouldBeInParallelRegion; 4989 } 4990 if (!NestingProhibited && CurrentRegion == OMPD_loop) { 4991 // OpenMP [5.1, 2.11.7, loop Construct, Restrictions] 4992 // If the bind clause is present on the loop construct and binding is 4993 // teams then the corresponding loop region must be strictly nested inside 4994 // a teams region. 4995 NestingProhibited = BindKind == OMPC_BIND_teams && 4996 ParentRegion != OMPD_teams && 4997 ParentRegion != OMPD_target_teams; 4998 Recommend = ShouldBeInTeamsRegion; 4999 } 5000 if (!NestingProhibited && 5001 isOpenMPNestingDistributeDirective(CurrentRegion)) { 5002 // OpenMP 4.5 [2.17 Nesting of Regions] 5003 // The region associated with the distribute construct must be strictly 5004 // nested inside a teams region 5005 NestingProhibited = 5006 (ParentRegion != OMPD_teams && ParentRegion != OMPD_target_teams); 5007 Recommend = ShouldBeInTeamsRegion; 5008 } 5009 if (!NestingProhibited && 5010 (isOpenMPTargetExecutionDirective(CurrentRegion) || 5011 isOpenMPTargetDataManagementDirective(CurrentRegion))) { 5012 // OpenMP 4.5 [2.17 Nesting of Regions] 5013 // If a target, target update, target data, target enter data, or 5014 // target exit data construct is encountered during execution of a 5015 // target region, the behavior is unspecified. 5016 NestingProhibited = Stack->hasDirective( 5017 [&OffendingRegion](OpenMPDirectiveKind K, const DeclarationNameInfo &, 5018 SourceLocation) { 5019 if (isOpenMPTargetExecutionDirective(K)) { 5020 OffendingRegion = K; 5021 return true; 5022 } 5023 return false; 5024 }, 5025 false /* don't skip top directive */); 5026 CloseNesting = false; 5027 } 5028 if (NestingProhibited) { 5029 if (OrphanSeen) { 5030 SemaRef.Diag(StartLoc, diag::err_omp_orphaned_device_directive) 5031 << getOpenMPDirectiveName(CurrentRegion) << Recommend; 5032 } else { 5033 SemaRef.Diag(StartLoc, diag::err_omp_prohibited_region) 5034 << CloseNesting << getOpenMPDirectiveName(OffendingRegion) 5035 << Recommend << getOpenMPDirectiveName(CurrentRegion); 5036 } 5037 return true; 5038 } 5039 } 5040 return false; 5041 } 5042 5043 struct Kind2Unsigned { 5044 using argument_type = OpenMPDirectiveKind; 5045 unsigned operator()(argument_type DK) { return unsigned(DK); } 5046 }; 5047 static bool checkIfClauses(Sema &S, OpenMPDirectiveKind Kind, 5048 ArrayRef<OMPClause *> Clauses, 5049 ArrayRef<OpenMPDirectiveKind> AllowedNameModifiers) { 5050 bool ErrorFound = false; 5051 unsigned NamedModifiersNumber = 0; 5052 llvm::IndexedMap<const OMPIfClause *, Kind2Unsigned> FoundNameModifiers; 5053 FoundNameModifiers.resize(llvm::omp::Directive_enumSize + 1); 5054 SmallVector<SourceLocation, 4> NameModifierLoc; 5055 for (const OMPClause *C : Clauses) { 5056 if (const auto *IC = dyn_cast_or_null<OMPIfClause>(C)) { 5057 // At most one if clause without a directive-name-modifier can appear on 5058 // the directive. 5059 OpenMPDirectiveKind CurNM = IC->getNameModifier(); 5060 if (FoundNameModifiers[CurNM]) { 5061 S.Diag(C->getBeginLoc(), diag::err_omp_more_one_clause) 5062 << getOpenMPDirectiveName(Kind) << getOpenMPClauseName(OMPC_if) 5063 << (CurNM != OMPD_unknown) << getOpenMPDirectiveName(CurNM); 5064 ErrorFound = true; 5065 } else if (CurNM != OMPD_unknown) { 5066 NameModifierLoc.push_back(IC->getNameModifierLoc()); 5067 ++NamedModifiersNumber; 5068 } 5069 FoundNameModifiers[CurNM] = IC; 5070 if (CurNM == OMPD_unknown) 5071 continue; 5072 // Check if the specified name modifier is allowed for the current 5073 // directive. 5074 // At most one if clause with the particular directive-name-modifier can 5075 // appear on the directive. 5076 if (!llvm::is_contained(AllowedNameModifiers, CurNM)) { 5077 S.Diag(IC->getNameModifierLoc(), 5078 diag::err_omp_wrong_if_directive_name_modifier) 5079 << getOpenMPDirectiveName(CurNM) << getOpenMPDirectiveName(Kind); 5080 ErrorFound = true; 5081 } 5082 } 5083 } 5084 // If any if clause on the directive includes a directive-name-modifier then 5085 // all if clauses on the directive must include a directive-name-modifier. 5086 if (FoundNameModifiers[OMPD_unknown] && NamedModifiersNumber > 0) { 5087 if (NamedModifiersNumber == AllowedNameModifiers.size()) { 5088 S.Diag(FoundNameModifiers[OMPD_unknown]->getBeginLoc(), 5089 diag::err_omp_no_more_if_clause); 5090 } else { 5091 std::string Values; 5092 std::string Sep(", "); 5093 unsigned AllowedCnt = 0; 5094 unsigned TotalAllowedNum = 5095 AllowedNameModifiers.size() - NamedModifiersNumber; 5096 for (unsigned Cnt = 0, End = AllowedNameModifiers.size(); Cnt < End; 5097 ++Cnt) { 5098 OpenMPDirectiveKind NM = AllowedNameModifiers[Cnt]; 5099 if (!FoundNameModifiers[NM]) { 5100 Values += "'"; 5101 Values += getOpenMPDirectiveName(NM); 5102 Values += "'"; 5103 if (AllowedCnt + 2 == TotalAllowedNum) 5104 Values += " or "; 5105 else if (AllowedCnt + 1 != TotalAllowedNum) 5106 Values += Sep; 5107 ++AllowedCnt; 5108 } 5109 } 5110 S.Diag(FoundNameModifiers[OMPD_unknown]->getCondition()->getBeginLoc(), 5111 diag::err_omp_unnamed_if_clause) 5112 << (TotalAllowedNum > 1) << Values; 5113 } 5114 for (SourceLocation Loc : NameModifierLoc) { 5115 S.Diag(Loc, diag::note_omp_previous_named_if_clause); 5116 } 5117 ErrorFound = true; 5118 } 5119 return ErrorFound; 5120 } 5121 5122 static std::pair<ValueDecl *, bool> getPrivateItem(Sema &S, Expr *&RefExpr, 5123 SourceLocation &ELoc, 5124 SourceRange &ERange, 5125 bool AllowArraySection) { 5126 if (RefExpr->isTypeDependent() || RefExpr->isValueDependent() || 5127 RefExpr->containsUnexpandedParameterPack()) 5128 return std::make_pair(nullptr, true); 5129 5130 // OpenMP [3.1, C/C++] 5131 // A list item is a variable name. 5132 // OpenMP [2.9.3.3, Restrictions, p.1] 5133 // A variable that is part of another variable (as an array or 5134 // structure element) cannot appear in a private clause. 5135 RefExpr = RefExpr->IgnoreParens(); 5136 enum { 5137 NoArrayExpr = -1, 5138 ArraySubscript = 0, 5139 OMPArraySection = 1 5140 } IsArrayExpr = NoArrayExpr; 5141 if (AllowArraySection) { 5142 if (auto *ASE = dyn_cast_or_null<ArraySubscriptExpr>(RefExpr)) { 5143 Expr *Base = ASE->getBase()->IgnoreParenImpCasts(); 5144 while (auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base)) 5145 Base = TempASE->getBase()->IgnoreParenImpCasts(); 5146 RefExpr = Base; 5147 IsArrayExpr = ArraySubscript; 5148 } else if (auto *OASE = dyn_cast_or_null<OMPArraySectionExpr>(RefExpr)) { 5149 Expr *Base = OASE->getBase()->IgnoreParenImpCasts(); 5150 while (auto *TempOASE = dyn_cast<OMPArraySectionExpr>(Base)) 5151 Base = TempOASE->getBase()->IgnoreParenImpCasts(); 5152 while (auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base)) 5153 Base = TempASE->getBase()->IgnoreParenImpCasts(); 5154 RefExpr = Base; 5155 IsArrayExpr = OMPArraySection; 5156 } 5157 } 5158 ELoc = RefExpr->getExprLoc(); 5159 ERange = RefExpr->getSourceRange(); 5160 RefExpr = RefExpr->IgnoreParenImpCasts(); 5161 auto *DE = dyn_cast_or_null<DeclRefExpr>(RefExpr); 5162 auto *ME = dyn_cast_or_null<MemberExpr>(RefExpr); 5163 if ((!DE || !isa<VarDecl>(DE->getDecl())) && 5164 (S.getCurrentThisType().isNull() || !ME || 5165 !isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts()) || 5166 !isa<FieldDecl>(ME->getMemberDecl()))) { 5167 if (IsArrayExpr != NoArrayExpr) { 5168 S.Diag(ELoc, diag::err_omp_expected_base_var_name) 5169 << IsArrayExpr << ERange; 5170 } else { 5171 S.Diag(ELoc, 5172 AllowArraySection 5173 ? diag::err_omp_expected_var_name_member_expr_or_array_item 5174 : diag::err_omp_expected_var_name_member_expr) 5175 << (S.getCurrentThisType().isNull() ? 0 : 1) << ERange; 5176 } 5177 return std::make_pair(nullptr, false); 5178 } 5179 return std::make_pair( 5180 getCanonicalDecl(DE ? DE->getDecl() : ME->getMemberDecl()), false); 5181 } 5182 5183 namespace { 5184 /// Checks if the allocator is used in uses_allocators clause to be allowed in 5185 /// target regions. 5186 class AllocatorChecker final : public ConstStmtVisitor<AllocatorChecker, bool> { 5187 DSAStackTy *S = nullptr; 5188 5189 public: 5190 bool VisitDeclRefExpr(const DeclRefExpr *E) { 5191 return S->isUsesAllocatorsDecl(E->getDecl()) 5192 .value_or(DSAStackTy::UsesAllocatorsDeclKind::AllocatorTrait) == 5193 DSAStackTy::UsesAllocatorsDeclKind::AllocatorTrait; 5194 } 5195 bool VisitStmt(const Stmt *S) { 5196 for (const Stmt *Child : S->children()) { 5197 if (Child && Visit(Child)) 5198 return true; 5199 } 5200 return false; 5201 } 5202 explicit AllocatorChecker(DSAStackTy *S) : S(S) {} 5203 }; 5204 } // namespace 5205 5206 static void checkAllocateClauses(Sema &S, DSAStackTy *Stack, 5207 ArrayRef<OMPClause *> Clauses) { 5208 assert(!S.CurContext->isDependentContext() && 5209 "Expected non-dependent context."); 5210 auto AllocateRange = 5211 llvm::make_filter_range(Clauses, OMPAllocateClause::classof); 5212 llvm::DenseMap<CanonicalDeclPtr<Decl>, CanonicalDeclPtr<VarDecl>> DeclToCopy; 5213 auto PrivateRange = llvm::make_filter_range(Clauses, [](const OMPClause *C) { 5214 return isOpenMPPrivate(C->getClauseKind()); 5215 }); 5216 for (OMPClause *Cl : PrivateRange) { 5217 MutableArrayRef<Expr *>::iterator I, It, Et; 5218 if (Cl->getClauseKind() == OMPC_private) { 5219 auto *PC = cast<OMPPrivateClause>(Cl); 5220 I = PC->private_copies().begin(); 5221 It = PC->varlist_begin(); 5222 Et = PC->varlist_end(); 5223 } else if (Cl->getClauseKind() == OMPC_firstprivate) { 5224 auto *PC = cast<OMPFirstprivateClause>(Cl); 5225 I = PC->private_copies().begin(); 5226 It = PC->varlist_begin(); 5227 Et = PC->varlist_end(); 5228 } else if (Cl->getClauseKind() == OMPC_lastprivate) { 5229 auto *PC = cast<OMPLastprivateClause>(Cl); 5230 I = PC->private_copies().begin(); 5231 It = PC->varlist_begin(); 5232 Et = PC->varlist_end(); 5233 } else if (Cl->getClauseKind() == OMPC_linear) { 5234 auto *PC = cast<OMPLinearClause>(Cl); 5235 I = PC->privates().begin(); 5236 It = PC->varlist_begin(); 5237 Et = PC->varlist_end(); 5238 } else if (Cl->getClauseKind() == OMPC_reduction) { 5239 auto *PC = cast<OMPReductionClause>(Cl); 5240 I = PC->privates().begin(); 5241 It = PC->varlist_begin(); 5242 Et = PC->varlist_end(); 5243 } else if (Cl->getClauseKind() == OMPC_task_reduction) { 5244 auto *PC = cast<OMPTaskReductionClause>(Cl); 5245 I = PC->privates().begin(); 5246 It = PC->varlist_begin(); 5247 Et = PC->varlist_end(); 5248 } else if (Cl->getClauseKind() == OMPC_in_reduction) { 5249 auto *PC = cast<OMPInReductionClause>(Cl); 5250 I = PC->privates().begin(); 5251 It = PC->varlist_begin(); 5252 Et = PC->varlist_end(); 5253 } else { 5254 llvm_unreachable("Expected private clause."); 5255 } 5256 for (Expr *E : llvm::make_range(It, Et)) { 5257 if (!*I) { 5258 ++I; 5259 continue; 5260 } 5261 SourceLocation ELoc; 5262 SourceRange ERange; 5263 Expr *SimpleRefExpr = E; 5264 auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange, 5265 /*AllowArraySection=*/true); 5266 DeclToCopy.try_emplace(Res.first, 5267 cast<VarDecl>(cast<DeclRefExpr>(*I)->getDecl())); 5268 ++I; 5269 } 5270 } 5271 for (OMPClause *C : AllocateRange) { 5272 auto *AC = cast<OMPAllocateClause>(C); 5273 if (S.getLangOpts().OpenMP >= 50 && 5274 !Stack->hasRequiresDeclWithClause<OMPDynamicAllocatorsClause>() && 5275 isOpenMPTargetExecutionDirective(Stack->getCurrentDirective()) && 5276 AC->getAllocator()) { 5277 Expr *Allocator = AC->getAllocator(); 5278 // OpenMP, 2.12.5 target Construct 5279 // Memory allocators that do not appear in a uses_allocators clause cannot 5280 // appear as an allocator in an allocate clause or be used in the target 5281 // region unless a requires directive with the dynamic_allocators clause 5282 // is present in the same compilation unit. 5283 AllocatorChecker Checker(Stack); 5284 if (Checker.Visit(Allocator)) 5285 S.Diag(Allocator->getExprLoc(), 5286 diag::err_omp_allocator_not_in_uses_allocators) 5287 << Allocator->getSourceRange(); 5288 } 5289 OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind = 5290 getAllocatorKind(S, Stack, AC->getAllocator()); 5291 // OpenMP, 2.11.4 allocate Clause, Restrictions. 5292 // For task, taskloop or target directives, allocation requests to memory 5293 // allocators with the trait access set to thread result in unspecified 5294 // behavior. 5295 if (AllocatorKind == OMPAllocateDeclAttr::OMPThreadMemAlloc && 5296 (isOpenMPTaskingDirective(Stack->getCurrentDirective()) || 5297 isOpenMPTargetExecutionDirective(Stack->getCurrentDirective()))) { 5298 S.Diag(AC->getAllocator()->getExprLoc(), 5299 diag::warn_omp_allocate_thread_on_task_target_directive) 5300 << getOpenMPDirectiveName(Stack->getCurrentDirective()); 5301 } 5302 for (Expr *E : AC->varlists()) { 5303 SourceLocation ELoc; 5304 SourceRange ERange; 5305 Expr *SimpleRefExpr = E; 5306 auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange); 5307 ValueDecl *VD = Res.first; 5308 DSAStackTy::DSAVarData Data = Stack->getTopDSA(VD, /*FromParent=*/false); 5309 if (!isOpenMPPrivate(Data.CKind)) { 5310 S.Diag(E->getExprLoc(), 5311 diag::err_omp_expected_private_copy_for_allocate); 5312 continue; 5313 } 5314 VarDecl *PrivateVD = DeclToCopy[VD]; 5315 if (checkPreviousOMPAllocateAttribute(S, Stack, E, PrivateVD, 5316 AllocatorKind, AC->getAllocator())) 5317 continue; 5318 // Placeholder until allocate clause supports align modifier. 5319 Expr *Alignment = nullptr; 5320 applyOMPAllocateAttribute(S, PrivateVD, AllocatorKind, AC->getAllocator(), 5321 Alignment, E->getSourceRange()); 5322 } 5323 } 5324 } 5325 5326 namespace { 5327 /// Rewrite statements and expressions for Sema \p Actions CurContext. 5328 /// 5329 /// Used to wrap already parsed statements/expressions into a new CapturedStmt 5330 /// context. DeclRefExpr used inside the new context are changed to refer to the 5331 /// captured variable instead. 5332 class CaptureVars : public TreeTransform<CaptureVars> { 5333 using BaseTransform = TreeTransform<CaptureVars>; 5334 5335 public: 5336 CaptureVars(Sema &Actions) : BaseTransform(Actions) {} 5337 5338 bool AlwaysRebuild() { return true; } 5339 }; 5340 } // namespace 5341 5342 static VarDecl *precomputeExpr(Sema &Actions, 5343 SmallVectorImpl<Stmt *> &BodyStmts, Expr *E, 5344 StringRef Name) { 5345 Expr *NewE = AssertSuccess(CaptureVars(Actions).TransformExpr(E)); 5346 VarDecl *NewVar = buildVarDecl(Actions, {}, NewE->getType(), Name, nullptr, 5347 dyn_cast<DeclRefExpr>(E->IgnoreImplicit())); 5348 auto *NewDeclStmt = cast<DeclStmt>(AssertSuccess( 5349 Actions.ActOnDeclStmt(Actions.ConvertDeclToDeclGroup(NewVar), {}, {}))); 5350 Actions.AddInitializerToDecl(NewDeclStmt->getSingleDecl(), NewE, false); 5351 BodyStmts.push_back(NewDeclStmt); 5352 return NewVar; 5353 } 5354 5355 /// Create a closure that computes the number of iterations of a loop. 5356 /// 5357 /// \param Actions The Sema object. 5358 /// \param LogicalTy Type for the logical iteration number. 5359 /// \param Rel Comparison operator of the loop condition. 5360 /// \param StartExpr Value of the loop counter at the first iteration. 5361 /// \param StopExpr Expression the loop counter is compared against in the loop 5362 /// condition. \param StepExpr Amount of increment after each iteration. 5363 /// 5364 /// \return Closure (CapturedStmt) of the distance calculation. 5365 static CapturedStmt *buildDistanceFunc(Sema &Actions, QualType LogicalTy, 5366 BinaryOperator::Opcode Rel, 5367 Expr *StartExpr, Expr *StopExpr, 5368 Expr *StepExpr) { 5369 ASTContext &Ctx = Actions.getASTContext(); 5370 TypeSourceInfo *LogicalTSI = Ctx.getTrivialTypeSourceInfo(LogicalTy); 5371 5372 // Captured regions currently don't support return values, we use an 5373 // out-parameter instead. All inputs are implicit captures. 5374 // TODO: Instead of capturing each DeclRefExpr occurring in 5375 // StartExpr/StopExpr/Step, these could also be passed as a value capture. 5376 QualType ResultTy = Ctx.getLValueReferenceType(LogicalTy); 5377 Sema::CapturedParamNameType Params[] = {{"Distance", ResultTy}, 5378 {StringRef(), QualType()}}; 5379 Actions.ActOnCapturedRegionStart({}, nullptr, CR_Default, Params); 5380 5381 Stmt *Body; 5382 { 5383 Sema::CompoundScopeRAII CompoundScope(Actions); 5384 CapturedDecl *CS = cast<CapturedDecl>(Actions.CurContext); 5385 5386 // Get the LValue expression for the result. 5387 ImplicitParamDecl *DistParam = CS->getParam(0); 5388 DeclRefExpr *DistRef = Actions.BuildDeclRefExpr( 5389 DistParam, LogicalTy, VK_LValue, {}, nullptr, nullptr, {}, nullptr); 5390 5391 SmallVector<Stmt *, 4> BodyStmts; 5392 5393 // Capture all referenced variable references. 5394 // TODO: Instead of computing NewStart/NewStop/NewStep inside the 5395 // CapturedStmt, we could compute them before and capture the result, to be 5396 // used jointly with the LoopVar function. 5397 VarDecl *NewStart = precomputeExpr(Actions, BodyStmts, StartExpr, ".start"); 5398 VarDecl *NewStop = precomputeExpr(Actions, BodyStmts, StopExpr, ".stop"); 5399 VarDecl *NewStep = precomputeExpr(Actions, BodyStmts, StepExpr, ".step"); 5400 auto BuildVarRef = [&](VarDecl *VD) { 5401 return buildDeclRefExpr(Actions, VD, VD->getType(), {}); 5402 }; 5403 5404 IntegerLiteral *Zero = IntegerLiteral::Create( 5405 Ctx, llvm::APInt(Ctx.getIntWidth(LogicalTy), 0), LogicalTy, {}); 5406 IntegerLiteral *One = IntegerLiteral::Create( 5407 Ctx, llvm::APInt(Ctx.getIntWidth(LogicalTy), 1), LogicalTy, {}); 5408 Expr *Dist; 5409 if (Rel == BO_NE) { 5410 // When using a != comparison, the increment can be +1 or -1. This can be 5411 // dynamic at runtime, so we need to check for the direction. 5412 Expr *IsNegStep = AssertSuccess( 5413 Actions.BuildBinOp(nullptr, {}, BO_LT, BuildVarRef(NewStep), Zero)); 5414 5415 // Positive increment. 5416 Expr *ForwardRange = AssertSuccess(Actions.BuildBinOp( 5417 nullptr, {}, BO_Sub, BuildVarRef(NewStop), BuildVarRef(NewStart))); 5418 ForwardRange = AssertSuccess( 5419 Actions.BuildCStyleCastExpr({}, LogicalTSI, {}, ForwardRange)); 5420 Expr *ForwardDist = AssertSuccess(Actions.BuildBinOp( 5421 nullptr, {}, BO_Div, ForwardRange, BuildVarRef(NewStep))); 5422 5423 // Negative increment. 5424 Expr *BackwardRange = AssertSuccess(Actions.BuildBinOp( 5425 nullptr, {}, BO_Sub, BuildVarRef(NewStart), BuildVarRef(NewStop))); 5426 BackwardRange = AssertSuccess( 5427 Actions.BuildCStyleCastExpr({}, LogicalTSI, {}, BackwardRange)); 5428 Expr *NegIncAmount = AssertSuccess( 5429 Actions.BuildUnaryOp(nullptr, {}, UO_Minus, BuildVarRef(NewStep))); 5430 Expr *BackwardDist = AssertSuccess( 5431 Actions.BuildBinOp(nullptr, {}, BO_Div, BackwardRange, NegIncAmount)); 5432 5433 // Use the appropriate case. 5434 Dist = AssertSuccess(Actions.ActOnConditionalOp( 5435 {}, {}, IsNegStep, BackwardDist, ForwardDist)); 5436 } else { 5437 assert((Rel == BO_LT || Rel == BO_LE || Rel == BO_GE || Rel == BO_GT) && 5438 "Expected one of these relational operators"); 5439 5440 // We can derive the direction from any other comparison operator. It is 5441 // non well-formed OpenMP if Step increments/decrements in the other 5442 // directions. Whether at least the first iteration passes the loop 5443 // condition. 5444 Expr *HasAnyIteration = AssertSuccess(Actions.BuildBinOp( 5445 nullptr, {}, Rel, BuildVarRef(NewStart), BuildVarRef(NewStop))); 5446 5447 // Compute the range between first and last counter value. 5448 Expr *Range; 5449 if (Rel == BO_GE || Rel == BO_GT) 5450 Range = AssertSuccess(Actions.BuildBinOp( 5451 nullptr, {}, BO_Sub, BuildVarRef(NewStart), BuildVarRef(NewStop))); 5452 else 5453 Range = AssertSuccess(Actions.BuildBinOp( 5454 nullptr, {}, BO_Sub, BuildVarRef(NewStop), BuildVarRef(NewStart))); 5455 5456 // Ensure unsigned range space. 5457 Range = 5458 AssertSuccess(Actions.BuildCStyleCastExpr({}, LogicalTSI, {}, Range)); 5459 5460 if (Rel == BO_LE || Rel == BO_GE) { 5461 // Add one to the range if the relational operator is inclusive. 5462 Range = 5463 AssertSuccess(Actions.BuildBinOp(nullptr, {}, BO_Add, Range, One)); 5464 } 5465 5466 // Divide by the absolute step amount. If the range is not a multiple of 5467 // the step size, rounding-up the effective upper bound ensures that the 5468 // last iteration is included. 5469 // Note that the rounding-up may cause an overflow in a temporry that 5470 // could be avoided, but would have occurred in a C-style for-loop as well. 5471 Expr *Divisor = BuildVarRef(NewStep); 5472 if (Rel == BO_GE || Rel == BO_GT) 5473 Divisor = 5474 AssertSuccess(Actions.BuildUnaryOp(nullptr, {}, UO_Minus, Divisor)); 5475 Expr *DivisorMinusOne = 5476 AssertSuccess(Actions.BuildBinOp(nullptr, {}, BO_Sub, Divisor, One)); 5477 Expr *RangeRoundUp = AssertSuccess( 5478 Actions.BuildBinOp(nullptr, {}, BO_Add, Range, DivisorMinusOne)); 5479 Dist = AssertSuccess( 5480 Actions.BuildBinOp(nullptr, {}, BO_Div, RangeRoundUp, Divisor)); 5481 5482 // If there is not at least one iteration, the range contains garbage. Fix 5483 // to zero in this case. 5484 Dist = AssertSuccess( 5485 Actions.ActOnConditionalOp({}, {}, HasAnyIteration, Dist, Zero)); 5486 } 5487 5488 // Assign the result to the out-parameter. 5489 Stmt *ResultAssign = AssertSuccess(Actions.BuildBinOp( 5490 Actions.getCurScope(), {}, BO_Assign, DistRef, Dist)); 5491 BodyStmts.push_back(ResultAssign); 5492 5493 Body = AssertSuccess(Actions.ActOnCompoundStmt({}, {}, BodyStmts, false)); 5494 } 5495 5496 return cast<CapturedStmt>( 5497 AssertSuccess(Actions.ActOnCapturedRegionEnd(Body))); 5498 } 5499 5500 /// Create a closure that computes the loop variable from the logical iteration 5501 /// number. 5502 /// 5503 /// \param Actions The Sema object. 5504 /// \param LoopVarTy Type for the loop variable used for result value. 5505 /// \param LogicalTy Type for the logical iteration number. 5506 /// \param StartExpr Value of the loop counter at the first iteration. 5507 /// \param Step Amount of increment after each iteration. 5508 /// \param Deref Whether the loop variable is a dereference of the loop 5509 /// counter variable. 5510 /// 5511 /// \return Closure (CapturedStmt) of the loop value calculation. 5512 static CapturedStmt *buildLoopVarFunc(Sema &Actions, QualType LoopVarTy, 5513 QualType LogicalTy, 5514 DeclRefExpr *StartExpr, Expr *Step, 5515 bool Deref) { 5516 ASTContext &Ctx = Actions.getASTContext(); 5517 5518 // Pass the result as an out-parameter. Passing as return value would require 5519 // the OpenMPIRBuilder to know additional C/C++ semantics, such as how to 5520 // invoke a copy constructor. 5521 QualType TargetParamTy = Ctx.getLValueReferenceType(LoopVarTy); 5522 Sema::CapturedParamNameType Params[] = {{"LoopVar", TargetParamTy}, 5523 {"Logical", LogicalTy}, 5524 {StringRef(), QualType()}}; 5525 Actions.ActOnCapturedRegionStart({}, nullptr, CR_Default, Params); 5526 5527 // Capture the initial iterator which represents the LoopVar value at the 5528 // zero's logical iteration. Since the original ForStmt/CXXForRangeStmt update 5529 // it in every iteration, capture it by value before it is modified. 5530 VarDecl *StartVar = cast<VarDecl>(StartExpr->getDecl()); 5531 bool Invalid = Actions.tryCaptureVariable(StartVar, {}, 5532 Sema::TryCapture_ExplicitByVal, {}); 5533 (void)Invalid; 5534 assert(!Invalid && "Expecting capture-by-value to work."); 5535 5536 Expr *Body; 5537 { 5538 Sema::CompoundScopeRAII CompoundScope(Actions); 5539 auto *CS = cast<CapturedDecl>(Actions.CurContext); 5540 5541 ImplicitParamDecl *TargetParam = CS->getParam(0); 5542 DeclRefExpr *TargetRef = Actions.BuildDeclRefExpr( 5543 TargetParam, LoopVarTy, VK_LValue, {}, nullptr, nullptr, {}, nullptr); 5544 ImplicitParamDecl *IndvarParam = CS->getParam(1); 5545 DeclRefExpr *LogicalRef = Actions.BuildDeclRefExpr( 5546 IndvarParam, LogicalTy, VK_LValue, {}, nullptr, nullptr, {}, nullptr); 5547 5548 // Capture the Start expression. 5549 CaptureVars Recap(Actions); 5550 Expr *NewStart = AssertSuccess(Recap.TransformExpr(StartExpr)); 5551 Expr *NewStep = AssertSuccess(Recap.TransformExpr(Step)); 5552 5553 Expr *Skip = AssertSuccess( 5554 Actions.BuildBinOp(nullptr, {}, BO_Mul, NewStep, LogicalRef)); 5555 // TODO: Explicitly cast to the iterator's difference_type instead of 5556 // relying on implicit conversion. 5557 Expr *Advanced = 5558 AssertSuccess(Actions.BuildBinOp(nullptr, {}, BO_Add, NewStart, Skip)); 5559 5560 if (Deref) { 5561 // For range-based for-loops convert the loop counter value to a concrete 5562 // loop variable value by dereferencing the iterator. 5563 Advanced = 5564 AssertSuccess(Actions.BuildUnaryOp(nullptr, {}, UO_Deref, Advanced)); 5565 } 5566 5567 // Assign the result to the output parameter. 5568 Body = AssertSuccess(Actions.BuildBinOp(Actions.getCurScope(), {}, 5569 BO_Assign, TargetRef, Advanced)); 5570 } 5571 return cast<CapturedStmt>( 5572 AssertSuccess(Actions.ActOnCapturedRegionEnd(Body))); 5573 } 5574 5575 StmtResult Sema::ActOnOpenMPCanonicalLoop(Stmt *AStmt) { 5576 ASTContext &Ctx = getASTContext(); 5577 5578 // Extract the common elements of ForStmt and CXXForRangeStmt: 5579 // Loop variable, repeat condition, increment 5580 Expr *Cond, *Inc; 5581 VarDecl *LIVDecl, *LUVDecl; 5582 if (auto *For = dyn_cast<ForStmt>(AStmt)) { 5583 Stmt *Init = For->getInit(); 5584 if (auto *LCVarDeclStmt = dyn_cast<DeclStmt>(Init)) { 5585 // For statement declares loop variable. 5586 LIVDecl = cast<VarDecl>(LCVarDeclStmt->getSingleDecl()); 5587 } else if (auto *LCAssign = dyn_cast<BinaryOperator>(Init)) { 5588 // For statement reuses variable. 5589 assert(LCAssign->getOpcode() == BO_Assign && 5590 "init part must be a loop variable assignment"); 5591 auto *CounterRef = cast<DeclRefExpr>(LCAssign->getLHS()); 5592 LIVDecl = cast<VarDecl>(CounterRef->getDecl()); 5593 } else 5594 llvm_unreachable("Cannot determine loop variable"); 5595 LUVDecl = LIVDecl; 5596 5597 Cond = For->getCond(); 5598 Inc = For->getInc(); 5599 } else if (auto *RangeFor = dyn_cast<CXXForRangeStmt>(AStmt)) { 5600 DeclStmt *BeginStmt = RangeFor->getBeginStmt(); 5601 LIVDecl = cast<VarDecl>(BeginStmt->getSingleDecl()); 5602 LUVDecl = RangeFor->getLoopVariable(); 5603 5604 Cond = RangeFor->getCond(); 5605 Inc = RangeFor->getInc(); 5606 } else 5607 llvm_unreachable("unhandled kind of loop"); 5608 5609 QualType CounterTy = LIVDecl->getType(); 5610 QualType LVTy = LUVDecl->getType(); 5611 5612 // Analyze the loop condition. 5613 Expr *LHS, *RHS; 5614 BinaryOperator::Opcode CondRel; 5615 Cond = Cond->IgnoreImplicit(); 5616 if (auto *CondBinExpr = dyn_cast<BinaryOperator>(Cond)) { 5617 LHS = CondBinExpr->getLHS(); 5618 RHS = CondBinExpr->getRHS(); 5619 CondRel = CondBinExpr->getOpcode(); 5620 } else if (auto *CondCXXOp = dyn_cast<CXXOperatorCallExpr>(Cond)) { 5621 assert(CondCXXOp->getNumArgs() == 2 && "Comparison should have 2 operands"); 5622 LHS = CondCXXOp->getArg(0); 5623 RHS = CondCXXOp->getArg(1); 5624 switch (CondCXXOp->getOperator()) { 5625 case OO_ExclaimEqual: 5626 CondRel = BO_NE; 5627 break; 5628 case OO_Less: 5629 CondRel = BO_LT; 5630 break; 5631 case OO_LessEqual: 5632 CondRel = BO_LE; 5633 break; 5634 case OO_Greater: 5635 CondRel = BO_GT; 5636 break; 5637 case OO_GreaterEqual: 5638 CondRel = BO_GE; 5639 break; 5640 default: 5641 llvm_unreachable("unexpected iterator operator"); 5642 } 5643 } else 5644 llvm_unreachable("unexpected loop condition"); 5645 5646 // Normalize such that the loop counter is on the LHS. 5647 if (!isa<DeclRefExpr>(LHS->IgnoreImplicit()) || 5648 cast<DeclRefExpr>(LHS->IgnoreImplicit())->getDecl() != LIVDecl) { 5649 std::swap(LHS, RHS); 5650 CondRel = BinaryOperator::reverseComparisonOp(CondRel); 5651 } 5652 auto *CounterRef = cast<DeclRefExpr>(LHS->IgnoreImplicit()); 5653 5654 // Decide the bit width for the logical iteration counter. By default use the 5655 // unsigned ptrdiff_t integer size (for iterators and pointers). 5656 // TODO: For iterators, use iterator::difference_type, 5657 // std::iterator_traits<>::difference_type or decltype(it - end). 5658 QualType LogicalTy = Ctx.getUnsignedPointerDiffType(); 5659 if (CounterTy->isIntegerType()) { 5660 unsigned BitWidth = Ctx.getIntWidth(CounterTy); 5661 LogicalTy = Ctx.getIntTypeForBitwidth(BitWidth, false); 5662 } 5663 5664 // Analyze the loop increment. 5665 Expr *Step; 5666 if (auto *IncUn = dyn_cast<UnaryOperator>(Inc)) { 5667 int Direction; 5668 switch (IncUn->getOpcode()) { 5669 case UO_PreInc: 5670 case UO_PostInc: 5671 Direction = 1; 5672 break; 5673 case UO_PreDec: 5674 case UO_PostDec: 5675 Direction = -1; 5676 break; 5677 default: 5678 llvm_unreachable("unhandled unary increment operator"); 5679 } 5680 Step = IntegerLiteral::Create( 5681 Ctx, llvm::APInt(Ctx.getIntWidth(LogicalTy), Direction), LogicalTy, {}); 5682 } else if (auto *IncBin = dyn_cast<BinaryOperator>(Inc)) { 5683 if (IncBin->getOpcode() == BO_AddAssign) { 5684 Step = IncBin->getRHS(); 5685 } else if (IncBin->getOpcode() == BO_SubAssign) { 5686 Step = 5687 AssertSuccess(BuildUnaryOp(nullptr, {}, UO_Minus, IncBin->getRHS())); 5688 } else 5689 llvm_unreachable("unhandled binary increment operator"); 5690 } else if (auto *CondCXXOp = dyn_cast<CXXOperatorCallExpr>(Inc)) { 5691 switch (CondCXXOp->getOperator()) { 5692 case OO_PlusPlus: 5693 Step = IntegerLiteral::Create( 5694 Ctx, llvm::APInt(Ctx.getIntWidth(LogicalTy), 1), LogicalTy, {}); 5695 break; 5696 case OO_MinusMinus: 5697 Step = IntegerLiteral::Create( 5698 Ctx, llvm::APInt(Ctx.getIntWidth(LogicalTy), -1), LogicalTy, {}); 5699 break; 5700 case OO_PlusEqual: 5701 Step = CondCXXOp->getArg(1); 5702 break; 5703 case OO_MinusEqual: 5704 Step = AssertSuccess( 5705 BuildUnaryOp(nullptr, {}, UO_Minus, CondCXXOp->getArg(1))); 5706 break; 5707 default: 5708 llvm_unreachable("unhandled overloaded increment operator"); 5709 } 5710 } else 5711 llvm_unreachable("unknown increment expression"); 5712 5713 CapturedStmt *DistanceFunc = 5714 buildDistanceFunc(*this, LogicalTy, CondRel, LHS, RHS, Step); 5715 CapturedStmt *LoopVarFunc = buildLoopVarFunc( 5716 *this, LVTy, LogicalTy, CounterRef, Step, isa<CXXForRangeStmt>(AStmt)); 5717 DeclRefExpr *LVRef = BuildDeclRefExpr(LUVDecl, LUVDecl->getType(), VK_LValue, 5718 {}, nullptr, nullptr, {}, nullptr); 5719 return OMPCanonicalLoop::create(getASTContext(), AStmt, DistanceFunc, 5720 LoopVarFunc, LVRef); 5721 } 5722 5723 StmtResult Sema::ActOnOpenMPLoopnest(Stmt *AStmt) { 5724 // Handle a literal loop. 5725 if (isa<ForStmt>(AStmt) || isa<CXXForRangeStmt>(AStmt)) 5726 return ActOnOpenMPCanonicalLoop(AStmt); 5727 5728 // If not a literal loop, it must be the result of a loop transformation. 5729 OMPExecutableDirective *LoopTransform = cast<OMPExecutableDirective>(AStmt); 5730 assert( 5731 isOpenMPLoopTransformationDirective(LoopTransform->getDirectiveKind()) && 5732 "Loop transformation directive expected"); 5733 return LoopTransform; 5734 } 5735 5736 static ExprResult buildUserDefinedMapperRef(Sema &SemaRef, Scope *S, 5737 CXXScopeSpec &MapperIdScopeSpec, 5738 const DeclarationNameInfo &MapperId, 5739 QualType Type, 5740 Expr *UnresolvedMapper); 5741 5742 /// Perform DFS through the structure/class data members trying to find 5743 /// member(s) with user-defined 'default' mapper and generate implicit map 5744 /// clauses for such members with the found 'default' mapper. 5745 static void 5746 processImplicitMapsWithDefaultMappers(Sema &S, DSAStackTy *Stack, 5747 SmallVectorImpl<OMPClause *> &Clauses) { 5748 // Check for the deault mapper for data members. 5749 if (S.getLangOpts().OpenMP < 50) 5750 return; 5751 SmallVector<OMPClause *, 4> ImplicitMaps; 5752 for (int Cnt = 0, EndCnt = Clauses.size(); Cnt < EndCnt; ++Cnt) { 5753 auto *C = dyn_cast<OMPMapClause>(Clauses[Cnt]); 5754 if (!C) 5755 continue; 5756 SmallVector<Expr *, 4> SubExprs; 5757 auto *MI = C->mapperlist_begin(); 5758 for (auto I = C->varlist_begin(), End = C->varlist_end(); I != End; 5759 ++I, ++MI) { 5760 // Expression is mapped using mapper - skip it. 5761 if (*MI) 5762 continue; 5763 Expr *E = *I; 5764 // Expression is dependent - skip it, build the mapper when it gets 5765 // instantiated. 5766 if (E->isTypeDependent() || E->isValueDependent() || 5767 E->containsUnexpandedParameterPack()) 5768 continue; 5769 // Array section - need to check for the mapping of the array section 5770 // element. 5771 QualType CanonType = E->getType().getCanonicalType(); 5772 if (CanonType->isSpecificBuiltinType(BuiltinType::OMPArraySection)) { 5773 const auto *OASE = cast<OMPArraySectionExpr>(E->IgnoreParenImpCasts()); 5774 QualType BaseType = 5775 OMPArraySectionExpr::getBaseOriginalType(OASE->getBase()); 5776 QualType ElemType; 5777 if (const auto *ATy = BaseType->getAsArrayTypeUnsafe()) 5778 ElemType = ATy->getElementType(); 5779 else 5780 ElemType = BaseType->getPointeeType(); 5781 CanonType = ElemType; 5782 } 5783 5784 // DFS over data members in structures/classes. 5785 SmallVector<std::pair<QualType, FieldDecl *>, 4> Types( 5786 1, {CanonType, nullptr}); 5787 llvm::DenseMap<const Type *, Expr *> Visited; 5788 SmallVector<std::pair<FieldDecl *, unsigned>, 4> ParentChain( 5789 1, {nullptr, 1}); 5790 while (!Types.empty()) { 5791 QualType BaseType; 5792 FieldDecl *CurFD; 5793 std::tie(BaseType, CurFD) = Types.pop_back_val(); 5794 while (ParentChain.back().second == 0) 5795 ParentChain.pop_back(); 5796 --ParentChain.back().second; 5797 if (BaseType.isNull()) 5798 continue; 5799 // Only structs/classes are allowed to have mappers. 5800 const RecordDecl *RD = BaseType.getCanonicalType()->getAsRecordDecl(); 5801 if (!RD) 5802 continue; 5803 auto It = Visited.find(BaseType.getTypePtr()); 5804 if (It == Visited.end()) { 5805 // Try to find the associated user-defined mapper. 5806 CXXScopeSpec MapperIdScopeSpec; 5807 DeclarationNameInfo DefaultMapperId; 5808 DefaultMapperId.setName(S.Context.DeclarationNames.getIdentifier( 5809 &S.Context.Idents.get("default"))); 5810 DefaultMapperId.setLoc(E->getExprLoc()); 5811 ExprResult ER = buildUserDefinedMapperRef( 5812 S, Stack->getCurScope(), MapperIdScopeSpec, DefaultMapperId, 5813 BaseType, /*UnresolvedMapper=*/nullptr); 5814 if (ER.isInvalid()) 5815 continue; 5816 It = Visited.try_emplace(BaseType.getTypePtr(), ER.get()).first; 5817 } 5818 // Found default mapper. 5819 if (It->second) { 5820 auto *OE = new (S.Context) OpaqueValueExpr(E->getExprLoc(), CanonType, 5821 VK_LValue, OK_Ordinary, E); 5822 OE->setIsUnique(/*V=*/true); 5823 Expr *BaseExpr = OE; 5824 for (const auto &P : ParentChain) { 5825 if (P.first) { 5826 BaseExpr = S.BuildMemberExpr( 5827 BaseExpr, /*IsArrow=*/false, E->getExprLoc(), 5828 NestedNameSpecifierLoc(), SourceLocation(), P.first, 5829 DeclAccessPair::make(P.first, P.first->getAccess()), 5830 /*HadMultipleCandidates=*/false, DeclarationNameInfo(), 5831 P.first->getType(), VK_LValue, OK_Ordinary); 5832 BaseExpr = S.DefaultLvalueConversion(BaseExpr).get(); 5833 } 5834 } 5835 if (CurFD) 5836 BaseExpr = S.BuildMemberExpr( 5837 BaseExpr, /*IsArrow=*/false, E->getExprLoc(), 5838 NestedNameSpecifierLoc(), SourceLocation(), CurFD, 5839 DeclAccessPair::make(CurFD, CurFD->getAccess()), 5840 /*HadMultipleCandidates=*/false, DeclarationNameInfo(), 5841 CurFD->getType(), VK_LValue, OK_Ordinary); 5842 SubExprs.push_back(BaseExpr); 5843 continue; 5844 } 5845 // Check for the "default" mapper for data members. 5846 bool FirstIter = true; 5847 for (FieldDecl *FD : RD->fields()) { 5848 if (!FD) 5849 continue; 5850 QualType FieldTy = FD->getType(); 5851 if (FieldTy.isNull() || 5852 !(FieldTy->isStructureOrClassType() || FieldTy->isUnionType())) 5853 continue; 5854 if (FirstIter) { 5855 FirstIter = false; 5856 ParentChain.emplace_back(CurFD, 1); 5857 } else { 5858 ++ParentChain.back().second; 5859 } 5860 Types.emplace_back(FieldTy, FD); 5861 } 5862 } 5863 } 5864 if (SubExprs.empty()) 5865 continue; 5866 CXXScopeSpec MapperIdScopeSpec; 5867 DeclarationNameInfo MapperId; 5868 if (OMPClause *NewClause = S.ActOnOpenMPMapClause( 5869 C->getMapTypeModifiers(), C->getMapTypeModifiersLoc(), 5870 MapperIdScopeSpec, MapperId, C->getMapType(), 5871 /*IsMapTypeImplicit=*/true, SourceLocation(), SourceLocation(), 5872 SubExprs, OMPVarListLocTy())) 5873 Clauses.push_back(NewClause); 5874 } 5875 } 5876 5877 StmtResult Sema::ActOnOpenMPExecutableDirective( 5878 OpenMPDirectiveKind Kind, const DeclarationNameInfo &DirName, 5879 OpenMPDirectiveKind CancelRegion, ArrayRef<OMPClause *> Clauses, 5880 Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc) { 5881 StmtResult Res = StmtError(); 5882 OpenMPBindClauseKind BindKind = OMPC_BIND_unknown; 5883 if (const OMPBindClause *BC = 5884 OMPExecutableDirective::getSingleClause<OMPBindClause>(Clauses)) 5885 BindKind = BC->getBindKind(); 5886 // First check CancelRegion which is then used in checkNestingOfRegions. 5887 if (checkCancelRegion(*this, Kind, CancelRegion, StartLoc) || 5888 checkNestingOfRegions(*this, DSAStack, Kind, DirName, CancelRegion, 5889 BindKind, StartLoc)) 5890 return StmtError(); 5891 5892 llvm::SmallVector<OMPClause *, 8> ClausesWithImplicit; 5893 VarsWithInheritedDSAType VarsWithInheritedDSA; 5894 bool ErrorFound = false; 5895 ClausesWithImplicit.append(Clauses.begin(), Clauses.end()); 5896 if (AStmt && !CurContext->isDependentContext() && Kind != OMPD_atomic && 5897 Kind != OMPD_critical && Kind != OMPD_section && Kind != OMPD_master && 5898 Kind != OMPD_masked && !isOpenMPLoopTransformationDirective(Kind)) { 5899 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 5900 5901 // Check default data sharing attributes for referenced variables. 5902 DSAAttrChecker DSAChecker(DSAStack, *this, cast<CapturedStmt>(AStmt)); 5903 int ThisCaptureLevel = getOpenMPCaptureLevels(Kind); 5904 Stmt *S = AStmt; 5905 while (--ThisCaptureLevel >= 0) 5906 S = cast<CapturedStmt>(S)->getCapturedStmt(); 5907 DSAChecker.Visit(S); 5908 if (!isOpenMPTargetDataManagementDirective(Kind) && 5909 !isOpenMPTaskingDirective(Kind)) { 5910 // Visit subcaptures to generate implicit clauses for captured vars. 5911 auto *CS = cast<CapturedStmt>(AStmt); 5912 SmallVector<OpenMPDirectiveKind, 4> CaptureRegions; 5913 getOpenMPCaptureRegions(CaptureRegions, Kind); 5914 // Ignore outer tasking regions for target directives. 5915 if (CaptureRegions.size() > 1 && CaptureRegions.front() == OMPD_task) 5916 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 5917 DSAChecker.visitSubCaptures(CS); 5918 } 5919 if (DSAChecker.isErrorFound()) 5920 return StmtError(); 5921 // Generate list of implicitly defined firstprivate variables. 5922 VarsWithInheritedDSA = DSAChecker.getVarsWithInheritedDSA(); 5923 5924 SmallVector<Expr *, 4> ImplicitFirstprivates( 5925 DSAChecker.getImplicitFirstprivate().begin(), 5926 DSAChecker.getImplicitFirstprivate().end()); 5927 SmallVector<Expr *, 4> ImplicitPrivates( 5928 DSAChecker.getImplicitPrivate().begin(), 5929 DSAChecker.getImplicitPrivate().end()); 5930 const unsigned DefaultmapKindNum = OMPC_DEFAULTMAP_pointer + 1; 5931 SmallVector<Expr *, 4> ImplicitMaps[DefaultmapKindNum][OMPC_MAP_delete]; 5932 SmallVector<OpenMPMapModifierKind, NumberOfOMPMapClauseModifiers> 5933 ImplicitMapModifiers[DefaultmapKindNum]; 5934 SmallVector<SourceLocation, NumberOfOMPMapClauseModifiers> 5935 ImplicitMapModifiersLoc[DefaultmapKindNum]; 5936 // Get the original location of present modifier from Defaultmap clause. 5937 SourceLocation PresentModifierLocs[DefaultmapKindNum]; 5938 for (OMPClause *C : Clauses) { 5939 if (auto *DMC = dyn_cast<OMPDefaultmapClause>(C)) 5940 if (DMC->getDefaultmapModifier() == OMPC_DEFAULTMAP_MODIFIER_present) 5941 PresentModifierLocs[DMC->getDefaultmapKind()] = 5942 DMC->getDefaultmapModifierLoc(); 5943 } 5944 for (unsigned VC = 0; VC < DefaultmapKindNum; ++VC) { 5945 auto Kind = static_cast<OpenMPDefaultmapClauseKind>(VC); 5946 for (unsigned I = 0; I < OMPC_MAP_delete; ++I) { 5947 ArrayRef<Expr *> ImplicitMap = DSAChecker.getImplicitMap( 5948 Kind, static_cast<OpenMPMapClauseKind>(I)); 5949 ImplicitMaps[VC][I].append(ImplicitMap.begin(), ImplicitMap.end()); 5950 } 5951 ArrayRef<OpenMPMapModifierKind> ImplicitModifier = 5952 DSAChecker.getImplicitMapModifier(Kind); 5953 ImplicitMapModifiers[VC].append(ImplicitModifier.begin(), 5954 ImplicitModifier.end()); 5955 std::fill_n(std::back_inserter(ImplicitMapModifiersLoc[VC]), 5956 ImplicitModifier.size(), PresentModifierLocs[VC]); 5957 } 5958 // Mark taskgroup task_reduction descriptors as implicitly firstprivate. 5959 for (OMPClause *C : Clauses) { 5960 if (auto *IRC = dyn_cast<OMPInReductionClause>(C)) { 5961 for (Expr *E : IRC->taskgroup_descriptors()) 5962 if (E) 5963 ImplicitFirstprivates.emplace_back(E); 5964 } 5965 // OpenMP 5.0, 2.10.1 task Construct 5966 // [detach clause]... The event-handle will be considered as if it was 5967 // specified on a firstprivate clause. 5968 if (auto *DC = dyn_cast<OMPDetachClause>(C)) 5969 ImplicitFirstprivates.push_back(DC->getEventHandler()); 5970 } 5971 if (!ImplicitFirstprivates.empty()) { 5972 if (OMPClause *Implicit = ActOnOpenMPFirstprivateClause( 5973 ImplicitFirstprivates, SourceLocation(), SourceLocation(), 5974 SourceLocation())) { 5975 ClausesWithImplicit.push_back(Implicit); 5976 ErrorFound = cast<OMPFirstprivateClause>(Implicit)->varlist_size() != 5977 ImplicitFirstprivates.size(); 5978 } else { 5979 ErrorFound = true; 5980 } 5981 } 5982 if (!ImplicitPrivates.empty()) { 5983 if (OMPClause *Implicit = 5984 ActOnOpenMPPrivateClause(ImplicitPrivates, SourceLocation(), 5985 SourceLocation(), SourceLocation())) { 5986 ClausesWithImplicit.push_back(Implicit); 5987 ErrorFound = cast<OMPPrivateClause>(Implicit)->varlist_size() != 5988 ImplicitPrivates.size(); 5989 } else { 5990 ErrorFound = true; 5991 } 5992 } 5993 // OpenMP 5.0 [2.19.7] 5994 // If a list item appears in a reduction, lastprivate or linear 5995 // clause on a combined target construct then it is treated as 5996 // if it also appears in a map clause with a map-type of tofrom 5997 if (getLangOpts().OpenMP >= 50 && Kind != OMPD_target && 5998 isOpenMPTargetExecutionDirective(Kind)) { 5999 SmallVector<Expr *, 4> ImplicitExprs; 6000 for (OMPClause *C : Clauses) { 6001 if (auto *RC = dyn_cast<OMPReductionClause>(C)) 6002 for (Expr *E : RC->varlists()) 6003 if (!isa<DeclRefExpr>(E->IgnoreParenImpCasts())) 6004 ImplicitExprs.emplace_back(E); 6005 } 6006 if (!ImplicitExprs.empty()) { 6007 ArrayRef<Expr *> Exprs = ImplicitExprs; 6008 CXXScopeSpec MapperIdScopeSpec; 6009 DeclarationNameInfo MapperId; 6010 if (OMPClause *Implicit = ActOnOpenMPMapClause( 6011 OMPC_MAP_MODIFIER_unknown, SourceLocation(), MapperIdScopeSpec, 6012 MapperId, OMPC_MAP_tofrom, 6013 /*IsMapTypeImplicit=*/true, SourceLocation(), SourceLocation(), 6014 Exprs, OMPVarListLocTy(), /*NoDiagnose=*/true)) 6015 ClausesWithImplicit.emplace_back(Implicit); 6016 } 6017 } 6018 for (unsigned I = 0, E = DefaultmapKindNum; I < E; ++I) { 6019 int ClauseKindCnt = -1; 6020 for (ArrayRef<Expr *> ImplicitMap : ImplicitMaps[I]) { 6021 ++ClauseKindCnt; 6022 if (ImplicitMap.empty()) 6023 continue; 6024 CXXScopeSpec MapperIdScopeSpec; 6025 DeclarationNameInfo MapperId; 6026 auto Kind = static_cast<OpenMPMapClauseKind>(ClauseKindCnt); 6027 if (OMPClause *Implicit = ActOnOpenMPMapClause( 6028 ImplicitMapModifiers[I], ImplicitMapModifiersLoc[I], 6029 MapperIdScopeSpec, MapperId, Kind, /*IsMapTypeImplicit=*/true, 6030 SourceLocation(), SourceLocation(), ImplicitMap, 6031 OMPVarListLocTy())) { 6032 ClausesWithImplicit.emplace_back(Implicit); 6033 ErrorFound |= cast<OMPMapClause>(Implicit)->varlist_size() != 6034 ImplicitMap.size(); 6035 } else { 6036 ErrorFound = true; 6037 } 6038 } 6039 } 6040 // Build expressions for implicit maps of data members with 'default' 6041 // mappers. 6042 if (LangOpts.OpenMP >= 50) 6043 processImplicitMapsWithDefaultMappers(*this, DSAStack, 6044 ClausesWithImplicit); 6045 } 6046 6047 llvm::SmallVector<OpenMPDirectiveKind, 4> AllowedNameModifiers; 6048 switch (Kind) { 6049 case OMPD_parallel: 6050 Res = ActOnOpenMPParallelDirective(ClausesWithImplicit, AStmt, StartLoc, 6051 EndLoc); 6052 AllowedNameModifiers.push_back(OMPD_parallel); 6053 break; 6054 case OMPD_simd: 6055 Res = ActOnOpenMPSimdDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc, 6056 VarsWithInheritedDSA); 6057 if (LangOpts.OpenMP >= 50) 6058 AllowedNameModifiers.push_back(OMPD_simd); 6059 break; 6060 case OMPD_tile: 6061 Res = 6062 ActOnOpenMPTileDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc); 6063 break; 6064 case OMPD_unroll: 6065 Res = ActOnOpenMPUnrollDirective(ClausesWithImplicit, AStmt, StartLoc, 6066 EndLoc); 6067 break; 6068 case OMPD_for: 6069 Res = ActOnOpenMPForDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc, 6070 VarsWithInheritedDSA); 6071 break; 6072 case OMPD_for_simd: 6073 Res = ActOnOpenMPForSimdDirective(ClausesWithImplicit, AStmt, StartLoc, 6074 EndLoc, VarsWithInheritedDSA); 6075 if (LangOpts.OpenMP >= 50) 6076 AllowedNameModifiers.push_back(OMPD_simd); 6077 break; 6078 case OMPD_sections: 6079 Res = ActOnOpenMPSectionsDirective(ClausesWithImplicit, AStmt, StartLoc, 6080 EndLoc); 6081 break; 6082 case OMPD_section: 6083 assert(ClausesWithImplicit.empty() && 6084 "No clauses are allowed for 'omp section' directive"); 6085 Res = ActOnOpenMPSectionDirective(AStmt, StartLoc, EndLoc); 6086 break; 6087 case OMPD_single: 6088 Res = ActOnOpenMPSingleDirective(ClausesWithImplicit, AStmt, StartLoc, 6089 EndLoc); 6090 break; 6091 case OMPD_master: 6092 assert(ClausesWithImplicit.empty() && 6093 "No clauses are allowed for 'omp master' directive"); 6094 Res = ActOnOpenMPMasterDirective(AStmt, StartLoc, EndLoc); 6095 break; 6096 case OMPD_masked: 6097 Res = ActOnOpenMPMaskedDirective(ClausesWithImplicit, AStmt, StartLoc, 6098 EndLoc); 6099 break; 6100 case OMPD_critical: 6101 Res = ActOnOpenMPCriticalDirective(DirName, ClausesWithImplicit, AStmt, 6102 StartLoc, EndLoc); 6103 break; 6104 case OMPD_parallel_for: 6105 Res = ActOnOpenMPParallelForDirective(ClausesWithImplicit, AStmt, StartLoc, 6106 EndLoc, VarsWithInheritedDSA); 6107 AllowedNameModifiers.push_back(OMPD_parallel); 6108 break; 6109 case OMPD_parallel_for_simd: 6110 Res = ActOnOpenMPParallelForSimdDirective( 6111 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 6112 AllowedNameModifiers.push_back(OMPD_parallel); 6113 if (LangOpts.OpenMP >= 50) 6114 AllowedNameModifiers.push_back(OMPD_simd); 6115 break; 6116 case OMPD_parallel_master: 6117 Res = ActOnOpenMPParallelMasterDirective(ClausesWithImplicit, AStmt, 6118 StartLoc, EndLoc); 6119 AllowedNameModifiers.push_back(OMPD_parallel); 6120 break; 6121 case OMPD_parallel_masked: 6122 Res = ActOnOpenMPParallelMaskedDirective(ClausesWithImplicit, AStmt, 6123 StartLoc, EndLoc); 6124 AllowedNameModifiers.push_back(OMPD_parallel); 6125 break; 6126 case OMPD_parallel_sections: 6127 Res = ActOnOpenMPParallelSectionsDirective(ClausesWithImplicit, AStmt, 6128 StartLoc, EndLoc); 6129 AllowedNameModifiers.push_back(OMPD_parallel); 6130 break; 6131 case OMPD_task: 6132 Res = 6133 ActOnOpenMPTaskDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc); 6134 AllowedNameModifiers.push_back(OMPD_task); 6135 break; 6136 case OMPD_taskyield: 6137 assert(ClausesWithImplicit.empty() && 6138 "No clauses are allowed for 'omp taskyield' directive"); 6139 assert(AStmt == nullptr && 6140 "No associated statement allowed for 'omp taskyield' directive"); 6141 Res = ActOnOpenMPTaskyieldDirective(StartLoc, EndLoc); 6142 break; 6143 case OMPD_barrier: 6144 assert(ClausesWithImplicit.empty() && 6145 "No clauses are allowed for 'omp barrier' directive"); 6146 assert(AStmt == nullptr && 6147 "No associated statement allowed for 'omp barrier' directive"); 6148 Res = ActOnOpenMPBarrierDirective(StartLoc, EndLoc); 6149 break; 6150 case OMPD_taskwait: 6151 assert(AStmt == nullptr && 6152 "No associated statement allowed for 'omp taskwait' directive"); 6153 Res = ActOnOpenMPTaskwaitDirective(ClausesWithImplicit, StartLoc, EndLoc); 6154 break; 6155 case OMPD_taskgroup: 6156 Res = ActOnOpenMPTaskgroupDirective(ClausesWithImplicit, AStmt, StartLoc, 6157 EndLoc); 6158 break; 6159 case OMPD_flush: 6160 assert(AStmt == nullptr && 6161 "No associated statement allowed for 'omp flush' directive"); 6162 Res = ActOnOpenMPFlushDirective(ClausesWithImplicit, StartLoc, EndLoc); 6163 break; 6164 case OMPD_depobj: 6165 assert(AStmt == nullptr && 6166 "No associated statement allowed for 'omp depobj' directive"); 6167 Res = ActOnOpenMPDepobjDirective(ClausesWithImplicit, StartLoc, EndLoc); 6168 break; 6169 case OMPD_scan: 6170 assert(AStmt == nullptr && 6171 "No associated statement allowed for 'omp scan' directive"); 6172 Res = ActOnOpenMPScanDirective(ClausesWithImplicit, StartLoc, EndLoc); 6173 break; 6174 case OMPD_ordered: 6175 Res = ActOnOpenMPOrderedDirective(ClausesWithImplicit, AStmt, StartLoc, 6176 EndLoc); 6177 break; 6178 case OMPD_atomic: 6179 Res = ActOnOpenMPAtomicDirective(ClausesWithImplicit, AStmt, StartLoc, 6180 EndLoc); 6181 break; 6182 case OMPD_teams: 6183 Res = 6184 ActOnOpenMPTeamsDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc); 6185 break; 6186 case OMPD_target: 6187 Res = ActOnOpenMPTargetDirective(ClausesWithImplicit, AStmt, StartLoc, 6188 EndLoc); 6189 AllowedNameModifiers.push_back(OMPD_target); 6190 break; 6191 case OMPD_target_parallel: 6192 Res = ActOnOpenMPTargetParallelDirective(ClausesWithImplicit, AStmt, 6193 StartLoc, EndLoc); 6194 AllowedNameModifiers.push_back(OMPD_target); 6195 AllowedNameModifiers.push_back(OMPD_parallel); 6196 break; 6197 case OMPD_target_parallel_for: 6198 Res = ActOnOpenMPTargetParallelForDirective( 6199 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 6200 AllowedNameModifiers.push_back(OMPD_target); 6201 AllowedNameModifiers.push_back(OMPD_parallel); 6202 break; 6203 case OMPD_cancellation_point: 6204 assert(ClausesWithImplicit.empty() && 6205 "No clauses are allowed for 'omp cancellation point' directive"); 6206 assert(AStmt == nullptr && "No associated statement allowed for 'omp " 6207 "cancellation point' directive"); 6208 Res = ActOnOpenMPCancellationPointDirective(StartLoc, EndLoc, CancelRegion); 6209 break; 6210 case OMPD_cancel: 6211 assert(AStmt == nullptr && 6212 "No associated statement allowed for 'omp cancel' directive"); 6213 Res = ActOnOpenMPCancelDirective(ClausesWithImplicit, StartLoc, EndLoc, 6214 CancelRegion); 6215 AllowedNameModifiers.push_back(OMPD_cancel); 6216 break; 6217 case OMPD_target_data: 6218 Res = ActOnOpenMPTargetDataDirective(ClausesWithImplicit, AStmt, StartLoc, 6219 EndLoc); 6220 AllowedNameModifiers.push_back(OMPD_target_data); 6221 break; 6222 case OMPD_target_enter_data: 6223 Res = ActOnOpenMPTargetEnterDataDirective(ClausesWithImplicit, StartLoc, 6224 EndLoc, AStmt); 6225 AllowedNameModifiers.push_back(OMPD_target_enter_data); 6226 break; 6227 case OMPD_target_exit_data: 6228 Res = ActOnOpenMPTargetExitDataDirective(ClausesWithImplicit, StartLoc, 6229 EndLoc, AStmt); 6230 AllowedNameModifiers.push_back(OMPD_target_exit_data); 6231 break; 6232 case OMPD_taskloop: 6233 Res = ActOnOpenMPTaskLoopDirective(ClausesWithImplicit, AStmt, StartLoc, 6234 EndLoc, VarsWithInheritedDSA); 6235 AllowedNameModifiers.push_back(OMPD_taskloop); 6236 break; 6237 case OMPD_taskloop_simd: 6238 Res = ActOnOpenMPTaskLoopSimdDirective(ClausesWithImplicit, AStmt, StartLoc, 6239 EndLoc, VarsWithInheritedDSA); 6240 AllowedNameModifiers.push_back(OMPD_taskloop); 6241 if (LangOpts.OpenMP >= 50) 6242 AllowedNameModifiers.push_back(OMPD_simd); 6243 break; 6244 case OMPD_master_taskloop: 6245 Res = ActOnOpenMPMasterTaskLoopDirective( 6246 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 6247 AllowedNameModifiers.push_back(OMPD_taskloop); 6248 break; 6249 case OMPD_master_taskloop_simd: 6250 Res = ActOnOpenMPMasterTaskLoopSimdDirective( 6251 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 6252 AllowedNameModifiers.push_back(OMPD_taskloop); 6253 if (LangOpts.OpenMP >= 50) 6254 AllowedNameModifiers.push_back(OMPD_simd); 6255 break; 6256 case OMPD_parallel_master_taskloop: 6257 Res = ActOnOpenMPParallelMasterTaskLoopDirective( 6258 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 6259 AllowedNameModifiers.push_back(OMPD_taskloop); 6260 AllowedNameModifiers.push_back(OMPD_parallel); 6261 break; 6262 case OMPD_parallel_master_taskloop_simd: 6263 Res = ActOnOpenMPParallelMasterTaskLoopSimdDirective( 6264 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 6265 AllowedNameModifiers.push_back(OMPD_taskloop); 6266 AllowedNameModifiers.push_back(OMPD_parallel); 6267 if (LangOpts.OpenMP >= 50) 6268 AllowedNameModifiers.push_back(OMPD_simd); 6269 break; 6270 case OMPD_distribute: 6271 Res = ActOnOpenMPDistributeDirective(ClausesWithImplicit, AStmt, StartLoc, 6272 EndLoc, VarsWithInheritedDSA); 6273 break; 6274 case OMPD_target_update: 6275 Res = ActOnOpenMPTargetUpdateDirective(ClausesWithImplicit, StartLoc, 6276 EndLoc, AStmt); 6277 AllowedNameModifiers.push_back(OMPD_target_update); 6278 break; 6279 case OMPD_distribute_parallel_for: 6280 Res = ActOnOpenMPDistributeParallelForDirective( 6281 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 6282 AllowedNameModifiers.push_back(OMPD_parallel); 6283 break; 6284 case OMPD_distribute_parallel_for_simd: 6285 Res = ActOnOpenMPDistributeParallelForSimdDirective( 6286 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 6287 AllowedNameModifiers.push_back(OMPD_parallel); 6288 if (LangOpts.OpenMP >= 50) 6289 AllowedNameModifiers.push_back(OMPD_simd); 6290 break; 6291 case OMPD_distribute_simd: 6292 Res = ActOnOpenMPDistributeSimdDirective( 6293 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 6294 if (LangOpts.OpenMP >= 50) 6295 AllowedNameModifiers.push_back(OMPD_simd); 6296 break; 6297 case OMPD_target_parallel_for_simd: 6298 Res = ActOnOpenMPTargetParallelForSimdDirective( 6299 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 6300 AllowedNameModifiers.push_back(OMPD_target); 6301 AllowedNameModifiers.push_back(OMPD_parallel); 6302 if (LangOpts.OpenMP >= 50) 6303 AllowedNameModifiers.push_back(OMPD_simd); 6304 break; 6305 case OMPD_target_simd: 6306 Res = ActOnOpenMPTargetSimdDirective(ClausesWithImplicit, AStmt, StartLoc, 6307 EndLoc, VarsWithInheritedDSA); 6308 AllowedNameModifiers.push_back(OMPD_target); 6309 if (LangOpts.OpenMP >= 50) 6310 AllowedNameModifiers.push_back(OMPD_simd); 6311 break; 6312 case OMPD_teams_distribute: 6313 Res = ActOnOpenMPTeamsDistributeDirective( 6314 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 6315 break; 6316 case OMPD_teams_distribute_simd: 6317 Res = ActOnOpenMPTeamsDistributeSimdDirective( 6318 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 6319 if (LangOpts.OpenMP >= 50) 6320 AllowedNameModifiers.push_back(OMPD_simd); 6321 break; 6322 case OMPD_teams_distribute_parallel_for_simd: 6323 Res = ActOnOpenMPTeamsDistributeParallelForSimdDirective( 6324 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 6325 AllowedNameModifiers.push_back(OMPD_parallel); 6326 if (LangOpts.OpenMP >= 50) 6327 AllowedNameModifiers.push_back(OMPD_simd); 6328 break; 6329 case OMPD_teams_distribute_parallel_for: 6330 Res = ActOnOpenMPTeamsDistributeParallelForDirective( 6331 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 6332 AllowedNameModifiers.push_back(OMPD_parallel); 6333 break; 6334 case OMPD_target_teams: 6335 Res = ActOnOpenMPTargetTeamsDirective(ClausesWithImplicit, AStmt, StartLoc, 6336 EndLoc); 6337 AllowedNameModifiers.push_back(OMPD_target); 6338 break; 6339 case OMPD_target_teams_distribute: 6340 Res = ActOnOpenMPTargetTeamsDistributeDirective( 6341 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 6342 AllowedNameModifiers.push_back(OMPD_target); 6343 break; 6344 case OMPD_target_teams_distribute_parallel_for: 6345 Res = ActOnOpenMPTargetTeamsDistributeParallelForDirective( 6346 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 6347 AllowedNameModifiers.push_back(OMPD_target); 6348 AllowedNameModifiers.push_back(OMPD_parallel); 6349 break; 6350 case OMPD_target_teams_distribute_parallel_for_simd: 6351 Res = ActOnOpenMPTargetTeamsDistributeParallelForSimdDirective( 6352 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 6353 AllowedNameModifiers.push_back(OMPD_target); 6354 AllowedNameModifiers.push_back(OMPD_parallel); 6355 if (LangOpts.OpenMP >= 50) 6356 AllowedNameModifiers.push_back(OMPD_simd); 6357 break; 6358 case OMPD_target_teams_distribute_simd: 6359 Res = ActOnOpenMPTargetTeamsDistributeSimdDirective( 6360 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 6361 AllowedNameModifiers.push_back(OMPD_target); 6362 if (LangOpts.OpenMP >= 50) 6363 AllowedNameModifiers.push_back(OMPD_simd); 6364 break; 6365 case OMPD_interop: 6366 assert(AStmt == nullptr && 6367 "No associated statement allowed for 'omp interop' directive"); 6368 Res = ActOnOpenMPInteropDirective(ClausesWithImplicit, StartLoc, EndLoc); 6369 break; 6370 case OMPD_dispatch: 6371 Res = ActOnOpenMPDispatchDirective(ClausesWithImplicit, AStmt, StartLoc, 6372 EndLoc); 6373 break; 6374 case OMPD_loop: 6375 Res = ActOnOpenMPGenericLoopDirective(ClausesWithImplicit, AStmt, StartLoc, 6376 EndLoc, VarsWithInheritedDSA); 6377 break; 6378 case OMPD_teams_loop: 6379 Res = ActOnOpenMPTeamsGenericLoopDirective( 6380 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 6381 break; 6382 case OMPD_target_teams_loop: 6383 Res = ActOnOpenMPTargetTeamsGenericLoopDirective( 6384 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 6385 break; 6386 case OMPD_parallel_loop: 6387 Res = ActOnOpenMPParallelGenericLoopDirective( 6388 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 6389 break; 6390 case OMPD_target_parallel_loop: 6391 Res = ActOnOpenMPTargetParallelGenericLoopDirective( 6392 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 6393 break; 6394 case OMPD_declare_target: 6395 case OMPD_end_declare_target: 6396 case OMPD_threadprivate: 6397 case OMPD_allocate: 6398 case OMPD_declare_reduction: 6399 case OMPD_declare_mapper: 6400 case OMPD_declare_simd: 6401 case OMPD_requires: 6402 case OMPD_declare_variant: 6403 case OMPD_begin_declare_variant: 6404 case OMPD_end_declare_variant: 6405 llvm_unreachable("OpenMP Directive is not allowed"); 6406 case OMPD_unknown: 6407 default: 6408 llvm_unreachable("Unknown OpenMP directive"); 6409 } 6410 6411 ErrorFound = Res.isInvalid() || ErrorFound; 6412 6413 // Check variables in the clauses if default(none) or 6414 // default(firstprivate) was specified. 6415 if (DSAStack->getDefaultDSA() == DSA_none || 6416 DSAStack->getDefaultDSA() == DSA_private || 6417 DSAStack->getDefaultDSA() == DSA_firstprivate) { 6418 DSAAttrChecker DSAChecker(DSAStack, *this, nullptr); 6419 for (OMPClause *C : Clauses) { 6420 switch (C->getClauseKind()) { 6421 case OMPC_num_threads: 6422 case OMPC_dist_schedule: 6423 // Do not analyse if no parent teams directive. 6424 if (isOpenMPTeamsDirective(Kind)) 6425 break; 6426 continue; 6427 case OMPC_if: 6428 if (isOpenMPTeamsDirective(Kind) && 6429 cast<OMPIfClause>(C)->getNameModifier() != OMPD_target) 6430 break; 6431 if (isOpenMPParallelDirective(Kind) && 6432 isOpenMPTaskLoopDirective(Kind) && 6433 cast<OMPIfClause>(C)->getNameModifier() != OMPD_parallel) 6434 break; 6435 continue; 6436 case OMPC_schedule: 6437 case OMPC_detach: 6438 break; 6439 case OMPC_grainsize: 6440 case OMPC_num_tasks: 6441 case OMPC_final: 6442 case OMPC_priority: 6443 case OMPC_novariants: 6444 case OMPC_nocontext: 6445 // Do not analyze if no parent parallel directive. 6446 if (isOpenMPParallelDirective(Kind)) 6447 break; 6448 continue; 6449 case OMPC_ordered: 6450 case OMPC_device: 6451 case OMPC_num_teams: 6452 case OMPC_thread_limit: 6453 case OMPC_hint: 6454 case OMPC_collapse: 6455 case OMPC_safelen: 6456 case OMPC_simdlen: 6457 case OMPC_sizes: 6458 case OMPC_default: 6459 case OMPC_proc_bind: 6460 case OMPC_private: 6461 case OMPC_firstprivate: 6462 case OMPC_lastprivate: 6463 case OMPC_shared: 6464 case OMPC_reduction: 6465 case OMPC_task_reduction: 6466 case OMPC_in_reduction: 6467 case OMPC_linear: 6468 case OMPC_aligned: 6469 case OMPC_copyin: 6470 case OMPC_copyprivate: 6471 case OMPC_nowait: 6472 case OMPC_untied: 6473 case OMPC_mergeable: 6474 case OMPC_allocate: 6475 case OMPC_read: 6476 case OMPC_write: 6477 case OMPC_update: 6478 case OMPC_capture: 6479 case OMPC_compare: 6480 case OMPC_seq_cst: 6481 case OMPC_acq_rel: 6482 case OMPC_acquire: 6483 case OMPC_release: 6484 case OMPC_relaxed: 6485 case OMPC_depend: 6486 case OMPC_threads: 6487 case OMPC_simd: 6488 case OMPC_map: 6489 case OMPC_nogroup: 6490 case OMPC_defaultmap: 6491 case OMPC_to: 6492 case OMPC_from: 6493 case OMPC_use_device_ptr: 6494 case OMPC_use_device_addr: 6495 case OMPC_is_device_ptr: 6496 case OMPC_has_device_addr: 6497 case OMPC_nontemporal: 6498 case OMPC_order: 6499 case OMPC_destroy: 6500 case OMPC_inclusive: 6501 case OMPC_exclusive: 6502 case OMPC_uses_allocators: 6503 case OMPC_affinity: 6504 case OMPC_bind: 6505 case OMPC_filter: 6506 continue; 6507 case OMPC_allocator: 6508 case OMPC_flush: 6509 case OMPC_depobj: 6510 case OMPC_threadprivate: 6511 case OMPC_uniform: 6512 case OMPC_unknown: 6513 case OMPC_unified_address: 6514 case OMPC_unified_shared_memory: 6515 case OMPC_reverse_offload: 6516 case OMPC_dynamic_allocators: 6517 case OMPC_atomic_default_mem_order: 6518 case OMPC_device_type: 6519 case OMPC_match: 6520 case OMPC_when: 6521 default: 6522 llvm_unreachable("Unexpected clause"); 6523 } 6524 for (Stmt *CC : C->children()) { 6525 if (CC) 6526 DSAChecker.Visit(CC); 6527 } 6528 } 6529 for (const auto &P : DSAChecker.getVarsWithInheritedDSA()) 6530 VarsWithInheritedDSA[P.getFirst()] = P.getSecond(); 6531 } 6532 for (const auto &P : VarsWithInheritedDSA) { 6533 if (P.getFirst()->isImplicit() || isa<OMPCapturedExprDecl>(P.getFirst())) 6534 continue; 6535 ErrorFound = true; 6536 if (DSAStack->getDefaultDSA() == DSA_none || 6537 DSAStack->getDefaultDSA() == DSA_private || 6538 DSAStack->getDefaultDSA() == DSA_firstprivate) { 6539 Diag(P.second->getExprLoc(), diag::err_omp_no_dsa_for_variable) 6540 << P.first << P.second->getSourceRange(); 6541 Diag(DSAStack->getDefaultDSALocation(), diag::note_omp_default_dsa_none); 6542 } else if (getLangOpts().OpenMP >= 50) { 6543 Diag(P.second->getExprLoc(), 6544 diag::err_omp_defaultmap_no_attr_for_variable) 6545 << P.first << P.second->getSourceRange(); 6546 Diag(DSAStack->getDefaultDSALocation(), 6547 diag::note_omp_defaultmap_attr_none); 6548 } 6549 } 6550 6551 if (!AllowedNameModifiers.empty()) 6552 ErrorFound = checkIfClauses(*this, Kind, Clauses, AllowedNameModifiers) || 6553 ErrorFound; 6554 6555 if (ErrorFound) 6556 return StmtError(); 6557 6558 if (!CurContext->isDependentContext() && 6559 isOpenMPTargetExecutionDirective(Kind) && 6560 !(DSAStack->hasRequiresDeclWithClause<OMPUnifiedSharedMemoryClause>() || 6561 DSAStack->hasRequiresDeclWithClause<OMPUnifiedAddressClause>() || 6562 DSAStack->hasRequiresDeclWithClause<OMPReverseOffloadClause>() || 6563 DSAStack->hasRequiresDeclWithClause<OMPDynamicAllocatorsClause>())) { 6564 // Register target to DSA Stack. 6565 DSAStack->addTargetDirLocation(StartLoc); 6566 } 6567 6568 return Res; 6569 } 6570 6571 Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareSimdDirective( 6572 DeclGroupPtrTy DG, OMPDeclareSimdDeclAttr::BranchStateTy BS, Expr *Simdlen, 6573 ArrayRef<Expr *> Uniforms, ArrayRef<Expr *> Aligneds, 6574 ArrayRef<Expr *> Alignments, ArrayRef<Expr *> Linears, 6575 ArrayRef<unsigned> LinModifiers, ArrayRef<Expr *> Steps, SourceRange SR) { 6576 assert(Aligneds.size() == Alignments.size()); 6577 assert(Linears.size() == LinModifiers.size()); 6578 assert(Linears.size() == Steps.size()); 6579 if (!DG || DG.get().isNull()) 6580 return DeclGroupPtrTy(); 6581 6582 const int SimdId = 0; 6583 if (!DG.get().isSingleDecl()) { 6584 Diag(SR.getBegin(), diag::err_omp_single_decl_in_declare_simd_variant) 6585 << SimdId; 6586 return DG; 6587 } 6588 Decl *ADecl = DG.get().getSingleDecl(); 6589 if (auto *FTD = dyn_cast<FunctionTemplateDecl>(ADecl)) 6590 ADecl = FTD->getTemplatedDecl(); 6591 6592 auto *FD = dyn_cast<FunctionDecl>(ADecl); 6593 if (!FD) { 6594 Diag(ADecl->getLocation(), diag::err_omp_function_expected) << SimdId; 6595 return DeclGroupPtrTy(); 6596 } 6597 6598 // OpenMP [2.8.2, declare simd construct, Description] 6599 // The parameter of the simdlen clause must be a constant positive integer 6600 // expression. 6601 ExprResult SL; 6602 if (Simdlen) 6603 SL = VerifyPositiveIntegerConstantInClause(Simdlen, OMPC_simdlen); 6604 // OpenMP [2.8.2, declare simd construct, Description] 6605 // The special this pointer can be used as if was one of the arguments to the 6606 // function in any of the linear, aligned, or uniform clauses. 6607 // The uniform clause declares one or more arguments to have an invariant 6608 // value for all concurrent invocations of the function in the execution of a 6609 // single SIMD loop. 6610 llvm::DenseMap<const Decl *, const Expr *> UniformedArgs; 6611 const Expr *UniformedLinearThis = nullptr; 6612 for (const Expr *E : Uniforms) { 6613 E = E->IgnoreParenImpCasts(); 6614 if (const auto *DRE = dyn_cast<DeclRefExpr>(E)) 6615 if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) 6616 if (FD->getNumParams() > PVD->getFunctionScopeIndex() && 6617 FD->getParamDecl(PVD->getFunctionScopeIndex()) 6618 ->getCanonicalDecl() == PVD->getCanonicalDecl()) { 6619 UniformedArgs.try_emplace(PVD->getCanonicalDecl(), E); 6620 continue; 6621 } 6622 if (isa<CXXThisExpr>(E)) { 6623 UniformedLinearThis = E; 6624 continue; 6625 } 6626 Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause) 6627 << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0); 6628 } 6629 // OpenMP [2.8.2, declare simd construct, Description] 6630 // The aligned clause declares that the object to which each list item points 6631 // is aligned to the number of bytes expressed in the optional parameter of 6632 // the aligned clause. 6633 // The special this pointer can be used as if was one of the arguments to the 6634 // function in any of the linear, aligned, or uniform clauses. 6635 // The type of list items appearing in the aligned clause must be array, 6636 // pointer, reference to array, or reference to pointer. 6637 llvm::DenseMap<const Decl *, const Expr *> AlignedArgs; 6638 const Expr *AlignedThis = nullptr; 6639 for (const Expr *E : Aligneds) { 6640 E = E->IgnoreParenImpCasts(); 6641 if (const auto *DRE = dyn_cast<DeclRefExpr>(E)) 6642 if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) { 6643 const VarDecl *CanonPVD = PVD->getCanonicalDecl(); 6644 if (FD->getNumParams() > PVD->getFunctionScopeIndex() && 6645 FD->getParamDecl(PVD->getFunctionScopeIndex()) 6646 ->getCanonicalDecl() == CanonPVD) { 6647 // OpenMP [2.8.1, simd construct, Restrictions] 6648 // A list-item cannot appear in more than one aligned clause. 6649 if (AlignedArgs.count(CanonPVD) > 0) { 6650 Diag(E->getExprLoc(), diag::err_omp_used_in_clause_twice) 6651 << 1 << getOpenMPClauseName(OMPC_aligned) 6652 << E->getSourceRange(); 6653 Diag(AlignedArgs[CanonPVD]->getExprLoc(), 6654 diag::note_omp_explicit_dsa) 6655 << getOpenMPClauseName(OMPC_aligned); 6656 continue; 6657 } 6658 AlignedArgs[CanonPVD] = E; 6659 QualType QTy = PVD->getType() 6660 .getNonReferenceType() 6661 .getUnqualifiedType() 6662 .getCanonicalType(); 6663 const Type *Ty = QTy.getTypePtrOrNull(); 6664 if (!Ty || (!Ty->isArrayType() && !Ty->isPointerType())) { 6665 Diag(E->getExprLoc(), diag::err_omp_aligned_expected_array_or_ptr) 6666 << QTy << getLangOpts().CPlusPlus << E->getSourceRange(); 6667 Diag(PVD->getLocation(), diag::note_previous_decl) << PVD; 6668 } 6669 continue; 6670 } 6671 } 6672 if (isa<CXXThisExpr>(E)) { 6673 if (AlignedThis) { 6674 Diag(E->getExprLoc(), diag::err_omp_used_in_clause_twice) 6675 << 2 << getOpenMPClauseName(OMPC_aligned) << E->getSourceRange(); 6676 Diag(AlignedThis->getExprLoc(), diag::note_omp_explicit_dsa) 6677 << getOpenMPClauseName(OMPC_aligned); 6678 } 6679 AlignedThis = E; 6680 continue; 6681 } 6682 Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause) 6683 << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0); 6684 } 6685 // The optional parameter of the aligned clause, alignment, must be a constant 6686 // positive integer expression. If no optional parameter is specified, 6687 // implementation-defined default alignments for SIMD instructions on the 6688 // target platforms are assumed. 6689 SmallVector<const Expr *, 4> NewAligns; 6690 for (Expr *E : Alignments) { 6691 ExprResult Align; 6692 if (E) 6693 Align = VerifyPositiveIntegerConstantInClause(E, OMPC_aligned); 6694 NewAligns.push_back(Align.get()); 6695 } 6696 // OpenMP [2.8.2, declare simd construct, Description] 6697 // The linear clause declares one or more list items to be private to a SIMD 6698 // lane and to have a linear relationship with respect to the iteration space 6699 // of a loop. 6700 // The special this pointer can be used as if was one of the arguments to the 6701 // function in any of the linear, aligned, or uniform clauses. 6702 // When a linear-step expression is specified in a linear clause it must be 6703 // either a constant integer expression or an integer-typed parameter that is 6704 // specified in a uniform clause on the directive. 6705 llvm::DenseMap<const Decl *, const Expr *> LinearArgs; 6706 const bool IsUniformedThis = UniformedLinearThis != nullptr; 6707 auto MI = LinModifiers.begin(); 6708 for (const Expr *E : Linears) { 6709 auto LinKind = static_cast<OpenMPLinearClauseKind>(*MI); 6710 ++MI; 6711 E = E->IgnoreParenImpCasts(); 6712 if (const auto *DRE = dyn_cast<DeclRefExpr>(E)) 6713 if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) { 6714 const VarDecl *CanonPVD = PVD->getCanonicalDecl(); 6715 if (FD->getNumParams() > PVD->getFunctionScopeIndex() && 6716 FD->getParamDecl(PVD->getFunctionScopeIndex()) 6717 ->getCanonicalDecl() == CanonPVD) { 6718 // OpenMP [2.15.3.7, linear Clause, Restrictions] 6719 // A list-item cannot appear in more than one linear clause. 6720 if (LinearArgs.count(CanonPVD) > 0) { 6721 Diag(E->getExprLoc(), diag::err_omp_wrong_dsa) 6722 << getOpenMPClauseName(OMPC_linear) 6723 << getOpenMPClauseName(OMPC_linear) << E->getSourceRange(); 6724 Diag(LinearArgs[CanonPVD]->getExprLoc(), 6725 diag::note_omp_explicit_dsa) 6726 << getOpenMPClauseName(OMPC_linear); 6727 continue; 6728 } 6729 // Each argument can appear in at most one uniform or linear clause. 6730 if (UniformedArgs.count(CanonPVD) > 0) { 6731 Diag(E->getExprLoc(), diag::err_omp_wrong_dsa) 6732 << getOpenMPClauseName(OMPC_linear) 6733 << getOpenMPClauseName(OMPC_uniform) << E->getSourceRange(); 6734 Diag(UniformedArgs[CanonPVD]->getExprLoc(), 6735 diag::note_omp_explicit_dsa) 6736 << getOpenMPClauseName(OMPC_uniform); 6737 continue; 6738 } 6739 LinearArgs[CanonPVD] = E; 6740 if (E->isValueDependent() || E->isTypeDependent() || 6741 E->isInstantiationDependent() || 6742 E->containsUnexpandedParameterPack()) 6743 continue; 6744 (void)CheckOpenMPLinearDecl(CanonPVD, E->getExprLoc(), LinKind, 6745 PVD->getOriginalType(), 6746 /*IsDeclareSimd=*/true); 6747 continue; 6748 } 6749 } 6750 if (isa<CXXThisExpr>(E)) { 6751 if (UniformedLinearThis) { 6752 Diag(E->getExprLoc(), diag::err_omp_wrong_dsa) 6753 << getOpenMPClauseName(OMPC_linear) 6754 << getOpenMPClauseName(IsUniformedThis ? OMPC_uniform : OMPC_linear) 6755 << E->getSourceRange(); 6756 Diag(UniformedLinearThis->getExprLoc(), diag::note_omp_explicit_dsa) 6757 << getOpenMPClauseName(IsUniformedThis ? OMPC_uniform 6758 : OMPC_linear); 6759 continue; 6760 } 6761 UniformedLinearThis = E; 6762 if (E->isValueDependent() || E->isTypeDependent() || 6763 E->isInstantiationDependent() || E->containsUnexpandedParameterPack()) 6764 continue; 6765 (void)CheckOpenMPLinearDecl(/*D=*/nullptr, E->getExprLoc(), LinKind, 6766 E->getType(), /*IsDeclareSimd=*/true); 6767 continue; 6768 } 6769 Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause) 6770 << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0); 6771 } 6772 Expr *Step = nullptr; 6773 Expr *NewStep = nullptr; 6774 SmallVector<Expr *, 4> NewSteps; 6775 for (Expr *E : Steps) { 6776 // Skip the same step expression, it was checked already. 6777 if (Step == E || !E) { 6778 NewSteps.push_back(E ? NewStep : nullptr); 6779 continue; 6780 } 6781 Step = E; 6782 if (const auto *DRE = dyn_cast<DeclRefExpr>(Step)) 6783 if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) { 6784 const VarDecl *CanonPVD = PVD->getCanonicalDecl(); 6785 if (UniformedArgs.count(CanonPVD) == 0) { 6786 Diag(Step->getExprLoc(), diag::err_omp_expected_uniform_param) 6787 << Step->getSourceRange(); 6788 } else if (E->isValueDependent() || E->isTypeDependent() || 6789 E->isInstantiationDependent() || 6790 E->containsUnexpandedParameterPack() || 6791 CanonPVD->getType()->hasIntegerRepresentation()) { 6792 NewSteps.push_back(Step); 6793 } else { 6794 Diag(Step->getExprLoc(), diag::err_omp_expected_int_param) 6795 << Step->getSourceRange(); 6796 } 6797 continue; 6798 } 6799 NewStep = Step; 6800 if (Step && !Step->isValueDependent() && !Step->isTypeDependent() && 6801 !Step->isInstantiationDependent() && 6802 !Step->containsUnexpandedParameterPack()) { 6803 NewStep = PerformOpenMPImplicitIntegerConversion(Step->getExprLoc(), Step) 6804 .get(); 6805 if (NewStep) 6806 NewStep = 6807 VerifyIntegerConstantExpression(NewStep, /*FIXME*/ AllowFold).get(); 6808 } 6809 NewSteps.push_back(NewStep); 6810 } 6811 auto *NewAttr = OMPDeclareSimdDeclAttr::CreateImplicit( 6812 Context, BS, SL.get(), const_cast<Expr **>(Uniforms.data()), 6813 Uniforms.size(), const_cast<Expr **>(Aligneds.data()), Aligneds.size(), 6814 const_cast<Expr **>(NewAligns.data()), NewAligns.size(), 6815 const_cast<Expr **>(Linears.data()), Linears.size(), 6816 const_cast<unsigned *>(LinModifiers.data()), LinModifiers.size(), 6817 NewSteps.data(), NewSteps.size(), SR); 6818 ADecl->addAttr(NewAttr); 6819 return DG; 6820 } 6821 6822 static void setPrototype(Sema &S, FunctionDecl *FD, FunctionDecl *FDWithProto, 6823 QualType NewType) { 6824 assert(NewType->isFunctionProtoType() && 6825 "Expected function type with prototype."); 6826 assert(FD->getType()->isFunctionNoProtoType() && 6827 "Expected function with type with no prototype."); 6828 assert(FDWithProto->getType()->isFunctionProtoType() && 6829 "Expected function with prototype."); 6830 // Synthesize parameters with the same types. 6831 FD->setType(NewType); 6832 SmallVector<ParmVarDecl *, 16> Params; 6833 for (const ParmVarDecl *P : FDWithProto->parameters()) { 6834 auto *Param = ParmVarDecl::Create(S.getASTContext(), FD, SourceLocation(), 6835 SourceLocation(), nullptr, P->getType(), 6836 /*TInfo=*/nullptr, SC_None, nullptr); 6837 Param->setScopeInfo(0, Params.size()); 6838 Param->setImplicit(); 6839 Params.push_back(Param); 6840 } 6841 6842 FD->setParams(Params); 6843 } 6844 6845 void Sema::ActOnFinishedFunctionDefinitionInOpenMPAssumeScope(Decl *D) { 6846 if (D->isInvalidDecl()) 6847 return; 6848 FunctionDecl *FD = nullptr; 6849 if (auto *UTemplDecl = dyn_cast<FunctionTemplateDecl>(D)) 6850 FD = UTemplDecl->getTemplatedDecl(); 6851 else 6852 FD = cast<FunctionDecl>(D); 6853 assert(FD && "Expected a function declaration!"); 6854 6855 // If we are instantiating templates we do *not* apply scoped assumptions but 6856 // only global ones. We apply scoped assumption to the template definition 6857 // though. 6858 if (!inTemplateInstantiation()) { 6859 for (AssumptionAttr *AA : OMPAssumeScoped) 6860 FD->addAttr(AA); 6861 } 6862 for (AssumptionAttr *AA : OMPAssumeGlobal) 6863 FD->addAttr(AA); 6864 } 6865 6866 Sema::OMPDeclareVariantScope::OMPDeclareVariantScope(OMPTraitInfo &TI) 6867 : TI(&TI), NameSuffix(TI.getMangledName()) {} 6868 6869 void Sema::ActOnStartOfFunctionDefinitionInOpenMPDeclareVariantScope( 6870 Scope *S, Declarator &D, MultiTemplateParamsArg TemplateParamLists, 6871 SmallVectorImpl<FunctionDecl *> &Bases) { 6872 if (!D.getIdentifier()) 6873 return; 6874 6875 OMPDeclareVariantScope &DVScope = OMPDeclareVariantScopes.back(); 6876 6877 // Template specialization is an extension, check if we do it. 6878 bool IsTemplated = !TemplateParamLists.empty(); 6879 if (IsTemplated & 6880 !DVScope.TI->isExtensionActive( 6881 llvm::omp::TraitProperty::implementation_extension_allow_templates)) 6882 return; 6883 6884 IdentifierInfo *BaseII = D.getIdentifier(); 6885 LookupResult Lookup(*this, DeclarationName(BaseII), D.getIdentifierLoc(), 6886 LookupOrdinaryName); 6887 LookupParsedName(Lookup, S, &D.getCXXScopeSpec()); 6888 6889 TypeSourceInfo *TInfo = GetTypeForDeclarator(D, S); 6890 QualType FType = TInfo->getType(); 6891 6892 bool IsConstexpr = 6893 D.getDeclSpec().getConstexprSpecifier() == ConstexprSpecKind::Constexpr; 6894 bool IsConsteval = 6895 D.getDeclSpec().getConstexprSpecifier() == ConstexprSpecKind::Consteval; 6896 6897 for (auto *Candidate : Lookup) { 6898 auto *CandidateDecl = Candidate->getUnderlyingDecl(); 6899 FunctionDecl *UDecl = nullptr; 6900 if (IsTemplated && isa<FunctionTemplateDecl>(CandidateDecl)) { 6901 auto *FTD = cast<FunctionTemplateDecl>(CandidateDecl); 6902 if (FTD->getTemplateParameters()->size() == TemplateParamLists.size()) 6903 UDecl = FTD->getTemplatedDecl(); 6904 } else if (!IsTemplated) 6905 UDecl = dyn_cast<FunctionDecl>(CandidateDecl); 6906 if (!UDecl) 6907 continue; 6908 6909 // Don't specialize constexpr/consteval functions with 6910 // non-constexpr/consteval functions. 6911 if (UDecl->isConstexpr() && !IsConstexpr) 6912 continue; 6913 if (UDecl->isConsteval() && !IsConsteval) 6914 continue; 6915 6916 QualType UDeclTy = UDecl->getType(); 6917 if (!UDeclTy->isDependentType()) { 6918 QualType NewType = Context.mergeFunctionTypes( 6919 FType, UDeclTy, /* OfBlockPointer */ false, 6920 /* Unqualified */ false, /* AllowCXX */ true); 6921 if (NewType.isNull()) 6922 continue; 6923 } 6924 6925 // Found a base! 6926 Bases.push_back(UDecl); 6927 } 6928 6929 bool UseImplicitBase = !DVScope.TI->isExtensionActive( 6930 llvm::omp::TraitProperty::implementation_extension_disable_implicit_base); 6931 // If no base was found we create a declaration that we use as base. 6932 if (Bases.empty() && UseImplicitBase) { 6933 D.setFunctionDefinitionKind(FunctionDefinitionKind::Declaration); 6934 Decl *BaseD = HandleDeclarator(S, D, TemplateParamLists); 6935 BaseD->setImplicit(true); 6936 if (auto *BaseTemplD = dyn_cast<FunctionTemplateDecl>(BaseD)) 6937 Bases.push_back(BaseTemplD->getTemplatedDecl()); 6938 else 6939 Bases.push_back(cast<FunctionDecl>(BaseD)); 6940 } 6941 6942 std::string MangledName; 6943 MangledName += D.getIdentifier()->getName(); 6944 MangledName += getOpenMPVariantManglingSeparatorStr(); 6945 MangledName += DVScope.NameSuffix; 6946 IdentifierInfo &VariantII = Context.Idents.get(MangledName); 6947 6948 VariantII.setMangledOpenMPVariantName(true); 6949 D.SetIdentifier(&VariantII, D.getBeginLoc()); 6950 } 6951 6952 void Sema::ActOnFinishedFunctionDefinitionInOpenMPDeclareVariantScope( 6953 Decl *D, SmallVectorImpl<FunctionDecl *> &Bases) { 6954 // Do not mark function as is used to prevent its emission if this is the 6955 // only place where it is used. 6956 EnterExpressionEvaluationContext Unevaluated( 6957 *this, Sema::ExpressionEvaluationContext::Unevaluated); 6958 6959 FunctionDecl *FD = nullptr; 6960 if (auto *UTemplDecl = dyn_cast<FunctionTemplateDecl>(D)) 6961 FD = UTemplDecl->getTemplatedDecl(); 6962 else 6963 FD = cast<FunctionDecl>(D); 6964 auto *VariantFuncRef = DeclRefExpr::Create( 6965 Context, NestedNameSpecifierLoc(), SourceLocation(), FD, 6966 /* RefersToEnclosingVariableOrCapture */ false, 6967 /* NameLoc */ FD->getLocation(), FD->getType(), 6968 ExprValueKind::VK_PRValue); 6969 6970 OMPDeclareVariantScope &DVScope = OMPDeclareVariantScopes.back(); 6971 auto *OMPDeclareVariantA = OMPDeclareVariantAttr::CreateImplicit( 6972 Context, VariantFuncRef, DVScope.TI, 6973 /*NothingArgs=*/nullptr, /*NothingArgsSize=*/0, 6974 /*NeedDevicePtrArgs=*/nullptr, /*NeedDevicePtrArgsSize=*/0, 6975 /*AppendArgs=*/nullptr, /*AppendArgsSize=*/0); 6976 for (FunctionDecl *BaseFD : Bases) 6977 BaseFD->addAttr(OMPDeclareVariantA); 6978 } 6979 6980 ExprResult Sema::ActOnOpenMPCall(ExprResult Call, Scope *Scope, 6981 SourceLocation LParenLoc, 6982 MultiExprArg ArgExprs, 6983 SourceLocation RParenLoc, Expr *ExecConfig) { 6984 // The common case is a regular call we do not want to specialize at all. Try 6985 // to make that case fast by bailing early. 6986 CallExpr *CE = dyn_cast<CallExpr>(Call.get()); 6987 if (!CE) 6988 return Call; 6989 6990 FunctionDecl *CalleeFnDecl = CE->getDirectCallee(); 6991 if (!CalleeFnDecl) 6992 return Call; 6993 6994 if (!CalleeFnDecl->hasAttr<OMPDeclareVariantAttr>()) 6995 return Call; 6996 6997 ASTContext &Context = getASTContext(); 6998 std::function<void(StringRef)> DiagUnknownTrait = [this, 6999 CE](StringRef ISATrait) { 7000 // TODO Track the selector locations in a way that is accessible here to 7001 // improve the diagnostic location. 7002 Diag(CE->getBeginLoc(), diag::warn_unknown_declare_variant_isa_trait) 7003 << ISATrait; 7004 }; 7005 TargetOMPContext OMPCtx(Context, std::move(DiagUnknownTrait), 7006 getCurFunctionDecl(), DSAStack->getConstructTraits()); 7007 7008 QualType CalleeFnType = CalleeFnDecl->getType(); 7009 7010 SmallVector<Expr *, 4> Exprs; 7011 SmallVector<VariantMatchInfo, 4> VMIs; 7012 while (CalleeFnDecl) { 7013 for (OMPDeclareVariantAttr *A : 7014 CalleeFnDecl->specific_attrs<OMPDeclareVariantAttr>()) { 7015 Expr *VariantRef = A->getVariantFuncRef(); 7016 7017 VariantMatchInfo VMI; 7018 OMPTraitInfo &TI = A->getTraitInfo(); 7019 TI.getAsVariantMatchInfo(Context, VMI); 7020 if (!isVariantApplicableInContext(VMI, OMPCtx, 7021 /* DeviceSetOnly */ false)) 7022 continue; 7023 7024 VMIs.push_back(VMI); 7025 Exprs.push_back(VariantRef); 7026 } 7027 7028 CalleeFnDecl = CalleeFnDecl->getPreviousDecl(); 7029 } 7030 7031 ExprResult NewCall; 7032 do { 7033 int BestIdx = getBestVariantMatchForContext(VMIs, OMPCtx); 7034 if (BestIdx < 0) 7035 return Call; 7036 Expr *BestExpr = cast<DeclRefExpr>(Exprs[BestIdx]); 7037 Decl *BestDecl = cast<DeclRefExpr>(BestExpr)->getDecl(); 7038 7039 { 7040 // Try to build a (member) call expression for the current best applicable 7041 // variant expression. We allow this to fail in which case we continue 7042 // with the next best variant expression. The fail case is part of the 7043 // implementation defined behavior in the OpenMP standard when it talks 7044 // about what differences in the function prototypes: "Any differences 7045 // that the specific OpenMP context requires in the prototype of the 7046 // variant from the base function prototype are implementation defined." 7047 // This wording is there to allow the specialized variant to have a 7048 // different type than the base function. This is intended and OK but if 7049 // we cannot create a call the difference is not in the "implementation 7050 // defined range" we allow. 7051 Sema::TentativeAnalysisScope Trap(*this); 7052 7053 if (auto *SpecializedMethod = dyn_cast<CXXMethodDecl>(BestDecl)) { 7054 auto *MemberCall = dyn_cast<CXXMemberCallExpr>(CE); 7055 BestExpr = MemberExpr::CreateImplicit( 7056 Context, MemberCall->getImplicitObjectArgument(), 7057 /* IsArrow */ false, SpecializedMethod, Context.BoundMemberTy, 7058 MemberCall->getValueKind(), MemberCall->getObjectKind()); 7059 } 7060 NewCall = BuildCallExpr(Scope, BestExpr, LParenLoc, ArgExprs, RParenLoc, 7061 ExecConfig); 7062 if (NewCall.isUsable()) { 7063 if (CallExpr *NCE = dyn_cast<CallExpr>(NewCall.get())) { 7064 FunctionDecl *NewCalleeFnDecl = NCE->getDirectCallee(); 7065 QualType NewType = Context.mergeFunctionTypes( 7066 CalleeFnType, NewCalleeFnDecl->getType(), 7067 /* OfBlockPointer */ false, 7068 /* Unqualified */ false, /* AllowCXX */ true); 7069 if (!NewType.isNull()) 7070 break; 7071 // Don't use the call if the function type was not compatible. 7072 NewCall = nullptr; 7073 } 7074 } 7075 } 7076 7077 VMIs.erase(VMIs.begin() + BestIdx); 7078 Exprs.erase(Exprs.begin() + BestIdx); 7079 } while (!VMIs.empty()); 7080 7081 if (!NewCall.isUsable()) 7082 return Call; 7083 return PseudoObjectExpr::Create(Context, CE, {NewCall.get()}, 0); 7084 } 7085 7086 Optional<std::pair<FunctionDecl *, Expr *>> 7087 Sema::checkOpenMPDeclareVariantFunction(Sema::DeclGroupPtrTy DG, 7088 Expr *VariantRef, OMPTraitInfo &TI, 7089 unsigned NumAppendArgs, 7090 SourceRange SR) { 7091 if (!DG || DG.get().isNull()) 7092 return None; 7093 7094 const int VariantId = 1; 7095 // Must be applied only to single decl. 7096 if (!DG.get().isSingleDecl()) { 7097 Diag(SR.getBegin(), diag::err_omp_single_decl_in_declare_simd_variant) 7098 << VariantId << SR; 7099 return None; 7100 } 7101 Decl *ADecl = DG.get().getSingleDecl(); 7102 if (auto *FTD = dyn_cast<FunctionTemplateDecl>(ADecl)) 7103 ADecl = FTD->getTemplatedDecl(); 7104 7105 // Decl must be a function. 7106 auto *FD = dyn_cast<FunctionDecl>(ADecl); 7107 if (!FD) { 7108 Diag(ADecl->getLocation(), diag::err_omp_function_expected) 7109 << VariantId << SR; 7110 return None; 7111 } 7112 7113 auto &&HasMultiVersionAttributes = [](const FunctionDecl *FD) { 7114 // The 'target' attribute needs to be separately checked because it does 7115 // not always signify a multiversion function declaration. 7116 return FD->isMultiVersion() || FD->hasAttr<TargetAttr>(); 7117 }; 7118 // OpenMP is not compatible with multiversion function attributes. 7119 if (HasMultiVersionAttributes(FD)) { 7120 Diag(FD->getLocation(), diag::err_omp_declare_variant_incompat_attributes) 7121 << SR; 7122 return None; 7123 } 7124 7125 // Allow #pragma omp declare variant only if the function is not used. 7126 if (FD->isUsed(false)) 7127 Diag(SR.getBegin(), diag::warn_omp_declare_variant_after_used) 7128 << FD->getLocation(); 7129 7130 // Check if the function was emitted already. 7131 const FunctionDecl *Definition; 7132 if (!FD->isThisDeclarationADefinition() && FD->isDefined(Definition) && 7133 (LangOpts.EmitAllDecls || Context.DeclMustBeEmitted(Definition))) 7134 Diag(SR.getBegin(), diag::warn_omp_declare_variant_after_emitted) 7135 << FD->getLocation(); 7136 7137 // The VariantRef must point to function. 7138 if (!VariantRef) { 7139 Diag(SR.getBegin(), diag::err_omp_function_expected) << VariantId; 7140 return None; 7141 } 7142 7143 auto ShouldDelayChecks = [](Expr *&E, bool) { 7144 return E && (E->isTypeDependent() || E->isValueDependent() || 7145 E->containsUnexpandedParameterPack() || 7146 E->isInstantiationDependent()); 7147 }; 7148 // Do not check templates, wait until instantiation. 7149 if (FD->isDependentContext() || ShouldDelayChecks(VariantRef, false) || 7150 TI.anyScoreOrCondition(ShouldDelayChecks)) 7151 return std::make_pair(FD, VariantRef); 7152 7153 // Deal with non-constant score and user condition expressions. 7154 auto HandleNonConstantScoresAndConditions = [this](Expr *&E, 7155 bool IsScore) -> bool { 7156 if (!E || E->isIntegerConstantExpr(Context)) 7157 return false; 7158 7159 if (IsScore) { 7160 // We warn on non-constant scores and pretend they were not present. 7161 Diag(E->getExprLoc(), diag::warn_omp_declare_variant_score_not_constant) 7162 << E; 7163 E = nullptr; 7164 } else { 7165 // We could replace a non-constant user condition with "false" but we 7166 // will soon need to handle these anyway for the dynamic version of 7167 // OpenMP context selectors. 7168 Diag(E->getExprLoc(), 7169 diag::err_omp_declare_variant_user_condition_not_constant) 7170 << E; 7171 } 7172 return true; 7173 }; 7174 if (TI.anyScoreOrCondition(HandleNonConstantScoresAndConditions)) 7175 return None; 7176 7177 QualType AdjustedFnType = FD->getType(); 7178 if (NumAppendArgs) { 7179 const auto *PTy = AdjustedFnType->getAsAdjusted<FunctionProtoType>(); 7180 if (!PTy) { 7181 Diag(FD->getLocation(), diag::err_omp_declare_variant_prototype_required) 7182 << SR; 7183 return None; 7184 } 7185 // Adjust the function type to account for an extra omp_interop_t for each 7186 // specified in the append_args clause. 7187 const TypeDecl *TD = nullptr; 7188 LookupResult Result(*this, &Context.Idents.get("omp_interop_t"), 7189 SR.getBegin(), Sema::LookupOrdinaryName); 7190 if (LookupName(Result, getCurScope())) { 7191 NamedDecl *ND = Result.getFoundDecl(); 7192 TD = dyn_cast_or_null<TypeDecl>(ND); 7193 } 7194 if (!TD) { 7195 Diag(SR.getBegin(), diag::err_omp_interop_type_not_found) << SR; 7196 return None; 7197 } 7198 QualType InteropType = Context.getTypeDeclType(TD); 7199 if (PTy->isVariadic()) { 7200 Diag(FD->getLocation(), diag::err_omp_append_args_with_varargs) << SR; 7201 return None; 7202 } 7203 llvm::SmallVector<QualType, 8> Params; 7204 Params.append(PTy->param_type_begin(), PTy->param_type_end()); 7205 Params.insert(Params.end(), NumAppendArgs, InteropType); 7206 AdjustedFnType = Context.getFunctionType(PTy->getReturnType(), Params, 7207 PTy->getExtProtoInfo()); 7208 } 7209 7210 // Convert VariantRef expression to the type of the original function to 7211 // resolve possible conflicts. 7212 ExprResult VariantRefCast = VariantRef; 7213 if (LangOpts.CPlusPlus) { 7214 QualType FnPtrType; 7215 auto *Method = dyn_cast<CXXMethodDecl>(FD); 7216 if (Method && !Method->isStatic()) { 7217 const Type *ClassType = 7218 Context.getTypeDeclType(Method->getParent()).getTypePtr(); 7219 FnPtrType = Context.getMemberPointerType(AdjustedFnType, ClassType); 7220 ExprResult ER; 7221 { 7222 // Build adrr_of unary op to correctly handle type checks for member 7223 // functions. 7224 Sema::TentativeAnalysisScope Trap(*this); 7225 ER = CreateBuiltinUnaryOp(VariantRef->getBeginLoc(), UO_AddrOf, 7226 VariantRef); 7227 } 7228 if (!ER.isUsable()) { 7229 Diag(VariantRef->getExprLoc(), diag::err_omp_function_expected) 7230 << VariantId << VariantRef->getSourceRange(); 7231 return None; 7232 } 7233 VariantRef = ER.get(); 7234 } else { 7235 FnPtrType = Context.getPointerType(AdjustedFnType); 7236 } 7237 QualType VarianPtrType = Context.getPointerType(VariantRef->getType()); 7238 if (VarianPtrType.getUnqualifiedType() != FnPtrType.getUnqualifiedType()) { 7239 ImplicitConversionSequence ICS = TryImplicitConversion( 7240 VariantRef, FnPtrType.getUnqualifiedType(), 7241 /*SuppressUserConversions=*/false, AllowedExplicit::None, 7242 /*InOverloadResolution=*/false, 7243 /*CStyle=*/false, 7244 /*AllowObjCWritebackConversion=*/false); 7245 if (ICS.isFailure()) { 7246 Diag(VariantRef->getExprLoc(), 7247 diag::err_omp_declare_variant_incompat_types) 7248 << VariantRef->getType() 7249 << ((Method && !Method->isStatic()) ? FnPtrType : FD->getType()) 7250 << (NumAppendArgs ? 1 : 0) << VariantRef->getSourceRange(); 7251 return None; 7252 } 7253 VariantRefCast = PerformImplicitConversion( 7254 VariantRef, FnPtrType.getUnqualifiedType(), AA_Converting); 7255 if (!VariantRefCast.isUsable()) 7256 return None; 7257 } 7258 // Drop previously built artificial addr_of unary op for member functions. 7259 if (Method && !Method->isStatic()) { 7260 Expr *PossibleAddrOfVariantRef = VariantRefCast.get(); 7261 if (auto *UO = dyn_cast<UnaryOperator>( 7262 PossibleAddrOfVariantRef->IgnoreImplicit())) 7263 VariantRefCast = UO->getSubExpr(); 7264 } 7265 } 7266 7267 ExprResult ER = CheckPlaceholderExpr(VariantRefCast.get()); 7268 if (!ER.isUsable() || 7269 !ER.get()->IgnoreParenImpCasts()->getType()->isFunctionType()) { 7270 Diag(VariantRef->getExprLoc(), diag::err_omp_function_expected) 7271 << VariantId << VariantRef->getSourceRange(); 7272 return None; 7273 } 7274 7275 // The VariantRef must point to function. 7276 auto *DRE = dyn_cast<DeclRefExpr>(ER.get()->IgnoreParenImpCasts()); 7277 if (!DRE) { 7278 Diag(VariantRef->getExprLoc(), diag::err_omp_function_expected) 7279 << VariantId << VariantRef->getSourceRange(); 7280 return None; 7281 } 7282 auto *NewFD = dyn_cast_or_null<FunctionDecl>(DRE->getDecl()); 7283 if (!NewFD) { 7284 Diag(VariantRef->getExprLoc(), diag::err_omp_function_expected) 7285 << VariantId << VariantRef->getSourceRange(); 7286 return None; 7287 } 7288 7289 if (FD->getCanonicalDecl() == NewFD->getCanonicalDecl()) { 7290 Diag(VariantRef->getExprLoc(), 7291 diag::err_omp_declare_variant_same_base_function) 7292 << VariantRef->getSourceRange(); 7293 return None; 7294 } 7295 7296 // Check if function types are compatible in C. 7297 if (!LangOpts.CPlusPlus) { 7298 QualType NewType = 7299 Context.mergeFunctionTypes(AdjustedFnType, NewFD->getType()); 7300 if (NewType.isNull()) { 7301 Diag(VariantRef->getExprLoc(), 7302 diag::err_omp_declare_variant_incompat_types) 7303 << NewFD->getType() << FD->getType() << (NumAppendArgs ? 1 : 0) 7304 << VariantRef->getSourceRange(); 7305 return None; 7306 } 7307 if (NewType->isFunctionProtoType()) { 7308 if (FD->getType()->isFunctionNoProtoType()) 7309 setPrototype(*this, FD, NewFD, NewType); 7310 else if (NewFD->getType()->isFunctionNoProtoType()) 7311 setPrototype(*this, NewFD, FD, NewType); 7312 } 7313 } 7314 7315 // Check if variant function is not marked with declare variant directive. 7316 if (NewFD->hasAttrs() && NewFD->hasAttr<OMPDeclareVariantAttr>()) { 7317 Diag(VariantRef->getExprLoc(), 7318 diag::warn_omp_declare_variant_marked_as_declare_variant) 7319 << VariantRef->getSourceRange(); 7320 SourceRange SR = 7321 NewFD->specific_attr_begin<OMPDeclareVariantAttr>()->getRange(); 7322 Diag(SR.getBegin(), diag::note_omp_marked_declare_variant_here) << SR; 7323 return None; 7324 } 7325 7326 enum DoesntSupport { 7327 VirtFuncs = 1, 7328 Constructors = 3, 7329 Destructors = 4, 7330 DeletedFuncs = 5, 7331 DefaultedFuncs = 6, 7332 ConstexprFuncs = 7, 7333 ConstevalFuncs = 8, 7334 }; 7335 if (const auto *CXXFD = dyn_cast<CXXMethodDecl>(FD)) { 7336 if (CXXFD->isVirtual()) { 7337 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support) 7338 << VirtFuncs; 7339 return None; 7340 } 7341 7342 if (isa<CXXConstructorDecl>(FD)) { 7343 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support) 7344 << Constructors; 7345 return None; 7346 } 7347 7348 if (isa<CXXDestructorDecl>(FD)) { 7349 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support) 7350 << Destructors; 7351 return None; 7352 } 7353 } 7354 7355 if (FD->isDeleted()) { 7356 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support) 7357 << DeletedFuncs; 7358 return None; 7359 } 7360 7361 if (FD->isDefaulted()) { 7362 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support) 7363 << DefaultedFuncs; 7364 return None; 7365 } 7366 7367 if (FD->isConstexpr()) { 7368 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support) 7369 << (NewFD->isConsteval() ? ConstevalFuncs : ConstexprFuncs); 7370 return None; 7371 } 7372 7373 // Check general compatibility. 7374 if (areMultiversionVariantFunctionsCompatible( 7375 FD, NewFD, PartialDiagnostic::NullDiagnostic(), 7376 PartialDiagnosticAt(SourceLocation(), 7377 PartialDiagnostic::NullDiagnostic()), 7378 PartialDiagnosticAt( 7379 VariantRef->getExprLoc(), 7380 PDiag(diag::err_omp_declare_variant_doesnt_support)), 7381 PartialDiagnosticAt(VariantRef->getExprLoc(), 7382 PDiag(diag::err_omp_declare_variant_diff) 7383 << FD->getLocation()), 7384 /*TemplatesSupported=*/true, /*ConstexprSupported=*/false, 7385 /*CLinkageMayDiffer=*/true)) 7386 return None; 7387 return std::make_pair(FD, cast<Expr>(DRE)); 7388 } 7389 7390 void Sema::ActOnOpenMPDeclareVariantDirective( 7391 FunctionDecl *FD, Expr *VariantRef, OMPTraitInfo &TI, 7392 ArrayRef<Expr *> AdjustArgsNothing, 7393 ArrayRef<Expr *> AdjustArgsNeedDevicePtr, 7394 ArrayRef<OMPDeclareVariantAttr::InteropType> AppendArgs, 7395 SourceLocation AdjustArgsLoc, SourceLocation AppendArgsLoc, 7396 SourceRange SR) { 7397 7398 // OpenMP 5.1 [2.3.5, declare variant directive, Restrictions] 7399 // An adjust_args clause or append_args clause can only be specified if the 7400 // dispatch selector of the construct selector set appears in the match 7401 // clause. 7402 7403 SmallVector<Expr *, 8> AllAdjustArgs; 7404 llvm::append_range(AllAdjustArgs, AdjustArgsNothing); 7405 llvm::append_range(AllAdjustArgs, AdjustArgsNeedDevicePtr); 7406 7407 if (!AllAdjustArgs.empty() || !AppendArgs.empty()) { 7408 VariantMatchInfo VMI; 7409 TI.getAsVariantMatchInfo(Context, VMI); 7410 if (!llvm::is_contained( 7411 VMI.ConstructTraits, 7412 llvm::omp::TraitProperty::construct_dispatch_dispatch)) { 7413 if (!AllAdjustArgs.empty()) 7414 Diag(AdjustArgsLoc, diag::err_omp_clause_requires_dispatch_construct) 7415 << getOpenMPClauseName(OMPC_adjust_args); 7416 if (!AppendArgs.empty()) 7417 Diag(AppendArgsLoc, diag::err_omp_clause_requires_dispatch_construct) 7418 << getOpenMPClauseName(OMPC_append_args); 7419 return; 7420 } 7421 } 7422 7423 // OpenMP 5.1 [2.3.5, declare variant directive, Restrictions] 7424 // Each argument can only appear in a single adjust_args clause for each 7425 // declare variant directive. 7426 llvm::SmallPtrSet<const VarDecl *, 4> AdjustVars; 7427 7428 for (Expr *E : AllAdjustArgs) { 7429 E = E->IgnoreParenImpCasts(); 7430 if (const auto *DRE = dyn_cast<DeclRefExpr>(E)) { 7431 if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) { 7432 const VarDecl *CanonPVD = PVD->getCanonicalDecl(); 7433 if (FD->getNumParams() > PVD->getFunctionScopeIndex() && 7434 FD->getParamDecl(PVD->getFunctionScopeIndex()) 7435 ->getCanonicalDecl() == CanonPVD) { 7436 // It's a parameter of the function, check duplicates. 7437 if (!AdjustVars.insert(CanonPVD).second) { 7438 Diag(DRE->getLocation(), diag::err_omp_adjust_arg_multiple_clauses) 7439 << PVD; 7440 return; 7441 } 7442 continue; 7443 } 7444 } 7445 } 7446 // Anything that is not a function parameter is an error. 7447 Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause) << FD << 0; 7448 return; 7449 } 7450 7451 auto *NewAttr = OMPDeclareVariantAttr::CreateImplicit( 7452 Context, VariantRef, &TI, const_cast<Expr **>(AdjustArgsNothing.data()), 7453 AdjustArgsNothing.size(), 7454 const_cast<Expr **>(AdjustArgsNeedDevicePtr.data()), 7455 AdjustArgsNeedDevicePtr.size(), 7456 const_cast<OMPDeclareVariantAttr::InteropType *>(AppendArgs.data()), 7457 AppendArgs.size(), SR); 7458 FD->addAttr(NewAttr); 7459 } 7460 7461 StmtResult Sema::ActOnOpenMPParallelDirective(ArrayRef<OMPClause *> Clauses, 7462 Stmt *AStmt, 7463 SourceLocation StartLoc, 7464 SourceLocation EndLoc) { 7465 if (!AStmt) 7466 return StmtError(); 7467 7468 auto *CS = cast<CapturedStmt>(AStmt); 7469 // 1.2.2 OpenMP Language Terminology 7470 // Structured block - An executable statement with a single entry at the 7471 // top and a single exit at the bottom. 7472 // The point of exit cannot be a branch out of the structured block. 7473 // longjmp() and throw() must not violate the entry/exit criteria. 7474 CS->getCapturedDecl()->setNothrow(); 7475 7476 setFunctionHasBranchProtectedScope(); 7477 7478 return OMPParallelDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt, 7479 DSAStack->getTaskgroupReductionRef(), 7480 DSAStack->isCancelRegion()); 7481 } 7482 7483 namespace { 7484 /// Iteration space of a single for loop. 7485 struct LoopIterationSpace final { 7486 /// True if the condition operator is the strict compare operator (<, > or 7487 /// !=). 7488 bool IsStrictCompare = false; 7489 /// Condition of the loop. 7490 Expr *PreCond = nullptr; 7491 /// This expression calculates the number of iterations in the loop. 7492 /// It is always possible to calculate it before starting the loop. 7493 Expr *NumIterations = nullptr; 7494 /// The loop counter variable. 7495 Expr *CounterVar = nullptr; 7496 /// Private loop counter variable. 7497 Expr *PrivateCounterVar = nullptr; 7498 /// This is initializer for the initial value of #CounterVar. 7499 Expr *CounterInit = nullptr; 7500 /// This is step for the #CounterVar used to generate its update: 7501 /// #CounterVar = #CounterInit + #CounterStep * CurrentIteration. 7502 Expr *CounterStep = nullptr; 7503 /// Should step be subtracted? 7504 bool Subtract = false; 7505 /// Source range of the loop init. 7506 SourceRange InitSrcRange; 7507 /// Source range of the loop condition. 7508 SourceRange CondSrcRange; 7509 /// Source range of the loop increment. 7510 SourceRange IncSrcRange; 7511 /// Minimum value that can have the loop control variable. Used to support 7512 /// non-rectangular loops. Applied only for LCV with the non-iterator types, 7513 /// since only such variables can be used in non-loop invariant expressions. 7514 Expr *MinValue = nullptr; 7515 /// Maximum value that can have the loop control variable. Used to support 7516 /// non-rectangular loops. Applied only for LCV with the non-iterator type, 7517 /// since only such variables can be used in non-loop invariant expressions. 7518 Expr *MaxValue = nullptr; 7519 /// true, if the lower bound depends on the outer loop control var. 7520 bool IsNonRectangularLB = false; 7521 /// true, if the upper bound depends on the outer loop control var. 7522 bool IsNonRectangularUB = false; 7523 /// Index of the loop this loop depends on and forms non-rectangular loop 7524 /// nest. 7525 unsigned LoopDependentIdx = 0; 7526 /// Final condition for the non-rectangular loop nest support. It is used to 7527 /// check that the number of iterations for this particular counter must be 7528 /// finished. 7529 Expr *FinalCondition = nullptr; 7530 }; 7531 7532 /// Helper class for checking canonical form of the OpenMP loops and 7533 /// extracting iteration space of each loop in the loop nest, that will be used 7534 /// for IR generation. 7535 class OpenMPIterationSpaceChecker { 7536 /// Reference to Sema. 7537 Sema &SemaRef; 7538 /// Does the loop associated directive support non-rectangular loops? 7539 bool SupportsNonRectangular; 7540 /// Data-sharing stack. 7541 DSAStackTy &Stack; 7542 /// A location for diagnostics (when there is no some better location). 7543 SourceLocation DefaultLoc; 7544 /// A location for diagnostics (when increment is not compatible). 7545 SourceLocation ConditionLoc; 7546 /// A source location for referring to loop init later. 7547 SourceRange InitSrcRange; 7548 /// A source location for referring to condition later. 7549 SourceRange ConditionSrcRange; 7550 /// A source location for referring to increment later. 7551 SourceRange IncrementSrcRange; 7552 /// Loop variable. 7553 ValueDecl *LCDecl = nullptr; 7554 /// Reference to loop variable. 7555 Expr *LCRef = nullptr; 7556 /// Lower bound (initializer for the var). 7557 Expr *LB = nullptr; 7558 /// Upper bound. 7559 Expr *UB = nullptr; 7560 /// Loop step (increment). 7561 Expr *Step = nullptr; 7562 /// This flag is true when condition is one of: 7563 /// Var < UB 7564 /// Var <= UB 7565 /// UB > Var 7566 /// UB >= Var 7567 /// This will have no value when the condition is != 7568 llvm::Optional<bool> TestIsLessOp; 7569 /// This flag is true when condition is strict ( < or > ). 7570 bool TestIsStrictOp = false; 7571 /// This flag is true when step is subtracted on each iteration. 7572 bool SubtractStep = false; 7573 /// The outer loop counter this loop depends on (if any). 7574 const ValueDecl *DepDecl = nullptr; 7575 /// Contains number of loop (starts from 1) on which loop counter init 7576 /// expression of this loop depends on. 7577 Optional<unsigned> InitDependOnLC; 7578 /// Contains number of loop (starts from 1) on which loop counter condition 7579 /// expression of this loop depends on. 7580 Optional<unsigned> CondDependOnLC; 7581 /// Checks if the provide statement depends on the loop counter. 7582 Optional<unsigned> doesDependOnLoopCounter(const Stmt *S, bool IsInitializer); 7583 /// Original condition required for checking of the exit condition for 7584 /// non-rectangular loop. 7585 Expr *Condition = nullptr; 7586 7587 public: 7588 OpenMPIterationSpaceChecker(Sema &SemaRef, bool SupportsNonRectangular, 7589 DSAStackTy &Stack, SourceLocation DefaultLoc) 7590 : SemaRef(SemaRef), SupportsNonRectangular(SupportsNonRectangular), 7591 Stack(Stack), DefaultLoc(DefaultLoc), ConditionLoc(DefaultLoc) {} 7592 /// Check init-expr for canonical loop form and save loop counter 7593 /// variable - #Var and its initialization value - #LB. 7594 bool checkAndSetInit(Stmt *S, bool EmitDiags = true); 7595 /// Check test-expr for canonical form, save upper-bound (#UB), flags 7596 /// for less/greater and for strict/non-strict comparison. 7597 bool checkAndSetCond(Expr *S); 7598 /// Check incr-expr for canonical loop form and return true if it 7599 /// does not conform, otherwise save loop step (#Step). 7600 bool checkAndSetInc(Expr *S); 7601 /// Return the loop counter variable. 7602 ValueDecl *getLoopDecl() const { return LCDecl; } 7603 /// Return the reference expression to loop counter variable. 7604 Expr *getLoopDeclRefExpr() const { return LCRef; } 7605 /// Source range of the loop init. 7606 SourceRange getInitSrcRange() const { return InitSrcRange; } 7607 /// Source range of the loop condition. 7608 SourceRange getConditionSrcRange() const { return ConditionSrcRange; } 7609 /// Source range of the loop increment. 7610 SourceRange getIncrementSrcRange() const { return IncrementSrcRange; } 7611 /// True if the step should be subtracted. 7612 bool shouldSubtractStep() const { return SubtractStep; } 7613 /// True, if the compare operator is strict (<, > or !=). 7614 bool isStrictTestOp() const { return TestIsStrictOp; } 7615 /// Build the expression to calculate the number of iterations. 7616 Expr *buildNumIterations( 7617 Scope *S, ArrayRef<LoopIterationSpace> ResultIterSpaces, bool LimitedType, 7618 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const; 7619 /// Build the precondition expression for the loops. 7620 Expr * 7621 buildPreCond(Scope *S, Expr *Cond, 7622 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const; 7623 /// Build reference expression to the counter be used for codegen. 7624 DeclRefExpr * 7625 buildCounterVar(llvm::MapVector<const Expr *, DeclRefExpr *> &Captures, 7626 DSAStackTy &DSA) const; 7627 /// Build reference expression to the private counter be used for 7628 /// codegen. 7629 Expr *buildPrivateCounterVar() const; 7630 /// Build initialization of the counter be used for codegen. 7631 Expr *buildCounterInit() const; 7632 /// Build step of the counter be used for codegen. 7633 Expr *buildCounterStep() const; 7634 /// Build loop data with counter value for depend clauses in ordered 7635 /// directives. 7636 Expr * 7637 buildOrderedLoopData(Scope *S, Expr *Counter, 7638 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures, 7639 SourceLocation Loc, Expr *Inc = nullptr, 7640 OverloadedOperatorKind OOK = OO_Amp); 7641 /// Builds the minimum value for the loop counter. 7642 std::pair<Expr *, Expr *> buildMinMaxValues( 7643 Scope *S, llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const; 7644 /// Builds final condition for the non-rectangular loops. 7645 Expr *buildFinalCondition(Scope *S) const; 7646 /// Return true if any expression is dependent. 7647 bool dependent() const; 7648 /// Returns true if the initializer forms non-rectangular loop. 7649 bool doesInitDependOnLC() const { return InitDependOnLC.hasValue(); } 7650 /// Returns true if the condition forms non-rectangular loop. 7651 bool doesCondDependOnLC() const { return CondDependOnLC.hasValue(); } 7652 /// Returns index of the loop we depend on (starting from 1), or 0 otherwise. 7653 unsigned getLoopDependentIdx() const { 7654 return InitDependOnLC.value_or(CondDependOnLC.value_or(0)); 7655 } 7656 7657 private: 7658 /// Check the right-hand side of an assignment in the increment 7659 /// expression. 7660 bool checkAndSetIncRHS(Expr *RHS); 7661 /// Helper to set loop counter variable and its initializer. 7662 bool setLCDeclAndLB(ValueDecl *NewLCDecl, Expr *NewDeclRefExpr, Expr *NewLB, 7663 bool EmitDiags); 7664 /// Helper to set upper bound. 7665 bool setUB(Expr *NewUB, llvm::Optional<bool> LessOp, bool StrictOp, 7666 SourceRange SR, SourceLocation SL); 7667 /// Helper to set loop increment. 7668 bool setStep(Expr *NewStep, bool Subtract); 7669 }; 7670 7671 bool OpenMPIterationSpaceChecker::dependent() const { 7672 if (!LCDecl) { 7673 assert(!LB && !UB && !Step); 7674 return false; 7675 } 7676 return LCDecl->getType()->isDependentType() || 7677 (LB && LB->isValueDependent()) || (UB && UB->isValueDependent()) || 7678 (Step && Step->isValueDependent()); 7679 } 7680 7681 bool OpenMPIterationSpaceChecker::setLCDeclAndLB(ValueDecl *NewLCDecl, 7682 Expr *NewLCRefExpr, 7683 Expr *NewLB, bool EmitDiags) { 7684 // State consistency checking to ensure correct usage. 7685 assert(LCDecl == nullptr && LB == nullptr && LCRef == nullptr && 7686 UB == nullptr && Step == nullptr && !TestIsLessOp && !TestIsStrictOp); 7687 if (!NewLCDecl || !NewLB || NewLB->containsErrors()) 7688 return true; 7689 LCDecl = getCanonicalDecl(NewLCDecl); 7690 LCRef = NewLCRefExpr; 7691 if (auto *CE = dyn_cast_or_null<CXXConstructExpr>(NewLB)) 7692 if (const CXXConstructorDecl *Ctor = CE->getConstructor()) 7693 if ((Ctor->isCopyOrMoveConstructor() || 7694 Ctor->isConvertingConstructor(/*AllowExplicit=*/false)) && 7695 CE->getNumArgs() > 0 && CE->getArg(0) != nullptr) 7696 NewLB = CE->getArg(0)->IgnoreParenImpCasts(); 7697 LB = NewLB; 7698 if (EmitDiags) 7699 InitDependOnLC = doesDependOnLoopCounter(LB, /*IsInitializer=*/true); 7700 return false; 7701 } 7702 7703 bool OpenMPIterationSpaceChecker::setUB(Expr *NewUB, 7704 llvm::Optional<bool> LessOp, 7705 bool StrictOp, SourceRange SR, 7706 SourceLocation SL) { 7707 // State consistency checking to ensure correct usage. 7708 assert(LCDecl != nullptr && LB != nullptr && UB == nullptr && 7709 Step == nullptr && !TestIsLessOp && !TestIsStrictOp); 7710 if (!NewUB || NewUB->containsErrors()) 7711 return true; 7712 UB = NewUB; 7713 if (LessOp) 7714 TestIsLessOp = LessOp; 7715 TestIsStrictOp = StrictOp; 7716 ConditionSrcRange = SR; 7717 ConditionLoc = SL; 7718 CondDependOnLC = doesDependOnLoopCounter(UB, /*IsInitializer=*/false); 7719 return false; 7720 } 7721 7722 bool OpenMPIterationSpaceChecker::setStep(Expr *NewStep, bool Subtract) { 7723 // State consistency checking to ensure correct usage. 7724 assert(LCDecl != nullptr && LB != nullptr && Step == nullptr); 7725 if (!NewStep || NewStep->containsErrors()) 7726 return true; 7727 if (!NewStep->isValueDependent()) { 7728 // Check that the step is integer expression. 7729 SourceLocation StepLoc = NewStep->getBeginLoc(); 7730 ExprResult Val = SemaRef.PerformOpenMPImplicitIntegerConversion( 7731 StepLoc, getExprAsWritten(NewStep)); 7732 if (Val.isInvalid()) 7733 return true; 7734 NewStep = Val.get(); 7735 7736 // OpenMP [2.6, Canonical Loop Form, Restrictions] 7737 // If test-expr is of form var relational-op b and relational-op is < or 7738 // <= then incr-expr must cause var to increase on each iteration of the 7739 // loop. If test-expr is of form var relational-op b and relational-op is 7740 // > or >= then incr-expr must cause var to decrease on each iteration of 7741 // the loop. 7742 // If test-expr is of form b relational-op var and relational-op is < or 7743 // <= then incr-expr must cause var to decrease on each iteration of the 7744 // loop. If test-expr is of form b relational-op var and relational-op is 7745 // > or >= then incr-expr must cause var to increase on each iteration of 7746 // the loop. 7747 Optional<llvm::APSInt> Result = 7748 NewStep->getIntegerConstantExpr(SemaRef.Context); 7749 bool IsUnsigned = !NewStep->getType()->hasSignedIntegerRepresentation(); 7750 bool IsConstNeg = 7751 Result && Result->isSigned() && (Subtract != Result->isNegative()); 7752 bool IsConstPos = 7753 Result && Result->isSigned() && (Subtract == Result->isNegative()); 7754 bool IsConstZero = Result && !Result->getBoolValue(); 7755 7756 // != with increment is treated as <; != with decrement is treated as > 7757 if (!TestIsLessOp.hasValue()) 7758 TestIsLessOp = IsConstPos || (IsUnsigned && !Subtract); 7759 if (UB && 7760 (IsConstZero || (TestIsLessOp.getValue() 7761 ? (IsConstNeg || (IsUnsigned && Subtract)) 7762 : (IsConstPos || (IsUnsigned && !Subtract))))) { 7763 SemaRef.Diag(NewStep->getExprLoc(), 7764 diag::err_omp_loop_incr_not_compatible) 7765 << LCDecl << TestIsLessOp.getValue() << NewStep->getSourceRange(); 7766 SemaRef.Diag(ConditionLoc, 7767 diag::note_omp_loop_cond_requres_compatible_incr) 7768 << TestIsLessOp.getValue() << ConditionSrcRange; 7769 return true; 7770 } 7771 if (TestIsLessOp.getValue() == Subtract) { 7772 NewStep = 7773 SemaRef.CreateBuiltinUnaryOp(NewStep->getExprLoc(), UO_Minus, NewStep) 7774 .get(); 7775 Subtract = !Subtract; 7776 } 7777 } 7778 7779 Step = NewStep; 7780 SubtractStep = Subtract; 7781 return false; 7782 } 7783 7784 namespace { 7785 /// Checker for the non-rectangular loops. Checks if the initializer or 7786 /// condition expression references loop counter variable. 7787 class LoopCounterRefChecker final 7788 : public ConstStmtVisitor<LoopCounterRefChecker, bool> { 7789 Sema &SemaRef; 7790 DSAStackTy &Stack; 7791 const ValueDecl *CurLCDecl = nullptr; 7792 const ValueDecl *DepDecl = nullptr; 7793 const ValueDecl *PrevDepDecl = nullptr; 7794 bool IsInitializer = true; 7795 bool SupportsNonRectangular; 7796 unsigned BaseLoopId = 0; 7797 bool checkDecl(const Expr *E, const ValueDecl *VD) { 7798 if (getCanonicalDecl(VD) == getCanonicalDecl(CurLCDecl)) { 7799 SemaRef.Diag(E->getExprLoc(), diag::err_omp_stmt_depends_on_loop_counter) 7800 << (IsInitializer ? 0 : 1); 7801 return false; 7802 } 7803 const auto &&Data = Stack.isLoopControlVariable(VD); 7804 // OpenMP, 2.9.1 Canonical Loop Form, Restrictions. 7805 // The type of the loop iterator on which we depend may not have a random 7806 // access iterator type. 7807 if (Data.first && VD->getType()->isRecordType()) { 7808 SmallString<128> Name; 7809 llvm::raw_svector_ostream OS(Name); 7810 VD->getNameForDiagnostic(OS, SemaRef.getPrintingPolicy(), 7811 /*Qualified=*/true); 7812 SemaRef.Diag(E->getExprLoc(), 7813 diag::err_omp_wrong_dependency_iterator_type) 7814 << OS.str(); 7815 SemaRef.Diag(VD->getLocation(), diag::note_previous_decl) << VD; 7816 return false; 7817 } 7818 if (Data.first && !SupportsNonRectangular) { 7819 SemaRef.Diag(E->getExprLoc(), diag::err_omp_invariant_dependency); 7820 return false; 7821 } 7822 if (Data.first && 7823 (DepDecl || (PrevDepDecl && 7824 getCanonicalDecl(VD) != getCanonicalDecl(PrevDepDecl)))) { 7825 if (!DepDecl && PrevDepDecl) 7826 DepDecl = PrevDepDecl; 7827 SmallString<128> Name; 7828 llvm::raw_svector_ostream OS(Name); 7829 DepDecl->getNameForDiagnostic(OS, SemaRef.getPrintingPolicy(), 7830 /*Qualified=*/true); 7831 SemaRef.Diag(E->getExprLoc(), 7832 diag::err_omp_invariant_or_linear_dependency) 7833 << OS.str(); 7834 return false; 7835 } 7836 if (Data.first) { 7837 DepDecl = VD; 7838 BaseLoopId = Data.first; 7839 } 7840 return Data.first; 7841 } 7842 7843 public: 7844 bool VisitDeclRefExpr(const DeclRefExpr *E) { 7845 const ValueDecl *VD = E->getDecl(); 7846 if (isa<VarDecl>(VD)) 7847 return checkDecl(E, VD); 7848 return false; 7849 } 7850 bool VisitMemberExpr(const MemberExpr *E) { 7851 if (isa<CXXThisExpr>(E->getBase()->IgnoreParens())) { 7852 const ValueDecl *VD = E->getMemberDecl(); 7853 if (isa<VarDecl>(VD) || isa<FieldDecl>(VD)) 7854 return checkDecl(E, VD); 7855 } 7856 return false; 7857 } 7858 bool VisitStmt(const Stmt *S) { 7859 bool Res = false; 7860 for (const Stmt *Child : S->children()) 7861 Res = (Child && Visit(Child)) || Res; 7862 return Res; 7863 } 7864 explicit LoopCounterRefChecker(Sema &SemaRef, DSAStackTy &Stack, 7865 const ValueDecl *CurLCDecl, bool IsInitializer, 7866 const ValueDecl *PrevDepDecl = nullptr, 7867 bool SupportsNonRectangular = true) 7868 : SemaRef(SemaRef), Stack(Stack), CurLCDecl(CurLCDecl), 7869 PrevDepDecl(PrevDepDecl), IsInitializer(IsInitializer), 7870 SupportsNonRectangular(SupportsNonRectangular) {} 7871 unsigned getBaseLoopId() const { 7872 assert(CurLCDecl && "Expected loop dependency."); 7873 return BaseLoopId; 7874 } 7875 const ValueDecl *getDepDecl() const { 7876 assert(CurLCDecl && "Expected loop dependency."); 7877 return DepDecl; 7878 } 7879 }; 7880 } // namespace 7881 7882 Optional<unsigned> 7883 OpenMPIterationSpaceChecker::doesDependOnLoopCounter(const Stmt *S, 7884 bool IsInitializer) { 7885 // Check for the non-rectangular loops. 7886 LoopCounterRefChecker LoopStmtChecker(SemaRef, Stack, LCDecl, IsInitializer, 7887 DepDecl, SupportsNonRectangular); 7888 if (LoopStmtChecker.Visit(S)) { 7889 DepDecl = LoopStmtChecker.getDepDecl(); 7890 return LoopStmtChecker.getBaseLoopId(); 7891 } 7892 return llvm::None; 7893 } 7894 7895 bool OpenMPIterationSpaceChecker::checkAndSetInit(Stmt *S, bool EmitDiags) { 7896 // Check init-expr for canonical loop form and save loop counter 7897 // variable - #Var and its initialization value - #LB. 7898 // OpenMP [2.6] Canonical loop form. init-expr may be one of the following: 7899 // var = lb 7900 // integer-type var = lb 7901 // random-access-iterator-type var = lb 7902 // pointer-type var = lb 7903 // 7904 if (!S) { 7905 if (EmitDiags) { 7906 SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_init); 7907 } 7908 return true; 7909 } 7910 if (auto *ExprTemp = dyn_cast<ExprWithCleanups>(S)) 7911 if (!ExprTemp->cleanupsHaveSideEffects()) 7912 S = ExprTemp->getSubExpr(); 7913 7914 InitSrcRange = S->getSourceRange(); 7915 if (Expr *E = dyn_cast<Expr>(S)) 7916 S = E->IgnoreParens(); 7917 if (auto *BO = dyn_cast<BinaryOperator>(S)) { 7918 if (BO->getOpcode() == BO_Assign) { 7919 Expr *LHS = BO->getLHS()->IgnoreParens(); 7920 if (auto *DRE = dyn_cast<DeclRefExpr>(LHS)) { 7921 if (auto *CED = dyn_cast<OMPCapturedExprDecl>(DRE->getDecl())) 7922 if (auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit()))) 7923 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(), 7924 EmitDiags); 7925 return setLCDeclAndLB(DRE->getDecl(), DRE, BO->getRHS(), EmitDiags); 7926 } 7927 if (auto *ME = dyn_cast<MemberExpr>(LHS)) { 7928 if (ME->isArrow() && 7929 isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts())) 7930 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(), 7931 EmitDiags); 7932 } 7933 } 7934 } else if (auto *DS = dyn_cast<DeclStmt>(S)) { 7935 if (DS->isSingleDecl()) { 7936 if (auto *Var = dyn_cast_or_null<VarDecl>(DS->getSingleDecl())) { 7937 if (Var->hasInit() && !Var->getType()->isReferenceType()) { 7938 // Accept non-canonical init form here but emit ext. warning. 7939 if (Var->getInitStyle() != VarDecl::CInit && EmitDiags) 7940 SemaRef.Diag(S->getBeginLoc(), 7941 diag::ext_omp_loop_not_canonical_init) 7942 << S->getSourceRange(); 7943 return setLCDeclAndLB( 7944 Var, 7945 buildDeclRefExpr(SemaRef, Var, 7946 Var->getType().getNonReferenceType(), 7947 DS->getBeginLoc()), 7948 Var->getInit(), EmitDiags); 7949 } 7950 } 7951 } 7952 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) { 7953 if (CE->getOperator() == OO_Equal) { 7954 Expr *LHS = CE->getArg(0); 7955 if (auto *DRE = dyn_cast<DeclRefExpr>(LHS)) { 7956 if (auto *CED = dyn_cast<OMPCapturedExprDecl>(DRE->getDecl())) 7957 if (auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit()))) 7958 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(), 7959 EmitDiags); 7960 return setLCDeclAndLB(DRE->getDecl(), DRE, CE->getArg(1), EmitDiags); 7961 } 7962 if (auto *ME = dyn_cast<MemberExpr>(LHS)) { 7963 if (ME->isArrow() && 7964 isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts())) 7965 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(), 7966 EmitDiags); 7967 } 7968 } 7969 } 7970 7971 if (dependent() || SemaRef.CurContext->isDependentContext()) 7972 return false; 7973 if (EmitDiags) { 7974 SemaRef.Diag(S->getBeginLoc(), diag::err_omp_loop_not_canonical_init) 7975 << S->getSourceRange(); 7976 } 7977 return true; 7978 } 7979 7980 /// Ignore parenthesizes, implicit casts, copy constructor and return the 7981 /// variable (which may be the loop variable) if possible. 7982 static const ValueDecl *getInitLCDecl(const Expr *E) { 7983 if (!E) 7984 return nullptr; 7985 E = getExprAsWritten(E); 7986 if (const auto *CE = dyn_cast_or_null<CXXConstructExpr>(E)) 7987 if (const CXXConstructorDecl *Ctor = CE->getConstructor()) 7988 if ((Ctor->isCopyOrMoveConstructor() || 7989 Ctor->isConvertingConstructor(/*AllowExplicit=*/false)) && 7990 CE->getNumArgs() > 0 && CE->getArg(0) != nullptr) 7991 E = CE->getArg(0)->IgnoreParenImpCasts(); 7992 if (const auto *DRE = dyn_cast_or_null<DeclRefExpr>(E)) { 7993 if (const auto *VD = dyn_cast<VarDecl>(DRE->getDecl())) 7994 return getCanonicalDecl(VD); 7995 } 7996 if (const auto *ME = dyn_cast_or_null<MemberExpr>(E)) 7997 if (ME->isArrow() && isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts())) 7998 return getCanonicalDecl(ME->getMemberDecl()); 7999 return nullptr; 8000 } 8001 8002 bool OpenMPIterationSpaceChecker::checkAndSetCond(Expr *S) { 8003 // Check test-expr for canonical form, save upper-bound UB, flags for 8004 // less/greater and for strict/non-strict comparison. 8005 // OpenMP [2.9] Canonical loop form. Test-expr may be one of the following: 8006 // var relational-op b 8007 // b relational-op var 8008 // 8009 bool IneqCondIsCanonical = SemaRef.getLangOpts().OpenMP >= 50; 8010 if (!S) { 8011 SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_cond) 8012 << (IneqCondIsCanonical ? 1 : 0) << LCDecl; 8013 return true; 8014 } 8015 Condition = S; 8016 S = getExprAsWritten(S); 8017 SourceLocation CondLoc = S->getBeginLoc(); 8018 auto &&CheckAndSetCond = [this, IneqCondIsCanonical]( 8019 BinaryOperatorKind Opcode, const Expr *LHS, 8020 const Expr *RHS, SourceRange SR, 8021 SourceLocation OpLoc) -> llvm::Optional<bool> { 8022 if (BinaryOperator::isRelationalOp(Opcode)) { 8023 if (getInitLCDecl(LHS) == LCDecl) 8024 return setUB(const_cast<Expr *>(RHS), 8025 (Opcode == BO_LT || Opcode == BO_LE), 8026 (Opcode == BO_LT || Opcode == BO_GT), SR, OpLoc); 8027 if (getInitLCDecl(RHS) == LCDecl) 8028 return setUB(const_cast<Expr *>(LHS), 8029 (Opcode == BO_GT || Opcode == BO_GE), 8030 (Opcode == BO_LT || Opcode == BO_GT), SR, OpLoc); 8031 } else if (IneqCondIsCanonical && Opcode == BO_NE) { 8032 return setUB(const_cast<Expr *>(getInitLCDecl(LHS) == LCDecl ? RHS : LHS), 8033 /*LessOp=*/llvm::None, 8034 /*StrictOp=*/true, SR, OpLoc); 8035 } 8036 return llvm::None; 8037 }; 8038 llvm::Optional<bool> Res; 8039 if (auto *RBO = dyn_cast<CXXRewrittenBinaryOperator>(S)) { 8040 CXXRewrittenBinaryOperator::DecomposedForm DF = RBO->getDecomposedForm(); 8041 Res = CheckAndSetCond(DF.Opcode, DF.LHS, DF.RHS, RBO->getSourceRange(), 8042 RBO->getOperatorLoc()); 8043 } else if (auto *BO = dyn_cast<BinaryOperator>(S)) { 8044 Res = CheckAndSetCond(BO->getOpcode(), BO->getLHS(), BO->getRHS(), 8045 BO->getSourceRange(), BO->getOperatorLoc()); 8046 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) { 8047 if (CE->getNumArgs() == 2) { 8048 Res = CheckAndSetCond( 8049 BinaryOperator::getOverloadedOpcode(CE->getOperator()), CE->getArg(0), 8050 CE->getArg(1), CE->getSourceRange(), CE->getOperatorLoc()); 8051 } 8052 } 8053 if (Res) 8054 return *Res; 8055 if (dependent() || SemaRef.CurContext->isDependentContext()) 8056 return false; 8057 SemaRef.Diag(CondLoc, diag::err_omp_loop_not_canonical_cond) 8058 << (IneqCondIsCanonical ? 1 : 0) << S->getSourceRange() << LCDecl; 8059 return true; 8060 } 8061 8062 bool OpenMPIterationSpaceChecker::checkAndSetIncRHS(Expr *RHS) { 8063 // RHS of canonical loop form increment can be: 8064 // var + incr 8065 // incr + var 8066 // var - incr 8067 // 8068 RHS = RHS->IgnoreParenImpCasts(); 8069 if (auto *BO = dyn_cast<BinaryOperator>(RHS)) { 8070 if (BO->isAdditiveOp()) { 8071 bool IsAdd = BO->getOpcode() == BO_Add; 8072 if (getInitLCDecl(BO->getLHS()) == LCDecl) 8073 return setStep(BO->getRHS(), !IsAdd); 8074 if (IsAdd && getInitLCDecl(BO->getRHS()) == LCDecl) 8075 return setStep(BO->getLHS(), /*Subtract=*/false); 8076 } 8077 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(RHS)) { 8078 bool IsAdd = CE->getOperator() == OO_Plus; 8079 if ((IsAdd || CE->getOperator() == OO_Minus) && CE->getNumArgs() == 2) { 8080 if (getInitLCDecl(CE->getArg(0)) == LCDecl) 8081 return setStep(CE->getArg(1), !IsAdd); 8082 if (IsAdd && getInitLCDecl(CE->getArg(1)) == LCDecl) 8083 return setStep(CE->getArg(0), /*Subtract=*/false); 8084 } 8085 } 8086 if (dependent() || SemaRef.CurContext->isDependentContext()) 8087 return false; 8088 SemaRef.Diag(RHS->getBeginLoc(), diag::err_omp_loop_not_canonical_incr) 8089 << RHS->getSourceRange() << LCDecl; 8090 return true; 8091 } 8092 8093 bool OpenMPIterationSpaceChecker::checkAndSetInc(Expr *S) { 8094 // Check incr-expr for canonical loop form and return true if it 8095 // does not conform. 8096 // OpenMP [2.6] Canonical loop form. Test-expr may be one of the following: 8097 // ++var 8098 // var++ 8099 // --var 8100 // var-- 8101 // var += incr 8102 // var -= incr 8103 // var = var + incr 8104 // var = incr + var 8105 // var = var - incr 8106 // 8107 if (!S) { 8108 SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_incr) << LCDecl; 8109 return true; 8110 } 8111 if (auto *ExprTemp = dyn_cast<ExprWithCleanups>(S)) 8112 if (!ExprTemp->cleanupsHaveSideEffects()) 8113 S = ExprTemp->getSubExpr(); 8114 8115 IncrementSrcRange = S->getSourceRange(); 8116 S = S->IgnoreParens(); 8117 if (auto *UO = dyn_cast<UnaryOperator>(S)) { 8118 if (UO->isIncrementDecrementOp() && 8119 getInitLCDecl(UO->getSubExpr()) == LCDecl) 8120 return setStep(SemaRef 8121 .ActOnIntegerConstant(UO->getBeginLoc(), 8122 (UO->isDecrementOp() ? -1 : 1)) 8123 .get(), 8124 /*Subtract=*/false); 8125 } else if (auto *BO = dyn_cast<BinaryOperator>(S)) { 8126 switch (BO->getOpcode()) { 8127 case BO_AddAssign: 8128 case BO_SubAssign: 8129 if (getInitLCDecl(BO->getLHS()) == LCDecl) 8130 return setStep(BO->getRHS(), BO->getOpcode() == BO_SubAssign); 8131 break; 8132 case BO_Assign: 8133 if (getInitLCDecl(BO->getLHS()) == LCDecl) 8134 return checkAndSetIncRHS(BO->getRHS()); 8135 break; 8136 default: 8137 break; 8138 } 8139 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) { 8140 switch (CE->getOperator()) { 8141 case OO_PlusPlus: 8142 case OO_MinusMinus: 8143 if (getInitLCDecl(CE->getArg(0)) == LCDecl) 8144 return setStep(SemaRef 8145 .ActOnIntegerConstant( 8146 CE->getBeginLoc(), 8147 ((CE->getOperator() == OO_MinusMinus) ? -1 : 1)) 8148 .get(), 8149 /*Subtract=*/false); 8150 break; 8151 case OO_PlusEqual: 8152 case OO_MinusEqual: 8153 if (getInitLCDecl(CE->getArg(0)) == LCDecl) 8154 return setStep(CE->getArg(1), CE->getOperator() == OO_MinusEqual); 8155 break; 8156 case OO_Equal: 8157 if (getInitLCDecl(CE->getArg(0)) == LCDecl) 8158 return checkAndSetIncRHS(CE->getArg(1)); 8159 break; 8160 default: 8161 break; 8162 } 8163 } 8164 if (dependent() || SemaRef.CurContext->isDependentContext()) 8165 return false; 8166 SemaRef.Diag(S->getBeginLoc(), diag::err_omp_loop_not_canonical_incr) 8167 << S->getSourceRange() << LCDecl; 8168 return true; 8169 } 8170 8171 static ExprResult 8172 tryBuildCapture(Sema &SemaRef, Expr *Capture, 8173 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) { 8174 if (SemaRef.CurContext->isDependentContext() || Capture->containsErrors()) 8175 return Capture; 8176 if (Capture->isEvaluatable(SemaRef.Context, Expr::SE_AllowSideEffects)) 8177 return SemaRef.PerformImplicitConversion( 8178 Capture->IgnoreImpCasts(), Capture->getType(), Sema::AA_Converting, 8179 /*AllowExplicit=*/true); 8180 auto I = Captures.find(Capture); 8181 if (I != Captures.end()) 8182 return buildCapture(SemaRef, Capture, I->second); 8183 DeclRefExpr *Ref = nullptr; 8184 ExprResult Res = buildCapture(SemaRef, Capture, Ref); 8185 Captures[Capture] = Ref; 8186 return Res; 8187 } 8188 8189 /// Calculate number of iterations, transforming to unsigned, if number of 8190 /// iterations may be larger than the original type. 8191 static Expr * 8192 calculateNumIters(Sema &SemaRef, Scope *S, SourceLocation DefaultLoc, 8193 Expr *Lower, Expr *Upper, Expr *Step, QualType LCTy, 8194 bool TestIsStrictOp, bool RoundToStep, 8195 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) { 8196 ExprResult NewStep = tryBuildCapture(SemaRef, Step, Captures); 8197 if (!NewStep.isUsable()) 8198 return nullptr; 8199 llvm::APSInt LRes, SRes; 8200 bool IsLowerConst = false, IsStepConst = false; 8201 if (Optional<llvm::APSInt> Res = 8202 Lower->getIntegerConstantExpr(SemaRef.Context)) { 8203 LRes = *Res; 8204 IsLowerConst = true; 8205 } 8206 if (Optional<llvm::APSInt> Res = 8207 Step->getIntegerConstantExpr(SemaRef.Context)) { 8208 SRes = *Res; 8209 IsStepConst = true; 8210 } 8211 bool NoNeedToConvert = IsLowerConst && !RoundToStep && 8212 ((!TestIsStrictOp && LRes.isNonNegative()) || 8213 (TestIsStrictOp && LRes.isStrictlyPositive())); 8214 bool NeedToReorganize = false; 8215 // Check if any subexpressions in Lower -Step [+ 1] lead to overflow. 8216 if (!NoNeedToConvert && IsLowerConst && 8217 (TestIsStrictOp || (RoundToStep && IsStepConst))) { 8218 NoNeedToConvert = true; 8219 if (RoundToStep) { 8220 unsigned BW = LRes.getBitWidth() > SRes.getBitWidth() 8221 ? LRes.getBitWidth() 8222 : SRes.getBitWidth(); 8223 LRes = LRes.extend(BW + 1); 8224 LRes.setIsSigned(true); 8225 SRes = SRes.extend(BW + 1); 8226 SRes.setIsSigned(true); 8227 LRes -= SRes; 8228 NoNeedToConvert = LRes.trunc(BW).extend(BW + 1) == LRes; 8229 LRes = LRes.trunc(BW); 8230 } 8231 if (TestIsStrictOp) { 8232 unsigned BW = LRes.getBitWidth(); 8233 LRes = LRes.extend(BW + 1); 8234 LRes.setIsSigned(true); 8235 ++LRes; 8236 NoNeedToConvert = 8237 NoNeedToConvert && LRes.trunc(BW).extend(BW + 1) == LRes; 8238 // truncate to the original bitwidth. 8239 LRes = LRes.trunc(BW); 8240 } 8241 NeedToReorganize = NoNeedToConvert; 8242 } 8243 llvm::APSInt URes; 8244 bool IsUpperConst = false; 8245 if (Optional<llvm::APSInt> Res = 8246 Upper->getIntegerConstantExpr(SemaRef.Context)) { 8247 URes = *Res; 8248 IsUpperConst = true; 8249 } 8250 if (NoNeedToConvert && IsLowerConst && IsUpperConst && 8251 (!RoundToStep || IsStepConst)) { 8252 unsigned BW = LRes.getBitWidth() > URes.getBitWidth() ? LRes.getBitWidth() 8253 : URes.getBitWidth(); 8254 LRes = LRes.extend(BW + 1); 8255 LRes.setIsSigned(true); 8256 URes = URes.extend(BW + 1); 8257 URes.setIsSigned(true); 8258 URes -= LRes; 8259 NoNeedToConvert = URes.trunc(BW).extend(BW + 1) == URes; 8260 NeedToReorganize = NoNeedToConvert; 8261 } 8262 // If the boundaries are not constant or (Lower - Step [+ 1]) is not constant 8263 // or less than zero (Upper - (Lower - Step [+ 1]) may overflow) - promote to 8264 // unsigned. 8265 if ((!NoNeedToConvert || (LRes.isNegative() && !IsUpperConst)) && 8266 !LCTy->isDependentType() && LCTy->isIntegerType()) { 8267 QualType LowerTy = Lower->getType(); 8268 QualType UpperTy = Upper->getType(); 8269 uint64_t LowerSize = SemaRef.Context.getTypeSize(LowerTy); 8270 uint64_t UpperSize = SemaRef.Context.getTypeSize(UpperTy); 8271 if ((LowerSize <= UpperSize && UpperTy->hasSignedIntegerRepresentation()) || 8272 (LowerSize > UpperSize && LowerTy->hasSignedIntegerRepresentation())) { 8273 QualType CastType = SemaRef.Context.getIntTypeForBitwidth( 8274 LowerSize > UpperSize ? LowerSize : UpperSize, /*Signed=*/0); 8275 Upper = 8276 SemaRef 8277 .PerformImplicitConversion( 8278 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Upper).get(), 8279 CastType, Sema::AA_Converting) 8280 .get(); 8281 Lower = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Lower).get(); 8282 NewStep = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, NewStep.get()); 8283 } 8284 } 8285 if (!Lower || !Upper || NewStep.isInvalid()) 8286 return nullptr; 8287 8288 ExprResult Diff; 8289 // If need to reorganize, then calculate the form as Upper - (Lower - Step [+ 8290 // 1]). 8291 if (NeedToReorganize) { 8292 Diff = Lower; 8293 8294 if (RoundToStep) { 8295 // Lower - Step 8296 Diff = 8297 SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Diff.get(), NewStep.get()); 8298 if (!Diff.isUsable()) 8299 return nullptr; 8300 } 8301 8302 // Lower - Step [+ 1] 8303 if (TestIsStrictOp) 8304 Diff = SemaRef.BuildBinOp( 8305 S, DefaultLoc, BO_Add, Diff.get(), 8306 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()); 8307 if (!Diff.isUsable()) 8308 return nullptr; 8309 8310 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get()); 8311 if (!Diff.isUsable()) 8312 return nullptr; 8313 8314 // Upper - (Lower - Step [+ 1]). 8315 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Diff.get()); 8316 if (!Diff.isUsable()) 8317 return nullptr; 8318 } else { 8319 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Lower); 8320 8321 if (!Diff.isUsable() && LCTy->getAsCXXRecordDecl()) { 8322 // BuildBinOp already emitted error, this one is to point user to upper 8323 // and lower bound, and to tell what is passed to 'operator-'. 8324 SemaRef.Diag(Upper->getBeginLoc(), diag::err_omp_loop_diff_cxx) 8325 << Upper->getSourceRange() << Lower->getSourceRange(); 8326 return nullptr; 8327 } 8328 8329 if (!Diff.isUsable()) 8330 return nullptr; 8331 8332 // Upper - Lower [- 1] 8333 if (TestIsStrictOp) 8334 Diff = SemaRef.BuildBinOp( 8335 S, DefaultLoc, BO_Sub, Diff.get(), 8336 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()); 8337 if (!Diff.isUsable()) 8338 return nullptr; 8339 8340 if (RoundToStep) { 8341 // Upper - Lower [- 1] + Step 8342 Diff = 8343 SemaRef.BuildBinOp(S, DefaultLoc, BO_Add, Diff.get(), NewStep.get()); 8344 if (!Diff.isUsable()) 8345 return nullptr; 8346 } 8347 } 8348 8349 // Parentheses (for dumping/debugging purposes only). 8350 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get()); 8351 if (!Diff.isUsable()) 8352 return nullptr; 8353 8354 // (Upper - Lower [- 1] + Step) / Step or (Upper - Lower) / Step 8355 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Div, Diff.get(), NewStep.get()); 8356 if (!Diff.isUsable()) 8357 return nullptr; 8358 8359 return Diff.get(); 8360 } 8361 8362 /// Build the expression to calculate the number of iterations. 8363 Expr *OpenMPIterationSpaceChecker::buildNumIterations( 8364 Scope *S, ArrayRef<LoopIterationSpace> ResultIterSpaces, bool LimitedType, 8365 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const { 8366 QualType VarType = LCDecl->getType().getNonReferenceType(); 8367 if (!VarType->isIntegerType() && !VarType->isPointerType() && 8368 !SemaRef.getLangOpts().CPlusPlus) 8369 return nullptr; 8370 Expr *LBVal = LB; 8371 Expr *UBVal = UB; 8372 // LB = TestIsLessOp.getValue() ? min(LB(MinVal), LB(MaxVal)) : 8373 // max(LB(MinVal), LB(MaxVal)) 8374 if (InitDependOnLC) { 8375 const LoopIterationSpace &IS = ResultIterSpaces[*InitDependOnLC - 1]; 8376 if (!IS.MinValue || !IS.MaxValue) 8377 return nullptr; 8378 // OuterVar = Min 8379 ExprResult MinValue = 8380 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MinValue); 8381 if (!MinValue.isUsable()) 8382 return nullptr; 8383 8384 ExprResult LBMinVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign, 8385 IS.CounterVar, MinValue.get()); 8386 if (!LBMinVal.isUsable()) 8387 return nullptr; 8388 // OuterVar = Min, LBVal 8389 LBMinVal = 8390 SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, LBMinVal.get(), LBVal); 8391 if (!LBMinVal.isUsable()) 8392 return nullptr; 8393 // (OuterVar = Min, LBVal) 8394 LBMinVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, LBMinVal.get()); 8395 if (!LBMinVal.isUsable()) 8396 return nullptr; 8397 8398 // OuterVar = Max 8399 ExprResult MaxValue = 8400 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MaxValue); 8401 if (!MaxValue.isUsable()) 8402 return nullptr; 8403 8404 ExprResult LBMaxVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign, 8405 IS.CounterVar, MaxValue.get()); 8406 if (!LBMaxVal.isUsable()) 8407 return nullptr; 8408 // OuterVar = Max, LBVal 8409 LBMaxVal = 8410 SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, LBMaxVal.get(), LBVal); 8411 if (!LBMaxVal.isUsable()) 8412 return nullptr; 8413 // (OuterVar = Max, LBVal) 8414 LBMaxVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, LBMaxVal.get()); 8415 if (!LBMaxVal.isUsable()) 8416 return nullptr; 8417 8418 Expr *LBMin = tryBuildCapture(SemaRef, LBMinVal.get(), Captures).get(); 8419 Expr *LBMax = tryBuildCapture(SemaRef, LBMaxVal.get(), Captures).get(); 8420 if (!LBMin || !LBMax) 8421 return nullptr; 8422 // LB(MinVal) < LB(MaxVal) 8423 ExprResult MinLessMaxRes = 8424 SemaRef.BuildBinOp(S, DefaultLoc, BO_LT, LBMin, LBMax); 8425 if (!MinLessMaxRes.isUsable()) 8426 return nullptr; 8427 Expr *MinLessMax = 8428 tryBuildCapture(SemaRef, MinLessMaxRes.get(), Captures).get(); 8429 if (!MinLessMax) 8430 return nullptr; 8431 if (*TestIsLessOp) { 8432 // LB(MinVal) < LB(MaxVal) ? LB(MinVal) : LB(MaxVal) - min(LB(MinVal), 8433 // LB(MaxVal)) 8434 ExprResult MinLB = SemaRef.ActOnConditionalOp(DefaultLoc, DefaultLoc, 8435 MinLessMax, LBMin, LBMax); 8436 if (!MinLB.isUsable()) 8437 return nullptr; 8438 LBVal = MinLB.get(); 8439 } else { 8440 // LB(MinVal) < LB(MaxVal) ? LB(MaxVal) : LB(MinVal) - max(LB(MinVal), 8441 // LB(MaxVal)) 8442 ExprResult MaxLB = SemaRef.ActOnConditionalOp(DefaultLoc, DefaultLoc, 8443 MinLessMax, LBMax, LBMin); 8444 if (!MaxLB.isUsable()) 8445 return nullptr; 8446 LBVal = MaxLB.get(); 8447 } 8448 } 8449 // UB = TestIsLessOp.getValue() ? max(UB(MinVal), UB(MaxVal)) : 8450 // min(UB(MinVal), UB(MaxVal)) 8451 if (CondDependOnLC) { 8452 const LoopIterationSpace &IS = ResultIterSpaces[*CondDependOnLC - 1]; 8453 if (!IS.MinValue || !IS.MaxValue) 8454 return nullptr; 8455 // OuterVar = Min 8456 ExprResult MinValue = 8457 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MinValue); 8458 if (!MinValue.isUsable()) 8459 return nullptr; 8460 8461 ExprResult UBMinVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign, 8462 IS.CounterVar, MinValue.get()); 8463 if (!UBMinVal.isUsable()) 8464 return nullptr; 8465 // OuterVar = Min, UBVal 8466 UBMinVal = 8467 SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, UBMinVal.get(), UBVal); 8468 if (!UBMinVal.isUsable()) 8469 return nullptr; 8470 // (OuterVar = Min, UBVal) 8471 UBMinVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, UBMinVal.get()); 8472 if (!UBMinVal.isUsable()) 8473 return nullptr; 8474 8475 // OuterVar = Max 8476 ExprResult MaxValue = 8477 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MaxValue); 8478 if (!MaxValue.isUsable()) 8479 return nullptr; 8480 8481 ExprResult UBMaxVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign, 8482 IS.CounterVar, MaxValue.get()); 8483 if (!UBMaxVal.isUsable()) 8484 return nullptr; 8485 // OuterVar = Max, UBVal 8486 UBMaxVal = 8487 SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, UBMaxVal.get(), UBVal); 8488 if (!UBMaxVal.isUsable()) 8489 return nullptr; 8490 // (OuterVar = Max, UBVal) 8491 UBMaxVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, UBMaxVal.get()); 8492 if (!UBMaxVal.isUsable()) 8493 return nullptr; 8494 8495 Expr *UBMin = tryBuildCapture(SemaRef, UBMinVal.get(), Captures).get(); 8496 Expr *UBMax = tryBuildCapture(SemaRef, UBMaxVal.get(), Captures).get(); 8497 if (!UBMin || !UBMax) 8498 return nullptr; 8499 // UB(MinVal) > UB(MaxVal) 8500 ExprResult MinGreaterMaxRes = 8501 SemaRef.BuildBinOp(S, DefaultLoc, BO_GT, UBMin, UBMax); 8502 if (!MinGreaterMaxRes.isUsable()) 8503 return nullptr; 8504 Expr *MinGreaterMax = 8505 tryBuildCapture(SemaRef, MinGreaterMaxRes.get(), Captures).get(); 8506 if (!MinGreaterMax) 8507 return nullptr; 8508 if (*TestIsLessOp) { 8509 // UB(MinVal) > UB(MaxVal) ? UB(MinVal) : UB(MaxVal) - max(UB(MinVal), 8510 // UB(MaxVal)) 8511 ExprResult MaxUB = SemaRef.ActOnConditionalOp( 8512 DefaultLoc, DefaultLoc, MinGreaterMax, UBMin, UBMax); 8513 if (!MaxUB.isUsable()) 8514 return nullptr; 8515 UBVal = MaxUB.get(); 8516 } else { 8517 // UB(MinVal) > UB(MaxVal) ? UB(MaxVal) : UB(MinVal) - min(UB(MinVal), 8518 // UB(MaxVal)) 8519 ExprResult MinUB = SemaRef.ActOnConditionalOp( 8520 DefaultLoc, DefaultLoc, MinGreaterMax, UBMax, UBMin); 8521 if (!MinUB.isUsable()) 8522 return nullptr; 8523 UBVal = MinUB.get(); 8524 } 8525 } 8526 Expr *UBExpr = TestIsLessOp.getValue() ? UBVal : LBVal; 8527 Expr *LBExpr = TestIsLessOp.getValue() ? LBVal : UBVal; 8528 Expr *Upper = tryBuildCapture(SemaRef, UBExpr, Captures).get(); 8529 Expr *Lower = tryBuildCapture(SemaRef, LBExpr, Captures).get(); 8530 if (!Upper || !Lower) 8531 return nullptr; 8532 8533 ExprResult Diff = calculateNumIters(SemaRef, S, DefaultLoc, Lower, Upper, 8534 Step, VarType, TestIsStrictOp, 8535 /*RoundToStep=*/true, Captures); 8536 if (!Diff.isUsable()) 8537 return nullptr; 8538 8539 // OpenMP runtime requires 32-bit or 64-bit loop variables. 8540 QualType Type = Diff.get()->getType(); 8541 ASTContext &C = SemaRef.Context; 8542 bool UseVarType = VarType->hasIntegerRepresentation() && 8543 C.getTypeSize(Type) > C.getTypeSize(VarType); 8544 if (!Type->isIntegerType() || UseVarType) { 8545 unsigned NewSize = 8546 UseVarType ? C.getTypeSize(VarType) : C.getTypeSize(Type); 8547 bool IsSigned = UseVarType ? VarType->hasSignedIntegerRepresentation() 8548 : Type->hasSignedIntegerRepresentation(); 8549 Type = C.getIntTypeForBitwidth(NewSize, IsSigned); 8550 if (!SemaRef.Context.hasSameType(Diff.get()->getType(), Type)) { 8551 Diff = SemaRef.PerformImplicitConversion( 8552 Diff.get(), Type, Sema::AA_Converting, /*AllowExplicit=*/true); 8553 if (!Diff.isUsable()) 8554 return nullptr; 8555 } 8556 } 8557 if (LimitedType) { 8558 unsigned NewSize = (C.getTypeSize(Type) > 32) ? 64 : 32; 8559 if (NewSize != C.getTypeSize(Type)) { 8560 if (NewSize < C.getTypeSize(Type)) { 8561 assert(NewSize == 64 && "incorrect loop var size"); 8562 SemaRef.Diag(DefaultLoc, diag::warn_omp_loop_64_bit_var) 8563 << InitSrcRange << ConditionSrcRange; 8564 } 8565 QualType NewType = C.getIntTypeForBitwidth( 8566 NewSize, Type->hasSignedIntegerRepresentation() || 8567 C.getTypeSize(Type) < NewSize); 8568 if (!SemaRef.Context.hasSameType(Diff.get()->getType(), NewType)) { 8569 Diff = SemaRef.PerformImplicitConversion(Diff.get(), NewType, 8570 Sema::AA_Converting, true); 8571 if (!Diff.isUsable()) 8572 return nullptr; 8573 } 8574 } 8575 } 8576 8577 return Diff.get(); 8578 } 8579 8580 std::pair<Expr *, Expr *> OpenMPIterationSpaceChecker::buildMinMaxValues( 8581 Scope *S, llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const { 8582 // Do not build for iterators, they cannot be used in non-rectangular loop 8583 // nests. 8584 if (LCDecl->getType()->isRecordType()) 8585 return std::make_pair(nullptr, nullptr); 8586 // If we subtract, the min is in the condition, otherwise the min is in the 8587 // init value. 8588 Expr *MinExpr = nullptr; 8589 Expr *MaxExpr = nullptr; 8590 Expr *LBExpr = TestIsLessOp.getValue() ? LB : UB; 8591 Expr *UBExpr = TestIsLessOp.getValue() ? UB : LB; 8592 bool LBNonRect = TestIsLessOp.getValue() ? InitDependOnLC.hasValue() 8593 : CondDependOnLC.hasValue(); 8594 bool UBNonRect = TestIsLessOp.getValue() ? CondDependOnLC.hasValue() 8595 : InitDependOnLC.hasValue(); 8596 Expr *Lower = 8597 LBNonRect ? LBExpr : tryBuildCapture(SemaRef, LBExpr, Captures).get(); 8598 Expr *Upper = 8599 UBNonRect ? UBExpr : tryBuildCapture(SemaRef, UBExpr, Captures).get(); 8600 if (!Upper || !Lower) 8601 return std::make_pair(nullptr, nullptr); 8602 8603 if (*TestIsLessOp) 8604 MinExpr = Lower; 8605 else 8606 MaxExpr = Upper; 8607 8608 // Build minimum/maximum value based on number of iterations. 8609 QualType VarType = LCDecl->getType().getNonReferenceType(); 8610 8611 ExprResult Diff = calculateNumIters(SemaRef, S, DefaultLoc, Lower, Upper, 8612 Step, VarType, TestIsStrictOp, 8613 /*RoundToStep=*/false, Captures); 8614 if (!Diff.isUsable()) 8615 return std::make_pair(nullptr, nullptr); 8616 8617 // ((Upper - Lower [- 1]) / Step) * Step 8618 // Parentheses (for dumping/debugging purposes only). 8619 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get()); 8620 if (!Diff.isUsable()) 8621 return std::make_pair(nullptr, nullptr); 8622 8623 ExprResult NewStep = tryBuildCapture(SemaRef, Step, Captures); 8624 if (!NewStep.isUsable()) 8625 return std::make_pair(nullptr, nullptr); 8626 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Mul, Diff.get(), NewStep.get()); 8627 if (!Diff.isUsable()) 8628 return std::make_pair(nullptr, nullptr); 8629 8630 // Parentheses (for dumping/debugging purposes only). 8631 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get()); 8632 if (!Diff.isUsable()) 8633 return std::make_pair(nullptr, nullptr); 8634 8635 // Convert to the ptrdiff_t, if original type is pointer. 8636 if (VarType->isAnyPointerType() && 8637 !SemaRef.Context.hasSameType( 8638 Diff.get()->getType(), 8639 SemaRef.Context.getUnsignedPointerDiffType())) { 8640 Diff = SemaRef.PerformImplicitConversion( 8641 Diff.get(), SemaRef.Context.getUnsignedPointerDiffType(), 8642 Sema::AA_Converting, /*AllowExplicit=*/true); 8643 } 8644 if (!Diff.isUsable()) 8645 return std::make_pair(nullptr, nullptr); 8646 8647 if (*TestIsLessOp) { 8648 // MinExpr = Lower; 8649 // MaxExpr = Lower + (((Upper - Lower [- 1]) / Step) * Step) 8650 Diff = SemaRef.BuildBinOp( 8651 S, DefaultLoc, BO_Add, 8652 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Lower).get(), 8653 Diff.get()); 8654 if (!Diff.isUsable()) 8655 return std::make_pair(nullptr, nullptr); 8656 } else { 8657 // MaxExpr = Upper; 8658 // MinExpr = Upper - (((Upper - Lower [- 1]) / Step) * Step) 8659 Diff = SemaRef.BuildBinOp( 8660 S, DefaultLoc, BO_Sub, 8661 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Upper).get(), 8662 Diff.get()); 8663 if (!Diff.isUsable()) 8664 return std::make_pair(nullptr, nullptr); 8665 } 8666 8667 // Convert to the original type. 8668 if (SemaRef.Context.hasSameType(Diff.get()->getType(), VarType)) 8669 Diff = SemaRef.PerformImplicitConversion(Diff.get(), VarType, 8670 Sema::AA_Converting, 8671 /*AllowExplicit=*/true); 8672 if (!Diff.isUsable()) 8673 return std::make_pair(nullptr, nullptr); 8674 8675 Sema::TentativeAnalysisScope Trap(SemaRef); 8676 Diff = SemaRef.ActOnFinishFullExpr(Diff.get(), /*DiscardedValue=*/false); 8677 if (!Diff.isUsable()) 8678 return std::make_pair(nullptr, nullptr); 8679 8680 if (*TestIsLessOp) 8681 MaxExpr = Diff.get(); 8682 else 8683 MinExpr = Diff.get(); 8684 8685 return std::make_pair(MinExpr, MaxExpr); 8686 } 8687 8688 Expr *OpenMPIterationSpaceChecker::buildFinalCondition(Scope *S) const { 8689 if (InitDependOnLC || CondDependOnLC) 8690 return Condition; 8691 return nullptr; 8692 } 8693 8694 Expr *OpenMPIterationSpaceChecker::buildPreCond( 8695 Scope *S, Expr *Cond, 8696 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const { 8697 // Do not build a precondition when the condition/initialization is dependent 8698 // to prevent pessimistic early loop exit. 8699 // TODO: this can be improved by calculating min/max values but not sure that 8700 // it will be very effective. 8701 if (CondDependOnLC || InitDependOnLC) 8702 return SemaRef 8703 .PerformImplicitConversion( 8704 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get(), 8705 SemaRef.Context.BoolTy, /*Action=*/Sema::AA_Casting, 8706 /*AllowExplicit=*/true) 8707 .get(); 8708 8709 // Try to build LB <op> UB, where <op> is <, >, <=, or >=. 8710 Sema::TentativeAnalysisScope Trap(SemaRef); 8711 8712 ExprResult NewLB = tryBuildCapture(SemaRef, LB, Captures); 8713 ExprResult NewUB = tryBuildCapture(SemaRef, UB, Captures); 8714 if (!NewLB.isUsable() || !NewUB.isUsable()) 8715 return nullptr; 8716 8717 ExprResult CondExpr = SemaRef.BuildBinOp( 8718 S, DefaultLoc, 8719 TestIsLessOp.getValue() ? (TestIsStrictOp ? BO_LT : BO_LE) 8720 : (TestIsStrictOp ? BO_GT : BO_GE), 8721 NewLB.get(), NewUB.get()); 8722 if (CondExpr.isUsable()) { 8723 if (!SemaRef.Context.hasSameUnqualifiedType(CondExpr.get()->getType(), 8724 SemaRef.Context.BoolTy)) 8725 CondExpr = SemaRef.PerformImplicitConversion( 8726 CondExpr.get(), SemaRef.Context.BoolTy, /*Action=*/Sema::AA_Casting, 8727 /*AllowExplicit=*/true); 8728 } 8729 8730 // Otherwise use original loop condition and evaluate it in runtime. 8731 return CondExpr.isUsable() ? CondExpr.get() : Cond; 8732 } 8733 8734 /// Build reference expression to the counter be used for codegen. 8735 DeclRefExpr *OpenMPIterationSpaceChecker::buildCounterVar( 8736 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures, 8737 DSAStackTy &DSA) const { 8738 auto *VD = dyn_cast<VarDecl>(LCDecl); 8739 if (!VD) { 8740 VD = SemaRef.isOpenMPCapturedDecl(LCDecl); 8741 DeclRefExpr *Ref = buildDeclRefExpr( 8742 SemaRef, VD, VD->getType().getNonReferenceType(), DefaultLoc); 8743 const DSAStackTy::DSAVarData Data = 8744 DSA.getTopDSA(LCDecl, /*FromParent=*/false); 8745 // If the loop control decl is explicitly marked as private, do not mark it 8746 // as captured again. 8747 if (!isOpenMPPrivate(Data.CKind) || !Data.RefExpr) 8748 Captures.insert(std::make_pair(LCRef, Ref)); 8749 return Ref; 8750 } 8751 return cast<DeclRefExpr>(LCRef); 8752 } 8753 8754 Expr *OpenMPIterationSpaceChecker::buildPrivateCounterVar() const { 8755 if (LCDecl && !LCDecl->isInvalidDecl()) { 8756 QualType Type = LCDecl->getType().getNonReferenceType(); 8757 VarDecl *PrivateVar = buildVarDecl( 8758 SemaRef, DefaultLoc, Type, LCDecl->getName(), 8759 LCDecl->hasAttrs() ? &LCDecl->getAttrs() : nullptr, 8760 isa<VarDecl>(LCDecl) 8761 ? buildDeclRefExpr(SemaRef, cast<VarDecl>(LCDecl), Type, DefaultLoc) 8762 : nullptr); 8763 if (PrivateVar->isInvalidDecl()) 8764 return nullptr; 8765 return buildDeclRefExpr(SemaRef, PrivateVar, Type, DefaultLoc); 8766 } 8767 return nullptr; 8768 } 8769 8770 /// Build initialization of the counter to be used for codegen. 8771 Expr *OpenMPIterationSpaceChecker::buildCounterInit() const { return LB; } 8772 8773 /// Build step of the counter be used for codegen. 8774 Expr *OpenMPIterationSpaceChecker::buildCounterStep() const { return Step; } 8775 8776 Expr *OpenMPIterationSpaceChecker::buildOrderedLoopData( 8777 Scope *S, Expr *Counter, 8778 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures, SourceLocation Loc, 8779 Expr *Inc, OverloadedOperatorKind OOK) { 8780 Expr *Cnt = SemaRef.DefaultLvalueConversion(Counter).get(); 8781 if (!Cnt) 8782 return nullptr; 8783 if (Inc) { 8784 assert((OOK == OO_Plus || OOK == OO_Minus) && 8785 "Expected only + or - operations for depend clauses."); 8786 BinaryOperatorKind BOK = (OOK == OO_Plus) ? BO_Add : BO_Sub; 8787 Cnt = SemaRef.BuildBinOp(S, Loc, BOK, Cnt, Inc).get(); 8788 if (!Cnt) 8789 return nullptr; 8790 } 8791 QualType VarType = LCDecl->getType().getNonReferenceType(); 8792 if (!VarType->isIntegerType() && !VarType->isPointerType() && 8793 !SemaRef.getLangOpts().CPlusPlus) 8794 return nullptr; 8795 // Upper - Lower 8796 Expr *Upper = TestIsLessOp.getValue() 8797 ? Cnt 8798 : tryBuildCapture(SemaRef, LB, Captures).get(); 8799 Expr *Lower = TestIsLessOp.getValue() 8800 ? tryBuildCapture(SemaRef, LB, Captures).get() 8801 : Cnt; 8802 if (!Upper || !Lower) 8803 return nullptr; 8804 8805 ExprResult Diff = calculateNumIters( 8806 SemaRef, S, DefaultLoc, Lower, Upper, Step, VarType, 8807 /*TestIsStrictOp=*/false, /*RoundToStep=*/false, Captures); 8808 if (!Diff.isUsable()) 8809 return nullptr; 8810 8811 return Diff.get(); 8812 } 8813 } // namespace 8814 8815 void Sema::ActOnOpenMPLoopInitialization(SourceLocation ForLoc, Stmt *Init) { 8816 assert(getLangOpts().OpenMP && "OpenMP is not active."); 8817 assert(Init && "Expected loop in canonical form."); 8818 unsigned AssociatedLoops = DSAStack->getAssociatedLoops(); 8819 if (AssociatedLoops > 0 && 8820 isOpenMPLoopDirective(DSAStack->getCurrentDirective())) { 8821 DSAStack->loopStart(); 8822 OpenMPIterationSpaceChecker ISC(*this, /*SupportsNonRectangular=*/true, 8823 *DSAStack, ForLoc); 8824 if (!ISC.checkAndSetInit(Init, /*EmitDiags=*/false)) { 8825 if (ValueDecl *D = ISC.getLoopDecl()) { 8826 auto *VD = dyn_cast<VarDecl>(D); 8827 DeclRefExpr *PrivateRef = nullptr; 8828 if (!VD) { 8829 if (VarDecl *Private = isOpenMPCapturedDecl(D)) { 8830 VD = Private; 8831 } else { 8832 PrivateRef = buildCapture(*this, D, ISC.getLoopDeclRefExpr(), 8833 /*WithInit=*/false); 8834 VD = cast<VarDecl>(PrivateRef->getDecl()); 8835 } 8836 } 8837 DSAStack->addLoopControlVariable(D, VD); 8838 const Decl *LD = DSAStack->getPossiblyLoopCunter(); 8839 if (LD != D->getCanonicalDecl()) { 8840 DSAStack->resetPossibleLoopCounter(); 8841 if (auto *Var = dyn_cast_or_null<VarDecl>(LD)) 8842 MarkDeclarationsReferencedInExpr( 8843 buildDeclRefExpr(*this, const_cast<VarDecl *>(Var), 8844 Var->getType().getNonLValueExprType(Context), 8845 ForLoc, /*RefersToCapture=*/true)); 8846 } 8847 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 8848 // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables 8849 // Referenced in a Construct, C/C++]. The loop iteration variable in the 8850 // associated for-loop of a simd construct with just one associated 8851 // for-loop may be listed in a linear clause with a constant-linear-step 8852 // that is the increment of the associated for-loop. The loop iteration 8853 // variable(s) in the associated for-loop(s) of a for or parallel for 8854 // construct may be listed in a private or lastprivate clause. 8855 DSAStackTy::DSAVarData DVar = 8856 DSAStack->getTopDSA(D, /*FromParent=*/false); 8857 // If LoopVarRefExpr is nullptr it means the corresponding loop variable 8858 // is declared in the loop and it is predetermined as a private. 8859 Expr *LoopDeclRefExpr = ISC.getLoopDeclRefExpr(); 8860 OpenMPClauseKind PredeterminedCKind = 8861 isOpenMPSimdDirective(DKind) 8862 ? (DSAStack->hasMutipleLoops() ? OMPC_lastprivate : OMPC_linear) 8863 : OMPC_private; 8864 if (((isOpenMPSimdDirective(DKind) && DVar.CKind != OMPC_unknown && 8865 DVar.CKind != PredeterminedCKind && DVar.RefExpr && 8866 (LangOpts.OpenMP <= 45 || (DVar.CKind != OMPC_lastprivate && 8867 DVar.CKind != OMPC_private))) || 8868 ((isOpenMPWorksharingDirective(DKind) || DKind == OMPD_taskloop || 8869 DKind == OMPD_master_taskloop || 8870 DKind == OMPD_parallel_master_taskloop || 8871 isOpenMPDistributeDirective(DKind)) && 8872 !isOpenMPSimdDirective(DKind) && DVar.CKind != OMPC_unknown && 8873 DVar.CKind != OMPC_private && DVar.CKind != OMPC_lastprivate)) && 8874 (DVar.CKind != OMPC_private || DVar.RefExpr)) { 8875 Diag(Init->getBeginLoc(), diag::err_omp_loop_var_dsa) 8876 << getOpenMPClauseName(DVar.CKind) 8877 << getOpenMPDirectiveName(DKind) 8878 << getOpenMPClauseName(PredeterminedCKind); 8879 if (DVar.RefExpr == nullptr) 8880 DVar.CKind = PredeterminedCKind; 8881 reportOriginalDsa(*this, DSAStack, D, DVar, 8882 /*IsLoopIterVar=*/true); 8883 } else if (LoopDeclRefExpr) { 8884 // Make the loop iteration variable private (for worksharing 8885 // constructs), linear (for simd directives with the only one 8886 // associated loop) or lastprivate (for simd directives with several 8887 // collapsed or ordered loops). 8888 if (DVar.CKind == OMPC_unknown) 8889 DSAStack->addDSA(D, LoopDeclRefExpr, PredeterminedCKind, 8890 PrivateRef); 8891 } 8892 } 8893 } 8894 DSAStack->setAssociatedLoops(AssociatedLoops - 1); 8895 } 8896 } 8897 8898 /// Called on a for stmt to check and extract its iteration space 8899 /// for further processing (such as collapsing). 8900 static bool checkOpenMPIterationSpace( 8901 OpenMPDirectiveKind DKind, Stmt *S, Sema &SemaRef, DSAStackTy &DSA, 8902 unsigned CurrentNestedLoopCount, unsigned NestedLoopCount, 8903 unsigned TotalNestedLoopCount, Expr *CollapseLoopCountExpr, 8904 Expr *OrderedLoopCountExpr, 8905 Sema::VarsWithInheritedDSAType &VarsWithImplicitDSA, 8906 llvm::MutableArrayRef<LoopIterationSpace> ResultIterSpaces, 8907 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) { 8908 bool SupportsNonRectangular = !isOpenMPLoopTransformationDirective(DKind); 8909 // OpenMP [2.9.1, Canonical Loop Form] 8910 // for (init-expr; test-expr; incr-expr) structured-block 8911 // for (range-decl: range-expr) structured-block 8912 if (auto *CanonLoop = dyn_cast_or_null<OMPCanonicalLoop>(S)) 8913 S = CanonLoop->getLoopStmt(); 8914 auto *For = dyn_cast_or_null<ForStmt>(S); 8915 auto *CXXFor = dyn_cast_or_null<CXXForRangeStmt>(S); 8916 // Ranged for is supported only in OpenMP 5.0. 8917 if (!For && (SemaRef.LangOpts.OpenMP <= 45 || !CXXFor)) { 8918 SemaRef.Diag(S->getBeginLoc(), diag::err_omp_not_for) 8919 << (CollapseLoopCountExpr != nullptr || OrderedLoopCountExpr != nullptr) 8920 << getOpenMPDirectiveName(DKind) << TotalNestedLoopCount 8921 << (CurrentNestedLoopCount > 0) << CurrentNestedLoopCount; 8922 if (TotalNestedLoopCount > 1) { 8923 if (CollapseLoopCountExpr && OrderedLoopCountExpr) 8924 SemaRef.Diag(DSA.getConstructLoc(), 8925 diag::note_omp_collapse_ordered_expr) 8926 << 2 << CollapseLoopCountExpr->getSourceRange() 8927 << OrderedLoopCountExpr->getSourceRange(); 8928 else if (CollapseLoopCountExpr) 8929 SemaRef.Diag(CollapseLoopCountExpr->getExprLoc(), 8930 diag::note_omp_collapse_ordered_expr) 8931 << 0 << CollapseLoopCountExpr->getSourceRange(); 8932 else 8933 SemaRef.Diag(OrderedLoopCountExpr->getExprLoc(), 8934 diag::note_omp_collapse_ordered_expr) 8935 << 1 << OrderedLoopCountExpr->getSourceRange(); 8936 } 8937 return true; 8938 } 8939 assert(((For && For->getBody()) || (CXXFor && CXXFor->getBody())) && 8940 "No loop body."); 8941 // Postpone analysis in dependent contexts for ranged for loops. 8942 if (CXXFor && SemaRef.CurContext->isDependentContext()) 8943 return false; 8944 8945 OpenMPIterationSpaceChecker ISC(SemaRef, SupportsNonRectangular, DSA, 8946 For ? For->getForLoc() : CXXFor->getForLoc()); 8947 8948 // Check init. 8949 Stmt *Init = For ? For->getInit() : CXXFor->getBeginStmt(); 8950 if (ISC.checkAndSetInit(Init)) 8951 return true; 8952 8953 bool HasErrors = false; 8954 8955 // Check loop variable's type. 8956 if (ValueDecl *LCDecl = ISC.getLoopDecl()) { 8957 // OpenMP [2.6, Canonical Loop Form] 8958 // Var is one of the following: 8959 // A variable of signed or unsigned integer type. 8960 // For C++, a variable of a random access iterator type. 8961 // For C, a variable of a pointer type. 8962 QualType VarType = LCDecl->getType().getNonReferenceType(); 8963 if (!VarType->isDependentType() && !VarType->isIntegerType() && 8964 !VarType->isPointerType() && 8965 !(SemaRef.getLangOpts().CPlusPlus && VarType->isOverloadableType())) { 8966 SemaRef.Diag(Init->getBeginLoc(), diag::err_omp_loop_variable_type) 8967 << SemaRef.getLangOpts().CPlusPlus; 8968 HasErrors = true; 8969 } 8970 8971 // OpenMP, 2.14.1.1 Data-sharing Attribute Rules for Variables Referenced in 8972 // a Construct 8973 // The loop iteration variable(s) in the associated for-loop(s) of a for or 8974 // parallel for construct is (are) private. 8975 // The loop iteration variable in the associated for-loop of a simd 8976 // construct with just one associated for-loop is linear with a 8977 // constant-linear-step that is the increment of the associated for-loop. 8978 // Exclude loop var from the list of variables with implicitly defined data 8979 // sharing attributes. 8980 VarsWithImplicitDSA.erase(LCDecl); 8981 8982 assert(isOpenMPLoopDirective(DKind) && "DSA for non-loop vars"); 8983 8984 // Check test-expr. 8985 HasErrors |= ISC.checkAndSetCond(For ? For->getCond() : CXXFor->getCond()); 8986 8987 // Check incr-expr. 8988 HasErrors |= ISC.checkAndSetInc(For ? For->getInc() : CXXFor->getInc()); 8989 } 8990 8991 if (ISC.dependent() || SemaRef.CurContext->isDependentContext() || HasErrors) 8992 return HasErrors; 8993 8994 // Build the loop's iteration space representation. 8995 ResultIterSpaces[CurrentNestedLoopCount].PreCond = ISC.buildPreCond( 8996 DSA.getCurScope(), For ? For->getCond() : CXXFor->getCond(), Captures); 8997 ResultIterSpaces[CurrentNestedLoopCount].NumIterations = 8998 ISC.buildNumIterations(DSA.getCurScope(), ResultIterSpaces, 8999 (isOpenMPWorksharingDirective(DKind) || 9000 isOpenMPGenericLoopDirective(DKind) || 9001 isOpenMPTaskLoopDirective(DKind) || 9002 isOpenMPDistributeDirective(DKind) || 9003 isOpenMPLoopTransformationDirective(DKind)), 9004 Captures); 9005 ResultIterSpaces[CurrentNestedLoopCount].CounterVar = 9006 ISC.buildCounterVar(Captures, DSA); 9007 ResultIterSpaces[CurrentNestedLoopCount].PrivateCounterVar = 9008 ISC.buildPrivateCounterVar(); 9009 ResultIterSpaces[CurrentNestedLoopCount].CounterInit = ISC.buildCounterInit(); 9010 ResultIterSpaces[CurrentNestedLoopCount].CounterStep = ISC.buildCounterStep(); 9011 ResultIterSpaces[CurrentNestedLoopCount].InitSrcRange = ISC.getInitSrcRange(); 9012 ResultIterSpaces[CurrentNestedLoopCount].CondSrcRange = 9013 ISC.getConditionSrcRange(); 9014 ResultIterSpaces[CurrentNestedLoopCount].IncSrcRange = 9015 ISC.getIncrementSrcRange(); 9016 ResultIterSpaces[CurrentNestedLoopCount].Subtract = ISC.shouldSubtractStep(); 9017 ResultIterSpaces[CurrentNestedLoopCount].IsStrictCompare = 9018 ISC.isStrictTestOp(); 9019 std::tie(ResultIterSpaces[CurrentNestedLoopCount].MinValue, 9020 ResultIterSpaces[CurrentNestedLoopCount].MaxValue) = 9021 ISC.buildMinMaxValues(DSA.getCurScope(), Captures); 9022 ResultIterSpaces[CurrentNestedLoopCount].FinalCondition = 9023 ISC.buildFinalCondition(DSA.getCurScope()); 9024 ResultIterSpaces[CurrentNestedLoopCount].IsNonRectangularLB = 9025 ISC.doesInitDependOnLC(); 9026 ResultIterSpaces[CurrentNestedLoopCount].IsNonRectangularUB = 9027 ISC.doesCondDependOnLC(); 9028 ResultIterSpaces[CurrentNestedLoopCount].LoopDependentIdx = 9029 ISC.getLoopDependentIdx(); 9030 9031 HasErrors |= 9032 (ResultIterSpaces[CurrentNestedLoopCount].PreCond == nullptr || 9033 ResultIterSpaces[CurrentNestedLoopCount].NumIterations == nullptr || 9034 ResultIterSpaces[CurrentNestedLoopCount].CounterVar == nullptr || 9035 ResultIterSpaces[CurrentNestedLoopCount].PrivateCounterVar == nullptr || 9036 ResultIterSpaces[CurrentNestedLoopCount].CounterInit == nullptr || 9037 ResultIterSpaces[CurrentNestedLoopCount].CounterStep == nullptr); 9038 if (!HasErrors && DSA.isOrderedRegion()) { 9039 if (DSA.getOrderedRegionParam().second->getNumForLoops()) { 9040 if (CurrentNestedLoopCount < 9041 DSA.getOrderedRegionParam().second->getLoopNumIterations().size()) { 9042 DSA.getOrderedRegionParam().second->setLoopNumIterations( 9043 CurrentNestedLoopCount, 9044 ResultIterSpaces[CurrentNestedLoopCount].NumIterations); 9045 DSA.getOrderedRegionParam().second->setLoopCounter( 9046 CurrentNestedLoopCount, 9047 ResultIterSpaces[CurrentNestedLoopCount].CounterVar); 9048 } 9049 } 9050 for (auto &Pair : DSA.getDoacrossDependClauses()) { 9051 if (CurrentNestedLoopCount >= Pair.first->getNumLoops()) { 9052 // Erroneous case - clause has some problems. 9053 continue; 9054 } 9055 if (Pair.first->getDependencyKind() == OMPC_DEPEND_sink && 9056 Pair.second.size() <= CurrentNestedLoopCount) { 9057 // Erroneous case - clause has some problems. 9058 Pair.first->setLoopData(CurrentNestedLoopCount, nullptr); 9059 continue; 9060 } 9061 Expr *CntValue; 9062 if (Pair.first->getDependencyKind() == OMPC_DEPEND_source) 9063 CntValue = ISC.buildOrderedLoopData( 9064 DSA.getCurScope(), 9065 ResultIterSpaces[CurrentNestedLoopCount].CounterVar, Captures, 9066 Pair.first->getDependencyLoc()); 9067 else 9068 CntValue = ISC.buildOrderedLoopData( 9069 DSA.getCurScope(), 9070 ResultIterSpaces[CurrentNestedLoopCount].CounterVar, Captures, 9071 Pair.first->getDependencyLoc(), 9072 Pair.second[CurrentNestedLoopCount].first, 9073 Pair.second[CurrentNestedLoopCount].second); 9074 Pair.first->setLoopData(CurrentNestedLoopCount, CntValue); 9075 } 9076 } 9077 9078 return HasErrors; 9079 } 9080 9081 /// Build 'VarRef = Start. 9082 static ExprResult 9083 buildCounterInit(Sema &SemaRef, Scope *S, SourceLocation Loc, ExprResult VarRef, 9084 ExprResult Start, bool IsNonRectangularLB, 9085 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) { 9086 // Build 'VarRef = Start. 9087 ExprResult NewStart = IsNonRectangularLB 9088 ? Start.get() 9089 : tryBuildCapture(SemaRef, Start.get(), Captures); 9090 if (!NewStart.isUsable()) 9091 return ExprError(); 9092 if (!SemaRef.Context.hasSameType(NewStart.get()->getType(), 9093 VarRef.get()->getType())) { 9094 NewStart = SemaRef.PerformImplicitConversion( 9095 NewStart.get(), VarRef.get()->getType(), Sema::AA_Converting, 9096 /*AllowExplicit=*/true); 9097 if (!NewStart.isUsable()) 9098 return ExprError(); 9099 } 9100 9101 ExprResult Init = 9102 SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), NewStart.get()); 9103 return Init; 9104 } 9105 9106 /// Build 'VarRef = Start + Iter * Step'. 9107 static ExprResult buildCounterUpdate( 9108 Sema &SemaRef, Scope *S, SourceLocation Loc, ExprResult VarRef, 9109 ExprResult Start, ExprResult Iter, ExprResult Step, bool Subtract, 9110 bool IsNonRectangularLB, 9111 llvm::MapVector<const Expr *, DeclRefExpr *> *Captures = nullptr) { 9112 // Add parentheses (for debugging purposes only). 9113 Iter = SemaRef.ActOnParenExpr(Loc, Loc, Iter.get()); 9114 if (!VarRef.isUsable() || !Start.isUsable() || !Iter.isUsable() || 9115 !Step.isUsable()) 9116 return ExprError(); 9117 9118 ExprResult NewStep = Step; 9119 if (Captures) 9120 NewStep = tryBuildCapture(SemaRef, Step.get(), *Captures); 9121 if (NewStep.isInvalid()) 9122 return ExprError(); 9123 ExprResult Update = 9124 SemaRef.BuildBinOp(S, Loc, BO_Mul, Iter.get(), NewStep.get()); 9125 if (!Update.isUsable()) 9126 return ExprError(); 9127 9128 // Try to build 'VarRef = Start, VarRef (+|-)= Iter * Step' or 9129 // 'VarRef = Start (+|-) Iter * Step'. 9130 if (!Start.isUsable()) 9131 return ExprError(); 9132 ExprResult NewStart = SemaRef.ActOnParenExpr(Loc, Loc, Start.get()); 9133 if (!NewStart.isUsable()) 9134 return ExprError(); 9135 if (Captures && !IsNonRectangularLB) 9136 NewStart = tryBuildCapture(SemaRef, Start.get(), *Captures); 9137 if (NewStart.isInvalid()) 9138 return ExprError(); 9139 9140 // First attempt: try to build 'VarRef = Start, VarRef += Iter * Step'. 9141 ExprResult SavedUpdate = Update; 9142 ExprResult UpdateVal; 9143 if (VarRef.get()->getType()->isOverloadableType() || 9144 NewStart.get()->getType()->isOverloadableType() || 9145 Update.get()->getType()->isOverloadableType()) { 9146 Sema::TentativeAnalysisScope Trap(SemaRef); 9147 9148 Update = 9149 SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), NewStart.get()); 9150 if (Update.isUsable()) { 9151 UpdateVal = 9152 SemaRef.BuildBinOp(S, Loc, Subtract ? BO_SubAssign : BO_AddAssign, 9153 VarRef.get(), SavedUpdate.get()); 9154 if (UpdateVal.isUsable()) { 9155 Update = SemaRef.CreateBuiltinBinOp(Loc, BO_Comma, Update.get(), 9156 UpdateVal.get()); 9157 } 9158 } 9159 } 9160 9161 // Second attempt: try to build 'VarRef = Start (+|-) Iter * Step'. 9162 if (!Update.isUsable() || !UpdateVal.isUsable()) { 9163 Update = SemaRef.BuildBinOp(S, Loc, Subtract ? BO_Sub : BO_Add, 9164 NewStart.get(), SavedUpdate.get()); 9165 if (!Update.isUsable()) 9166 return ExprError(); 9167 9168 if (!SemaRef.Context.hasSameType(Update.get()->getType(), 9169 VarRef.get()->getType())) { 9170 Update = SemaRef.PerformImplicitConversion( 9171 Update.get(), VarRef.get()->getType(), Sema::AA_Converting, true); 9172 if (!Update.isUsable()) 9173 return ExprError(); 9174 } 9175 9176 Update = SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), Update.get()); 9177 } 9178 return Update; 9179 } 9180 9181 /// Convert integer expression \a E to make it have at least \a Bits 9182 /// bits. 9183 static ExprResult widenIterationCount(unsigned Bits, Expr *E, Sema &SemaRef) { 9184 if (E == nullptr) 9185 return ExprError(); 9186 ASTContext &C = SemaRef.Context; 9187 QualType OldType = E->getType(); 9188 unsigned HasBits = C.getTypeSize(OldType); 9189 if (HasBits >= Bits) 9190 return ExprResult(E); 9191 // OK to convert to signed, because new type has more bits than old. 9192 QualType NewType = C.getIntTypeForBitwidth(Bits, /* Signed */ true); 9193 return SemaRef.PerformImplicitConversion(E, NewType, Sema::AA_Converting, 9194 true); 9195 } 9196 9197 /// Check if the given expression \a E is a constant integer that fits 9198 /// into \a Bits bits. 9199 static bool fitsInto(unsigned Bits, bool Signed, const Expr *E, Sema &SemaRef) { 9200 if (E == nullptr) 9201 return false; 9202 if (Optional<llvm::APSInt> Result = 9203 E->getIntegerConstantExpr(SemaRef.Context)) 9204 return Signed ? Result->isSignedIntN(Bits) : Result->isIntN(Bits); 9205 return false; 9206 } 9207 9208 /// Build preinits statement for the given declarations. 9209 static Stmt *buildPreInits(ASTContext &Context, 9210 MutableArrayRef<Decl *> PreInits) { 9211 if (!PreInits.empty()) { 9212 return new (Context) DeclStmt( 9213 DeclGroupRef::Create(Context, PreInits.begin(), PreInits.size()), 9214 SourceLocation(), SourceLocation()); 9215 } 9216 return nullptr; 9217 } 9218 9219 /// Build preinits statement for the given declarations. 9220 static Stmt * 9221 buildPreInits(ASTContext &Context, 9222 const llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) { 9223 if (!Captures.empty()) { 9224 SmallVector<Decl *, 16> PreInits; 9225 for (const auto &Pair : Captures) 9226 PreInits.push_back(Pair.second->getDecl()); 9227 return buildPreInits(Context, PreInits); 9228 } 9229 return nullptr; 9230 } 9231 9232 /// Build postupdate expression for the given list of postupdates expressions. 9233 static Expr *buildPostUpdate(Sema &S, ArrayRef<Expr *> PostUpdates) { 9234 Expr *PostUpdate = nullptr; 9235 if (!PostUpdates.empty()) { 9236 for (Expr *E : PostUpdates) { 9237 Expr *ConvE = S.BuildCStyleCastExpr( 9238 E->getExprLoc(), 9239 S.Context.getTrivialTypeSourceInfo(S.Context.VoidTy), 9240 E->getExprLoc(), E) 9241 .get(); 9242 PostUpdate = PostUpdate 9243 ? S.CreateBuiltinBinOp(ConvE->getExprLoc(), BO_Comma, 9244 PostUpdate, ConvE) 9245 .get() 9246 : ConvE; 9247 } 9248 } 9249 return PostUpdate; 9250 } 9251 9252 /// Called on a for stmt to check itself and nested loops (if any). 9253 /// \return Returns 0 if one of the collapsed stmts is not canonical for loop, 9254 /// number of collapsed loops otherwise. 9255 static unsigned 9256 checkOpenMPLoop(OpenMPDirectiveKind DKind, Expr *CollapseLoopCountExpr, 9257 Expr *OrderedLoopCountExpr, Stmt *AStmt, Sema &SemaRef, 9258 DSAStackTy &DSA, 9259 Sema::VarsWithInheritedDSAType &VarsWithImplicitDSA, 9260 OMPLoopBasedDirective::HelperExprs &Built) { 9261 unsigned NestedLoopCount = 1; 9262 bool SupportsNonPerfectlyNested = (SemaRef.LangOpts.OpenMP >= 50) && 9263 !isOpenMPLoopTransformationDirective(DKind); 9264 9265 if (CollapseLoopCountExpr) { 9266 // Found 'collapse' clause - calculate collapse number. 9267 Expr::EvalResult Result; 9268 if (!CollapseLoopCountExpr->isValueDependent() && 9269 CollapseLoopCountExpr->EvaluateAsInt(Result, SemaRef.getASTContext())) { 9270 NestedLoopCount = Result.Val.getInt().getLimitedValue(); 9271 } else { 9272 Built.clear(/*Size=*/1); 9273 return 1; 9274 } 9275 } 9276 unsigned OrderedLoopCount = 1; 9277 if (OrderedLoopCountExpr) { 9278 // Found 'ordered' clause - calculate collapse number. 9279 Expr::EvalResult EVResult; 9280 if (!OrderedLoopCountExpr->isValueDependent() && 9281 OrderedLoopCountExpr->EvaluateAsInt(EVResult, 9282 SemaRef.getASTContext())) { 9283 llvm::APSInt Result = EVResult.Val.getInt(); 9284 if (Result.getLimitedValue() < NestedLoopCount) { 9285 SemaRef.Diag(OrderedLoopCountExpr->getExprLoc(), 9286 diag::err_omp_wrong_ordered_loop_count) 9287 << OrderedLoopCountExpr->getSourceRange(); 9288 SemaRef.Diag(CollapseLoopCountExpr->getExprLoc(), 9289 diag::note_collapse_loop_count) 9290 << CollapseLoopCountExpr->getSourceRange(); 9291 } 9292 OrderedLoopCount = Result.getLimitedValue(); 9293 } else { 9294 Built.clear(/*Size=*/1); 9295 return 1; 9296 } 9297 } 9298 // This is helper routine for loop directives (e.g., 'for', 'simd', 9299 // 'for simd', etc.). 9300 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 9301 unsigned NumLoops = std::max(OrderedLoopCount, NestedLoopCount); 9302 SmallVector<LoopIterationSpace, 4> IterSpaces(NumLoops); 9303 if (!OMPLoopBasedDirective::doForAllLoops( 9304 AStmt->IgnoreContainers(!isOpenMPLoopTransformationDirective(DKind)), 9305 SupportsNonPerfectlyNested, NumLoops, 9306 [DKind, &SemaRef, &DSA, NumLoops, NestedLoopCount, 9307 CollapseLoopCountExpr, OrderedLoopCountExpr, &VarsWithImplicitDSA, 9308 &IterSpaces, &Captures](unsigned Cnt, Stmt *CurStmt) { 9309 if (checkOpenMPIterationSpace( 9310 DKind, CurStmt, SemaRef, DSA, Cnt, NestedLoopCount, 9311 NumLoops, CollapseLoopCountExpr, OrderedLoopCountExpr, 9312 VarsWithImplicitDSA, IterSpaces, Captures)) 9313 return true; 9314 if (Cnt > 0 && Cnt >= NestedLoopCount && 9315 IterSpaces[Cnt].CounterVar) { 9316 // Handle initialization of captured loop iterator variables. 9317 auto *DRE = cast<DeclRefExpr>(IterSpaces[Cnt].CounterVar); 9318 if (isa<OMPCapturedExprDecl>(DRE->getDecl())) { 9319 Captures[DRE] = DRE; 9320 } 9321 } 9322 return false; 9323 }, 9324 [&SemaRef, &Captures](OMPLoopTransformationDirective *Transform) { 9325 Stmt *DependentPreInits = Transform->getPreInits(); 9326 if (!DependentPreInits) 9327 return; 9328 for (Decl *C : cast<DeclStmt>(DependentPreInits)->getDeclGroup()) { 9329 auto *D = cast<VarDecl>(C); 9330 DeclRefExpr *Ref = buildDeclRefExpr(SemaRef, D, D->getType(), 9331 Transform->getBeginLoc()); 9332 Captures[Ref] = Ref; 9333 } 9334 })) 9335 return 0; 9336 9337 Built.clear(/* size */ NestedLoopCount); 9338 9339 if (SemaRef.CurContext->isDependentContext()) 9340 return NestedLoopCount; 9341 9342 // An example of what is generated for the following code: 9343 // 9344 // #pragma omp simd collapse(2) ordered(2) 9345 // for (i = 0; i < NI; ++i) 9346 // for (k = 0; k < NK; ++k) 9347 // for (j = J0; j < NJ; j+=2) { 9348 // <loop body> 9349 // } 9350 // 9351 // We generate the code below. 9352 // Note: the loop body may be outlined in CodeGen. 9353 // Note: some counters may be C++ classes, operator- is used to find number of 9354 // iterations and operator+= to calculate counter value. 9355 // Note: decltype(NumIterations) must be integer type (in 'omp for', only i32 9356 // or i64 is currently supported). 9357 // 9358 // #define NumIterations (NI * ((NJ - J0 - 1 + 2) / 2)) 9359 // for (int[32|64]_t IV = 0; IV < NumIterations; ++IV ) { 9360 // .local.i = IV / ((NJ - J0 - 1 + 2) / 2); 9361 // .local.j = J0 + (IV % ((NJ - J0 - 1 + 2) / 2)) * 2; 9362 // // similar updates for vars in clauses (e.g. 'linear') 9363 // <loop body (using local i and j)> 9364 // } 9365 // i = NI; // assign final values of counters 9366 // j = NJ; 9367 // 9368 9369 // Last iteration number is (I1 * I2 * ... In) - 1, where I1, I2 ... In are 9370 // the iteration counts of the collapsed for loops. 9371 // Precondition tests if there is at least one iteration (all conditions are 9372 // true). 9373 auto PreCond = ExprResult(IterSpaces[0].PreCond); 9374 Expr *N0 = IterSpaces[0].NumIterations; 9375 ExprResult LastIteration32 = 9376 widenIterationCount(/*Bits=*/32, 9377 SemaRef 9378 .PerformImplicitConversion( 9379 N0->IgnoreImpCasts(), N0->getType(), 9380 Sema::AA_Converting, /*AllowExplicit=*/true) 9381 .get(), 9382 SemaRef); 9383 ExprResult LastIteration64 = widenIterationCount( 9384 /*Bits=*/64, 9385 SemaRef 9386 .PerformImplicitConversion(N0->IgnoreImpCasts(), N0->getType(), 9387 Sema::AA_Converting, 9388 /*AllowExplicit=*/true) 9389 .get(), 9390 SemaRef); 9391 9392 if (!LastIteration32.isUsable() || !LastIteration64.isUsable()) 9393 return NestedLoopCount; 9394 9395 ASTContext &C = SemaRef.Context; 9396 bool AllCountsNeedLessThan32Bits = C.getTypeSize(N0->getType()) < 32; 9397 9398 Scope *CurScope = DSA.getCurScope(); 9399 for (unsigned Cnt = 1; Cnt < NestedLoopCount; ++Cnt) { 9400 if (PreCond.isUsable()) { 9401 PreCond = 9402 SemaRef.BuildBinOp(CurScope, PreCond.get()->getExprLoc(), BO_LAnd, 9403 PreCond.get(), IterSpaces[Cnt].PreCond); 9404 } 9405 Expr *N = IterSpaces[Cnt].NumIterations; 9406 SourceLocation Loc = N->getExprLoc(); 9407 AllCountsNeedLessThan32Bits &= C.getTypeSize(N->getType()) < 32; 9408 if (LastIteration32.isUsable()) 9409 LastIteration32 = SemaRef.BuildBinOp( 9410 CurScope, Loc, BO_Mul, LastIteration32.get(), 9411 SemaRef 9412 .PerformImplicitConversion(N->IgnoreImpCasts(), N->getType(), 9413 Sema::AA_Converting, 9414 /*AllowExplicit=*/true) 9415 .get()); 9416 if (LastIteration64.isUsable()) 9417 LastIteration64 = SemaRef.BuildBinOp( 9418 CurScope, Loc, BO_Mul, LastIteration64.get(), 9419 SemaRef 9420 .PerformImplicitConversion(N->IgnoreImpCasts(), N->getType(), 9421 Sema::AA_Converting, 9422 /*AllowExplicit=*/true) 9423 .get()); 9424 } 9425 9426 // Choose either the 32-bit or 64-bit version. 9427 ExprResult LastIteration = LastIteration64; 9428 if (SemaRef.getLangOpts().OpenMPOptimisticCollapse || 9429 (LastIteration32.isUsable() && 9430 C.getTypeSize(LastIteration32.get()->getType()) == 32 && 9431 (AllCountsNeedLessThan32Bits || NestedLoopCount == 1 || 9432 fitsInto( 9433 /*Bits=*/32, 9434 LastIteration32.get()->getType()->hasSignedIntegerRepresentation(), 9435 LastIteration64.get(), SemaRef)))) 9436 LastIteration = LastIteration32; 9437 QualType VType = LastIteration.get()->getType(); 9438 QualType RealVType = VType; 9439 QualType StrideVType = VType; 9440 if (isOpenMPTaskLoopDirective(DKind)) { 9441 VType = 9442 SemaRef.Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/0); 9443 StrideVType = 9444 SemaRef.Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/1); 9445 } 9446 9447 if (!LastIteration.isUsable()) 9448 return 0; 9449 9450 // Save the number of iterations. 9451 ExprResult NumIterations = LastIteration; 9452 { 9453 LastIteration = SemaRef.BuildBinOp( 9454 CurScope, LastIteration.get()->getExprLoc(), BO_Sub, 9455 LastIteration.get(), 9456 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()); 9457 if (!LastIteration.isUsable()) 9458 return 0; 9459 } 9460 9461 // Calculate the last iteration number beforehand instead of doing this on 9462 // each iteration. Do not do this if the number of iterations may be kfold-ed. 9463 bool IsConstant = LastIteration.get()->isIntegerConstantExpr(SemaRef.Context); 9464 ExprResult CalcLastIteration; 9465 if (!IsConstant) { 9466 ExprResult SaveRef = 9467 tryBuildCapture(SemaRef, LastIteration.get(), Captures); 9468 LastIteration = SaveRef; 9469 9470 // Prepare SaveRef + 1. 9471 NumIterations = SemaRef.BuildBinOp( 9472 CurScope, SaveRef.get()->getExprLoc(), BO_Add, SaveRef.get(), 9473 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()); 9474 if (!NumIterations.isUsable()) 9475 return 0; 9476 } 9477 9478 SourceLocation InitLoc = IterSpaces[0].InitSrcRange.getBegin(); 9479 9480 // Build variables passed into runtime, necessary for worksharing directives. 9481 ExprResult LB, UB, IL, ST, EUB, CombLB, CombUB, PrevLB, PrevUB, CombEUB; 9482 if (isOpenMPWorksharingDirective(DKind) || isOpenMPTaskLoopDirective(DKind) || 9483 isOpenMPDistributeDirective(DKind) || 9484 isOpenMPGenericLoopDirective(DKind) || 9485 isOpenMPLoopTransformationDirective(DKind)) { 9486 // Lower bound variable, initialized with zero. 9487 VarDecl *LBDecl = buildVarDecl(SemaRef, InitLoc, VType, ".omp.lb"); 9488 LB = buildDeclRefExpr(SemaRef, LBDecl, VType, InitLoc); 9489 SemaRef.AddInitializerToDecl(LBDecl, 9490 SemaRef.ActOnIntegerConstant(InitLoc, 0).get(), 9491 /*DirectInit*/ false); 9492 9493 // Upper bound variable, initialized with last iteration number. 9494 VarDecl *UBDecl = buildVarDecl(SemaRef, InitLoc, VType, ".omp.ub"); 9495 UB = buildDeclRefExpr(SemaRef, UBDecl, VType, InitLoc); 9496 SemaRef.AddInitializerToDecl(UBDecl, LastIteration.get(), 9497 /*DirectInit*/ false); 9498 9499 // A 32-bit variable-flag where runtime returns 1 for the last iteration. 9500 // This will be used to implement clause 'lastprivate'. 9501 QualType Int32Ty = SemaRef.Context.getIntTypeForBitwidth(32, true); 9502 VarDecl *ILDecl = buildVarDecl(SemaRef, InitLoc, Int32Ty, ".omp.is_last"); 9503 IL = buildDeclRefExpr(SemaRef, ILDecl, Int32Ty, InitLoc); 9504 SemaRef.AddInitializerToDecl(ILDecl, 9505 SemaRef.ActOnIntegerConstant(InitLoc, 0).get(), 9506 /*DirectInit*/ false); 9507 9508 // Stride variable returned by runtime (we initialize it to 1 by default). 9509 VarDecl *STDecl = 9510 buildVarDecl(SemaRef, InitLoc, StrideVType, ".omp.stride"); 9511 ST = buildDeclRefExpr(SemaRef, STDecl, StrideVType, InitLoc); 9512 SemaRef.AddInitializerToDecl(STDecl, 9513 SemaRef.ActOnIntegerConstant(InitLoc, 1).get(), 9514 /*DirectInit*/ false); 9515 9516 // Build expression: UB = min(UB, LastIteration) 9517 // It is necessary for CodeGen of directives with static scheduling. 9518 ExprResult IsUBGreater = SemaRef.BuildBinOp(CurScope, InitLoc, BO_GT, 9519 UB.get(), LastIteration.get()); 9520 ExprResult CondOp = SemaRef.ActOnConditionalOp( 9521 LastIteration.get()->getExprLoc(), InitLoc, IsUBGreater.get(), 9522 LastIteration.get(), UB.get()); 9523 EUB = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, UB.get(), 9524 CondOp.get()); 9525 EUB = SemaRef.ActOnFinishFullExpr(EUB.get(), /*DiscardedValue*/ false); 9526 9527 // If we have a combined directive that combines 'distribute', 'for' or 9528 // 'simd' we need to be able to access the bounds of the schedule of the 9529 // enclosing region. E.g. in 'distribute parallel for' the bounds obtained 9530 // by scheduling 'distribute' have to be passed to the schedule of 'for'. 9531 if (isOpenMPLoopBoundSharingDirective(DKind)) { 9532 // Lower bound variable, initialized with zero. 9533 VarDecl *CombLBDecl = 9534 buildVarDecl(SemaRef, InitLoc, VType, ".omp.comb.lb"); 9535 CombLB = buildDeclRefExpr(SemaRef, CombLBDecl, VType, InitLoc); 9536 SemaRef.AddInitializerToDecl( 9537 CombLBDecl, SemaRef.ActOnIntegerConstant(InitLoc, 0).get(), 9538 /*DirectInit*/ false); 9539 9540 // Upper bound variable, initialized with last iteration number. 9541 VarDecl *CombUBDecl = 9542 buildVarDecl(SemaRef, InitLoc, VType, ".omp.comb.ub"); 9543 CombUB = buildDeclRefExpr(SemaRef, CombUBDecl, VType, InitLoc); 9544 SemaRef.AddInitializerToDecl(CombUBDecl, LastIteration.get(), 9545 /*DirectInit*/ false); 9546 9547 ExprResult CombIsUBGreater = SemaRef.BuildBinOp( 9548 CurScope, InitLoc, BO_GT, CombUB.get(), LastIteration.get()); 9549 ExprResult CombCondOp = 9550 SemaRef.ActOnConditionalOp(InitLoc, InitLoc, CombIsUBGreater.get(), 9551 LastIteration.get(), CombUB.get()); 9552 CombEUB = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, CombUB.get(), 9553 CombCondOp.get()); 9554 CombEUB = 9555 SemaRef.ActOnFinishFullExpr(CombEUB.get(), /*DiscardedValue*/ false); 9556 9557 const CapturedDecl *CD = cast<CapturedStmt>(AStmt)->getCapturedDecl(); 9558 // We expect to have at least 2 more parameters than the 'parallel' 9559 // directive does - the lower and upper bounds of the previous schedule. 9560 assert(CD->getNumParams() >= 4 && 9561 "Unexpected number of parameters in loop combined directive"); 9562 9563 // Set the proper type for the bounds given what we learned from the 9564 // enclosed loops. 9565 ImplicitParamDecl *PrevLBDecl = CD->getParam(/*PrevLB=*/2); 9566 ImplicitParamDecl *PrevUBDecl = CD->getParam(/*PrevUB=*/3); 9567 9568 // Previous lower and upper bounds are obtained from the region 9569 // parameters. 9570 PrevLB = 9571 buildDeclRefExpr(SemaRef, PrevLBDecl, PrevLBDecl->getType(), InitLoc); 9572 PrevUB = 9573 buildDeclRefExpr(SemaRef, PrevUBDecl, PrevUBDecl->getType(), InitLoc); 9574 } 9575 } 9576 9577 // Build the iteration variable and its initialization before loop. 9578 ExprResult IV; 9579 ExprResult Init, CombInit; 9580 { 9581 VarDecl *IVDecl = buildVarDecl(SemaRef, InitLoc, RealVType, ".omp.iv"); 9582 IV = buildDeclRefExpr(SemaRef, IVDecl, RealVType, InitLoc); 9583 Expr *RHS = (isOpenMPWorksharingDirective(DKind) || 9584 isOpenMPGenericLoopDirective(DKind) || 9585 isOpenMPTaskLoopDirective(DKind) || 9586 isOpenMPDistributeDirective(DKind) || 9587 isOpenMPLoopTransformationDirective(DKind)) 9588 ? LB.get() 9589 : SemaRef.ActOnIntegerConstant(SourceLocation(), 0).get(); 9590 Init = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, IV.get(), RHS); 9591 Init = SemaRef.ActOnFinishFullExpr(Init.get(), /*DiscardedValue*/ false); 9592 9593 if (isOpenMPLoopBoundSharingDirective(DKind)) { 9594 Expr *CombRHS = 9595 (isOpenMPWorksharingDirective(DKind) || 9596 isOpenMPGenericLoopDirective(DKind) || 9597 isOpenMPTaskLoopDirective(DKind) || 9598 isOpenMPDistributeDirective(DKind)) 9599 ? CombLB.get() 9600 : SemaRef.ActOnIntegerConstant(SourceLocation(), 0).get(); 9601 CombInit = 9602 SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, IV.get(), CombRHS); 9603 CombInit = 9604 SemaRef.ActOnFinishFullExpr(CombInit.get(), /*DiscardedValue*/ false); 9605 } 9606 } 9607 9608 bool UseStrictCompare = 9609 RealVType->hasUnsignedIntegerRepresentation() && 9610 llvm::all_of(IterSpaces, [](const LoopIterationSpace &LIS) { 9611 return LIS.IsStrictCompare; 9612 }); 9613 // Loop condition (IV < NumIterations) or (IV <= UB or IV < UB + 1 (for 9614 // unsigned IV)) for worksharing loops. 9615 SourceLocation CondLoc = AStmt->getBeginLoc(); 9616 Expr *BoundUB = UB.get(); 9617 if (UseStrictCompare) { 9618 BoundUB = 9619 SemaRef 9620 .BuildBinOp(CurScope, CondLoc, BO_Add, BoundUB, 9621 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()) 9622 .get(); 9623 BoundUB = 9624 SemaRef.ActOnFinishFullExpr(BoundUB, /*DiscardedValue*/ false).get(); 9625 } 9626 ExprResult Cond = 9627 (isOpenMPWorksharingDirective(DKind) || 9628 isOpenMPGenericLoopDirective(DKind) || 9629 isOpenMPTaskLoopDirective(DKind) || isOpenMPDistributeDirective(DKind) || 9630 isOpenMPLoopTransformationDirective(DKind)) 9631 ? SemaRef.BuildBinOp(CurScope, CondLoc, 9632 UseStrictCompare ? BO_LT : BO_LE, IV.get(), 9633 BoundUB) 9634 : SemaRef.BuildBinOp(CurScope, CondLoc, BO_LT, IV.get(), 9635 NumIterations.get()); 9636 ExprResult CombDistCond; 9637 if (isOpenMPLoopBoundSharingDirective(DKind)) { 9638 CombDistCond = SemaRef.BuildBinOp(CurScope, CondLoc, BO_LT, IV.get(), 9639 NumIterations.get()); 9640 } 9641 9642 ExprResult CombCond; 9643 if (isOpenMPLoopBoundSharingDirective(DKind)) { 9644 Expr *BoundCombUB = CombUB.get(); 9645 if (UseStrictCompare) { 9646 BoundCombUB = 9647 SemaRef 9648 .BuildBinOp( 9649 CurScope, CondLoc, BO_Add, BoundCombUB, 9650 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()) 9651 .get(); 9652 BoundCombUB = 9653 SemaRef.ActOnFinishFullExpr(BoundCombUB, /*DiscardedValue*/ false) 9654 .get(); 9655 } 9656 CombCond = 9657 SemaRef.BuildBinOp(CurScope, CondLoc, UseStrictCompare ? BO_LT : BO_LE, 9658 IV.get(), BoundCombUB); 9659 } 9660 // Loop increment (IV = IV + 1) 9661 SourceLocation IncLoc = AStmt->getBeginLoc(); 9662 ExprResult Inc = 9663 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, IV.get(), 9664 SemaRef.ActOnIntegerConstant(IncLoc, 1).get()); 9665 if (!Inc.isUsable()) 9666 return 0; 9667 Inc = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, IV.get(), Inc.get()); 9668 Inc = SemaRef.ActOnFinishFullExpr(Inc.get(), /*DiscardedValue*/ false); 9669 if (!Inc.isUsable()) 9670 return 0; 9671 9672 // Increments for worksharing loops (LB = LB + ST; UB = UB + ST). 9673 // Used for directives with static scheduling. 9674 // In combined construct, add combined version that use CombLB and CombUB 9675 // base variables for the update 9676 ExprResult NextLB, NextUB, CombNextLB, CombNextUB; 9677 if (isOpenMPWorksharingDirective(DKind) || isOpenMPTaskLoopDirective(DKind) || 9678 isOpenMPGenericLoopDirective(DKind) || 9679 isOpenMPDistributeDirective(DKind) || 9680 isOpenMPLoopTransformationDirective(DKind)) { 9681 // LB + ST 9682 NextLB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, LB.get(), ST.get()); 9683 if (!NextLB.isUsable()) 9684 return 0; 9685 // LB = LB + ST 9686 NextLB = 9687 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, LB.get(), NextLB.get()); 9688 NextLB = 9689 SemaRef.ActOnFinishFullExpr(NextLB.get(), /*DiscardedValue*/ false); 9690 if (!NextLB.isUsable()) 9691 return 0; 9692 // UB + ST 9693 NextUB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, UB.get(), ST.get()); 9694 if (!NextUB.isUsable()) 9695 return 0; 9696 // UB = UB + ST 9697 NextUB = 9698 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, UB.get(), NextUB.get()); 9699 NextUB = 9700 SemaRef.ActOnFinishFullExpr(NextUB.get(), /*DiscardedValue*/ false); 9701 if (!NextUB.isUsable()) 9702 return 0; 9703 if (isOpenMPLoopBoundSharingDirective(DKind)) { 9704 CombNextLB = 9705 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, CombLB.get(), ST.get()); 9706 if (!NextLB.isUsable()) 9707 return 0; 9708 // LB = LB + ST 9709 CombNextLB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, CombLB.get(), 9710 CombNextLB.get()); 9711 CombNextLB = SemaRef.ActOnFinishFullExpr(CombNextLB.get(), 9712 /*DiscardedValue*/ false); 9713 if (!CombNextLB.isUsable()) 9714 return 0; 9715 // UB + ST 9716 CombNextUB = 9717 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, CombUB.get(), ST.get()); 9718 if (!CombNextUB.isUsable()) 9719 return 0; 9720 // UB = UB + ST 9721 CombNextUB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, CombUB.get(), 9722 CombNextUB.get()); 9723 CombNextUB = SemaRef.ActOnFinishFullExpr(CombNextUB.get(), 9724 /*DiscardedValue*/ false); 9725 if (!CombNextUB.isUsable()) 9726 return 0; 9727 } 9728 } 9729 9730 // Create increment expression for distribute loop when combined in a same 9731 // directive with for as IV = IV + ST; ensure upper bound expression based 9732 // on PrevUB instead of NumIterations - used to implement 'for' when found 9733 // in combination with 'distribute', like in 'distribute parallel for' 9734 SourceLocation DistIncLoc = AStmt->getBeginLoc(); 9735 ExprResult DistCond, DistInc, PrevEUB, ParForInDistCond; 9736 if (isOpenMPLoopBoundSharingDirective(DKind)) { 9737 DistCond = SemaRef.BuildBinOp( 9738 CurScope, CondLoc, UseStrictCompare ? BO_LT : BO_LE, IV.get(), BoundUB); 9739 assert(DistCond.isUsable() && "distribute cond expr was not built"); 9740 9741 DistInc = 9742 SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Add, IV.get(), ST.get()); 9743 assert(DistInc.isUsable() && "distribute inc expr was not built"); 9744 DistInc = SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Assign, IV.get(), 9745 DistInc.get()); 9746 DistInc = 9747 SemaRef.ActOnFinishFullExpr(DistInc.get(), /*DiscardedValue*/ false); 9748 assert(DistInc.isUsable() && "distribute inc expr was not built"); 9749 9750 // Build expression: UB = min(UB, prevUB) for #for in composite or combined 9751 // construct 9752 ExprResult NewPrevUB = PrevUB; 9753 SourceLocation DistEUBLoc = AStmt->getBeginLoc(); 9754 if (!SemaRef.Context.hasSameType(UB.get()->getType(), 9755 PrevUB.get()->getType())) { 9756 NewPrevUB = SemaRef.BuildCStyleCastExpr( 9757 DistEUBLoc, 9758 SemaRef.Context.getTrivialTypeSourceInfo(UB.get()->getType()), 9759 DistEUBLoc, NewPrevUB.get()); 9760 if (!NewPrevUB.isUsable()) 9761 return 0; 9762 } 9763 ExprResult IsUBGreater = SemaRef.BuildBinOp(CurScope, DistEUBLoc, BO_GT, 9764 UB.get(), NewPrevUB.get()); 9765 ExprResult CondOp = SemaRef.ActOnConditionalOp( 9766 DistEUBLoc, DistEUBLoc, IsUBGreater.get(), NewPrevUB.get(), UB.get()); 9767 PrevEUB = SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Assign, UB.get(), 9768 CondOp.get()); 9769 PrevEUB = 9770 SemaRef.ActOnFinishFullExpr(PrevEUB.get(), /*DiscardedValue*/ false); 9771 9772 // Build IV <= PrevUB or IV < PrevUB + 1 for unsigned IV to be used in 9773 // parallel for is in combination with a distribute directive with 9774 // schedule(static, 1) 9775 Expr *BoundPrevUB = PrevUB.get(); 9776 if (UseStrictCompare) { 9777 BoundPrevUB = 9778 SemaRef 9779 .BuildBinOp( 9780 CurScope, CondLoc, BO_Add, BoundPrevUB, 9781 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()) 9782 .get(); 9783 BoundPrevUB = 9784 SemaRef.ActOnFinishFullExpr(BoundPrevUB, /*DiscardedValue*/ false) 9785 .get(); 9786 } 9787 ParForInDistCond = 9788 SemaRef.BuildBinOp(CurScope, CondLoc, UseStrictCompare ? BO_LT : BO_LE, 9789 IV.get(), BoundPrevUB); 9790 } 9791 9792 // Build updates and final values of the loop counters. 9793 bool HasErrors = false; 9794 Built.Counters.resize(NestedLoopCount); 9795 Built.Inits.resize(NestedLoopCount); 9796 Built.Updates.resize(NestedLoopCount); 9797 Built.Finals.resize(NestedLoopCount); 9798 Built.DependentCounters.resize(NestedLoopCount); 9799 Built.DependentInits.resize(NestedLoopCount); 9800 Built.FinalsConditions.resize(NestedLoopCount); 9801 { 9802 // We implement the following algorithm for obtaining the 9803 // original loop iteration variable values based on the 9804 // value of the collapsed loop iteration variable IV. 9805 // 9806 // Let n+1 be the number of collapsed loops in the nest. 9807 // Iteration variables (I0, I1, .... In) 9808 // Iteration counts (N0, N1, ... Nn) 9809 // 9810 // Acc = IV; 9811 // 9812 // To compute Ik for loop k, 0 <= k <= n, generate: 9813 // Prod = N(k+1) * N(k+2) * ... * Nn; 9814 // Ik = Acc / Prod; 9815 // Acc -= Ik * Prod; 9816 // 9817 ExprResult Acc = IV; 9818 for (unsigned int Cnt = 0; Cnt < NestedLoopCount; ++Cnt) { 9819 LoopIterationSpace &IS = IterSpaces[Cnt]; 9820 SourceLocation UpdLoc = IS.IncSrcRange.getBegin(); 9821 ExprResult Iter; 9822 9823 // Compute prod 9824 ExprResult Prod = SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get(); 9825 for (unsigned int K = Cnt + 1; K < NestedLoopCount; ++K) 9826 Prod = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Mul, Prod.get(), 9827 IterSpaces[K].NumIterations); 9828 9829 // Iter = Acc / Prod 9830 // If there is at least one more inner loop to avoid 9831 // multiplication by 1. 9832 if (Cnt + 1 < NestedLoopCount) 9833 Iter = 9834 SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Div, Acc.get(), Prod.get()); 9835 else 9836 Iter = Acc; 9837 if (!Iter.isUsable()) { 9838 HasErrors = true; 9839 break; 9840 } 9841 9842 // Update Acc: 9843 // Acc -= Iter * Prod 9844 // Check if there is at least one more inner loop to avoid 9845 // multiplication by 1. 9846 if (Cnt + 1 < NestedLoopCount) 9847 Prod = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Mul, Iter.get(), 9848 Prod.get()); 9849 else 9850 Prod = Iter; 9851 Acc = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Sub, Acc.get(), Prod.get()); 9852 9853 // Build update: IS.CounterVar(Private) = IS.Start + Iter * IS.Step 9854 auto *VD = cast<VarDecl>(cast<DeclRefExpr>(IS.CounterVar)->getDecl()); 9855 DeclRefExpr *CounterVar = buildDeclRefExpr( 9856 SemaRef, VD, IS.CounterVar->getType(), IS.CounterVar->getExprLoc(), 9857 /*RefersToCapture=*/true); 9858 ExprResult Init = 9859 buildCounterInit(SemaRef, CurScope, UpdLoc, CounterVar, 9860 IS.CounterInit, IS.IsNonRectangularLB, Captures); 9861 if (!Init.isUsable()) { 9862 HasErrors = true; 9863 break; 9864 } 9865 ExprResult Update = buildCounterUpdate( 9866 SemaRef, CurScope, UpdLoc, CounterVar, IS.CounterInit, Iter, 9867 IS.CounterStep, IS.Subtract, IS.IsNonRectangularLB, &Captures); 9868 if (!Update.isUsable()) { 9869 HasErrors = true; 9870 break; 9871 } 9872 9873 // Build final: IS.CounterVar = IS.Start + IS.NumIters * IS.Step 9874 ExprResult Final = 9875 buildCounterUpdate(SemaRef, CurScope, UpdLoc, CounterVar, 9876 IS.CounterInit, IS.NumIterations, IS.CounterStep, 9877 IS.Subtract, IS.IsNonRectangularLB, &Captures); 9878 if (!Final.isUsable()) { 9879 HasErrors = true; 9880 break; 9881 } 9882 9883 if (!Update.isUsable() || !Final.isUsable()) { 9884 HasErrors = true; 9885 break; 9886 } 9887 // Save results 9888 Built.Counters[Cnt] = IS.CounterVar; 9889 Built.PrivateCounters[Cnt] = IS.PrivateCounterVar; 9890 Built.Inits[Cnt] = Init.get(); 9891 Built.Updates[Cnt] = Update.get(); 9892 Built.Finals[Cnt] = Final.get(); 9893 Built.DependentCounters[Cnt] = nullptr; 9894 Built.DependentInits[Cnt] = nullptr; 9895 Built.FinalsConditions[Cnt] = nullptr; 9896 if (IS.IsNonRectangularLB || IS.IsNonRectangularUB) { 9897 Built.DependentCounters[Cnt] = 9898 Built.Counters[NestedLoopCount - 1 - IS.LoopDependentIdx]; 9899 Built.DependentInits[Cnt] = 9900 Built.Inits[NestedLoopCount - 1 - IS.LoopDependentIdx]; 9901 Built.FinalsConditions[Cnt] = IS.FinalCondition; 9902 } 9903 } 9904 } 9905 9906 if (HasErrors) 9907 return 0; 9908 9909 // Save results 9910 Built.IterationVarRef = IV.get(); 9911 Built.LastIteration = LastIteration.get(); 9912 Built.NumIterations = NumIterations.get(); 9913 Built.CalcLastIteration = SemaRef 9914 .ActOnFinishFullExpr(CalcLastIteration.get(), 9915 /*DiscardedValue=*/false) 9916 .get(); 9917 Built.PreCond = PreCond.get(); 9918 Built.PreInits = buildPreInits(C, Captures); 9919 Built.Cond = Cond.get(); 9920 Built.Init = Init.get(); 9921 Built.Inc = Inc.get(); 9922 Built.LB = LB.get(); 9923 Built.UB = UB.get(); 9924 Built.IL = IL.get(); 9925 Built.ST = ST.get(); 9926 Built.EUB = EUB.get(); 9927 Built.NLB = NextLB.get(); 9928 Built.NUB = NextUB.get(); 9929 Built.PrevLB = PrevLB.get(); 9930 Built.PrevUB = PrevUB.get(); 9931 Built.DistInc = DistInc.get(); 9932 Built.PrevEUB = PrevEUB.get(); 9933 Built.DistCombinedFields.LB = CombLB.get(); 9934 Built.DistCombinedFields.UB = CombUB.get(); 9935 Built.DistCombinedFields.EUB = CombEUB.get(); 9936 Built.DistCombinedFields.Init = CombInit.get(); 9937 Built.DistCombinedFields.Cond = CombCond.get(); 9938 Built.DistCombinedFields.NLB = CombNextLB.get(); 9939 Built.DistCombinedFields.NUB = CombNextUB.get(); 9940 Built.DistCombinedFields.DistCond = CombDistCond.get(); 9941 Built.DistCombinedFields.ParForInDistCond = ParForInDistCond.get(); 9942 9943 return NestedLoopCount; 9944 } 9945 9946 static Expr *getCollapseNumberExpr(ArrayRef<OMPClause *> Clauses) { 9947 auto CollapseClauses = 9948 OMPExecutableDirective::getClausesOfKind<OMPCollapseClause>(Clauses); 9949 if (CollapseClauses.begin() != CollapseClauses.end()) 9950 return (*CollapseClauses.begin())->getNumForLoops(); 9951 return nullptr; 9952 } 9953 9954 static Expr *getOrderedNumberExpr(ArrayRef<OMPClause *> Clauses) { 9955 auto OrderedClauses = 9956 OMPExecutableDirective::getClausesOfKind<OMPOrderedClause>(Clauses); 9957 if (OrderedClauses.begin() != OrderedClauses.end()) 9958 return (*OrderedClauses.begin())->getNumForLoops(); 9959 return nullptr; 9960 } 9961 9962 static bool checkSimdlenSafelenSpecified(Sema &S, 9963 const ArrayRef<OMPClause *> Clauses) { 9964 const OMPSafelenClause *Safelen = nullptr; 9965 const OMPSimdlenClause *Simdlen = nullptr; 9966 9967 for (const OMPClause *Clause : Clauses) { 9968 if (Clause->getClauseKind() == OMPC_safelen) 9969 Safelen = cast<OMPSafelenClause>(Clause); 9970 else if (Clause->getClauseKind() == OMPC_simdlen) 9971 Simdlen = cast<OMPSimdlenClause>(Clause); 9972 if (Safelen && Simdlen) 9973 break; 9974 } 9975 9976 if (Simdlen && Safelen) { 9977 const Expr *SimdlenLength = Simdlen->getSimdlen(); 9978 const Expr *SafelenLength = Safelen->getSafelen(); 9979 if (SimdlenLength->isValueDependent() || SimdlenLength->isTypeDependent() || 9980 SimdlenLength->isInstantiationDependent() || 9981 SimdlenLength->containsUnexpandedParameterPack()) 9982 return false; 9983 if (SafelenLength->isValueDependent() || SafelenLength->isTypeDependent() || 9984 SafelenLength->isInstantiationDependent() || 9985 SafelenLength->containsUnexpandedParameterPack()) 9986 return false; 9987 Expr::EvalResult SimdlenResult, SafelenResult; 9988 SimdlenLength->EvaluateAsInt(SimdlenResult, S.Context); 9989 SafelenLength->EvaluateAsInt(SafelenResult, S.Context); 9990 llvm::APSInt SimdlenRes = SimdlenResult.Val.getInt(); 9991 llvm::APSInt SafelenRes = SafelenResult.Val.getInt(); 9992 // OpenMP 4.5 [2.8.1, simd Construct, Restrictions] 9993 // If both simdlen and safelen clauses are specified, the value of the 9994 // simdlen parameter must be less than or equal to the value of the safelen 9995 // parameter. 9996 if (SimdlenRes > SafelenRes) { 9997 S.Diag(SimdlenLength->getExprLoc(), 9998 diag::err_omp_wrong_simdlen_safelen_values) 9999 << SimdlenLength->getSourceRange() << SafelenLength->getSourceRange(); 10000 return true; 10001 } 10002 } 10003 return false; 10004 } 10005 10006 StmtResult 10007 Sema::ActOnOpenMPSimdDirective(ArrayRef<OMPClause *> Clauses, Stmt *AStmt, 10008 SourceLocation StartLoc, SourceLocation EndLoc, 10009 VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10010 if (!AStmt) 10011 return StmtError(); 10012 10013 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 10014 OMPLoopBasedDirective::HelperExprs B; 10015 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 10016 // define the nested loops number. 10017 unsigned NestedLoopCount = checkOpenMPLoop( 10018 OMPD_simd, getCollapseNumberExpr(Clauses), getOrderedNumberExpr(Clauses), 10019 AStmt, *this, *DSAStack, VarsWithImplicitDSA, B); 10020 if (NestedLoopCount == 0) 10021 return StmtError(); 10022 10023 assert((CurContext->isDependentContext() || B.builtAll()) && 10024 "omp simd loop exprs were not built"); 10025 10026 if (!CurContext->isDependentContext()) { 10027 // Finalize the clauses that need pre-built expressions for CodeGen. 10028 for (OMPClause *C : Clauses) { 10029 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 10030 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 10031 B.NumIterations, *this, CurScope, 10032 DSAStack)) 10033 return StmtError(); 10034 } 10035 } 10036 10037 if (checkSimdlenSafelenSpecified(*this, Clauses)) 10038 return StmtError(); 10039 10040 setFunctionHasBranchProtectedScope(); 10041 return OMPSimdDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount, 10042 Clauses, AStmt, B); 10043 } 10044 10045 StmtResult 10046 Sema::ActOnOpenMPForDirective(ArrayRef<OMPClause *> Clauses, Stmt *AStmt, 10047 SourceLocation StartLoc, SourceLocation EndLoc, 10048 VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10049 if (!AStmt) 10050 return StmtError(); 10051 10052 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 10053 OMPLoopBasedDirective::HelperExprs B; 10054 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 10055 // define the nested loops number. 10056 unsigned NestedLoopCount = checkOpenMPLoop( 10057 OMPD_for, getCollapseNumberExpr(Clauses), getOrderedNumberExpr(Clauses), 10058 AStmt, *this, *DSAStack, VarsWithImplicitDSA, B); 10059 if (NestedLoopCount == 0) 10060 return StmtError(); 10061 10062 assert((CurContext->isDependentContext() || B.builtAll()) && 10063 "omp for loop exprs were not built"); 10064 10065 if (!CurContext->isDependentContext()) { 10066 // Finalize the clauses that need pre-built expressions for CodeGen. 10067 for (OMPClause *C : Clauses) { 10068 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 10069 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 10070 B.NumIterations, *this, CurScope, 10071 DSAStack)) 10072 return StmtError(); 10073 } 10074 } 10075 10076 setFunctionHasBranchProtectedScope(); 10077 return OMPForDirective::Create( 10078 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B, 10079 DSAStack->getTaskgroupReductionRef(), DSAStack->isCancelRegion()); 10080 } 10081 10082 StmtResult Sema::ActOnOpenMPForSimdDirective( 10083 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10084 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10085 if (!AStmt) 10086 return StmtError(); 10087 10088 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 10089 OMPLoopBasedDirective::HelperExprs B; 10090 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 10091 // define the nested loops number. 10092 unsigned NestedLoopCount = 10093 checkOpenMPLoop(OMPD_for_simd, getCollapseNumberExpr(Clauses), 10094 getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack, 10095 VarsWithImplicitDSA, B); 10096 if (NestedLoopCount == 0) 10097 return StmtError(); 10098 10099 assert((CurContext->isDependentContext() || B.builtAll()) && 10100 "omp for simd loop exprs were not built"); 10101 10102 if (!CurContext->isDependentContext()) { 10103 // Finalize the clauses that need pre-built expressions for CodeGen. 10104 for (OMPClause *C : Clauses) { 10105 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 10106 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 10107 B.NumIterations, *this, CurScope, 10108 DSAStack)) 10109 return StmtError(); 10110 } 10111 } 10112 10113 if (checkSimdlenSafelenSpecified(*this, Clauses)) 10114 return StmtError(); 10115 10116 setFunctionHasBranchProtectedScope(); 10117 return OMPForSimdDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount, 10118 Clauses, AStmt, B); 10119 } 10120 10121 StmtResult Sema::ActOnOpenMPSectionsDirective(ArrayRef<OMPClause *> Clauses, 10122 Stmt *AStmt, 10123 SourceLocation StartLoc, 10124 SourceLocation EndLoc) { 10125 if (!AStmt) 10126 return StmtError(); 10127 10128 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 10129 auto BaseStmt = AStmt; 10130 while (auto *CS = dyn_cast_or_null<CapturedStmt>(BaseStmt)) 10131 BaseStmt = CS->getCapturedStmt(); 10132 if (auto *C = dyn_cast_or_null<CompoundStmt>(BaseStmt)) { 10133 auto S = C->children(); 10134 if (S.begin() == S.end()) 10135 return StmtError(); 10136 // All associated statements must be '#pragma omp section' except for 10137 // the first one. 10138 for (Stmt *SectionStmt : llvm::drop_begin(S)) { 10139 if (!SectionStmt || !isa<OMPSectionDirective>(SectionStmt)) { 10140 if (SectionStmt) 10141 Diag(SectionStmt->getBeginLoc(), 10142 diag::err_omp_sections_substmt_not_section); 10143 return StmtError(); 10144 } 10145 cast<OMPSectionDirective>(SectionStmt) 10146 ->setHasCancel(DSAStack->isCancelRegion()); 10147 } 10148 } else { 10149 Diag(AStmt->getBeginLoc(), diag::err_omp_sections_not_compound_stmt); 10150 return StmtError(); 10151 } 10152 10153 setFunctionHasBranchProtectedScope(); 10154 10155 return OMPSectionsDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt, 10156 DSAStack->getTaskgroupReductionRef(), 10157 DSAStack->isCancelRegion()); 10158 } 10159 10160 StmtResult Sema::ActOnOpenMPSectionDirective(Stmt *AStmt, 10161 SourceLocation StartLoc, 10162 SourceLocation EndLoc) { 10163 if (!AStmt) 10164 return StmtError(); 10165 10166 setFunctionHasBranchProtectedScope(); 10167 DSAStack->setParentCancelRegion(DSAStack->isCancelRegion()); 10168 10169 return OMPSectionDirective::Create(Context, StartLoc, EndLoc, AStmt, 10170 DSAStack->isCancelRegion()); 10171 } 10172 10173 static Expr *getDirectCallExpr(Expr *E) { 10174 E = E->IgnoreParenCasts()->IgnoreImplicit(); 10175 if (auto *CE = dyn_cast<CallExpr>(E)) 10176 if (CE->getDirectCallee()) 10177 return E; 10178 return nullptr; 10179 } 10180 10181 StmtResult Sema::ActOnOpenMPDispatchDirective(ArrayRef<OMPClause *> Clauses, 10182 Stmt *AStmt, 10183 SourceLocation StartLoc, 10184 SourceLocation EndLoc) { 10185 if (!AStmt) 10186 return StmtError(); 10187 10188 Stmt *S = cast<CapturedStmt>(AStmt)->getCapturedStmt(); 10189 10190 // 5.1 OpenMP 10191 // expression-stmt : an expression statement with one of the following forms: 10192 // expression = target-call ( [expression-list] ); 10193 // target-call ( [expression-list] ); 10194 10195 SourceLocation TargetCallLoc; 10196 10197 if (!CurContext->isDependentContext()) { 10198 Expr *TargetCall = nullptr; 10199 10200 auto *E = dyn_cast<Expr>(S); 10201 if (!E) { 10202 Diag(S->getBeginLoc(), diag::err_omp_dispatch_statement_call); 10203 return StmtError(); 10204 } 10205 10206 E = E->IgnoreParenCasts()->IgnoreImplicit(); 10207 10208 if (auto *BO = dyn_cast<BinaryOperator>(E)) { 10209 if (BO->getOpcode() == BO_Assign) 10210 TargetCall = getDirectCallExpr(BO->getRHS()); 10211 } else { 10212 if (auto *COCE = dyn_cast<CXXOperatorCallExpr>(E)) 10213 if (COCE->getOperator() == OO_Equal) 10214 TargetCall = getDirectCallExpr(COCE->getArg(1)); 10215 if (!TargetCall) 10216 TargetCall = getDirectCallExpr(E); 10217 } 10218 if (!TargetCall) { 10219 Diag(E->getBeginLoc(), diag::err_omp_dispatch_statement_call); 10220 return StmtError(); 10221 } 10222 TargetCallLoc = TargetCall->getExprLoc(); 10223 } 10224 10225 setFunctionHasBranchProtectedScope(); 10226 10227 return OMPDispatchDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt, 10228 TargetCallLoc); 10229 } 10230 10231 static bool checkGenericLoopLastprivate(Sema &S, ArrayRef<OMPClause *> Clauses, 10232 OpenMPDirectiveKind K, 10233 DSAStackTy *Stack) { 10234 bool ErrorFound = false; 10235 for (OMPClause *C : Clauses) { 10236 if (auto *LPC = dyn_cast<OMPLastprivateClause>(C)) { 10237 for (Expr *RefExpr : LPC->varlists()) { 10238 SourceLocation ELoc; 10239 SourceRange ERange; 10240 Expr *SimpleRefExpr = RefExpr; 10241 auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange); 10242 if (ValueDecl *D = Res.first) { 10243 auto &&Info = Stack->isLoopControlVariable(D); 10244 if (!Info.first) { 10245 S.Diag(ELoc, diag::err_omp_lastprivate_loop_var_non_loop_iteration) 10246 << getOpenMPDirectiveName(K); 10247 ErrorFound = true; 10248 } 10249 } 10250 } 10251 } 10252 } 10253 return ErrorFound; 10254 } 10255 10256 StmtResult Sema::ActOnOpenMPGenericLoopDirective( 10257 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10258 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10259 if (!AStmt) 10260 return StmtError(); 10261 10262 // OpenMP 5.1 [2.11.7, loop construct, Restrictions] 10263 // A list item may not appear in a lastprivate clause unless it is the 10264 // loop iteration variable of a loop that is associated with the construct. 10265 if (checkGenericLoopLastprivate(*this, Clauses, OMPD_loop, DSAStack)) 10266 return StmtError(); 10267 10268 auto *CS = cast<CapturedStmt>(AStmt); 10269 // 1.2.2 OpenMP Language Terminology 10270 // Structured block - An executable statement with a single entry at the 10271 // top and a single exit at the bottom. 10272 // The point of exit cannot be a branch out of the structured block. 10273 // longjmp() and throw() must not violate the entry/exit criteria. 10274 CS->getCapturedDecl()->setNothrow(); 10275 10276 OMPLoopDirective::HelperExprs B; 10277 // In presence of clause 'collapse', it will define the nested loops number. 10278 unsigned NestedLoopCount = checkOpenMPLoop( 10279 OMPD_loop, getCollapseNumberExpr(Clauses), getOrderedNumberExpr(Clauses), 10280 AStmt, *this, *DSAStack, VarsWithImplicitDSA, B); 10281 if (NestedLoopCount == 0) 10282 return StmtError(); 10283 10284 assert((CurContext->isDependentContext() || B.builtAll()) && 10285 "omp loop exprs were not built"); 10286 10287 setFunctionHasBranchProtectedScope(); 10288 return OMPGenericLoopDirective::Create(Context, StartLoc, EndLoc, 10289 NestedLoopCount, Clauses, AStmt, B); 10290 } 10291 10292 StmtResult Sema::ActOnOpenMPTeamsGenericLoopDirective( 10293 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10294 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10295 if (!AStmt) 10296 return StmtError(); 10297 10298 // OpenMP 5.1 [2.11.7, loop construct, Restrictions] 10299 // A list item may not appear in a lastprivate clause unless it is the 10300 // loop iteration variable of a loop that is associated with the construct. 10301 if (checkGenericLoopLastprivate(*this, Clauses, OMPD_teams_loop, DSAStack)) 10302 return StmtError(); 10303 10304 auto *CS = cast<CapturedStmt>(AStmt); 10305 // 1.2.2 OpenMP Language Terminology 10306 // Structured block - An executable statement with a single entry at the 10307 // top and a single exit at the bottom. 10308 // The point of exit cannot be a branch out of the structured block. 10309 // longjmp() and throw() must not violate the entry/exit criteria. 10310 CS->getCapturedDecl()->setNothrow(); 10311 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_teams_loop); 10312 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10313 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10314 // 1.2.2 OpenMP Language Terminology 10315 // Structured block - An executable statement with a single entry at the 10316 // top and a single exit at the bottom. 10317 // The point of exit cannot be a branch out of the structured block. 10318 // longjmp() and throw() must not violate the entry/exit criteria. 10319 CS->getCapturedDecl()->setNothrow(); 10320 } 10321 10322 OMPLoopDirective::HelperExprs B; 10323 // In presence of clause 'collapse', it will define the nested loops number. 10324 unsigned NestedLoopCount = 10325 checkOpenMPLoop(OMPD_teams_loop, getCollapseNumberExpr(Clauses), 10326 /*OrderedLoopCountExpr=*/nullptr, CS, *this, *DSAStack, 10327 VarsWithImplicitDSA, B); 10328 if (NestedLoopCount == 0) 10329 return StmtError(); 10330 10331 assert((CurContext->isDependentContext() || B.builtAll()) && 10332 "omp loop exprs were not built"); 10333 10334 setFunctionHasBranchProtectedScope(); 10335 DSAStack->setParentTeamsRegionLoc(StartLoc); 10336 10337 return OMPTeamsGenericLoopDirective::Create( 10338 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 10339 } 10340 10341 StmtResult Sema::ActOnOpenMPTargetTeamsGenericLoopDirective( 10342 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10343 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10344 if (!AStmt) 10345 return StmtError(); 10346 10347 // OpenMP 5.1 [2.11.7, loop construct, Restrictions] 10348 // A list item may not appear in a lastprivate clause unless it is the 10349 // loop iteration variable of a loop that is associated with the construct. 10350 if (checkGenericLoopLastprivate(*this, Clauses, OMPD_target_teams_loop, 10351 DSAStack)) 10352 return StmtError(); 10353 10354 auto *CS = cast<CapturedStmt>(AStmt); 10355 // 1.2.2 OpenMP Language Terminology 10356 // Structured block - An executable statement with a single entry at the 10357 // top and a single exit at the bottom. 10358 // The point of exit cannot be a branch out of the structured block. 10359 // longjmp() and throw() must not violate the entry/exit criteria. 10360 CS->getCapturedDecl()->setNothrow(); 10361 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_teams_loop); 10362 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10363 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10364 // 1.2.2 OpenMP Language Terminology 10365 // Structured block - An executable statement with a single entry at the 10366 // top and a single exit at the bottom. 10367 // The point of exit cannot be a branch out of the structured block. 10368 // longjmp() and throw() must not violate the entry/exit criteria. 10369 CS->getCapturedDecl()->setNothrow(); 10370 } 10371 10372 OMPLoopDirective::HelperExprs B; 10373 // In presence of clause 'collapse', it will define the nested loops number. 10374 unsigned NestedLoopCount = 10375 checkOpenMPLoop(OMPD_target_teams_loop, getCollapseNumberExpr(Clauses), 10376 /*OrderedLoopCountExpr=*/nullptr, CS, *this, *DSAStack, 10377 VarsWithImplicitDSA, B); 10378 if (NestedLoopCount == 0) 10379 return StmtError(); 10380 10381 assert((CurContext->isDependentContext() || B.builtAll()) && 10382 "omp loop exprs were not built"); 10383 10384 setFunctionHasBranchProtectedScope(); 10385 10386 return OMPTargetTeamsGenericLoopDirective::Create( 10387 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 10388 } 10389 10390 StmtResult Sema::ActOnOpenMPParallelGenericLoopDirective( 10391 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10392 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10393 if (!AStmt) 10394 return StmtError(); 10395 10396 // OpenMP 5.1 [2.11.7, loop construct, Restrictions] 10397 // A list item may not appear in a lastprivate clause unless it is the 10398 // loop iteration variable of a loop that is associated with the construct. 10399 if (checkGenericLoopLastprivate(*this, Clauses, OMPD_parallel_loop, DSAStack)) 10400 return StmtError(); 10401 10402 auto *CS = cast<CapturedStmt>(AStmt); 10403 // 1.2.2 OpenMP Language Terminology 10404 // Structured block - An executable statement with a single entry at the 10405 // top and a single exit at the bottom. 10406 // The point of exit cannot be a branch out of the structured block. 10407 // longjmp() and throw() must not violate the entry/exit criteria. 10408 CS->getCapturedDecl()->setNothrow(); 10409 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_parallel_loop); 10410 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10411 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10412 // 1.2.2 OpenMP Language Terminology 10413 // Structured block - An executable statement with a single entry at the 10414 // top and a single exit at the bottom. 10415 // The point of exit cannot be a branch out of the structured block. 10416 // longjmp() and throw() must not violate the entry/exit criteria. 10417 CS->getCapturedDecl()->setNothrow(); 10418 } 10419 10420 OMPLoopDirective::HelperExprs B; 10421 // In presence of clause 'collapse', it will define the nested loops number. 10422 unsigned NestedLoopCount = 10423 checkOpenMPLoop(OMPD_parallel_loop, getCollapseNumberExpr(Clauses), 10424 /*OrderedLoopCountExpr=*/nullptr, CS, *this, *DSAStack, 10425 VarsWithImplicitDSA, B); 10426 if (NestedLoopCount == 0) 10427 return StmtError(); 10428 10429 assert((CurContext->isDependentContext() || B.builtAll()) && 10430 "omp loop exprs were not built"); 10431 10432 setFunctionHasBranchProtectedScope(); 10433 10434 return OMPParallelGenericLoopDirective::Create( 10435 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 10436 } 10437 10438 StmtResult Sema::ActOnOpenMPTargetParallelGenericLoopDirective( 10439 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10440 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10441 if (!AStmt) 10442 return StmtError(); 10443 10444 // OpenMP 5.1 [2.11.7, loop construct, Restrictions] 10445 // A list item may not appear in a lastprivate clause unless it is the 10446 // loop iteration variable of a loop that is associated with the construct. 10447 if (checkGenericLoopLastprivate(*this, Clauses, OMPD_target_parallel_loop, 10448 DSAStack)) 10449 return StmtError(); 10450 10451 auto *CS = cast<CapturedStmt>(AStmt); 10452 // 1.2.2 OpenMP Language Terminology 10453 // Structured block - An executable statement with a single entry at the 10454 // top and a single exit at the bottom. 10455 // The point of exit cannot be a branch out of the structured block. 10456 // longjmp() and throw() must not violate the entry/exit criteria. 10457 CS->getCapturedDecl()->setNothrow(); 10458 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel_loop); 10459 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10460 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10461 // 1.2.2 OpenMP Language Terminology 10462 // Structured block - An executable statement with a single entry at the 10463 // top and a single exit at the bottom. 10464 // The point of exit cannot be a branch out of the structured block. 10465 // longjmp() and throw() must not violate the entry/exit criteria. 10466 CS->getCapturedDecl()->setNothrow(); 10467 } 10468 10469 OMPLoopDirective::HelperExprs B; 10470 // In presence of clause 'collapse', it will define the nested loops number. 10471 unsigned NestedLoopCount = 10472 checkOpenMPLoop(OMPD_target_parallel_loop, getCollapseNumberExpr(Clauses), 10473 /*OrderedLoopCountExpr=*/nullptr, CS, *this, *DSAStack, 10474 VarsWithImplicitDSA, B); 10475 if (NestedLoopCount == 0) 10476 return StmtError(); 10477 10478 assert((CurContext->isDependentContext() || B.builtAll()) && 10479 "omp loop exprs were not built"); 10480 10481 setFunctionHasBranchProtectedScope(); 10482 10483 return OMPTargetParallelGenericLoopDirective::Create( 10484 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 10485 } 10486 10487 StmtResult Sema::ActOnOpenMPSingleDirective(ArrayRef<OMPClause *> Clauses, 10488 Stmt *AStmt, 10489 SourceLocation StartLoc, 10490 SourceLocation EndLoc) { 10491 if (!AStmt) 10492 return StmtError(); 10493 10494 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 10495 10496 setFunctionHasBranchProtectedScope(); 10497 10498 // OpenMP [2.7.3, single Construct, Restrictions] 10499 // The copyprivate clause must not be used with the nowait clause. 10500 const OMPClause *Nowait = nullptr; 10501 const OMPClause *Copyprivate = nullptr; 10502 for (const OMPClause *Clause : Clauses) { 10503 if (Clause->getClauseKind() == OMPC_nowait) 10504 Nowait = Clause; 10505 else if (Clause->getClauseKind() == OMPC_copyprivate) 10506 Copyprivate = Clause; 10507 if (Copyprivate && Nowait) { 10508 Diag(Copyprivate->getBeginLoc(), 10509 diag::err_omp_single_copyprivate_with_nowait); 10510 Diag(Nowait->getBeginLoc(), diag::note_omp_nowait_clause_here); 10511 return StmtError(); 10512 } 10513 } 10514 10515 return OMPSingleDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt); 10516 } 10517 10518 StmtResult Sema::ActOnOpenMPMasterDirective(Stmt *AStmt, 10519 SourceLocation StartLoc, 10520 SourceLocation EndLoc) { 10521 if (!AStmt) 10522 return StmtError(); 10523 10524 setFunctionHasBranchProtectedScope(); 10525 10526 return OMPMasterDirective::Create(Context, StartLoc, EndLoc, AStmt); 10527 } 10528 10529 StmtResult Sema::ActOnOpenMPMaskedDirective(ArrayRef<OMPClause *> Clauses, 10530 Stmt *AStmt, 10531 SourceLocation StartLoc, 10532 SourceLocation EndLoc) { 10533 if (!AStmt) 10534 return StmtError(); 10535 10536 setFunctionHasBranchProtectedScope(); 10537 10538 return OMPMaskedDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt); 10539 } 10540 10541 StmtResult Sema::ActOnOpenMPCriticalDirective( 10542 const DeclarationNameInfo &DirName, ArrayRef<OMPClause *> Clauses, 10543 Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc) { 10544 if (!AStmt) 10545 return StmtError(); 10546 10547 bool ErrorFound = false; 10548 llvm::APSInt Hint; 10549 SourceLocation HintLoc; 10550 bool DependentHint = false; 10551 for (const OMPClause *C : Clauses) { 10552 if (C->getClauseKind() == OMPC_hint) { 10553 if (!DirName.getName()) { 10554 Diag(C->getBeginLoc(), diag::err_omp_hint_clause_no_name); 10555 ErrorFound = true; 10556 } 10557 Expr *E = cast<OMPHintClause>(C)->getHint(); 10558 if (E->isTypeDependent() || E->isValueDependent() || 10559 E->isInstantiationDependent()) { 10560 DependentHint = true; 10561 } else { 10562 Hint = E->EvaluateKnownConstInt(Context); 10563 HintLoc = C->getBeginLoc(); 10564 } 10565 } 10566 } 10567 if (ErrorFound) 10568 return StmtError(); 10569 const auto Pair = DSAStack->getCriticalWithHint(DirName); 10570 if (Pair.first && DirName.getName() && !DependentHint) { 10571 if (llvm::APSInt::compareValues(Hint, Pair.second) != 0) { 10572 Diag(StartLoc, diag::err_omp_critical_with_hint); 10573 if (HintLoc.isValid()) 10574 Diag(HintLoc, diag::note_omp_critical_hint_here) 10575 << 0 << toString(Hint, /*Radix=*/10, /*Signed=*/false); 10576 else 10577 Diag(StartLoc, diag::note_omp_critical_no_hint) << 0; 10578 if (const auto *C = Pair.first->getSingleClause<OMPHintClause>()) { 10579 Diag(C->getBeginLoc(), diag::note_omp_critical_hint_here) 10580 << 1 10581 << toString(C->getHint()->EvaluateKnownConstInt(Context), 10582 /*Radix=*/10, /*Signed=*/false); 10583 } else { 10584 Diag(Pair.first->getBeginLoc(), diag::note_omp_critical_no_hint) << 1; 10585 } 10586 } 10587 } 10588 10589 setFunctionHasBranchProtectedScope(); 10590 10591 auto *Dir = OMPCriticalDirective::Create(Context, DirName, StartLoc, EndLoc, 10592 Clauses, AStmt); 10593 if (!Pair.first && DirName.getName() && !DependentHint) 10594 DSAStack->addCriticalWithHint(Dir, Hint); 10595 return Dir; 10596 } 10597 10598 StmtResult Sema::ActOnOpenMPParallelForDirective( 10599 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10600 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10601 if (!AStmt) 10602 return StmtError(); 10603 10604 auto *CS = cast<CapturedStmt>(AStmt); 10605 // 1.2.2 OpenMP Language Terminology 10606 // Structured block - An executable statement with a single entry at the 10607 // top and a single exit at the bottom. 10608 // The point of exit cannot be a branch out of the structured block. 10609 // longjmp() and throw() must not violate the entry/exit criteria. 10610 CS->getCapturedDecl()->setNothrow(); 10611 10612 OMPLoopBasedDirective::HelperExprs B; 10613 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 10614 // define the nested loops number. 10615 unsigned NestedLoopCount = 10616 checkOpenMPLoop(OMPD_parallel_for, getCollapseNumberExpr(Clauses), 10617 getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack, 10618 VarsWithImplicitDSA, B); 10619 if (NestedLoopCount == 0) 10620 return StmtError(); 10621 10622 assert((CurContext->isDependentContext() || B.builtAll()) && 10623 "omp parallel for loop exprs were not built"); 10624 10625 if (!CurContext->isDependentContext()) { 10626 // Finalize the clauses that need pre-built expressions for CodeGen. 10627 for (OMPClause *C : Clauses) { 10628 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 10629 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 10630 B.NumIterations, *this, CurScope, 10631 DSAStack)) 10632 return StmtError(); 10633 } 10634 } 10635 10636 setFunctionHasBranchProtectedScope(); 10637 return OMPParallelForDirective::Create( 10638 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B, 10639 DSAStack->getTaskgroupReductionRef(), DSAStack->isCancelRegion()); 10640 } 10641 10642 StmtResult Sema::ActOnOpenMPParallelForSimdDirective( 10643 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10644 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10645 if (!AStmt) 10646 return StmtError(); 10647 10648 auto *CS = cast<CapturedStmt>(AStmt); 10649 // 1.2.2 OpenMP Language Terminology 10650 // Structured block - An executable statement with a single entry at the 10651 // top and a single exit at the bottom. 10652 // The point of exit cannot be a branch out of the structured block. 10653 // longjmp() and throw() must not violate the entry/exit criteria. 10654 CS->getCapturedDecl()->setNothrow(); 10655 10656 OMPLoopBasedDirective::HelperExprs B; 10657 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 10658 // define the nested loops number. 10659 unsigned NestedLoopCount = 10660 checkOpenMPLoop(OMPD_parallel_for_simd, getCollapseNumberExpr(Clauses), 10661 getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack, 10662 VarsWithImplicitDSA, B); 10663 if (NestedLoopCount == 0) 10664 return StmtError(); 10665 10666 if (!CurContext->isDependentContext()) { 10667 // Finalize the clauses that need pre-built expressions for CodeGen. 10668 for (OMPClause *C : Clauses) { 10669 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 10670 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 10671 B.NumIterations, *this, CurScope, 10672 DSAStack)) 10673 return StmtError(); 10674 } 10675 } 10676 10677 if (checkSimdlenSafelenSpecified(*this, Clauses)) 10678 return StmtError(); 10679 10680 setFunctionHasBranchProtectedScope(); 10681 return OMPParallelForSimdDirective::Create( 10682 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 10683 } 10684 10685 StmtResult 10686 Sema::ActOnOpenMPParallelMasterDirective(ArrayRef<OMPClause *> Clauses, 10687 Stmt *AStmt, SourceLocation StartLoc, 10688 SourceLocation EndLoc) { 10689 if (!AStmt) 10690 return StmtError(); 10691 10692 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 10693 auto *CS = cast<CapturedStmt>(AStmt); 10694 // 1.2.2 OpenMP Language Terminology 10695 // Structured block - An executable statement with a single entry at the 10696 // top and a single exit at the bottom. 10697 // The point of exit cannot be a branch out of the structured block. 10698 // longjmp() and throw() must not violate the entry/exit criteria. 10699 CS->getCapturedDecl()->setNothrow(); 10700 10701 setFunctionHasBranchProtectedScope(); 10702 10703 return OMPParallelMasterDirective::Create( 10704 Context, StartLoc, EndLoc, Clauses, AStmt, 10705 DSAStack->getTaskgroupReductionRef()); 10706 } 10707 10708 StmtResult 10709 Sema::ActOnOpenMPParallelMaskedDirective(ArrayRef<OMPClause *> Clauses, 10710 Stmt *AStmt, SourceLocation StartLoc, 10711 SourceLocation EndLoc) { 10712 if (!AStmt) 10713 return StmtError(); 10714 10715 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 10716 auto *CS = cast<CapturedStmt>(AStmt); 10717 // 1.2.2 OpenMP Language Terminology 10718 // Structured block - An executable statement with a single entry at the 10719 // top and a single exit at the bottom. 10720 // The point of exit cannot be a branch out of the structured block. 10721 // longjmp() and throw() must not violate the entry/exit criteria. 10722 CS->getCapturedDecl()->setNothrow(); 10723 10724 setFunctionHasBranchProtectedScope(); 10725 10726 return OMPParallelMaskedDirective::Create( 10727 Context, StartLoc, EndLoc, Clauses, AStmt, 10728 DSAStack->getTaskgroupReductionRef()); 10729 } 10730 10731 StmtResult 10732 Sema::ActOnOpenMPParallelSectionsDirective(ArrayRef<OMPClause *> Clauses, 10733 Stmt *AStmt, SourceLocation StartLoc, 10734 SourceLocation EndLoc) { 10735 if (!AStmt) 10736 return StmtError(); 10737 10738 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 10739 auto BaseStmt = AStmt; 10740 while (auto *CS = dyn_cast_or_null<CapturedStmt>(BaseStmt)) 10741 BaseStmt = CS->getCapturedStmt(); 10742 if (auto *C = dyn_cast_or_null<CompoundStmt>(BaseStmt)) { 10743 auto S = C->children(); 10744 if (S.begin() == S.end()) 10745 return StmtError(); 10746 // All associated statements must be '#pragma omp section' except for 10747 // the first one. 10748 for (Stmt *SectionStmt : llvm::drop_begin(S)) { 10749 if (!SectionStmt || !isa<OMPSectionDirective>(SectionStmt)) { 10750 if (SectionStmt) 10751 Diag(SectionStmt->getBeginLoc(), 10752 diag::err_omp_parallel_sections_substmt_not_section); 10753 return StmtError(); 10754 } 10755 cast<OMPSectionDirective>(SectionStmt) 10756 ->setHasCancel(DSAStack->isCancelRegion()); 10757 } 10758 } else { 10759 Diag(AStmt->getBeginLoc(), 10760 diag::err_omp_parallel_sections_not_compound_stmt); 10761 return StmtError(); 10762 } 10763 10764 setFunctionHasBranchProtectedScope(); 10765 10766 return OMPParallelSectionsDirective::Create( 10767 Context, StartLoc, EndLoc, Clauses, AStmt, 10768 DSAStack->getTaskgroupReductionRef(), DSAStack->isCancelRegion()); 10769 } 10770 10771 /// Find and diagnose mutually exclusive clause kinds. 10772 static bool checkMutuallyExclusiveClauses( 10773 Sema &S, ArrayRef<OMPClause *> Clauses, 10774 ArrayRef<OpenMPClauseKind> MutuallyExclusiveClauses) { 10775 const OMPClause *PrevClause = nullptr; 10776 bool ErrorFound = false; 10777 for (const OMPClause *C : Clauses) { 10778 if (llvm::is_contained(MutuallyExclusiveClauses, C->getClauseKind())) { 10779 if (!PrevClause) { 10780 PrevClause = C; 10781 } else if (PrevClause->getClauseKind() != C->getClauseKind()) { 10782 S.Diag(C->getBeginLoc(), diag::err_omp_clauses_mutually_exclusive) 10783 << getOpenMPClauseName(C->getClauseKind()) 10784 << getOpenMPClauseName(PrevClause->getClauseKind()); 10785 S.Diag(PrevClause->getBeginLoc(), diag::note_omp_previous_clause) 10786 << getOpenMPClauseName(PrevClause->getClauseKind()); 10787 ErrorFound = true; 10788 } 10789 } 10790 } 10791 return ErrorFound; 10792 } 10793 10794 StmtResult Sema::ActOnOpenMPTaskDirective(ArrayRef<OMPClause *> Clauses, 10795 Stmt *AStmt, SourceLocation StartLoc, 10796 SourceLocation EndLoc) { 10797 if (!AStmt) 10798 return StmtError(); 10799 10800 // OpenMP 5.0, 2.10.1 task Construct 10801 // If a detach clause appears on the directive, then a mergeable clause cannot 10802 // appear on the same directive. 10803 if (checkMutuallyExclusiveClauses(*this, Clauses, 10804 {OMPC_detach, OMPC_mergeable})) 10805 return StmtError(); 10806 10807 auto *CS = cast<CapturedStmt>(AStmt); 10808 // 1.2.2 OpenMP Language Terminology 10809 // Structured block - An executable statement with a single entry at the 10810 // top and a single exit at the bottom. 10811 // The point of exit cannot be a branch out of the structured block. 10812 // longjmp() and throw() must not violate the entry/exit criteria. 10813 CS->getCapturedDecl()->setNothrow(); 10814 10815 setFunctionHasBranchProtectedScope(); 10816 10817 return OMPTaskDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt, 10818 DSAStack->isCancelRegion()); 10819 } 10820 10821 StmtResult Sema::ActOnOpenMPTaskyieldDirective(SourceLocation StartLoc, 10822 SourceLocation EndLoc) { 10823 return OMPTaskyieldDirective::Create(Context, StartLoc, EndLoc); 10824 } 10825 10826 StmtResult Sema::ActOnOpenMPBarrierDirective(SourceLocation StartLoc, 10827 SourceLocation EndLoc) { 10828 return OMPBarrierDirective::Create(Context, StartLoc, EndLoc); 10829 } 10830 10831 StmtResult Sema::ActOnOpenMPTaskwaitDirective(ArrayRef<OMPClause *> Clauses, 10832 SourceLocation StartLoc, 10833 SourceLocation EndLoc) { 10834 return OMPTaskwaitDirective::Create(Context, StartLoc, EndLoc, Clauses); 10835 } 10836 10837 StmtResult Sema::ActOnOpenMPTaskgroupDirective(ArrayRef<OMPClause *> Clauses, 10838 Stmt *AStmt, 10839 SourceLocation StartLoc, 10840 SourceLocation EndLoc) { 10841 if (!AStmt) 10842 return StmtError(); 10843 10844 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 10845 10846 setFunctionHasBranchProtectedScope(); 10847 10848 return OMPTaskgroupDirective::Create(Context, StartLoc, EndLoc, Clauses, 10849 AStmt, 10850 DSAStack->getTaskgroupReductionRef()); 10851 } 10852 10853 StmtResult Sema::ActOnOpenMPFlushDirective(ArrayRef<OMPClause *> Clauses, 10854 SourceLocation StartLoc, 10855 SourceLocation EndLoc) { 10856 OMPFlushClause *FC = nullptr; 10857 OMPClause *OrderClause = nullptr; 10858 for (OMPClause *C : Clauses) { 10859 if (C->getClauseKind() == OMPC_flush) 10860 FC = cast<OMPFlushClause>(C); 10861 else 10862 OrderClause = C; 10863 } 10864 OpenMPClauseKind MemOrderKind = OMPC_unknown; 10865 SourceLocation MemOrderLoc; 10866 for (const OMPClause *C : Clauses) { 10867 if (C->getClauseKind() == OMPC_acq_rel || 10868 C->getClauseKind() == OMPC_acquire || 10869 C->getClauseKind() == OMPC_release) { 10870 if (MemOrderKind != OMPC_unknown) { 10871 Diag(C->getBeginLoc(), diag::err_omp_several_mem_order_clauses) 10872 << getOpenMPDirectiveName(OMPD_flush) << 1 10873 << SourceRange(C->getBeginLoc(), C->getEndLoc()); 10874 Diag(MemOrderLoc, diag::note_omp_previous_mem_order_clause) 10875 << getOpenMPClauseName(MemOrderKind); 10876 } else { 10877 MemOrderKind = C->getClauseKind(); 10878 MemOrderLoc = C->getBeginLoc(); 10879 } 10880 } 10881 } 10882 if (FC && OrderClause) { 10883 Diag(FC->getLParenLoc(), diag::err_omp_flush_order_clause_and_list) 10884 << getOpenMPClauseName(OrderClause->getClauseKind()); 10885 Diag(OrderClause->getBeginLoc(), diag::note_omp_flush_order_clause_here) 10886 << getOpenMPClauseName(OrderClause->getClauseKind()); 10887 return StmtError(); 10888 } 10889 return OMPFlushDirective::Create(Context, StartLoc, EndLoc, Clauses); 10890 } 10891 10892 StmtResult Sema::ActOnOpenMPDepobjDirective(ArrayRef<OMPClause *> Clauses, 10893 SourceLocation StartLoc, 10894 SourceLocation EndLoc) { 10895 if (Clauses.empty()) { 10896 Diag(StartLoc, diag::err_omp_depobj_expected); 10897 return StmtError(); 10898 } else if (Clauses[0]->getClauseKind() != OMPC_depobj) { 10899 Diag(Clauses[0]->getBeginLoc(), diag::err_omp_depobj_expected); 10900 return StmtError(); 10901 } 10902 // Only depobj expression and another single clause is allowed. 10903 if (Clauses.size() > 2) { 10904 Diag(Clauses[2]->getBeginLoc(), 10905 diag::err_omp_depobj_single_clause_expected); 10906 return StmtError(); 10907 } else if (Clauses.size() < 1) { 10908 Diag(Clauses[0]->getEndLoc(), diag::err_omp_depobj_single_clause_expected); 10909 return StmtError(); 10910 } 10911 return OMPDepobjDirective::Create(Context, StartLoc, EndLoc, Clauses); 10912 } 10913 10914 StmtResult Sema::ActOnOpenMPScanDirective(ArrayRef<OMPClause *> Clauses, 10915 SourceLocation StartLoc, 10916 SourceLocation EndLoc) { 10917 // Check that exactly one clause is specified. 10918 if (Clauses.size() != 1) { 10919 Diag(Clauses.empty() ? EndLoc : Clauses[1]->getBeginLoc(), 10920 diag::err_omp_scan_single_clause_expected); 10921 return StmtError(); 10922 } 10923 // Check that scan directive is used in the scopeof the OpenMP loop body. 10924 if (Scope *S = DSAStack->getCurScope()) { 10925 Scope *ParentS = S->getParent(); 10926 if (!ParentS || ParentS->getParent() != ParentS->getBreakParent() || 10927 !ParentS->getBreakParent()->isOpenMPLoopScope()) 10928 return StmtError(Diag(StartLoc, diag::err_omp_orphaned_device_directive) 10929 << getOpenMPDirectiveName(OMPD_scan) << 5); 10930 } 10931 // Check that only one instance of scan directives is used in the same outer 10932 // region. 10933 if (DSAStack->doesParentHasScanDirective()) { 10934 Diag(StartLoc, diag::err_omp_several_directives_in_region) << "scan"; 10935 Diag(DSAStack->getParentScanDirectiveLoc(), 10936 diag::note_omp_previous_directive) 10937 << "scan"; 10938 return StmtError(); 10939 } 10940 DSAStack->setParentHasScanDirective(StartLoc); 10941 return OMPScanDirective::Create(Context, StartLoc, EndLoc, Clauses); 10942 } 10943 10944 StmtResult Sema::ActOnOpenMPOrderedDirective(ArrayRef<OMPClause *> Clauses, 10945 Stmt *AStmt, 10946 SourceLocation StartLoc, 10947 SourceLocation EndLoc) { 10948 const OMPClause *DependFound = nullptr; 10949 const OMPClause *DependSourceClause = nullptr; 10950 const OMPClause *DependSinkClause = nullptr; 10951 bool ErrorFound = false; 10952 const OMPThreadsClause *TC = nullptr; 10953 const OMPSIMDClause *SC = nullptr; 10954 for (const OMPClause *C : Clauses) { 10955 if (auto *DC = dyn_cast<OMPDependClause>(C)) { 10956 DependFound = C; 10957 if (DC->getDependencyKind() == OMPC_DEPEND_source) { 10958 if (DependSourceClause) { 10959 Diag(C->getBeginLoc(), diag::err_omp_more_one_clause) 10960 << getOpenMPDirectiveName(OMPD_ordered) 10961 << getOpenMPClauseName(OMPC_depend) << 2; 10962 ErrorFound = true; 10963 } else { 10964 DependSourceClause = C; 10965 } 10966 if (DependSinkClause) { 10967 Diag(C->getBeginLoc(), diag::err_omp_depend_sink_source_not_allowed) 10968 << 0; 10969 ErrorFound = true; 10970 } 10971 } else if (DC->getDependencyKind() == OMPC_DEPEND_sink) { 10972 if (DependSourceClause) { 10973 Diag(C->getBeginLoc(), diag::err_omp_depend_sink_source_not_allowed) 10974 << 1; 10975 ErrorFound = true; 10976 } 10977 DependSinkClause = C; 10978 } 10979 } else if (C->getClauseKind() == OMPC_threads) { 10980 TC = cast<OMPThreadsClause>(C); 10981 } else if (C->getClauseKind() == OMPC_simd) { 10982 SC = cast<OMPSIMDClause>(C); 10983 } 10984 } 10985 if (!ErrorFound && !SC && 10986 isOpenMPSimdDirective(DSAStack->getParentDirective())) { 10987 // OpenMP [2.8.1,simd Construct, Restrictions] 10988 // An ordered construct with the simd clause is the only OpenMP construct 10989 // that can appear in the simd region. 10990 Diag(StartLoc, diag::err_omp_prohibited_region_simd) 10991 << (LangOpts.OpenMP >= 50 ? 1 : 0); 10992 ErrorFound = true; 10993 } else if (DependFound && (TC || SC)) { 10994 Diag(DependFound->getBeginLoc(), diag::err_omp_depend_clause_thread_simd) 10995 << getOpenMPClauseName(TC ? TC->getClauseKind() : SC->getClauseKind()); 10996 ErrorFound = true; 10997 } else if (DependFound && !DSAStack->getParentOrderedRegionParam().first) { 10998 Diag(DependFound->getBeginLoc(), 10999 diag::err_omp_ordered_directive_without_param); 11000 ErrorFound = true; 11001 } else if (TC || Clauses.empty()) { 11002 if (const Expr *Param = DSAStack->getParentOrderedRegionParam().first) { 11003 SourceLocation ErrLoc = TC ? TC->getBeginLoc() : StartLoc; 11004 Diag(ErrLoc, diag::err_omp_ordered_directive_with_param) 11005 << (TC != nullptr); 11006 Diag(Param->getBeginLoc(), diag::note_omp_ordered_param) << 1; 11007 ErrorFound = true; 11008 } 11009 } 11010 if ((!AStmt && !DependFound) || ErrorFound) 11011 return StmtError(); 11012 11013 // OpenMP 5.0, 2.17.9, ordered Construct, Restrictions. 11014 // During execution of an iteration of a worksharing-loop or a loop nest 11015 // within a worksharing-loop, simd, or worksharing-loop SIMD region, a thread 11016 // must not execute more than one ordered region corresponding to an ordered 11017 // construct without a depend clause. 11018 if (!DependFound) { 11019 if (DSAStack->doesParentHasOrderedDirective()) { 11020 Diag(StartLoc, diag::err_omp_several_directives_in_region) << "ordered"; 11021 Diag(DSAStack->getParentOrderedDirectiveLoc(), 11022 diag::note_omp_previous_directive) 11023 << "ordered"; 11024 return StmtError(); 11025 } 11026 DSAStack->setParentHasOrderedDirective(StartLoc); 11027 } 11028 11029 if (AStmt) { 11030 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 11031 11032 setFunctionHasBranchProtectedScope(); 11033 } 11034 11035 return OMPOrderedDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt); 11036 } 11037 11038 namespace { 11039 /// Helper class for checking expression in 'omp atomic [update]' 11040 /// construct. 11041 class OpenMPAtomicUpdateChecker { 11042 /// Error results for atomic update expressions. 11043 enum ExprAnalysisErrorCode { 11044 /// A statement is not an expression statement. 11045 NotAnExpression, 11046 /// Expression is not builtin binary or unary operation. 11047 NotABinaryOrUnaryExpression, 11048 /// Unary operation is not post-/pre- increment/decrement operation. 11049 NotAnUnaryIncDecExpression, 11050 /// An expression is not of scalar type. 11051 NotAScalarType, 11052 /// A binary operation is not an assignment operation. 11053 NotAnAssignmentOp, 11054 /// RHS part of the binary operation is not a binary expression. 11055 NotABinaryExpression, 11056 /// RHS part is not additive/multiplicative/shift/biwise binary 11057 /// expression. 11058 NotABinaryOperator, 11059 /// RHS binary operation does not have reference to the updated LHS 11060 /// part. 11061 NotAnUpdateExpression, 11062 /// No errors is found. 11063 NoError 11064 }; 11065 /// Reference to Sema. 11066 Sema &SemaRef; 11067 /// A location for note diagnostics (when error is found). 11068 SourceLocation NoteLoc; 11069 /// 'x' lvalue part of the source atomic expression. 11070 Expr *X; 11071 /// 'expr' rvalue part of the source atomic expression. 11072 Expr *E; 11073 /// Helper expression of the form 11074 /// 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or 11075 /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'. 11076 Expr *UpdateExpr; 11077 /// Is 'x' a LHS in a RHS part of full update expression. It is 11078 /// important for non-associative operations. 11079 bool IsXLHSInRHSPart; 11080 BinaryOperatorKind Op; 11081 SourceLocation OpLoc; 11082 /// true if the source expression is a postfix unary operation, false 11083 /// if it is a prefix unary operation. 11084 bool IsPostfixUpdate; 11085 11086 public: 11087 OpenMPAtomicUpdateChecker(Sema &SemaRef) 11088 : SemaRef(SemaRef), X(nullptr), E(nullptr), UpdateExpr(nullptr), 11089 IsXLHSInRHSPart(false), Op(BO_PtrMemD), IsPostfixUpdate(false) {} 11090 /// Check specified statement that it is suitable for 'atomic update' 11091 /// constructs and extract 'x', 'expr' and Operation from the original 11092 /// expression. If DiagId and NoteId == 0, then only check is performed 11093 /// without error notification. 11094 /// \param DiagId Diagnostic which should be emitted if error is found. 11095 /// \param NoteId Diagnostic note for the main error message. 11096 /// \return true if statement is not an update expression, false otherwise. 11097 bool checkStatement(Stmt *S, unsigned DiagId = 0, unsigned NoteId = 0); 11098 /// Return the 'x' lvalue part of the source atomic expression. 11099 Expr *getX() const { return X; } 11100 /// Return the 'expr' rvalue part of the source atomic expression. 11101 Expr *getExpr() const { return E; } 11102 /// Return the update expression used in calculation of the updated 11103 /// value. Always has form 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or 11104 /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'. 11105 Expr *getUpdateExpr() const { return UpdateExpr; } 11106 /// Return true if 'x' is LHS in RHS part of full update expression, 11107 /// false otherwise. 11108 bool isXLHSInRHSPart() const { return IsXLHSInRHSPart; } 11109 11110 /// true if the source expression is a postfix unary operation, false 11111 /// if it is a prefix unary operation. 11112 bool isPostfixUpdate() const { return IsPostfixUpdate; } 11113 11114 private: 11115 bool checkBinaryOperation(BinaryOperator *AtomicBinOp, unsigned DiagId = 0, 11116 unsigned NoteId = 0); 11117 }; 11118 11119 bool OpenMPAtomicUpdateChecker::checkBinaryOperation( 11120 BinaryOperator *AtomicBinOp, unsigned DiagId, unsigned NoteId) { 11121 ExprAnalysisErrorCode ErrorFound = NoError; 11122 SourceLocation ErrorLoc, NoteLoc; 11123 SourceRange ErrorRange, NoteRange; 11124 // Allowed constructs are: 11125 // x = x binop expr; 11126 // x = expr binop x; 11127 if (AtomicBinOp->getOpcode() == BO_Assign) { 11128 X = AtomicBinOp->getLHS(); 11129 if (const auto *AtomicInnerBinOp = dyn_cast<BinaryOperator>( 11130 AtomicBinOp->getRHS()->IgnoreParenImpCasts())) { 11131 if (AtomicInnerBinOp->isMultiplicativeOp() || 11132 AtomicInnerBinOp->isAdditiveOp() || AtomicInnerBinOp->isShiftOp() || 11133 AtomicInnerBinOp->isBitwiseOp()) { 11134 Op = AtomicInnerBinOp->getOpcode(); 11135 OpLoc = AtomicInnerBinOp->getOperatorLoc(); 11136 Expr *LHS = AtomicInnerBinOp->getLHS(); 11137 Expr *RHS = AtomicInnerBinOp->getRHS(); 11138 llvm::FoldingSetNodeID XId, LHSId, RHSId; 11139 X->IgnoreParenImpCasts()->Profile(XId, SemaRef.getASTContext(), 11140 /*Canonical=*/true); 11141 LHS->IgnoreParenImpCasts()->Profile(LHSId, SemaRef.getASTContext(), 11142 /*Canonical=*/true); 11143 RHS->IgnoreParenImpCasts()->Profile(RHSId, SemaRef.getASTContext(), 11144 /*Canonical=*/true); 11145 if (XId == LHSId) { 11146 E = RHS; 11147 IsXLHSInRHSPart = true; 11148 } else if (XId == RHSId) { 11149 E = LHS; 11150 IsXLHSInRHSPart = false; 11151 } else { 11152 ErrorLoc = AtomicInnerBinOp->getExprLoc(); 11153 ErrorRange = AtomicInnerBinOp->getSourceRange(); 11154 NoteLoc = X->getExprLoc(); 11155 NoteRange = X->getSourceRange(); 11156 ErrorFound = NotAnUpdateExpression; 11157 } 11158 } else { 11159 ErrorLoc = AtomicInnerBinOp->getExprLoc(); 11160 ErrorRange = AtomicInnerBinOp->getSourceRange(); 11161 NoteLoc = AtomicInnerBinOp->getOperatorLoc(); 11162 NoteRange = SourceRange(NoteLoc, NoteLoc); 11163 ErrorFound = NotABinaryOperator; 11164 } 11165 } else { 11166 NoteLoc = ErrorLoc = AtomicBinOp->getRHS()->getExprLoc(); 11167 NoteRange = ErrorRange = AtomicBinOp->getRHS()->getSourceRange(); 11168 ErrorFound = NotABinaryExpression; 11169 } 11170 } else { 11171 ErrorLoc = AtomicBinOp->getExprLoc(); 11172 ErrorRange = AtomicBinOp->getSourceRange(); 11173 NoteLoc = AtomicBinOp->getOperatorLoc(); 11174 NoteRange = SourceRange(NoteLoc, NoteLoc); 11175 ErrorFound = NotAnAssignmentOp; 11176 } 11177 if (ErrorFound != NoError && DiagId != 0 && NoteId != 0) { 11178 SemaRef.Diag(ErrorLoc, DiagId) << ErrorRange; 11179 SemaRef.Diag(NoteLoc, NoteId) << ErrorFound << NoteRange; 11180 return true; 11181 } 11182 if (SemaRef.CurContext->isDependentContext()) 11183 E = X = UpdateExpr = nullptr; 11184 return ErrorFound != NoError; 11185 } 11186 11187 bool OpenMPAtomicUpdateChecker::checkStatement(Stmt *S, unsigned DiagId, 11188 unsigned NoteId) { 11189 ExprAnalysisErrorCode ErrorFound = NoError; 11190 SourceLocation ErrorLoc, NoteLoc; 11191 SourceRange ErrorRange, NoteRange; 11192 // Allowed constructs are: 11193 // x++; 11194 // x--; 11195 // ++x; 11196 // --x; 11197 // x binop= expr; 11198 // x = x binop expr; 11199 // x = expr binop x; 11200 if (auto *AtomicBody = dyn_cast<Expr>(S)) { 11201 AtomicBody = AtomicBody->IgnoreParenImpCasts(); 11202 if (AtomicBody->getType()->isScalarType() || 11203 AtomicBody->isInstantiationDependent()) { 11204 if (const auto *AtomicCompAssignOp = dyn_cast<CompoundAssignOperator>( 11205 AtomicBody->IgnoreParenImpCasts())) { 11206 // Check for Compound Assignment Operation 11207 Op = BinaryOperator::getOpForCompoundAssignment( 11208 AtomicCompAssignOp->getOpcode()); 11209 OpLoc = AtomicCompAssignOp->getOperatorLoc(); 11210 E = AtomicCompAssignOp->getRHS(); 11211 X = AtomicCompAssignOp->getLHS()->IgnoreParens(); 11212 IsXLHSInRHSPart = true; 11213 } else if (auto *AtomicBinOp = dyn_cast<BinaryOperator>( 11214 AtomicBody->IgnoreParenImpCasts())) { 11215 // Check for Binary Operation 11216 if (checkBinaryOperation(AtomicBinOp, DiagId, NoteId)) 11217 return true; 11218 } else if (const auto *AtomicUnaryOp = dyn_cast<UnaryOperator>( 11219 AtomicBody->IgnoreParenImpCasts())) { 11220 // Check for Unary Operation 11221 if (AtomicUnaryOp->isIncrementDecrementOp()) { 11222 IsPostfixUpdate = AtomicUnaryOp->isPostfix(); 11223 Op = AtomicUnaryOp->isIncrementOp() ? BO_Add : BO_Sub; 11224 OpLoc = AtomicUnaryOp->getOperatorLoc(); 11225 X = AtomicUnaryOp->getSubExpr()->IgnoreParens(); 11226 E = SemaRef.ActOnIntegerConstant(OpLoc, /*uint64_t Val=*/1).get(); 11227 IsXLHSInRHSPart = true; 11228 } else { 11229 ErrorFound = NotAnUnaryIncDecExpression; 11230 ErrorLoc = AtomicUnaryOp->getExprLoc(); 11231 ErrorRange = AtomicUnaryOp->getSourceRange(); 11232 NoteLoc = AtomicUnaryOp->getOperatorLoc(); 11233 NoteRange = SourceRange(NoteLoc, NoteLoc); 11234 } 11235 } else if (!AtomicBody->isInstantiationDependent()) { 11236 ErrorFound = NotABinaryOrUnaryExpression; 11237 NoteLoc = ErrorLoc = AtomicBody->getExprLoc(); 11238 NoteRange = ErrorRange = AtomicBody->getSourceRange(); 11239 } 11240 } else { 11241 ErrorFound = NotAScalarType; 11242 NoteLoc = ErrorLoc = AtomicBody->getBeginLoc(); 11243 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc); 11244 } 11245 } else { 11246 ErrorFound = NotAnExpression; 11247 NoteLoc = ErrorLoc = S->getBeginLoc(); 11248 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc); 11249 } 11250 if (ErrorFound != NoError && DiagId != 0 && NoteId != 0) { 11251 SemaRef.Diag(ErrorLoc, DiagId) << ErrorRange; 11252 SemaRef.Diag(NoteLoc, NoteId) << ErrorFound << NoteRange; 11253 return true; 11254 } 11255 if (SemaRef.CurContext->isDependentContext()) 11256 E = X = UpdateExpr = nullptr; 11257 if (ErrorFound == NoError && E && X) { 11258 // Build an update expression of form 'OpaqueValueExpr(x) binop 11259 // OpaqueValueExpr(expr)' or 'OpaqueValueExpr(expr) binop 11260 // OpaqueValueExpr(x)' and then cast it to the type of the 'x' expression. 11261 auto *OVEX = new (SemaRef.getASTContext()) 11262 OpaqueValueExpr(X->getExprLoc(), X->getType(), VK_PRValue); 11263 auto *OVEExpr = new (SemaRef.getASTContext()) 11264 OpaqueValueExpr(E->getExprLoc(), E->getType(), VK_PRValue); 11265 ExprResult Update = 11266 SemaRef.CreateBuiltinBinOp(OpLoc, Op, IsXLHSInRHSPart ? OVEX : OVEExpr, 11267 IsXLHSInRHSPart ? OVEExpr : OVEX); 11268 if (Update.isInvalid()) 11269 return true; 11270 Update = SemaRef.PerformImplicitConversion(Update.get(), X->getType(), 11271 Sema::AA_Casting); 11272 if (Update.isInvalid()) 11273 return true; 11274 UpdateExpr = Update.get(); 11275 } 11276 return ErrorFound != NoError; 11277 } 11278 11279 /// Get the node id of the fixed point of an expression \a S. 11280 llvm::FoldingSetNodeID getNodeId(ASTContext &Context, const Expr *S) { 11281 llvm::FoldingSetNodeID Id; 11282 S->IgnoreParenImpCasts()->Profile(Id, Context, true); 11283 return Id; 11284 } 11285 11286 /// Check if two expressions are same. 11287 bool checkIfTwoExprsAreSame(ASTContext &Context, const Expr *LHS, 11288 const Expr *RHS) { 11289 return getNodeId(Context, LHS) == getNodeId(Context, RHS); 11290 } 11291 11292 class OpenMPAtomicCompareChecker { 11293 public: 11294 /// All kinds of errors that can occur in `atomic compare` 11295 enum ErrorTy { 11296 /// Empty compound statement. 11297 NoStmt = 0, 11298 /// More than one statement in a compound statement. 11299 MoreThanOneStmt, 11300 /// Not an assignment binary operator. 11301 NotAnAssignment, 11302 /// Not a conditional operator. 11303 NotCondOp, 11304 /// Wrong false expr. According to the spec, 'x' should be at the false 11305 /// expression of a conditional expression. 11306 WrongFalseExpr, 11307 /// The condition of a conditional expression is not a binary operator. 11308 NotABinaryOp, 11309 /// Invalid binary operator (not <, >, or ==). 11310 InvalidBinaryOp, 11311 /// Invalid comparison (not x == e, e == x, x ordop expr, or expr ordop x). 11312 InvalidComparison, 11313 /// X is not a lvalue. 11314 XNotLValue, 11315 /// Not a scalar. 11316 NotScalar, 11317 /// Not an integer. 11318 NotInteger, 11319 /// 'else' statement is not expected. 11320 UnexpectedElse, 11321 /// Not an equality operator. 11322 NotEQ, 11323 /// Invalid assignment (not v == x). 11324 InvalidAssignment, 11325 /// Not if statement 11326 NotIfStmt, 11327 /// More than two statements in a compund statement. 11328 MoreThanTwoStmts, 11329 /// Not a compound statement. 11330 NotCompoundStmt, 11331 /// No else statement. 11332 NoElse, 11333 /// Not 'if (r)'. 11334 InvalidCondition, 11335 /// No error. 11336 NoError, 11337 }; 11338 11339 struct ErrorInfoTy { 11340 ErrorTy Error; 11341 SourceLocation ErrorLoc; 11342 SourceRange ErrorRange; 11343 SourceLocation NoteLoc; 11344 SourceRange NoteRange; 11345 }; 11346 11347 OpenMPAtomicCompareChecker(Sema &S) : ContextRef(S.getASTContext()) {} 11348 11349 /// Check if statement \a S is valid for <tt>atomic compare</tt>. 11350 bool checkStmt(Stmt *S, ErrorInfoTy &ErrorInfo); 11351 11352 Expr *getX() const { return X; } 11353 Expr *getE() const { return E; } 11354 Expr *getD() const { return D; } 11355 Expr *getCond() const { return C; } 11356 bool isXBinopExpr() const { return IsXBinopExpr; } 11357 11358 protected: 11359 /// Reference to ASTContext 11360 ASTContext &ContextRef; 11361 /// 'x' lvalue part of the source atomic expression. 11362 Expr *X = nullptr; 11363 /// 'expr' or 'e' rvalue part of the source atomic expression. 11364 Expr *E = nullptr; 11365 /// 'd' rvalue part of the source atomic expression. 11366 Expr *D = nullptr; 11367 /// 'cond' part of the source atomic expression. It is in one of the following 11368 /// forms: 11369 /// expr ordop x 11370 /// x ordop expr 11371 /// x == e 11372 /// e == x 11373 Expr *C = nullptr; 11374 /// True if the cond expr is in the form of 'x ordop expr'. 11375 bool IsXBinopExpr = true; 11376 11377 /// Check if it is a valid conditional update statement (cond-update-stmt). 11378 bool checkCondUpdateStmt(IfStmt *S, ErrorInfoTy &ErrorInfo); 11379 11380 /// Check if it is a valid conditional expression statement (cond-expr-stmt). 11381 bool checkCondExprStmt(Stmt *S, ErrorInfoTy &ErrorInfo); 11382 11383 /// Check if all captured values have right type. 11384 bool checkType(ErrorInfoTy &ErrorInfo) const; 11385 11386 static bool CheckValue(const Expr *E, ErrorInfoTy &ErrorInfo, 11387 bool ShouldBeLValue) { 11388 if (ShouldBeLValue && !E->isLValue()) { 11389 ErrorInfo.Error = ErrorTy::XNotLValue; 11390 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = E->getExprLoc(); 11391 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = E->getSourceRange(); 11392 return false; 11393 } 11394 11395 if (!E->isInstantiationDependent()) { 11396 QualType QTy = E->getType(); 11397 if (!QTy->isScalarType()) { 11398 ErrorInfo.Error = ErrorTy::NotScalar; 11399 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = E->getExprLoc(); 11400 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = E->getSourceRange(); 11401 return false; 11402 } 11403 11404 if (!QTy->isIntegerType()) { 11405 ErrorInfo.Error = ErrorTy::NotInteger; 11406 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = E->getExprLoc(); 11407 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = E->getSourceRange(); 11408 return false; 11409 } 11410 } 11411 11412 return true; 11413 } 11414 }; 11415 11416 bool OpenMPAtomicCompareChecker::checkCondUpdateStmt(IfStmt *S, 11417 ErrorInfoTy &ErrorInfo) { 11418 auto *Then = S->getThen(); 11419 if (auto *CS = dyn_cast<CompoundStmt>(Then)) { 11420 if (CS->body_empty()) { 11421 ErrorInfo.Error = ErrorTy::NoStmt; 11422 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = CS->getBeginLoc(); 11423 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = CS->getSourceRange(); 11424 return false; 11425 } 11426 if (CS->size() > 1) { 11427 ErrorInfo.Error = ErrorTy::MoreThanOneStmt; 11428 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = CS->getBeginLoc(); 11429 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = S->getSourceRange(); 11430 return false; 11431 } 11432 Then = CS->body_front(); 11433 } 11434 11435 auto *BO = dyn_cast<BinaryOperator>(Then); 11436 if (!BO) { 11437 ErrorInfo.Error = ErrorTy::NotAnAssignment; 11438 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = Then->getBeginLoc(); 11439 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = Then->getSourceRange(); 11440 return false; 11441 } 11442 if (BO->getOpcode() != BO_Assign) { 11443 ErrorInfo.Error = ErrorTy::NotAnAssignment; 11444 ErrorInfo.ErrorLoc = BO->getExprLoc(); 11445 ErrorInfo.NoteLoc = BO->getOperatorLoc(); 11446 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = BO->getSourceRange(); 11447 return false; 11448 } 11449 11450 X = BO->getLHS(); 11451 11452 auto *Cond = dyn_cast<BinaryOperator>(S->getCond()); 11453 if (!Cond) { 11454 ErrorInfo.Error = ErrorTy::NotABinaryOp; 11455 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = S->getCond()->getExprLoc(); 11456 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = S->getCond()->getSourceRange(); 11457 return false; 11458 } 11459 11460 switch (Cond->getOpcode()) { 11461 case BO_EQ: { 11462 C = Cond; 11463 D = BO->getRHS(); 11464 if (checkIfTwoExprsAreSame(ContextRef, X, Cond->getLHS())) { 11465 E = Cond->getRHS(); 11466 } else if (checkIfTwoExprsAreSame(ContextRef, X, Cond->getRHS())) { 11467 E = Cond->getLHS(); 11468 } else { 11469 ErrorInfo.Error = ErrorTy::InvalidComparison; 11470 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = Cond->getExprLoc(); 11471 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = Cond->getSourceRange(); 11472 return false; 11473 } 11474 break; 11475 } 11476 case BO_LT: 11477 case BO_GT: { 11478 E = BO->getRHS(); 11479 if (checkIfTwoExprsAreSame(ContextRef, X, Cond->getLHS()) && 11480 checkIfTwoExprsAreSame(ContextRef, E, Cond->getRHS())) { 11481 C = Cond; 11482 } else if (checkIfTwoExprsAreSame(ContextRef, E, Cond->getLHS()) && 11483 checkIfTwoExprsAreSame(ContextRef, X, Cond->getRHS())) { 11484 C = Cond; 11485 IsXBinopExpr = false; 11486 } else { 11487 ErrorInfo.Error = ErrorTy::InvalidComparison; 11488 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = Cond->getExprLoc(); 11489 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = Cond->getSourceRange(); 11490 return false; 11491 } 11492 break; 11493 } 11494 default: 11495 ErrorInfo.Error = ErrorTy::InvalidBinaryOp; 11496 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = Cond->getExprLoc(); 11497 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = Cond->getSourceRange(); 11498 return false; 11499 } 11500 11501 if (S->getElse()) { 11502 ErrorInfo.Error = ErrorTy::UnexpectedElse; 11503 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = S->getElse()->getBeginLoc(); 11504 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = S->getElse()->getSourceRange(); 11505 return false; 11506 } 11507 11508 return true; 11509 } 11510 11511 bool OpenMPAtomicCompareChecker::checkCondExprStmt(Stmt *S, 11512 ErrorInfoTy &ErrorInfo) { 11513 auto *BO = dyn_cast<BinaryOperator>(S); 11514 if (!BO) { 11515 ErrorInfo.Error = ErrorTy::NotAnAssignment; 11516 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = S->getBeginLoc(); 11517 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = S->getSourceRange(); 11518 return false; 11519 } 11520 if (BO->getOpcode() != BO_Assign) { 11521 ErrorInfo.Error = ErrorTy::NotAnAssignment; 11522 ErrorInfo.ErrorLoc = BO->getExprLoc(); 11523 ErrorInfo.NoteLoc = BO->getOperatorLoc(); 11524 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = BO->getSourceRange(); 11525 return false; 11526 } 11527 11528 X = BO->getLHS(); 11529 11530 auto *CO = dyn_cast<ConditionalOperator>(BO->getRHS()->IgnoreParenImpCasts()); 11531 if (!CO) { 11532 ErrorInfo.Error = ErrorTy::NotCondOp; 11533 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = BO->getRHS()->getExprLoc(); 11534 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = BO->getRHS()->getSourceRange(); 11535 return false; 11536 } 11537 11538 if (!checkIfTwoExprsAreSame(ContextRef, X, CO->getFalseExpr())) { 11539 ErrorInfo.Error = ErrorTy::WrongFalseExpr; 11540 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = CO->getFalseExpr()->getExprLoc(); 11541 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = 11542 CO->getFalseExpr()->getSourceRange(); 11543 return false; 11544 } 11545 11546 auto *Cond = dyn_cast<BinaryOperator>(CO->getCond()); 11547 if (!Cond) { 11548 ErrorInfo.Error = ErrorTy::NotABinaryOp; 11549 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = CO->getCond()->getExprLoc(); 11550 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = 11551 CO->getCond()->getSourceRange(); 11552 return false; 11553 } 11554 11555 switch (Cond->getOpcode()) { 11556 case BO_EQ: { 11557 C = Cond; 11558 D = CO->getTrueExpr(); 11559 if (checkIfTwoExprsAreSame(ContextRef, X, Cond->getLHS())) { 11560 E = Cond->getRHS(); 11561 } else if (checkIfTwoExprsAreSame(ContextRef, X, Cond->getRHS())) { 11562 E = Cond->getLHS(); 11563 } else { 11564 ErrorInfo.Error = ErrorTy::InvalidComparison; 11565 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = Cond->getExprLoc(); 11566 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = Cond->getSourceRange(); 11567 return false; 11568 } 11569 break; 11570 } 11571 case BO_LT: 11572 case BO_GT: { 11573 E = CO->getTrueExpr(); 11574 if (checkIfTwoExprsAreSame(ContextRef, X, Cond->getLHS()) && 11575 checkIfTwoExprsAreSame(ContextRef, E, Cond->getRHS())) { 11576 C = Cond; 11577 } else if (checkIfTwoExprsAreSame(ContextRef, E, Cond->getLHS()) && 11578 checkIfTwoExprsAreSame(ContextRef, X, Cond->getRHS())) { 11579 C = Cond; 11580 IsXBinopExpr = false; 11581 } else { 11582 ErrorInfo.Error = ErrorTy::InvalidComparison; 11583 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = Cond->getExprLoc(); 11584 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = Cond->getSourceRange(); 11585 return false; 11586 } 11587 break; 11588 } 11589 default: 11590 ErrorInfo.Error = ErrorTy::InvalidBinaryOp; 11591 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = Cond->getExprLoc(); 11592 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = Cond->getSourceRange(); 11593 return false; 11594 } 11595 11596 return true; 11597 } 11598 11599 bool OpenMPAtomicCompareChecker::checkType(ErrorInfoTy &ErrorInfo) const { 11600 // 'x' and 'e' cannot be nullptr 11601 assert(X && E && "X and E cannot be nullptr"); 11602 11603 if (!CheckValue(X, ErrorInfo, true)) 11604 return false; 11605 11606 if (!CheckValue(E, ErrorInfo, false)) 11607 return false; 11608 11609 if (D && !CheckValue(D, ErrorInfo, false)) 11610 return false; 11611 11612 return true; 11613 } 11614 11615 bool OpenMPAtomicCompareChecker::checkStmt( 11616 Stmt *S, OpenMPAtomicCompareChecker::ErrorInfoTy &ErrorInfo) { 11617 auto *CS = dyn_cast<CompoundStmt>(S); 11618 if (CS) { 11619 if (CS->body_empty()) { 11620 ErrorInfo.Error = ErrorTy::NoStmt; 11621 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = CS->getBeginLoc(); 11622 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = CS->getSourceRange(); 11623 return false; 11624 } 11625 11626 if (CS->size() != 1) { 11627 ErrorInfo.Error = ErrorTy::MoreThanOneStmt; 11628 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = CS->getBeginLoc(); 11629 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = CS->getSourceRange(); 11630 return false; 11631 } 11632 S = CS->body_front(); 11633 } 11634 11635 auto Res = false; 11636 11637 if (auto *IS = dyn_cast<IfStmt>(S)) { 11638 // Check if the statement is in one of the following forms 11639 // (cond-update-stmt): 11640 // if (expr ordop x) { x = expr; } 11641 // if (x ordop expr) { x = expr; } 11642 // if (x == e) { x = d; } 11643 Res = checkCondUpdateStmt(IS, ErrorInfo); 11644 } else { 11645 // Check if the statement is in one of the following forms (cond-expr-stmt): 11646 // x = expr ordop x ? expr : x; 11647 // x = x ordop expr ? expr : x; 11648 // x = x == e ? d : x; 11649 Res = checkCondExprStmt(S, ErrorInfo); 11650 } 11651 11652 if (!Res) 11653 return false; 11654 11655 return checkType(ErrorInfo); 11656 } 11657 11658 class OpenMPAtomicCompareCaptureChecker final 11659 : public OpenMPAtomicCompareChecker { 11660 public: 11661 OpenMPAtomicCompareCaptureChecker(Sema &S) : OpenMPAtomicCompareChecker(S) {} 11662 11663 Expr *getV() const { return V; } 11664 Expr *getR() const { return R; } 11665 bool isFailOnly() const { return IsFailOnly; } 11666 bool isPostfixUpdate() const { return IsPostfixUpdate; } 11667 11668 /// Check if statement \a S is valid for <tt>atomic compare capture</tt>. 11669 bool checkStmt(Stmt *S, ErrorInfoTy &ErrorInfo); 11670 11671 private: 11672 bool checkType(ErrorInfoTy &ErrorInfo); 11673 11674 // NOTE: Form 3, 4, 5 in the following comments mean the 3rd, 4th, and 5th 11675 // form of 'conditional-update-capture-atomic' structured block on the v5.2 11676 // spec p.p. 82: 11677 // (1) { v = x; cond-update-stmt } 11678 // (2) { cond-update-stmt v = x; } 11679 // (3) if(x == e) { x = d; } else { v = x; } 11680 // (4) { r = x == e; if(r) { x = d; } } 11681 // (5) { r = x == e; if(r) { x = d; } else { v = x; } } 11682 11683 /// Check if it is valid 'if(x == e) { x = d; } else { v = x; }' (form 3) 11684 bool checkForm3(IfStmt *S, ErrorInfoTy &ErrorInfo); 11685 11686 /// Check if it is valid '{ r = x == e; if(r) { x = d; } }', 11687 /// or '{ r = x == e; if(r) { x = d; } else { v = x; } }' (form 4 and 5) 11688 bool checkForm45(Stmt *S, ErrorInfoTy &ErrorInfo); 11689 11690 /// 'v' lvalue part of the source atomic expression. 11691 Expr *V = nullptr; 11692 /// 'r' lvalue part of the source atomic expression. 11693 Expr *R = nullptr; 11694 /// If 'v' is only updated when the comparison fails. 11695 bool IsFailOnly = false; 11696 /// If original value of 'x' must be stored in 'v', not an updated one. 11697 bool IsPostfixUpdate = false; 11698 }; 11699 11700 bool OpenMPAtomicCompareCaptureChecker::checkType(ErrorInfoTy &ErrorInfo) { 11701 if (!OpenMPAtomicCompareChecker::checkType(ErrorInfo)) 11702 return false; 11703 11704 if (V && !CheckValue(V, ErrorInfo, true)) 11705 return false; 11706 11707 if (R && !CheckValue(R, ErrorInfo, true)) 11708 return false; 11709 11710 return true; 11711 } 11712 11713 bool OpenMPAtomicCompareCaptureChecker::checkForm3(IfStmt *S, 11714 ErrorInfoTy &ErrorInfo) { 11715 IsFailOnly = true; 11716 11717 auto *Then = S->getThen(); 11718 if (auto *CS = dyn_cast<CompoundStmt>(Then)) { 11719 if (CS->body_empty()) { 11720 ErrorInfo.Error = ErrorTy::NoStmt; 11721 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = CS->getBeginLoc(); 11722 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = CS->getSourceRange(); 11723 return false; 11724 } 11725 if (CS->size() > 1) { 11726 ErrorInfo.Error = ErrorTy::MoreThanOneStmt; 11727 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = CS->getBeginLoc(); 11728 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = CS->getSourceRange(); 11729 return false; 11730 } 11731 Then = CS->body_front(); 11732 } 11733 11734 auto *BO = dyn_cast<BinaryOperator>(Then); 11735 if (!BO) { 11736 ErrorInfo.Error = ErrorTy::NotAnAssignment; 11737 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = Then->getBeginLoc(); 11738 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = Then->getSourceRange(); 11739 return false; 11740 } 11741 if (BO->getOpcode() != BO_Assign) { 11742 ErrorInfo.Error = ErrorTy::NotAnAssignment; 11743 ErrorInfo.ErrorLoc = BO->getExprLoc(); 11744 ErrorInfo.NoteLoc = BO->getOperatorLoc(); 11745 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = BO->getSourceRange(); 11746 return false; 11747 } 11748 11749 X = BO->getLHS(); 11750 D = BO->getRHS(); 11751 11752 auto *Cond = dyn_cast<BinaryOperator>(S->getCond()); 11753 if (!Cond) { 11754 ErrorInfo.Error = ErrorTy::NotABinaryOp; 11755 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = S->getCond()->getExprLoc(); 11756 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = S->getCond()->getSourceRange(); 11757 return false; 11758 } 11759 if (Cond->getOpcode() != BO_EQ) { 11760 ErrorInfo.Error = ErrorTy::NotEQ; 11761 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = Cond->getExprLoc(); 11762 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = Cond->getSourceRange(); 11763 return false; 11764 } 11765 11766 if (checkIfTwoExprsAreSame(ContextRef, X, Cond->getLHS())) { 11767 E = Cond->getRHS(); 11768 } else if (checkIfTwoExprsAreSame(ContextRef, X, Cond->getRHS())) { 11769 E = Cond->getLHS(); 11770 } else { 11771 ErrorInfo.Error = ErrorTy::InvalidComparison; 11772 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = Cond->getExprLoc(); 11773 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = Cond->getSourceRange(); 11774 return false; 11775 } 11776 11777 C = Cond; 11778 11779 if (!S->getElse()) { 11780 ErrorInfo.Error = ErrorTy::NoElse; 11781 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = S->getBeginLoc(); 11782 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = S->getSourceRange(); 11783 return false; 11784 } 11785 11786 auto *Else = S->getElse(); 11787 if (auto *CS = dyn_cast<CompoundStmt>(Else)) { 11788 if (CS->body_empty()) { 11789 ErrorInfo.Error = ErrorTy::NoStmt; 11790 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = CS->getBeginLoc(); 11791 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = CS->getSourceRange(); 11792 return false; 11793 } 11794 if (CS->size() > 1) { 11795 ErrorInfo.Error = ErrorTy::MoreThanOneStmt; 11796 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = CS->getBeginLoc(); 11797 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = S->getSourceRange(); 11798 return false; 11799 } 11800 Else = CS->body_front(); 11801 } 11802 11803 auto *ElseBO = dyn_cast<BinaryOperator>(Else); 11804 if (!ElseBO) { 11805 ErrorInfo.Error = ErrorTy::NotAnAssignment; 11806 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = Else->getBeginLoc(); 11807 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = Else->getSourceRange(); 11808 return false; 11809 } 11810 if (ElseBO->getOpcode() != BO_Assign) { 11811 ErrorInfo.Error = ErrorTy::NotAnAssignment; 11812 ErrorInfo.ErrorLoc = ElseBO->getExprLoc(); 11813 ErrorInfo.NoteLoc = ElseBO->getOperatorLoc(); 11814 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = ElseBO->getSourceRange(); 11815 return false; 11816 } 11817 11818 if (!checkIfTwoExprsAreSame(ContextRef, X, ElseBO->getRHS())) { 11819 ErrorInfo.Error = ErrorTy::InvalidAssignment; 11820 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = ElseBO->getRHS()->getExprLoc(); 11821 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = 11822 ElseBO->getRHS()->getSourceRange(); 11823 return false; 11824 } 11825 11826 V = ElseBO->getLHS(); 11827 11828 return checkType(ErrorInfo); 11829 } 11830 11831 bool OpenMPAtomicCompareCaptureChecker::checkForm45(Stmt *S, 11832 ErrorInfoTy &ErrorInfo) { 11833 // We don't check here as they should be already done before call this 11834 // function. 11835 auto *CS = cast<CompoundStmt>(S); 11836 assert(CS->size() == 2 && "CompoundStmt size is not expected"); 11837 auto *S1 = cast<BinaryOperator>(CS->body_front()); 11838 auto *S2 = cast<IfStmt>(CS->body_back()); 11839 assert(S1->getOpcode() == BO_Assign && "unexpected binary operator"); 11840 11841 if (!checkIfTwoExprsAreSame(ContextRef, S1->getLHS(), S2->getCond())) { 11842 ErrorInfo.Error = ErrorTy::InvalidCondition; 11843 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = S2->getCond()->getExprLoc(); 11844 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = S1->getLHS()->getSourceRange(); 11845 return false; 11846 } 11847 11848 R = S1->getLHS(); 11849 11850 auto *Then = S2->getThen(); 11851 if (auto *ThenCS = dyn_cast<CompoundStmt>(Then)) { 11852 if (ThenCS->body_empty()) { 11853 ErrorInfo.Error = ErrorTy::NoStmt; 11854 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = ThenCS->getBeginLoc(); 11855 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = ThenCS->getSourceRange(); 11856 return false; 11857 } 11858 if (ThenCS->size() > 1) { 11859 ErrorInfo.Error = ErrorTy::MoreThanOneStmt; 11860 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = ThenCS->getBeginLoc(); 11861 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = ThenCS->getSourceRange(); 11862 return false; 11863 } 11864 Then = ThenCS->body_front(); 11865 } 11866 11867 auto *ThenBO = dyn_cast<BinaryOperator>(Then); 11868 if (!ThenBO) { 11869 ErrorInfo.Error = ErrorTy::NotAnAssignment; 11870 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = S2->getBeginLoc(); 11871 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = S2->getSourceRange(); 11872 return false; 11873 } 11874 if (ThenBO->getOpcode() != BO_Assign) { 11875 ErrorInfo.Error = ErrorTy::NotAnAssignment; 11876 ErrorInfo.ErrorLoc = ThenBO->getExprLoc(); 11877 ErrorInfo.NoteLoc = ThenBO->getOperatorLoc(); 11878 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = ThenBO->getSourceRange(); 11879 return false; 11880 } 11881 11882 X = ThenBO->getLHS(); 11883 D = ThenBO->getRHS(); 11884 11885 auto *BO = cast<BinaryOperator>(S1->getRHS()->IgnoreImpCasts()); 11886 if (BO->getOpcode() != BO_EQ) { 11887 ErrorInfo.Error = ErrorTy::NotEQ; 11888 ErrorInfo.ErrorLoc = BO->getExprLoc(); 11889 ErrorInfo.NoteLoc = BO->getOperatorLoc(); 11890 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = BO->getSourceRange(); 11891 return false; 11892 } 11893 11894 C = BO; 11895 11896 if (checkIfTwoExprsAreSame(ContextRef, X, BO->getLHS())) { 11897 E = BO->getRHS(); 11898 } else if (checkIfTwoExprsAreSame(ContextRef, X, BO->getRHS())) { 11899 E = BO->getLHS(); 11900 } else { 11901 ErrorInfo.Error = ErrorTy::InvalidComparison; 11902 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = BO->getExprLoc(); 11903 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = BO->getSourceRange(); 11904 return false; 11905 } 11906 11907 if (S2->getElse()) { 11908 IsFailOnly = true; 11909 11910 auto *Else = S2->getElse(); 11911 if (auto *ElseCS = dyn_cast<CompoundStmt>(Else)) { 11912 if (ElseCS->body_empty()) { 11913 ErrorInfo.Error = ErrorTy::NoStmt; 11914 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = ElseCS->getBeginLoc(); 11915 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = ElseCS->getSourceRange(); 11916 return false; 11917 } 11918 if (ElseCS->size() > 1) { 11919 ErrorInfo.Error = ErrorTy::MoreThanOneStmt; 11920 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = ElseCS->getBeginLoc(); 11921 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = ElseCS->getSourceRange(); 11922 return false; 11923 } 11924 Else = ElseCS->body_front(); 11925 } 11926 11927 auto *ElseBO = dyn_cast<BinaryOperator>(Else); 11928 if (!ElseBO) { 11929 ErrorInfo.Error = ErrorTy::NotAnAssignment; 11930 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = Else->getBeginLoc(); 11931 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = Else->getSourceRange(); 11932 return false; 11933 } 11934 if (ElseBO->getOpcode() != BO_Assign) { 11935 ErrorInfo.Error = ErrorTy::NotAnAssignment; 11936 ErrorInfo.ErrorLoc = ElseBO->getExprLoc(); 11937 ErrorInfo.NoteLoc = ElseBO->getOperatorLoc(); 11938 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = ElseBO->getSourceRange(); 11939 return false; 11940 } 11941 if (!checkIfTwoExprsAreSame(ContextRef, X, ElseBO->getRHS())) { 11942 ErrorInfo.Error = ErrorTy::InvalidAssignment; 11943 ErrorInfo.ErrorLoc = ElseBO->getRHS()->getExprLoc(); 11944 ErrorInfo.NoteLoc = X->getExprLoc(); 11945 ErrorInfo.ErrorRange = ElseBO->getRHS()->getSourceRange(); 11946 ErrorInfo.NoteRange = X->getSourceRange(); 11947 return false; 11948 } 11949 11950 V = ElseBO->getLHS(); 11951 } 11952 11953 return checkType(ErrorInfo); 11954 } 11955 11956 bool OpenMPAtomicCompareCaptureChecker::checkStmt(Stmt *S, 11957 ErrorInfoTy &ErrorInfo) { 11958 // if(x == e) { x = d; } else { v = x; } 11959 if (auto *IS = dyn_cast<IfStmt>(S)) 11960 return checkForm3(IS, ErrorInfo); 11961 11962 auto *CS = dyn_cast<CompoundStmt>(S); 11963 if (!CS) { 11964 ErrorInfo.Error = ErrorTy::NotCompoundStmt; 11965 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = S->getBeginLoc(); 11966 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = S->getSourceRange(); 11967 return false; 11968 } 11969 if (CS->body_empty()) { 11970 ErrorInfo.Error = ErrorTy::NoStmt; 11971 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = CS->getBeginLoc(); 11972 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = CS->getSourceRange(); 11973 return false; 11974 } 11975 11976 // { if(x == e) { x = d; } else { v = x; } } 11977 if (CS->size() == 1) { 11978 auto *IS = dyn_cast<IfStmt>(CS->body_front()); 11979 if (!IS) { 11980 ErrorInfo.Error = ErrorTy::NotIfStmt; 11981 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = CS->body_front()->getBeginLoc(); 11982 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = 11983 CS->body_front()->getSourceRange(); 11984 return false; 11985 } 11986 11987 return checkForm3(IS, ErrorInfo); 11988 } else if (CS->size() == 2) { 11989 auto *S1 = CS->body_front(); 11990 auto *S2 = CS->body_back(); 11991 11992 Stmt *UpdateStmt = nullptr; 11993 Stmt *CondUpdateStmt = nullptr; 11994 11995 if (auto *BO = dyn_cast<BinaryOperator>(S1)) { 11996 // { v = x; cond-update-stmt } or form 45. 11997 UpdateStmt = S1; 11998 CondUpdateStmt = S2; 11999 // Check if form 45. 12000 if (isa<BinaryOperator>(BO->getRHS()->IgnoreImpCasts()) && 12001 isa<IfStmt>(S2)) 12002 return checkForm45(CS, ErrorInfo); 12003 // It cannot be set before we the check for form45. 12004 IsPostfixUpdate = true; 12005 } else { 12006 // { cond-update-stmt v = x; } 12007 UpdateStmt = S2; 12008 CondUpdateStmt = S1; 12009 } 12010 12011 auto CheckCondUpdateStmt = [this, &ErrorInfo](Stmt *CUS) { 12012 auto *IS = dyn_cast<IfStmt>(CUS); 12013 if (!IS) { 12014 ErrorInfo.Error = ErrorTy::NotIfStmt; 12015 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = CUS->getBeginLoc(); 12016 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = CUS->getSourceRange(); 12017 return false; 12018 } 12019 12020 if (!checkCondUpdateStmt(IS, ErrorInfo)) 12021 return false; 12022 12023 return true; 12024 }; 12025 12026 // CheckUpdateStmt has to be called *after* CheckCondUpdateStmt. 12027 auto CheckUpdateStmt = [this, &ErrorInfo](Stmt *US) { 12028 auto *BO = dyn_cast<BinaryOperator>(US); 12029 if (!BO) { 12030 ErrorInfo.Error = ErrorTy::NotAnAssignment; 12031 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = US->getBeginLoc(); 12032 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = US->getSourceRange(); 12033 return false; 12034 } 12035 if (BO->getOpcode() != BO_Assign) { 12036 ErrorInfo.Error = ErrorTy::NotAnAssignment; 12037 ErrorInfo.ErrorLoc = BO->getExprLoc(); 12038 ErrorInfo.NoteLoc = BO->getOperatorLoc(); 12039 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = BO->getSourceRange(); 12040 return false; 12041 } 12042 if (!checkIfTwoExprsAreSame(ContextRef, this->X, BO->getRHS())) { 12043 ErrorInfo.Error = ErrorTy::InvalidAssignment; 12044 ErrorInfo.ErrorLoc = BO->getRHS()->getExprLoc(); 12045 ErrorInfo.NoteLoc = this->X->getExprLoc(); 12046 ErrorInfo.ErrorRange = BO->getRHS()->getSourceRange(); 12047 ErrorInfo.NoteRange = this->X->getSourceRange(); 12048 return false; 12049 } 12050 12051 this->V = BO->getLHS(); 12052 12053 return true; 12054 }; 12055 12056 if (!CheckCondUpdateStmt(CondUpdateStmt)) 12057 return false; 12058 if (!CheckUpdateStmt(UpdateStmt)) 12059 return false; 12060 } else { 12061 ErrorInfo.Error = ErrorTy::MoreThanTwoStmts; 12062 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = CS->getBeginLoc(); 12063 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = CS->getSourceRange(); 12064 return false; 12065 } 12066 12067 return checkType(ErrorInfo); 12068 } 12069 } // namespace 12070 12071 StmtResult Sema::ActOnOpenMPAtomicDirective(ArrayRef<OMPClause *> Clauses, 12072 Stmt *AStmt, 12073 SourceLocation StartLoc, 12074 SourceLocation EndLoc) { 12075 // Register location of the first atomic directive. 12076 DSAStack->addAtomicDirectiveLoc(StartLoc); 12077 if (!AStmt) 12078 return StmtError(); 12079 12080 // 1.2.2 OpenMP Language Terminology 12081 // Structured block - An executable statement with a single entry at the 12082 // top and a single exit at the bottom. 12083 // The point of exit cannot be a branch out of the structured block. 12084 // longjmp() and throw() must not violate the entry/exit criteria. 12085 OpenMPClauseKind AtomicKind = OMPC_unknown; 12086 SourceLocation AtomicKindLoc; 12087 OpenMPClauseKind MemOrderKind = OMPC_unknown; 12088 SourceLocation MemOrderLoc; 12089 bool MutexClauseEncountered = false; 12090 llvm::SmallSet<OpenMPClauseKind, 2> EncounteredAtomicKinds; 12091 for (const OMPClause *C : Clauses) { 12092 switch (C->getClauseKind()) { 12093 case OMPC_read: 12094 case OMPC_write: 12095 case OMPC_update: 12096 MutexClauseEncountered = true; 12097 LLVM_FALLTHROUGH; 12098 case OMPC_capture: 12099 case OMPC_compare: { 12100 if (AtomicKind != OMPC_unknown && MutexClauseEncountered) { 12101 Diag(C->getBeginLoc(), diag::err_omp_atomic_several_clauses) 12102 << SourceRange(C->getBeginLoc(), C->getEndLoc()); 12103 Diag(AtomicKindLoc, diag::note_omp_previous_mem_order_clause) 12104 << getOpenMPClauseName(AtomicKind); 12105 } else { 12106 AtomicKind = C->getClauseKind(); 12107 AtomicKindLoc = C->getBeginLoc(); 12108 if (!EncounteredAtomicKinds.insert(C->getClauseKind()).second) { 12109 Diag(C->getBeginLoc(), diag::err_omp_atomic_several_clauses) 12110 << SourceRange(C->getBeginLoc(), C->getEndLoc()); 12111 Diag(AtomicKindLoc, diag::note_omp_previous_mem_order_clause) 12112 << getOpenMPClauseName(AtomicKind); 12113 } 12114 } 12115 break; 12116 } 12117 case OMPC_seq_cst: 12118 case OMPC_acq_rel: 12119 case OMPC_acquire: 12120 case OMPC_release: 12121 case OMPC_relaxed: { 12122 if (MemOrderKind != OMPC_unknown) { 12123 Diag(C->getBeginLoc(), diag::err_omp_several_mem_order_clauses) 12124 << getOpenMPDirectiveName(OMPD_atomic) << 0 12125 << SourceRange(C->getBeginLoc(), C->getEndLoc()); 12126 Diag(MemOrderLoc, diag::note_omp_previous_mem_order_clause) 12127 << getOpenMPClauseName(MemOrderKind); 12128 } else { 12129 MemOrderKind = C->getClauseKind(); 12130 MemOrderLoc = C->getBeginLoc(); 12131 } 12132 break; 12133 } 12134 // The following clauses are allowed, but we don't need to do anything here. 12135 case OMPC_hint: 12136 break; 12137 default: 12138 llvm_unreachable("unknown clause is encountered"); 12139 } 12140 } 12141 bool IsCompareCapture = false; 12142 if (EncounteredAtomicKinds.contains(OMPC_compare) && 12143 EncounteredAtomicKinds.contains(OMPC_capture)) { 12144 IsCompareCapture = true; 12145 AtomicKind = OMPC_compare; 12146 } 12147 // OpenMP 5.0, 2.17.7 atomic Construct, Restrictions 12148 // If atomic-clause is read then memory-order-clause must not be acq_rel or 12149 // release. 12150 // If atomic-clause is write then memory-order-clause must not be acq_rel or 12151 // acquire. 12152 // If atomic-clause is update or not present then memory-order-clause must not 12153 // be acq_rel or acquire. 12154 if ((AtomicKind == OMPC_read && 12155 (MemOrderKind == OMPC_acq_rel || MemOrderKind == OMPC_release)) || 12156 ((AtomicKind == OMPC_write || AtomicKind == OMPC_update || 12157 AtomicKind == OMPC_unknown) && 12158 (MemOrderKind == OMPC_acq_rel || MemOrderKind == OMPC_acquire))) { 12159 SourceLocation Loc = AtomicKindLoc; 12160 if (AtomicKind == OMPC_unknown) 12161 Loc = StartLoc; 12162 Diag(Loc, diag::err_omp_atomic_incompatible_mem_order_clause) 12163 << getOpenMPClauseName(AtomicKind) 12164 << (AtomicKind == OMPC_unknown ? 1 : 0) 12165 << getOpenMPClauseName(MemOrderKind); 12166 Diag(MemOrderLoc, diag::note_omp_previous_mem_order_clause) 12167 << getOpenMPClauseName(MemOrderKind); 12168 } 12169 12170 Stmt *Body = AStmt; 12171 if (auto *EWC = dyn_cast<ExprWithCleanups>(Body)) 12172 Body = EWC->getSubExpr(); 12173 12174 Expr *X = nullptr; 12175 Expr *V = nullptr; 12176 Expr *E = nullptr; 12177 Expr *UE = nullptr; 12178 Expr *D = nullptr; 12179 Expr *CE = nullptr; 12180 Expr *R = nullptr; 12181 bool IsXLHSInRHSPart = false; 12182 bool IsPostfixUpdate = false; 12183 bool IsFailOnly = false; 12184 // OpenMP [2.12.6, atomic Construct] 12185 // In the next expressions: 12186 // * x and v (as applicable) are both l-value expressions with scalar type. 12187 // * During the execution of an atomic region, multiple syntactic 12188 // occurrences of x must designate the same storage location. 12189 // * Neither of v and expr (as applicable) may access the storage location 12190 // designated by x. 12191 // * Neither of x and expr (as applicable) may access the storage location 12192 // designated by v. 12193 // * expr is an expression with scalar type. 12194 // * binop is one of +, *, -, /, &, ^, |, <<, or >>. 12195 // * binop, binop=, ++, and -- are not overloaded operators. 12196 // * The expression x binop expr must be numerically equivalent to x binop 12197 // (expr). This requirement is satisfied if the operators in expr have 12198 // precedence greater than binop, or by using parentheses around expr or 12199 // subexpressions of expr. 12200 // * The expression expr binop x must be numerically equivalent to (expr) 12201 // binop x. This requirement is satisfied if the operators in expr have 12202 // precedence equal to or greater than binop, or by using parentheses around 12203 // expr or subexpressions of expr. 12204 // * For forms that allow multiple occurrences of x, the number of times 12205 // that x is evaluated is unspecified. 12206 if (AtomicKind == OMPC_read) { 12207 enum { 12208 NotAnExpression, 12209 NotAnAssignmentOp, 12210 NotAScalarType, 12211 NotAnLValue, 12212 NoError 12213 } ErrorFound = NoError; 12214 SourceLocation ErrorLoc, NoteLoc; 12215 SourceRange ErrorRange, NoteRange; 12216 // If clause is read: 12217 // v = x; 12218 if (const auto *AtomicBody = dyn_cast<Expr>(Body)) { 12219 const auto *AtomicBinOp = 12220 dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts()); 12221 if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) { 12222 X = AtomicBinOp->getRHS()->IgnoreParenImpCasts(); 12223 V = AtomicBinOp->getLHS()->IgnoreParenImpCasts(); 12224 if ((X->isInstantiationDependent() || X->getType()->isScalarType()) && 12225 (V->isInstantiationDependent() || V->getType()->isScalarType())) { 12226 if (!X->isLValue() || !V->isLValue()) { 12227 const Expr *NotLValueExpr = X->isLValue() ? V : X; 12228 ErrorFound = NotAnLValue; 12229 ErrorLoc = AtomicBinOp->getExprLoc(); 12230 ErrorRange = AtomicBinOp->getSourceRange(); 12231 NoteLoc = NotLValueExpr->getExprLoc(); 12232 NoteRange = NotLValueExpr->getSourceRange(); 12233 } 12234 } else if (!X->isInstantiationDependent() || 12235 !V->isInstantiationDependent()) { 12236 const Expr *NotScalarExpr = 12237 (X->isInstantiationDependent() || X->getType()->isScalarType()) 12238 ? V 12239 : X; 12240 ErrorFound = NotAScalarType; 12241 ErrorLoc = AtomicBinOp->getExprLoc(); 12242 ErrorRange = AtomicBinOp->getSourceRange(); 12243 NoteLoc = NotScalarExpr->getExprLoc(); 12244 NoteRange = NotScalarExpr->getSourceRange(); 12245 } 12246 } else if (!AtomicBody->isInstantiationDependent()) { 12247 ErrorFound = NotAnAssignmentOp; 12248 ErrorLoc = AtomicBody->getExprLoc(); 12249 ErrorRange = AtomicBody->getSourceRange(); 12250 NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc() 12251 : AtomicBody->getExprLoc(); 12252 NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange() 12253 : AtomicBody->getSourceRange(); 12254 } 12255 } else { 12256 ErrorFound = NotAnExpression; 12257 NoteLoc = ErrorLoc = Body->getBeginLoc(); 12258 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc); 12259 } 12260 if (ErrorFound != NoError) { 12261 Diag(ErrorLoc, diag::err_omp_atomic_read_not_expression_statement) 12262 << ErrorRange; 12263 Diag(NoteLoc, diag::note_omp_atomic_read_write) 12264 << ErrorFound << NoteRange; 12265 return StmtError(); 12266 } 12267 if (CurContext->isDependentContext()) 12268 V = X = nullptr; 12269 } else if (AtomicKind == OMPC_write) { 12270 enum { 12271 NotAnExpression, 12272 NotAnAssignmentOp, 12273 NotAScalarType, 12274 NotAnLValue, 12275 NoError 12276 } ErrorFound = NoError; 12277 SourceLocation ErrorLoc, NoteLoc; 12278 SourceRange ErrorRange, NoteRange; 12279 // If clause is write: 12280 // x = expr; 12281 if (const auto *AtomicBody = dyn_cast<Expr>(Body)) { 12282 const auto *AtomicBinOp = 12283 dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts()); 12284 if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) { 12285 X = AtomicBinOp->getLHS(); 12286 E = AtomicBinOp->getRHS(); 12287 if ((X->isInstantiationDependent() || X->getType()->isScalarType()) && 12288 (E->isInstantiationDependent() || E->getType()->isScalarType())) { 12289 if (!X->isLValue()) { 12290 ErrorFound = NotAnLValue; 12291 ErrorLoc = AtomicBinOp->getExprLoc(); 12292 ErrorRange = AtomicBinOp->getSourceRange(); 12293 NoteLoc = X->getExprLoc(); 12294 NoteRange = X->getSourceRange(); 12295 } 12296 } else if (!X->isInstantiationDependent() || 12297 !E->isInstantiationDependent()) { 12298 const Expr *NotScalarExpr = 12299 (X->isInstantiationDependent() || X->getType()->isScalarType()) 12300 ? E 12301 : X; 12302 ErrorFound = NotAScalarType; 12303 ErrorLoc = AtomicBinOp->getExprLoc(); 12304 ErrorRange = AtomicBinOp->getSourceRange(); 12305 NoteLoc = NotScalarExpr->getExprLoc(); 12306 NoteRange = NotScalarExpr->getSourceRange(); 12307 } 12308 } else if (!AtomicBody->isInstantiationDependent()) { 12309 ErrorFound = NotAnAssignmentOp; 12310 ErrorLoc = AtomicBody->getExprLoc(); 12311 ErrorRange = AtomicBody->getSourceRange(); 12312 NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc() 12313 : AtomicBody->getExprLoc(); 12314 NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange() 12315 : AtomicBody->getSourceRange(); 12316 } 12317 } else { 12318 ErrorFound = NotAnExpression; 12319 NoteLoc = ErrorLoc = Body->getBeginLoc(); 12320 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc); 12321 } 12322 if (ErrorFound != NoError) { 12323 Diag(ErrorLoc, diag::err_omp_atomic_write_not_expression_statement) 12324 << ErrorRange; 12325 Diag(NoteLoc, diag::note_omp_atomic_read_write) 12326 << ErrorFound << NoteRange; 12327 return StmtError(); 12328 } 12329 if (CurContext->isDependentContext()) 12330 E = X = nullptr; 12331 } else if (AtomicKind == OMPC_update || AtomicKind == OMPC_unknown) { 12332 // If clause is update: 12333 // x++; 12334 // x--; 12335 // ++x; 12336 // --x; 12337 // x binop= expr; 12338 // x = x binop expr; 12339 // x = expr binop x; 12340 OpenMPAtomicUpdateChecker Checker(*this); 12341 if (Checker.checkStatement( 12342 Body, 12343 (AtomicKind == OMPC_update) 12344 ? diag::err_omp_atomic_update_not_expression_statement 12345 : diag::err_omp_atomic_not_expression_statement, 12346 diag::note_omp_atomic_update)) 12347 return StmtError(); 12348 if (!CurContext->isDependentContext()) { 12349 E = Checker.getExpr(); 12350 X = Checker.getX(); 12351 UE = Checker.getUpdateExpr(); 12352 IsXLHSInRHSPart = Checker.isXLHSInRHSPart(); 12353 } 12354 } else if (AtomicKind == OMPC_capture) { 12355 enum { 12356 NotAnAssignmentOp, 12357 NotACompoundStatement, 12358 NotTwoSubstatements, 12359 NotASpecificExpression, 12360 NoError 12361 } ErrorFound = NoError; 12362 SourceLocation ErrorLoc, NoteLoc; 12363 SourceRange ErrorRange, NoteRange; 12364 if (const auto *AtomicBody = dyn_cast<Expr>(Body)) { 12365 // If clause is a capture: 12366 // v = x++; 12367 // v = x--; 12368 // v = ++x; 12369 // v = --x; 12370 // v = x binop= expr; 12371 // v = x = x binop expr; 12372 // v = x = expr binop x; 12373 const auto *AtomicBinOp = 12374 dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts()); 12375 if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) { 12376 V = AtomicBinOp->getLHS(); 12377 Body = AtomicBinOp->getRHS()->IgnoreParenImpCasts(); 12378 OpenMPAtomicUpdateChecker Checker(*this); 12379 if (Checker.checkStatement( 12380 Body, diag::err_omp_atomic_capture_not_expression_statement, 12381 diag::note_omp_atomic_update)) 12382 return StmtError(); 12383 E = Checker.getExpr(); 12384 X = Checker.getX(); 12385 UE = Checker.getUpdateExpr(); 12386 IsXLHSInRHSPart = Checker.isXLHSInRHSPart(); 12387 IsPostfixUpdate = Checker.isPostfixUpdate(); 12388 } else if (!AtomicBody->isInstantiationDependent()) { 12389 ErrorLoc = AtomicBody->getExprLoc(); 12390 ErrorRange = AtomicBody->getSourceRange(); 12391 NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc() 12392 : AtomicBody->getExprLoc(); 12393 NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange() 12394 : AtomicBody->getSourceRange(); 12395 ErrorFound = NotAnAssignmentOp; 12396 } 12397 if (ErrorFound != NoError) { 12398 Diag(ErrorLoc, diag::err_omp_atomic_capture_not_expression_statement) 12399 << ErrorRange; 12400 Diag(NoteLoc, diag::note_omp_atomic_capture) << ErrorFound << NoteRange; 12401 return StmtError(); 12402 } 12403 if (CurContext->isDependentContext()) 12404 UE = V = E = X = nullptr; 12405 } else { 12406 // If clause is a capture: 12407 // { v = x; x = expr; } 12408 // { v = x; x++; } 12409 // { v = x; x--; } 12410 // { v = x; ++x; } 12411 // { v = x; --x; } 12412 // { v = x; x binop= expr; } 12413 // { v = x; x = x binop expr; } 12414 // { v = x; x = expr binop x; } 12415 // { x++; v = x; } 12416 // { x--; v = x; } 12417 // { ++x; v = x; } 12418 // { --x; v = x; } 12419 // { x binop= expr; v = x; } 12420 // { x = x binop expr; v = x; } 12421 // { x = expr binop x; v = x; } 12422 if (auto *CS = dyn_cast<CompoundStmt>(Body)) { 12423 // Check that this is { expr1; expr2; } 12424 if (CS->size() == 2) { 12425 Stmt *First = CS->body_front(); 12426 Stmt *Second = CS->body_back(); 12427 if (auto *EWC = dyn_cast<ExprWithCleanups>(First)) 12428 First = EWC->getSubExpr()->IgnoreParenImpCasts(); 12429 if (auto *EWC = dyn_cast<ExprWithCleanups>(Second)) 12430 Second = EWC->getSubExpr()->IgnoreParenImpCasts(); 12431 // Need to find what subexpression is 'v' and what is 'x'. 12432 OpenMPAtomicUpdateChecker Checker(*this); 12433 bool IsUpdateExprFound = !Checker.checkStatement(Second); 12434 BinaryOperator *BinOp = nullptr; 12435 if (IsUpdateExprFound) { 12436 BinOp = dyn_cast<BinaryOperator>(First); 12437 IsUpdateExprFound = BinOp && BinOp->getOpcode() == BO_Assign; 12438 } 12439 if (IsUpdateExprFound && !CurContext->isDependentContext()) { 12440 // { v = x; x++; } 12441 // { v = x; x--; } 12442 // { v = x; ++x; } 12443 // { v = x; --x; } 12444 // { v = x; x binop= expr; } 12445 // { v = x; x = x binop expr; } 12446 // { v = x; x = expr binop x; } 12447 // Check that the first expression has form v = x. 12448 Expr *PossibleX = BinOp->getRHS()->IgnoreParenImpCasts(); 12449 llvm::FoldingSetNodeID XId, PossibleXId; 12450 Checker.getX()->Profile(XId, Context, /*Canonical=*/true); 12451 PossibleX->Profile(PossibleXId, Context, /*Canonical=*/true); 12452 IsUpdateExprFound = XId == PossibleXId; 12453 if (IsUpdateExprFound) { 12454 V = BinOp->getLHS(); 12455 X = Checker.getX(); 12456 E = Checker.getExpr(); 12457 UE = Checker.getUpdateExpr(); 12458 IsXLHSInRHSPart = Checker.isXLHSInRHSPart(); 12459 IsPostfixUpdate = true; 12460 } 12461 } 12462 if (!IsUpdateExprFound) { 12463 IsUpdateExprFound = !Checker.checkStatement(First); 12464 BinOp = nullptr; 12465 if (IsUpdateExprFound) { 12466 BinOp = dyn_cast<BinaryOperator>(Second); 12467 IsUpdateExprFound = BinOp && BinOp->getOpcode() == BO_Assign; 12468 } 12469 if (IsUpdateExprFound && !CurContext->isDependentContext()) { 12470 // { x++; v = x; } 12471 // { x--; v = x; } 12472 // { ++x; v = x; } 12473 // { --x; v = x; } 12474 // { x binop= expr; v = x; } 12475 // { x = x binop expr; v = x; } 12476 // { x = expr binop x; v = x; } 12477 // Check that the second expression has form v = x. 12478 Expr *PossibleX = BinOp->getRHS()->IgnoreParenImpCasts(); 12479 llvm::FoldingSetNodeID XId, PossibleXId; 12480 Checker.getX()->Profile(XId, Context, /*Canonical=*/true); 12481 PossibleX->Profile(PossibleXId, Context, /*Canonical=*/true); 12482 IsUpdateExprFound = XId == PossibleXId; 12483 if (IsUpdateExprFound) { 12484 V = BinOp->getLHS(); 12485 X = Checker.getX(); 12486 E = Checker.getExpr(); 12487 UE = Checker.getUpdateExpr(); 12488 IsXLHSInRHSPart = Checker.isXLHSInRHSPart(); 12489 IsPostfixUpdate = false; 12490 } 12491 } 12492 } 12493 if (!IsUpdateExprFound) { 12494 // { v = x; x = expr; } 12495 auto *FirstExpr = dyn_cast<Expr>(First); 12496 auto *SecondExpr = dyn_cast<Expr>(Second); 12497 if (!FirstExpr || !SecondExpr || 12498 !(FirstExpr->isInstantiationDependent() || 12499 SecondExpr->isInstantiationDependent())) { 12500 auto *FirstBinOp = dyn_cast<BinaryOperator>(First); 12501 if (!FirstBinOp || FirstBinOp->getOpcode() != BO_Assign) { 12502 ErrorFound = NotAnAssignmentOp; 12503 NoteLoc = ErrorLoc = FirstBinOp ? FirstBinOp->getOperatorLoc() 12504 : First->getBeginLoc(); 12505 NoteRange = ErrorRange = FirstBinOp 12506 ? FirstBinOp->getSourceRange() 12507 : SourceRange(ErrorLoc, ErrorLoc); 12508 } else { 12509 auto *SecondBinOp = dyn_cast<BinaryOperator>(Second); 12510 if (!SecondBinOp || SecondBinOp->getOpcode() != BO_Assign) { 12511 ErrorFound = NotAnAssignmentOp; 12512 NoteLoc = ErrorLoc = SecondBinOp 12513 ? SecondBinOp->getOperatorLoc() 12514 : Second->getBeginLoc(); 12515 NoteRange = ErrorRange = 12516 SecondBinOp ? SecondBinOp->getSourceRange() 12517 : SourceRange(ErrorLoc, ErrorLoc); 12518 } else { 12519 Expr *PossibleXRHSInFirst = 12520 FirstBinOp->getRHS()->IgnoreParenImpCasts(); 12521 Expr *PossibleXLHSInSecond = 12522 SecondBinOp->getLHS()->IgnoreParenImpCasts(); 12523 llvm::FoldingSetNodeID X1Id, X2Id; 12524 PossibleXRHSInFirst->Profile(X1Id, Context, 12525 /*Canonical=*/true); 12526 PossibleXLHSInSecond->Profile(X2Id, Context, 12527 /*Canonical=*/true); 12528 IsUpdateExprFound = X1Id == X2Id; 12529 if (IsUpdateExprFound) { 12530 V = FirstBinOp->getLHS(); 12531 X = SecondBinOp->getLHS(); 12532 E = SecondBinOp->getRHS(); 12533 UE = nullptr; 12534 IsXLHSInRHSPart = false; 12535 IsPostfixUpdate = true; 12536 } else { 12537 ErrorFound = NotASpecificExpression; 12538 ErrorLoc = FirstBinOp->getExprLoc(); 12539 ErrorRange = FirstBinOp->getSourceRange(); 12540 NoteLoc = SecondBinOp->getLHS()->getExprLoc(); 12541 NoteRange = SecondBinOp->getRHS()->getSourceRange(); 12542 } 12543 } 12544 } 12545 } 12546 } 12547 } else { 12548 NoteLoc = ErrorLoc = Body->getBeginLoc(); 12549 NoteRange = ErrorRange = 12550 SourceRange(Body->getBeginLoc(), Body->getBeginLoc()); 12551 ErrorFound = NotTwoSubstatements; 12552 } 12553 } else { 12554 NoteLoc = ErrorLoc = Body->getBeginLoc(); 12555 NoteRange = ErrorRange = 12556 SourceRange(Body->getBeginLoc(), Body->getBeginLoc()); 12557 ErrorFound = NotACompoundStatement; 12558 } 12559 } 12560 if (ErrorFound != NoError) { 12561 Diag(ErrorLoc, diag::err_omp_atomic_capture_not_compound_statement) 12562 << ErrorRange; 12563 Diag(NoteLoc, diag::note_omp_atomic_capture) << ErrorFound << NoteRange; 12564 return StmtError(); 12565 } 12566 if (CurContext->isDependentContext()) 12567 UE = V = E = X = nullptr; 12568 } else if (AtomicKind == OMPC_compare) { 12569 if (IsCompareCapture) { 12570 OpenMPAtomicCompareCaptureChecker::ErrorInfoTy ErrorInfo; 12571 OpenMPAtomicCompareCaptureChecker Checker(*this); 12572 if (!Checker.checkStmt(Body, ErrorInfo)) { 12573 Diag(ErrorInfo.ErrorLoc, diag::err_omp_atomic_compare_capture) 12574 << ErrorInfo.ErrorRange; 12575 Diag(ErrorInfo.NoteLoc, diag::note_omp_atomic_compare) 12576 << ErrorInfo.Error << ErrorInfo.NoteRange; 12577 return StmtError(); 12578 } 12579 X = Checker.getX(); 12580 E = Checker.getE(); 12581 D = Checker.getD(); 12582 CE = Checker.getCond(); 12583 V = Checker.getV(); 12584 R = Checker.getR(); 12585 // We reuse IsXLHSInRHSPart to tell if it is in the form 'x ordop expr'. 12586 IsXLHSInRHSPart = Checker.isXBinopExpr(); 12587 IsFailOnly = Checker.isFailOnly(); 12588 IsPostfixUpdate = Checker.isPostfixUpdate(); 12589 } else { 12590 OpenMPAtomicCompareChecker::ErrorInfoTy ErrorInfo; 12591 OpenMPAtomicCompareChecker Checker(*this); 12592 if (!Checker.checkStmt(Body, ErrorInfo)) { 12593 Diag(ErrorInfo.ErrorLoc, diag::err_omp_atomic_compare) 12594 << ErrorInfo.ErrorRange; 12595 Diag(ErrorInfo.NoteLoc, diag::note_omp_atomic_compare) 12596 << ErrorInfo.Error << ErrorInfo.NoteRange; 12597 return StmtError(); 12598 } 12599 X = Checker.getX(); 12600 E = Checker.getE(); 12601 D = Checker.getD(); 12602 CE = Checker.getCond(); 12603 // We reuse IsXLHSInRHSPart to tell if it is in the form 'x ordop expr'. 12604 IsXLHSInRHSPart = Checker.isXBinopExpr(); 12605 } 12606 } 12607 12608 setFunctionHasBranchProtectedScope(); 12609 12610 return OMPAtomicDirective::Create( 12611 Context, StartLoc, EndLoc, Clauses, AStmt, 12612 {X, V, R, E, UE, D, CE, IsXLHSInRHSPart, IsPostfixUpdate, IsFailOnly}); 12613 } 12614 12615 StmtResult Sema::ActOnOpenMPTargetDirective(ArrayRef<OMPClause *> Clauses, 12616 Stmt *AStmt, 12617 SourceLocation StartLoc, 12618 SourceLocation EndLoc) { 12619 if (!AStmt) 12620 return StmtError(); 12621 12622 auto *CS = cast<CapturedStmt>(AStmt); 12623 // 1.2.2 OpenMP Language Terminology 12624 // Structured block - An executable statement with a single entry at the 12625 // top and a single exit at the bottom. 12626 // The point of exit cannot be a branch out of the structured block. 12627 // longjmp() and throw() must not violate the entry/exit criteria. 12628 CS->getCapturedDecl()->setNothrow(); 12629 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target); 12630 ThisCaptureLevel > 1; --ThisCaptureLevel) { 12631 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 12632 // 1.2.2 OpenMP Language Terminology 12633 // Structured block - An executable statement with a single entry at the 12634 // top and a single exit at the bottom. 12635 // The point of exit cannot be a branch out of the structured block. 12636 // longjmp() and throw() must not violate the entry/exit criteria. 12637 CS->getCapturedDecl()->setNothrow(); 12638 } 12639 12640 // OpenMP [2.16, Nesting of Regions] 12641 // If specified, a teams construct must be contained within a target 12642 // construct. That target construct must contain no statements or directives 12643 // outside of the teams construct. 12644 if (DSAStack->hasInnerTeamsRegion()) { 12645 const Stmt *S = CS->IgnoreContainers(/*IgnoreCaptured=*/true); 12646 bool OMPTeamsFound = true; 12647 if (const auto *CS = dyn_cast<CompoundStmt>(S)) { 12648 auto I = CS->body_begin(); 12649 while (I != CS->body_end()) { 12650 const auto *OED = dyn_cast<OMPExecutableDirective>(*I); 12651 if (!OED || !isOpenMPTeamsDirective(OED->getDirectiveKind()) || 12652 OMPTeamsFound) { 12653 12654 OMPTeamsFound = false; 12655 break; 12656 } 12657 ++I; 12658 } 12659 assert(I != CS->body_end() && "Not found statement"); 12660 S = *I; 12661 } else { 12662 const auto *OED = dyn_cast<OMPExecutableDirective>(S); 12663 OMPTeamsFound = OED && isOpenMPTeamsDirective(OED->getDirectiveKind()); 12664 } 12665 if (!OMPTeamsFound) { 12666 Diag(StartLoc, diag::err_omp_target_contains_not_only_teams); 12667 Diag(DSAStack->getInnerTeamsRegionLoc(), 12668 diag::note_omp_nested_teams_construct_here); 12669 Diag(S->getBeginLoc(), diag::note_omp_nested_statement_here) 12670 << isa<OMPExecutableDirective>(S); 12671 return StmtError(); 12672 } 12673 } 12674 12675 setFunctionHasBranchProtectedScope(); 12676 12677 return OMPTargetDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt); 12678 } 12679 12680 StmtResult 12681 Sema::ActOnOpenMPTargetParallelDirective(ArrayRef<OMPClause *> Clauses, 12682 Stmt *AStmt, SourceLocation StartLoc, 12683 SourceLocation EndLoc) { 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); 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 setFunctionHasBranchProtectedScope(); 12706 12707 return OMPTargetParallelDirective::Create( 12708 Context, StartLoc, EndLoc, Clauses, AStmt, 12709 DSAStack->getTaskgroupReductionRef(), DSAStack->isCancelRegion()); 12710 } 12711 12712 StmtResult Sema::ActOnOpenMPTargetParallelForDirective( 12713 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 12714 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 12715 if (!AStmt) 12716 return StmtError(); 12717 12718 auto *CS = cast<CapturedStmt>(AStmt); 12719 // 1.2.2 OpenMP Language Terminology 12720 // Structured block - An executable statement with a single entry at the 12721 // top and a single exit at the bottom. 12722 // The point of exit cannot be a branch out of the structured block. 12723 // longjmp() and throw() must not violate the entry/exit criteria. 12724 CS->getCapturedDecl()->setNothrow(); 12725 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel_for); 12726 ThisCaptureLevel > 1; --ThisCaptureLevel) { 12727 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 12728 // 1.2.2 OpenMP Language Terminology 12729 // Structured block - An executable statement with a single entry at the 12730 // top and a single exit at the bottom. 12731 // The point of exit cannot be a branch out of the structured block. 12732 // longjmp() and throw() must not violate the entry/exit criteria. 12733 CS->getCapturedDecl()->setNothrow(); 12734 } 12735 12736 OMPLoopBasedDirective::HelperExprs B; 12737 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 12738 // define the nested loops number. 12739 unsigned NestedLoopCount = 12740 checkOpenMPLoop(OMPD_target_parallel_for, getCollapseNumberExpr(Clauses), 12741 getOrderedNumberExpr(Clauses), CS, *this, *DSAStack, 12742 VarsWithImplicitDSA, B); 12743 if (NestedLoopCount == 0) 12744 return StmtError(); 12745 12746 assert((CurContext->isDependentContext() || B.builtAll()) && 12747 "omp target parallel for loop exprs were not built"); 12748 12749 if (!CurContext->isDependentContext()) { 12750 // Finalize the clauses that need pre-built expressions for CodeGen. 12751 for (OMPClause *C : Clauses) { 12752 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 12753 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 12754 B.NumIterations, *this, CurScope, 12755 DSAStack)) 12756 return StmtError(); 12757 } 12758 } 12759 12760 setFunctionHasBranchProtectedScope(); 12761 return OMPTargetParallelForDirective::Create( 12762 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B, 12763 DSAStack->getTaskgroupReductionRef(), DSAStack->isCancelRegion()); 12764 } 12765 12766 /// Check for existence of a map clause in the list of clauses. 12767 static bool hasClauses(ArrayRef<OMPClause *> Clauses, 12768 const OpenMPClauseKind K) { 12769 return llvm::any_of( 12770 Clauses, [K](const OMPClause *C) { return C->getClauseKind() == K; }); 12771 } 12772 12773 template <typename... Params> 12774 static bool hasClauses(ArrayRef<OMPClause *> Clauses, const OpenMPClauseKind K, 12775 const Params... ClauseTypes) { 12776 return hasClauses(Clauses, K) || hasClauses(Clauses, ClauseTypes...); 12777 } 12778 12779 /// Check if the variables in the mapping clause are externally visible. 12780 static bool isClauseMappable(ArrayRef<OMPClause *> Clauses) { 12781 for (const OMPClause *C : Clauses) { 12782 if (auto *TC = dyn_cast<OMPToClause>(C)) 12783 return llvm::all_of(TC->all_decls(), [](ValueDecl *VD) { 12784 return !VD || !VD->hasAttr<OMPDeclareTargetDeclAttr>() || 12785 (VD->isExternallyVisible() && 12786 VD->getVisibility() != HiddenVisibility); 12787 }); 12788 else if (auto *FC = dyn_cast<OMPFromClause>(C)) 12789 return llvm::all_of(FC->all_decls(), [](ValueDecl *VD) { 12790 return !VD || !VD->hasAttr<OMPDeclareTargetDeclAttr>() || 12791 (VD->isExternallyVisible() && 12792 VD->getVisibility() != HiddenVisibility); 12793 }); 12794 } 12795 12796 return true; 12797 } 12798 12799 StmtResult Sema::ActOnOpenMPTargetDataDirective(ArrayRef<OMPClause *> Clauses, 12800 Stmt *AStmt, 12801 SourceLocation StartLoc, 12802 SourceLocation EndLoc) { 12803 if (!AStmt) 12804 return StmtError(); 12805 12806 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 12807 12808 // OpenMP [2.12.2, target data Construct, Restrictions] 12809 // At least one map, use_device_addr or use_device_ptr clause must appear on 12810 // the directive. 12811 if (!hasClauses(Clauses, OMPC_map, OMPC_use_device_ptr) && 12812 (LangOpts.OpenMP < 50 || !hasClauses(Clauses, OMPC_use_device_addr))) { 12813 StringRef Expected; 12814 if (LangOpts.OpenMP < 50) 12815 Expected = "'map' or 'use_device_ptr'"; 12816 else 12817 Expected = "'map', 'use_device_ptr', or 'use_device_addr'"; 12818 Diag(StartLoc, diag::err_omp_no_clause_for_directive) 12819 << Expected << getOpenMPDirectiveName(OMPD_target_data); 12820 return StmtError(); 12821 } 12822 12823 setFunctionHasBranchProtectedScope(); 12824 12825 return OMPTargetDataDirective::Create(Context, StartLoc, EndLoc, Clauses, 12826 AStmt); 12827 } 12828 12829 StmtResult 12830 Sema::ActOnOpenMPTargetEnterDataDirective(ArrayRef<OMPClause *> Clauses, 12831 SourceLocation StartLoc, 12832 SourceLocation EndLoc, Stmt *AStmt) { 12833 if (!AStmt) 12834 return StmtError(); 12835 12836 auto *CS = cast<CapturedStmt>(AStmt); 12837 // 1.2.2 OpenMP Language Terminology 12838 // Structured block - An executable statement with a single entry at the 12839 // top and a single exit at the bottom. 12840 // The point of exit cannot be a branch out of the structured block. 12841 // longjmp() and throw() must not violate the entry/exit criteria. 12842 CS->getCapturedDecl()->setNothrow(); 12843 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_enter_data); 12844 ThisCaptureLevel > 1; --ThisCaptureLevel) { 12845 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 12846 // 1.2.2 OpenMP Language Terminology 12847 // Structured block - An executable statement with a single entry at the 12848 // top and a single exit at the bottom. 12849 // The point of exit cannot be a branch out of the structured block. 12850 // longjmp() and throw() must not violate the entry/exit criteria. 12851 CS->getCapturedDecl()->setNothrow(); 12852 } 12853 12854 // OpenMP [2.10.2, Restrictions, p. 99] 12855 // At least one map clause must appear on the directive. 12856 if (!hasClauses(Clauses, OMPC_map)) { 12857 Diag(StartLoc, diag::err_omp_no_clause_for_directive) 12858 << "'map'" << getOpenMPDirectiveName(OMPD_target_enter_data); 12859 return StmtError(); 12860 } 12861 12862 return OMPTargetEnterDataDirective::Create(Context, StartLoc, EndLoc, Clauses, 12863 AStmt); 12864 } 12865 12866 StmtResult 12867 Sema::ActOnOpenMPTargetExitDataDirective(ArrayRef<OMPClause *> Clauses, 12868 SourceLocation StartLoc, 12869 SourceLocation EndLoc, Stmt *AStmt) { 12870 if (!AStmt) 12871 return StmtError(); 12872 12873 auto *CS = cast<CapturedStmt>(AStmt); 12874 // 1.2.2 OpenMP Language Terminology 12875 // Structured block - An executable statement with a single entry at the 12876 // top and a single exit at the bottom. 12877 // The point of exit cannot be a branch out of the structured block. 12878 // longjmp() and throw() must not violate the entry/exit criteria. 12879 CS->getCapturedDecl()->setNothrow(); 12880 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_exit_data); 12881 ThisCaptureLevel > 1; --ThisCaptureLevel) { 12882 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 12883 // 1.2.2 OpenMP Language Terminology 12884 // Structured block - An executable statement with a single entry at the 12885 // top and a single exit at the bottom. 12886 // The point of exit cannot be a branch out of the structured block. 12887 // longjmp() and throw() must not violate the entry/exit criteria. 12888 CS->getCapturedDecl()->setNothrow(); 12889 } 12890 12891 // OpenMP [2.10.3, Restrictions, p. 102] 12892 // At least one map clause must appear on the directive. 12893 if (!hasClauses(Clauses, OMPC_map)) { 12894 Diag(StartLoc, diag::err_omp_no_clause_for_directive) 12895 << "'map'" << getOpenMPDirectiveName(OMPD_target_exit_data); 12896 return StmtError(); 12897 } 12898 12899 return OMPTargetExitDataDirective::Create(Context, StartLoc, EndLoc, Clauses, 12900 AStmt); 12901 } 12902 12903 StmtResult Sema::ActOnOpenMPTargetUpdateDirective(ArrayRef<OMPClause *> Clauses, 12904 SourceLocation StartLoc, 12905 SourceLocation EndLoc, 12906 Stmt *AStmt) { 12907 if (!AStmt) 12908 return StmtError(); 12909 12910 auto *CS = cast<CapturedStmt>(AStmt); 12911 // 1.2.2 OpenMP Language Terminology 12912 // Structured block - An executable statement with a single entry at the 12913 // top and a single exit at the bottom. 12914 // The point of exit cannot be a branch out of the structured block. 12915 // longjmp() and throw() must not violate the entry/exit criteria. 12916 CS->getCapturedDecl()->setNothrow(); 12917 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_update); 12918 ThisCaptureLevel > 1; --ThisCaptureLevel) { 12919 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 12920 // 1.2.2 OpenMP Language Terminology 12921 // Structured block - An executable statement with a single entry at the 12922 // top and a single exit at the bottom. 12923 // The point of exit cannot be a branch out of the structured block. 12924 // longjmp() and throw() must not violate the entry/exit criteria. 12925 CS->getCapturedDecl()->setNothrow(); 12926 } 12927 12928 if (!hasClauses(Clauses, OMPC_to, OMPC_from)) { 12929 Diag(StartLoc, diag::err_omp_at_least_one_motion_clause_required); 12930 return StmtError(); 12931 } 12932 12933 if (!isClauseMappable(Clauses)) { 12934 Diag(StartLoc, diag::err_omp_cannot_update_with_internal_linkage); 12935 return StmtError(); 12936 } 12937 12938 return OMPTargetUpdateDirective::Create(Context, StartLoc, EndLoc, Clauses, 12939 AStmt); 12940 } 12941 12942 StmtResult Sema::ActOnOpenMPTeamsDirective(ArrayRef<OMPClause *> Clauses, 12943 Stmt *AStmt, SourceLocation StartLoc, 12944 SourceLocation EndLoc) { 12945 if (!AStmt) 12946 return StmtError(); 12947 12948 auto *CS = cast<CapturedStmt>(AStmt); 12949 // 1.2.2 OpenMP Language Terminology 12950 // Structured block - An executable statement with a single entry at the 12951 // top and a single exit at the bottom. 12952 // The point of exit cannot be a branch out of the structured block. 12953 // longjmp() and throw() must not violate the entry/exit criteria. 12954 CS->getCapturedDecl()->setNothrow(); 12955 12956 setFunctionHasBranchProtectedScope(); 12957 12958 DSAStack->setParentTeamsRegionLoc(StartLoc); 12959 12960 return OMPTeamsDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt); 12961 } 12962 12963 StmtResult 12964 Sema::ActOnOpenMPCancellationPointDirective(SourceLocation StartLoc, 12965 SourceLocation EndLoc, 12966 OpenMPDirectiveKind CancelRegion) { 12967 if (DSAStack->isParentNowaitRegion()) { 12968 Diag(StartLoc, diag::err_omp_parent_cancel_region_nowait) << 0; 12969 return StmtError(); 12970 } 12971 if (DSAStack->isParentOrderedRegion()) { 12972 Diag(StartLoc, diag::err_omp_parent_cancel_region_ordered) << 0; 12973 return StmtError(); 12974 } 12975 return OMPCancellationPointDirective::Create(Context, StartLoc, EndLoc, 12976 CancelRegion); 12977 } 12978 12979 StmtResult Sema::ActOnOpenMPCancelDirective(ArrayRef<OMPClause *> Clauses, 12980 SourceLocation StartLoc, 12981 SourceLocation EndLoc, 12982 OpenMPDirectiveKind CancelRegion) { 12983 if (DSAStack->isParentNowaitRegion()) { 12984 Diag(StartLoc, diag::err_omp_parent_cancel_region_nowait) << 1; 12985 return StmtError(); 12986 } 12987 if (DSAStack->isParentOrderedRegion()) { 12988 Diag(StartLoc, diag::err_omp_parent_cancel_region_ordered) << 1; 12989 return StmtError(); 12990 } 12991 DSAStack->setParentCancelRegion(/*Cancel=*/true); 12992 return OMPCancelDirective::Create(Context, StartLoc, EndLoc, Clauses, 12993 CancelRegion); 12994 } 12995 12996 static bool checkReductionClauseWithNogroup(Sema &S, 12997 ArrayRef<OMPClause *> Clauses) { 12998 const OMPClause *ReductionClause = nullptr; 12999 const OMPClause *NogroupClause = nullptr; 13000 for (const OMPClause *C : Clauses) { 13001 if (C->getClauseKind() == OMPC_reduction) { 13002 ReductionClause = C; 13003 if (NogroupClause) 13004 break; 13005 continue; 13006 } 13007 if (C->getClauseKind() == OMPC_nogroup) { 13008 NogroupClause = C; 13009 if (ReductionClause) 13010 break; 13011 continue; 13012 } 13013 } 13014 if (ReductionClause && NogroupClause) { 13015 S.Diag(ReductionClause->getBeginLoc(), diag::err_omp_reduction_with_nogroup) 13016 << SourceRange(NogroupClause->getBeginLoc(), 13017 NogroupClause->getEndLoc()); 13018 return true; 13019 } 13020 return false; 13021 } 13022 13023 StmtResult Sema::ActOnOpenMPTaskLoopDirective( 13024 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 13025 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 13026 if (!AStmt) 13027 return StmtError(); 13028 13029 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 13030 OMPLoopBasedDirective::HelperExprs B; 13031 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 13032 // define the nested loops number. 13033 unsigned NestedLoopCount = 13034 checkOpenMPLoop(OMPD_taskloop, getCollapseNumberExpr(Clauses), 13035 /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack, 13036 VarsWithImplicitDSA, B); 13037 if (NestedLoopCount == 0) 13038 return StmtError(); 13039 13040 assert((CurContext->isDependentContext() || B.builtAll()) && 13041 "omp for loop exprs were not built"); 13042 13043 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 13044 // The grainsize clause and num_tasks clause are mutually exclusive and may 13045 // not appear on the same taskloop directive. 13046 if (checkMutuallyExclusiveClauses(*this, Clauses, 13047 {OMPC_grainsize, OMPC_num_tasks})) 13048 return StmtError(); 13049 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 13050 // If a reduction clause is present on the taskloop directive, the nogroup 13051 // clause must not be specified. 13052 if (checkReductionClauseWithNogroup(*this, Clauses)) 13053 return StmtError(); 13054 13055 setFunctionHasBranchProtectedScope(); 13056 return OMPTaskLoopDirective::Create(Context, StartLoc, EndLoc, 13057 NestedLoopCount, Clauses, AStmt, B, 13058 DSAStack->isCancelRegion()); 13059 } 13060 13061 StmtResult Sema::ActOnOpenMPTaskLoopSimdDirective( 13062 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 13063 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 13064 if (!AStmt) 13065 return StmtError(); 13066 13067 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 13068 OMPLoopBasedDirective::HelperExprs B; 13069 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 13070 // define the nested loops number. 13071 unsigned NestedLoopCount = 13072 checkOpenMPLoop(OMPD_taskloop_simd, getCollapseNumberExpr(Clauses), 13073 /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack, 13074 VarsWithImplicitDSA, B); 13075 if (NestedLoopCount == 0) 13076 return StmtError(); 13077 13078 assert((CurContext->isDependentContext() || B.builtAll()) && 13079 "omp for loop exprs were not built"); 13080 13081 if (!CurContext->isDependentContext()) { 13082 // Finalize the clauses that need pre-built expressions for CodeGen. 13083 for (OMPClause *C : Clauses) { 13084 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 13085 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 13086 B.NumIterations, *this, CurScope, 13087 DSAStack)) 13088 return StmtError(); 13089 } 13090 } 13091 13092 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 13093 // The grainsize clause and num_tasks clause are mutually exclusive and may 13094 // not appear on the same taskloop directive. 13095 if (checkMutuallyExclusiveClauses(*this, Clauses, 13096 {OMPC_grainsize, OMPC_num_tasks})) 13097 return StmtError(); 13098 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 13099 // If a reduction clause is present on the taskloop directive, the nogroup 13100 // clause must not be specified. 13101 if (checkReductionClauseWithNogroup(*this, Clauses)) 13102 return StmtError(); 13103 if (checkSimdlenSafelenSpecified(*this, Clauses)) 13104 return StmtError(); 13105 13106 setFunctionHasBranchProtectedScope(); 13107 return OMPTaskLoopSimdDirective::Create(Context, StartLoc, EndLoc, 13108 NestedLoopCount, Clauses, AStmt, B); 13109 } 13110 13111 StmtResult Sema::ActOnOpenMPMasterTaskLoopDirective( 13112 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 13113 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 13114 if (!AStmt) 13115 return StmtError(); 13116 13117 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 13118 OMPLoopBasedDirective::HelperExprs B; 13119 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 13120 // define the nested loops number. 13121 unsigned NestedLoopCount = 13122 checkOpenMPLoop(OMPD_master_taskloop, getCollapseNumberExpr(Clauses), 13123 /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack, 13124 VarsWithImplicitDSA, B); 13125 if (NestedLoopCount == 0) 13126 return StmtError(); 13127 13128 assert((CurContext->isDependentContext() || B.builtAll()) && 13129 "omp for loop exprs were not built"); 13130 13131 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 13132 // The grainsize clause and num_tasks clause are mutually exclusive and may 13133 // not appear on the same taskloop directive. 13134 if (checkMutuallyExclusiveClauses(*this, Clauses, 13135 {OMPC_grainsize, OMPC_num_tasks})) 13136 return StmtError(); 13137 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 13138 // If a reduction clause is present on the taskloop directive, the nogroup 13139 // clause must not be specified. 13140 if (checkReductionClauseWithNogroup(*this, Clauses)) 13141 return StmtError(); 13142 13143 setFunctionHasBranchProtectedScope(); 13144 return OMPMasterTaskLoopDirective::Create(Context, StartLoc, EndLoc, 13145 NestedLoopCount, Clauses, AStmt, B, 13146 DSAStack->isCancelRegion()); 13147 } 13148 13149 StmtResult Sema::ActOnOpenMPMasterTaskLoopSimdDirective( 13150 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 13151 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 13152 if (!AStmt) 13153 return StmtError(); 13154 13155 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 13156 OMPLoopBasedDirective::HelperExprs B; 13157 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 13158 // define the nested loops number. 13159 unsigned NestedLoopCount = 13160 checkOpenMPLoop(OMPD_master_taskloop_simd, getCollapseNumberExpr(Clauses), 13161 /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack, 13162 VarsWithImplicitDSA, B); 13163 if (NestedLoopCount == 0) 13164 return StmtError(); 13165 13166 assert((CurContext->isDependentContext() || B.builtAll()) && 13167 "omp for loop exprs were not built"); 13168 13169 if (!CurContext->isDependentContext()) { 13170 // Finalize the clauses that need pre-built expressions for CodeGen. 13171 for (OMPClause *C : Clauses) { 13172 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 13173 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 13174 B.NumIterations, *this, CurScope, 13175 DSAStack)) 13176 return StmtError(); 13177 } 13178 } 13179 13180 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 13181 // The grainsize clause and num_tasks clause are mutually exclusive and may 13182 // not appear on the same taskloop directive. 13183 if (checkMutuallyExclusiveClauses(*this, Clauses, 13184 {OMPC_grainsize, OMPC_num_tasks})) 13185 return StmtError(); 13186 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 13187 // If a reduction clause is present on the taskloop directive, the nogroup 13188 // clause must not be specified. 13189 if (checkReductionClauseWithNogroup(*this, Clauses)) 13190 return StmtError(); 13191 if (checkSimdlenSafelenSpecified(*this, Clauses)) 13192 return StmtError(); 13193 13194 setFunctionHasBranchProtectedScope(); 13195 return OMPMasterTaskLoopSimdDirective::Create( 13196 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 13197 } 13198 13199 StmtResult Sema::ActOnOpenMPParallelMasterTaskLoopDirective( 13200 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 13201 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 13202 if (!AStmt) 13203 return StmtError(); 13204 13205 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 13206 auto *CS = cast<CapturedStmt>(AStmt); 13207 // 1.2.2 OpenMP Language Terminology 13208 // Structured block - An executable statement with a single entry at the 13209 // top and a single exit at the bottom. 13210 // The point of exit cannot be a branch out of the structured block. 13211 // longjmp() and throw() must not violate the entry/exit criteria. 13212 CS->getCapturedDecl()->setNothrow(); 13213 for (int ThisCaptureLevel = 13214 getOpenMPCaptureLevels(OMPD_parallel_master_taskloop); 13215 ThisCaptureLevel > 1; --ThisCaptureLevel) { 13216 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 13217 // 1.2.2 OpenMP Language Terminology 13218 // Structured block - An executable statement with a single entry at the 13219 // top and a single exit at the bottom. 13220 // The point of exit cannot be a branch out of the structured block. 13221 // longjmp() and throw() must not violate the entry/exit criteria. 13222 CS->getCapturedDecl()->setNothrow(); 13223 } 13224 13225 OMPLoopBasedDirective::HelperExprs B; 13226 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 13227 // define the nested loops number. 13228 unsigned NestedLoopCount = checkOpenMPLoop( 13229 OMPD_parallel_master_taskloop, getCollapseNumberExpr(Clauses), 13230 /*OrderedLoopCountExpr=*/nullptr, CS, *this, *DSAStack, 13231 VarsWithImplicitDSA, B); 13232 if (NestedLoopCount == 0) 13233 return StmtError(); 13234 13235 assert((CurContext->isDependentContext() || B.builtAll()) && 13236 "omp for loop exprs were not built"); 13237 13238 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 13239 // The grainsize clause and num_tasks clause are mutually exclusive and may 13240 // not appear on the same taskloop directive. 13241 if (checkMutuallyExclusiveClauses(*this, Clauses, 13242 {OMPC_grainsize, OMPC_num_tasks})) 13243 return StmtError(); 13244 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 13245 // If a reduction clause is present on the taskloop directive, the nogroup 13246 // clause must not be specified. 13247 if (checkReductionClauseWithNogroup(*this, Clauses)) 13248 return StmtError(); 13249 13250 setFunctionHasBranchProtectedScope(); 13251 return OMPParallelMasterTaskLoopDirective::Create( 13252 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B, 13253 DSAStack->isCancelRegion()); 13254 } 13255 13256 StmtResult Sema::ActOnOpenMPParallelMasterTaskLoopSimdDirective( 13257 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 13258 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 13259 if (!AStmt) 13260 return StmtError(); 13261 13262 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 13263 auto *CS = cast<CapturedStmt>(AStmt); 13264 // 1.2.2 OpenMP Language Terminology 13265 // Structured block - An executable statement with a single entry at the 13266 // top and a single exit at the bottom. 13267 // The point of exit cannot be a branch out of the structured block. 13268 // longjmp() and throw() must not violate the entry/exit criteria. 13269 CS->getCapturedDecl()->setNothrow(); 13270 for (int ThisCaptureLevel = 13271 getOpenMPCaptureLevels(OMPD_parallel_master_taskloop_simd); 13272 ThisCaptureLevel > 1; --ThisCaptureLevel) { 13273 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 13274 // 1.2.2 OpenMP Language Terminology 13275 // Structured block - An executable statement with a single entry at the 13276 // top and a single exit at the bottom. 13277 // The point of exit cannot be a branch out of the structured block. 13278 // longjmp() and throw() must not violate the entry/exit criteria. 13279 CS->getCapturedDecl()->setNothrow(); 13280 } 13281 13282 OMPLoopBasedDirective::HelperExprs B; 13283 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 13284 // define the nested loops number. 13285 unsigned NestedLoopCount = checkOpenMPLoop( 13286 OMPD_parallel_master_taskloop_simd, getCollapseNumberExpr(Clauses), 13287 /*OrderedLoopCountExpr=*/nullptr, CS, *this, *DSAStack, 13288 VarsWithImplicitDSA, B); 13289 if (NestedLoopCount == 0) 13290 return StmtError(); 13291 13292 assert((CurContext->isDependentContext() || B.builtAll()) && 13293 "omp for loop exprs were not built"); 13294 13295 if (!CurContext->isDependentContext()) { 13296 // Finalize the clauses that need pre-built expressions for CodeGen. 13297 for (OMPClause *C : Clauses) { 13298 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 13299 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 13300 B.NumIterations, *this, CurScope, 13301 DSAStack)) 13302 return StmtError(); 13303 } 13304 } 13305 13306 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 13307 // The grainsize clause and num_tasks clause are mutually exclusive and may 13308 // not appear on the same taskloop directive. 13309 if (checkMutuallyExclusiveClauses(*this, Clauses, 13310 {OMPC_grainsize, OMPC_num_tasks})) 13311 return StmtError(); 13312 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 13313 // If a reduction clause is present on the taskloop directive, the nogroup 13314 // clause must not be specified. 13315 if (checkReductionClauseWithNogroup(*this, Clauses)) 13316 return StmtError(); 13317 if (checkSimdlenSafelenSpecified(*this, Clauses)) 13318 return StmtError(); 13319 13320 setFunctionHasBranchProtectedScope(); 13321 return OMPParallelMasterTaskLoopSimdDirective::Create( 13322 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 13323 } 13324 13325 StmtResult Sema::ActOnOpenMPDistributeDirective( 13326 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 13327 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 13328 if (!AStmt) 13329 return StmtError(); 13330 13331 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 13332 OMPLoopBasedDirective::HelperExprs B; 13333 // In presence of clause 'collapse' with number of loops, it will 13334 // define the nested loops number. 13335 unsigned NestedLoopCount = 13336 checkOpenMPLoop(OMPD_distribute, getCollapseNumberExpr(Clauses), 13337 nullptr /*ordered not a clause on distribute*/, AStmt, 13338 *this, *DSAStack, VarsWithImplicitDSA, B); 13339 if (NestedLoopCount == 0) 13340 return StmtError(); 13341 13342 assert((CurContext->isDependentContext() || B.builtAll()) && 13343 "omp for loop exprs were not built"); 13344 13345 setFunctionHasBranchProtectedScope(); 13346 return OMPDistributeDirective::Create(Context, StartLoc, EndLoc, 13347 NestedLoopCount, Clauses, AStmt, B); 13348 } 13349 13350 StmtResult Sema::ActOnOpenMPDistributeParallelForDirective( 13351 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 13352 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 13353 if (!AStmt) 13354 return StmtError(); 13355 13356 auto *CS = cast<CapturedStmt>(AStmt); 13357 // 1.2.2 OpenMP Language Terminology 13358 // Structured block - An executable statement with a single entry at the 13359 // top and a single exit at the bottom. 13360 // The point of exit cannot be a branch out of the structured block. 13361 // longjmp() and throw() must not violate the entry/exit criteria. 13362 CS->getCapturedDecl()->setNothrow(); 13363 for (int ThisCaptureLevel = 13364 getOpenMPCaptureLevels(OMPD_distribute_parallel_for); 13365 ThisCaptureLevel > 1; --ThisCaptureLevel) { 13366 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 13367 // 1.2.2 OpenMP Language Terminology 13368 // Structured block - An executable statement with a single entry at the 13369 // top and a single exit at the bottom. 13370 // The point of exit cannot be a branch out of the structured block. 13371 // longjmp() and throw() must not violate the entry/exit criteria. 13372 CS->getCapturedDecl()->setNothrow(); 13373 } 13374 13375 OMPLoopBasedDirective::HelperExprs B; 13376 // In presence of clause 'collapse' with number of loops, it will 13377 // define the nested loops number. 13378 unsigned NestedLoopCount = checkOpenMPLoop( 13379 OMPD_distribute_parallel_for, getCollapseNumberExpr(Clauses), 13380 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 13381 VarsWithImplicitDSA, B); 13382 if (NestedLoopCount == 0) 13383 return StmtError(); 13384 13385 assert((CurContext->isDependentContext() || B.builtAll()) && 13386 "omp for loop exprs were not built"); 13387 13388 setFunctionHasBranchProtectedScope(); 13389 return OMPDistributeParallelForDirective::Create( 13390 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B, 13391 DSAStack->getTaskgroupReductionRef(), DSAStack->isCancelRegion()); 13392 } 13393 13394 StmtResult Sema::ActOnOpenMPDistributeParallelForSimdDirective( 13395 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 13396 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 13397 if (!AStmt) 13398 return StmtError(); 13399 13400 auto *CS = cast<CapturedStmt>(AStmt); 13401 // 1.2.2 OpenMP Language Terminology 13402 // Structured block - An executable statement with a single entry at the 13403 // top and a single exit at the bottom. 13404 // The point of exit cannot be a branch out of the structured block. 13405 // longjmp() and throw() must not violate the entry/exit criteria. 13406 CS->getCapturedDecl()->setNothrow(); 13407 for (int ThisCaptureLevel = 13408 getOpenMPCaptureLevels(OMPD_distribute_parallel_for_simd); 13409 ThisCaptureLevel > 1; --ThisCaptureLevel) { 13410 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 13411 // 1.2.2 OpenMP Language Terminology 13412 // Structured block - An executable statement with a single entry at the 13413 // top and a single exit at the bottom. 13414 // The point of exit cannot be a branch out of the structured block. 13415 // longjmp() and throw() must not violate the entry/exit criteria. 13416 CS->getCapturedDecl()->setNothrow(); 13417 } 13418 13419 OMPLoopBasedDirective::HelperExprs B; 13420 // In presence of clause 'collapse' with number of loops, it will 13421 // define the nested loops number. 13422 unsigned NestedLoopCount = checkOpenMPLoop( 13423 OMPD_distribute_parallel_for_simd, getCollapseNumberExpr(Clauses), 13424 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 13425 VarsWithImplicitDSA, B); 13426 if (NestedLoopCount == 0) 13427 return StmtError(); 13428 13429 assert((CurContext->isDependentContext() || B.builtAll()) && 13430 "omp for loop exprs were not built"); 13431 13432 if (!CurContext->isDependentContext()) { 13433 // Finalize the clauses that need pre-built expressions for CodeGen. 13434 for (OMPClause *C : Clauses) { 13435 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 13436 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 13437 B.NumIterations, *this, CurScope, 13438 DSAStack)) 13439 return StmtError(); 13440 } 13441 } 13442 13443 if (checkSimdlenSafelenSpecified(*this, Clauses)) 13444 return StmtError(); 13445 13446 setFunctionHasBranchProtectedScope(); 13447 return OMPDistributeParallelForSimdDirective::Create( 13448 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 13449 } 13450 13451 StmtResult Sema::ActOnOpenMPDistributeSimdDirective( 13452 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 13453 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 13454 if (!AStmt) 13455 return StmtError(); 13456 13457 auto *CS = cast<CapturedStmt>(AStmt); 13458 // 1.2.2 OpenMP Language Terminology 13459 // Structured block - An executable statement with a single entry at the 13460 // top and a single exit at the bottom. 13461 // The point of exit cannot be a branch out of the structured block. 13462 // longjmp() and throw() must not violate the entry/exit criteria. 13463 CS->getCapturedDecl()->setNothrow(); 13464 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_distribute_simd); 13465 ThisCaptureLevel > 1; --ThisCaptureLevel) { 13466 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 13467 // 1.2.2 OpenMP Language Terminology 13468 // Structured block - An executable statement with a single entry at the 13469 // top and a single exit at the bottom. 13470 // The point of exit cannot be a branch out of the structured block. 13471 // longjmp() and throw() must not violate the entry/exit criteria. 13472 CS->getCapturedDecl()->setNothrow(); 13473 } 13474 13475 OMPLoopBasedDirective::HelperExprs B; 13476 // In presence of clause 'collapse' with number of loops, it will 13477 // define the nested loops number. 13478 unsigned NestedLoopCount = 13479 checkOpenMPLoop(OMPD_distribute_simd, getCollapseNumberExpr(Clauses), 13480 nullptr /*ordered not a clause on distribute*/, CS, *this, 13481 *DSAStack, VarsWithImplicitDSA, B); 13482 if (NestedLoopCount == 0) 13483 return StmtError(); 13484 13485 assert((CurContext->isDependentContext() || B.builtAll()) && 13486 "omp for loop exprs were not built"); 13487 13488 if (!CurContext->isDependentContext()) { 13489 // Finalize the clauses that need pre-built expressions for CodeGen. 13490 for (OMPClause *C : Clauses) { 13491 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 13492 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 13493 B.NumIterations, *this, CurScope, 13494 DSAStack)) 13495 return StmtError(); 13496 } 13497 } 13498 13499 if (checkSimdlenSafelenSpecified(*this, Clauses)) 13500 return StmtError(); 13501 13502 setFunctionHasBranchProtectedScope(); 13503 return OMPDistributeSimdDirective::Create(Context, StartLoc, EndLoc, 13504 NestedLoopCount, Clauses, AStmt, B); 13505 } 13506 13507 StmtResult Sema::ActOnOpenMPTargetParallelForSimdDirective( 13508 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 13509 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 13510 if (!AStmt) 13511 return StmtError(); 13512 13513 auto *CS = cast<CapturedStmt>(AStmt); 13514 // 1.2.2 OpenMP Language Terminology 13515 // Structured block - An executable statement with a single entry at the 13516 // top and a single exit at the bottom. 13517 // The point of exit cannot be a branch out of the structured block. 13518 // longjmp() and throw() must not violate the entry/exit criteria. 13519 CS->getCapturedDecl()->setNothrow(); 13520 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel_for); 13521 ThisCaptureLevel > 1; --ThisCaptureLevel) { 13522 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 13523 // 1.2.2 OpenMP Language Terminology 13524 // Structured block - An executable statement with a single entry at the 13525 // top and a single exit at the bottom. 13526 // The point of exit cannot be a branch out of the structured block. 13527 // longjmp() and throw() must not violate the entry/exit criteria. 13528 CS->getCapturedDecl()->setNothrow(); 13529 } 13530 13531 OMPLoopBasedDirective::HelperExprs B; 13532 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 13533 // define the nested loops number. 13534 unsigned NestedLoopCount = checkOpenMPLoop( 13535 OMPD_target_parallel_for_simd, getCollapseNumberExpr(Clauses), 13536 getOrderedNumberExpr(Clauses), CS, *this, *DSAStack, VarsWithImplicitDSA, 13537 B); 13538 if (NestedLoopCount == 0) 13539 return StmtError(); 13540 13541 assert((CurContext->isDependentContext() || B.builtAll()) && 13542 "omp target parallel for simd loop exprs were not built"); 13543 13544 if (!CurContext->isDependentContext()) { 13545 // Finalize the clauses that need pre-built expressions for CodeGen. 13546 for (OMPClause *C : Clauses) { 13547 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 13548 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 13549 B.NumIterations, *this, CurScope, 13550 DSAStack)) 13551 return StmtError(); 13552 } 13553 } 13554 if (checkSimdlenSafelenSpecified(*this, Clauses)) 13555 return StmtError(); 13556 13557 setFunctionHasBranchProtectedScope(); 13558 return OMPTargetParallelForSimdDirective::Create( 13559 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 13560 } 13561 13562 StmtResult Sema::ActOnOpenMPTargetSimdDirective( 13563 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 13564 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 13565 if (!AStmt) 13566 return StmtError(); 13567 13568 auto *CS = cast<CapturedStmt>(AStmt); 13569 // 1.2.2 OpenMP Language Terminology 13570 // Structured block - An executable statement with a single entry at the 13571 // top and a single exit at the bottom. 13572 // The point of exit cannot be a branch out of the structured block. 13573 // longjmp() and throw() must not violate the entry/exit criteria. 13574 CS->getCapturedDecl()->setNothrow(); 13575 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_simd); 13576 ThisCaptureLevel > 1; --ThisCaptureLevel) { 13577 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 13578 // 1.2.2 OpenMP Language Terminology 13579 // Structured block - An executable statement with a single entry at the 13580 // top and a single exit at the bottom. 13581 // The point of exit cannot be a branch out of the structured block. 13582 // longjmp() and throw() must not violate the entry/exit criteria. 13583 CS->getCapturedDecl()->setNothrow(); 13584 } 13585 13586 OMPLoopBasedDirective::HelperExprs B; 13587 // In presence of clause 'collapse' with number of loops, it will define the 13588 // nested loops number. 13589 unsigned NestedLoopCount = 13590 checkOpenMPLoop(OMPD_target_simd, getCollapseNumberExpr(Clauses), 13591 getOrderedNumberExpr(Clauses), CS, *this, *DSAStack, 13592 VarsWithImplicitDSA, B); 13593 if (NestedLoopCount == 0) 13594 return StmtError(); 13595 13596 assert((CurContext->isDependentContext() || B.builtAll()) && 13597 "omp target simd loop exprs were not built"); 13598 13599 if (!CurContext->isDependentContext()) { 13600 // Finalize the clauses that need pre-built expressions for CodeGen. 13601 for (OMPClause *C : Clauses) { 13602 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 13603 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 13604 B.NumIterations, *this, CurScope, 13605 DSAStack)) 13606 return StmtError(); 13607 } 13608 } 13609 13610 if (checkSimdlenSafelenSpecified(*this, Clauses)) 13611 return StmtError(); 13612 13613 setFunctionHasBranchProtectedScope(); 13614 return OMPTargetSimdDirective::Create(Context, StartLoc, EndLoc, 13615 NestedLoopCount, Clauses, AStmt, B); 13616 } 13617 13618 StmtResult Sema::ActOnOpenMPTeamsDistributeDirective( 13619 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 13620 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 13621 if (!AStmt) 13622 return StmtError(); 13623 13624 auto *CS = cast<CapturedStmt>(AStmt); 13625 // 1.2.2 OpenMP Language Terminology 13626 // Structured block - An executable statement with a single entry at the 13627 // top and a single exit at the bottom. 13628 // The point of exit cannot be a branch out of the structured block. 13629 // longjmp() and throw() must not violate the entry/exit criteria. 13630 CS->getCapturedDecl()->setNothrow(); 13631 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_teams_distribute); 13632 ThisCaptureLevel > 1; --ThisCaptureLevel) { 13633 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 13634 // 1.2.2 OpenMP Language Terminology 13635 // Structured block - An executable statement with a single entry at the 13636 // top and a single exit at the bottom. 13637 // The point of exit cannot be a branch out of the structured block. 13638 // longjmp() and throw() must not violate the entry/exit criteria. 13639 CS->getCapturedDecl()->setNothrow(); 13640 } 13641 13642 OMPLoopBasedDirective::HelperExprs B; 13643 // In presence of clause 'collapse' with number of loops, it will 13644 // define the nested loops number. 13645 unsigned NestedLoopCount = 13646 checkOpenMPLoop(OMPD_teams_distribute, getCollapseNumberExpr(Clauses), 13647 nullptr /*ordered not a clause on distribute*/, CS, *this, 13648 *DSAStack, VarsWithImplicitDSA, B); 13649 if (NestedLoopCount == 0) 13650 return StmtError(); 13651 13652 assert((CurContext->isDependentContext() || B.builtAll()) && 13653 "omp teams distribute loop exprs were not built"); 13654 13655 setFunctionHasBranchProtectedScope(); 13656 13657 DSAStack->setParentTeamsRegionLoc(StartLoc); 13658 13659 return OMPTeamsDistributeDirective::Create( 13660 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 13661 } 13662 13663 StmtResult Sema::ActOnOpenMPTeamsDistributeSimdDirective( 13664 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 13665 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 13666 if (!AStmt) 13667 return StmtError(); 13668 13669 auto *CS = cast<CapturedStmt>(AStmt); 13670 // 1.2.2 OpenMP Language Terminology 13671 // Structured block - An executable statement with a single entry at the 13672 // top and a single exit at the bottom. 13673 // The point of exit cannot be a branch out of the structured block. 13674 // longjmp() and throw() must not violate the entry/exit criteria. 13675 CS->getCapturedDecl()->setNothrow(); 13676 for (int ThisCaptureLevel = 13677 getOpenMPCaptureLevels(OMPD_teams_distribute_simd); 13678 ThisCaptureLevel > 1; --ThisCaptureLevel) { 13679 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 13680 // 1.2.2 OpenMP Language Terminology 13681 // Structured block - An executable statement with a single entry at the 13682 // top and a single exit at the bottom. 13683 // The point of exit cannot be a branch out of the structured block. 13684 // longjmp() and throw() must not violate the entry/exit criteria. 13685 CS->getCapturedDecl()->setNothrow(); 13686 } 13687 13688 OMPLoopBasedDirective::HelperExprs B; 13689 // In presence of clause 'collapse' with number of loops, it will 13690 // define the nested loops number. 13691 unsigned NestedLoopCount = checkOpenMPLoop( 13692 OMPD_teams_distribute_simd, getCollapseNumberExpr(Clauses), 13693 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 13694 VarsWithImplicitDSA, B); 13695 13696 if (NestedLoopCount == 0) 13697 return StmtError(); 13698 13699 assert((CurContext->isDependentContext() || B.builtAll()) && 13700 "omp teams distribute simd loop exprs were not built"); 13701 13702 if (!CurContext->isDependentContext()) { 13703 // Finalize the clauses that need pre-built expressions for CodeGen. 13704 for (OMPClause *C : Clauses) { 13705 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 13706 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 13707 B.NumIterations, *this, CurScope, 13708 DSAStack)) 13709 return StmtError(); 13710 } 13711 } 13712 13713 if (checkSimdlenSafelenSpecified(*this, Clauses)) 13714 return StmtError(); 13715 13716 setFunctionHasBranchProtectedScope(); 13717 13718 DSAStack->setParentTeamsRegionLoc(StartLoc); 13719 13720 return OMPTeamsDistributeSimdDirective::Create( 13721 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 13722 } 13723 13724 StmtResult Sema::ActOnOpenMPTeamsDistributeParallelForSimdDirective( 13725 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 13726 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 13727 if (!AStmt) 13728 return StmtError(); 13729 13730 auto *CS = cast<CapturedStmt>(AStmt); 13731 // 1.2.2 OpenMP Language Terminology 13732 // Structured block - An executable statement with a single entry at the 13733 // top and a single exit at the bottom. 13734 // The point of exit cannot be a branch out of the structured block. 13735 // longjmp() and throw() must not violate the entry/exit criteria. 13736 CS->getCapturedDecl()->setNothrow(); 13737 13738 for (int ThisCaptureLevel = 13739 getOpenMPCaptureLevels(OMPD_teams_distribute_parallel_for_simd); 13740 ThisCaptureLevel > 1; --ThisCaptureLevel) { 13741 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 13742 // 1.2.2 OpenMP Language Terminology 13743 // Structured block - An executable statement with a single entry at the 13744 // top and a single exit at the bottom. 13745 // The point of exit cannot be a branch out of the structured block. 13746 // longjmp() and throw() must not violate the entry/exit criteria. 13747 CS->getCapturedDecl()->setNothrow(); 13748 } 13749 13750 OMPLoopBasedDirective::HelperExprs B; 13751 // In presence of clause 'collapse' with number of loops, it will 13752 // define the nested loops number. 13753 unsigned NestedLoopCount = checkOpenMPLoop( 13754 OMPD_teams_distribute_parallel_for_simd, getCollapseNumberExpr(Clauses), 13755 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 13756 VarsWithImplicitDSA, B); 13757 13758 if (NestedLoopCount == 0) 13759 return StmtError(); 13760 13761 assert((CurContext->isDependentContext() || B.builtAll()) && 13762 "omp for loop exprs were not built"); 13763 13764 if (!CurContext->isDependentContext()) { 13765 // Finalize the clauses that need pre-built expressions for CodeGen. 13766 for (OMPClause *C : Clauses) { 13767 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 13768 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 13769 B.NumIterations, *this, CurScope, 13770 DSAStack)) 13771 return StmtError(); 13772 } 13773 } 13774 13775 if (checkSimdlenSafelenSpecified(*this, Clauses)) 13776 return StmtError(); 13777 13778 setFunctionHasBranchProtectedScope(); 13779 13780 DSAStack->setParentTeamsRegionLoc(StartLoc); 13781 13782 return OMPTeamsDistributeParallelForSimdDirective::Create( 13783 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 13784 } 13785 13786 StmtResult Sema::ActOnOpenMPTeamsDistributeParallelForDirective( 13787 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 13788 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 13789 if (!AStmt) 13790 return StmtError(); 13791 13792 auto *CS = cast<CapturedStmt>(AStmt); 13793 // 1.2.2 OpenMP Language Terminology 13794 // Structured block - An executable statement with a single entry at the 13795 // top and a single exit at the bottom. 13796 // The point of exit cannot be a branch out of the structured block. 13797 // longjmp() and throw() must not violate the entry/exit criteria. 13798 CS->getCapturedDecl()->setNothrow(); 13799 13800 for (int ThisCaptureLevel = 13801 getOpenMPCaptureLevels(OMPD_teams_distribute_parallel_for); 13802 ThisCaptureLevel > 1; --ThisCaptureLevel) { 13803 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 13804 // 1.2.2 OpenMP Language Terminology 13805 // Structured block - An executable statement with a single entry at the 13806 // top and a single exit at the bottom. 13807 // The point of exit cannot be a branch out of the structured block. 13808 // longjmp() and throw() must not violate the entry/exit criteria. 13809 CS->getCapturedDecl()->setNothrow(); 13810 } 13811 13812 OMPLoopBasedDirective::HelperExprs B; 13813 // In presence of clause 'collapse' with number of loops, it will 13814 // define the nested loops number. 13815 unsigned NestedLoopCount = checkOpenMPLoop( 13816 OMPD_teams_distribute_parallel_for, getCollapseNumberExpr(Clauses), 13817 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 13818 VarsWithImplicitDSA, B); 13819 13820 if (NestedLoopCount == 0) 13821 return StmtError(); 13822 13823 assert((CurContext->isDependentContext() || B.builtAll()) && 13824 "omp for loop exprs were not built"); 13825 13826 setFunctionHasBranchProtectedScope(); 13827 13828 DSAStack->setParentTeamsRegionLoc(StartLoc); 13829 13830 return OMPTeamsDistributeParallelForDirective::Create( 13831 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B, 13832 DSAStack->getTaskgroupReductionRef(), DSAStack->isCancelRegion()); 13833 } 13834 13835 StmtResult Sema::ActOnOpenMPTargetTeamsDirective(ArrayRef<OMPClause *> Clauses, 13836 Stmt *AStmt, 13837 SourceLocation StartLoc, 13838 SourceLocation EndLoc) { 13839 if (!AStmt) 13840 return StmtError(); 13841 13842 auto *CS = cast<CapturedStmt>(AStmt); 13843 // 1.2.2 OpenMP Language Terminology 13844 // Structured block - An executable statement with a single entry at the 13845 // top and a single exit at the bottom. 13846 // The point of exit cannot be a branch out of the structured block. 13847 // longjmp() and throw() must not violate the entry/exit criteria. 13848 CS->getCapturedDecl()->setNothrow(); 13849 13850 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_teams); 13851 ThisCaptureLevel > 1; --ThisCaptureLevel) { 13852 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 13853 // 1.2.2 OpenMP Language Terminology 13854 // Structured block - An executable statement with a single entry at the 13855 // top and a single exit at the bottom. 13856 // The point of exit cannot be a branch out of the structured block. 13857 // longjmp() and throw() must not violate the entry/exit criteria. 13858 CS->getCapturedDecl()->setNothrow(); 13859 } 13860 setFunctionHasBranchProtectedScope(); 13861 13862 return OMPTargetTeamsDirective::Create(Context, StartLoc, EndLoc, Clauses, 13863 AStmt); 13864 } 13865 13866 StmtResult Sema::ActOnOpenMPTargetTeamsDistributeDirective( 13867 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 13868 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 13869 if (!AStmt) 13870 return StmtError(); 13871 13872 auto *CS = cast<CapturedStmt>(AStmt); 13873 // 1.2.2 OpenMP Language Terminology 13874 // Structured block - An executable statement with a single entry at the 13875 // top and a single exit at the bottom. 13876 // The point of exit cannot be a branch out of the structured block. 13877 // longjmp() and throw() must not violate the entry/exit criteria. 13878 CS->getCapturedDecl()->setNothrow(); 13879 for (int ThisCaptureLevel = 13880 getOpenMPCaptureLevels(OMPD_target_teams_distribute); 13881 ThisCaptureLevel > 1; --ThisCaptureLevel) { 13882 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 13883 // 1.2.2 OpenMP Language Terminology 13884 // Structured block - An executable statement with a single entry at the 13885 // top and a single exit at the bottom. 13886 // The point of exit cannot be a branch out of the structured block. 13887 // longjmp() and throw() must not violate the entry/exit criteria. 13888 CS->getCapturedDecl()->setNothrow(); 13889 } 13890 13891 OMPLoopBasedDirective::HelperExprs B; 13892 // In presence of clause 'collapse' with number of loops, it will 13893 // define the nested loops number. 13894 unsigned NestedLoopCount = checkOpenMPLoop( 13895 OMPD_target_teams_distribute, getCollapseNumberExpr(Clauses), 13896 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 13897 VarsWithImplicitDSA, B); 13898 if (NestedLoopCount == 0) 13899 return StmtError(); 13900 13901 assert((CurContext->isDependentContext() || B.builtAll()) && 13902 "omp target teams distribute loop exprs were not built"); 13903 13904 setFunctionHasBranchProtectedScope(); 13905 return OMPTargetTeamsDistributeDirective::Create( 13906 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 13907 } 13908 13909 StmtResult Sema::ActOnOpenMPTargetTeamsDistributeParallelForDirective( 13910 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 13911 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 13912 if (!AStmt) 13913 return StmtError(); 13914 13915 auto *CS = cast<CapturedStmt>(AStmt); 13916 // 1.2.2 OpenMP Language Terminology 13917 // Structured block - An executable statement with a single entry at the 13918 // top and a single exit at the bottom. 13919 // The point of exit cannot be a branch out of the structured block. 13920 // longjmp() and throw() must not violate the entry/exit criteria. 13921 CS->getCapturedDecl()->setNothrow(); 13922 for (int ThisCaptureLevel = 13923 getOpenMPCaptureLevels(OMPD_target_teams_distribute_parallel_for); 13924 ThisCaptureLevel > 1; --ThisCaptureLevel) { 13925 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 13926 // 1.2.2 OpenMP Language Terminology 13927 // Structured block - An executable statement with a single entry at the 13928 // top and a single exit at the bottom. 13929 // The point of exit cannot be a branch out of the structured block. 13930 // longjmp() and throw() must not violate the entry/exit criteria. 13931 CS->getCapturedDecl()->setNothrow(); 13932 } 13933 13934 OMPLoopBasedDirective::HelperExprs B; 13935 // In presence of clause 'collapse' with number of loops, it will 13936 // define the nested loops number. 13937 unsigned NestedLoopCount = checkOpenMPLoop( 13938 OMPD_target_teams_distribute_parallel_for, getCollapseNumberExpr(Clauses), 13939 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 13940 VarsWithImplicitDSA, B); 13941 if (NestedLoopCount == 0) 13942 return StmtError(); 13943 13944 assert((CurContext->isDependentContext() || B.builtAll()) && 13945 "omp target teams distribute parallel for loop exprs were not built"); 13946 13947 if (!CurContext->isDependentContext()) { 13948 // Finalize the clauses that need pre-built expressions for CodeGen. 13949 for (OMPClause *C : Clauses) { 13950 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 13951 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 13952 B.NumIterations, *this, CurScope, 13953 DSAStack)) 13954 return StmtError(); 13955 } 13956 } 13957 13958 setFunctionHasBranchProtectedScope(); 13959 return OMPTargetTeamsDistributeParallelForDirective::Create( 13960 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B, 13961 DSAStack->getTaskgroupReductionRef(), DSAStack->isCancelRegion()); 13962 } 13963 13964 StmtResult Sema::ActOnOpenMPTargetTeamsDistributeParallelForSimdDirective( 13965 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 13966 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 13967 if (!AStmt) 13968 return StmtError(); 13969 13970 auto *CS = cast<CapturedStmt>(AStmt); 13971 // 1.2.2 OpenMP Language Terminology 13972 // Structured block - An executable statement with a single entry at the 13973 // top and a single exit at the bottom. 13974 // The point of exit cannot be a branch out of the structured block. 13975 // longjmp() and throw() must not violate the entry/exit criteria. 13976 CS->getCapturedDecl()->setNothrow(); 13977 for (int ThisCaptureLevel = getOpenMPCaptureLevels( 13978 OMPD_target_teams_distribute_parallel_for_simd); 13979 ThisCaptureLevel > 1; --ThisCaptureLevel) { 13980 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 13981 // 1.2.2 OpenMP Language Terminology 13982 // Structured block - An executable statement with a single entry at the 13983 // top and a single exit at the bottom. 13984 // The point of exit cannot be a branch out of the structured block. 13985 // longjmp() and throw() must not violate the entry/exit criteria. 13986 CS->getCapturedDecl()->setNothrow(); 13987 } 13988 13989 OMPLoopBasedDirective::HelperExprs B; 13990 // In presence of clause 'collapse' with number of loops, it will 13991 // define the nested loops number. 13992 unsigned NestedLoopCount = 13993 checkOpenMPLoop(OMPD_target_teams_distribute_parallel_for_simd, 13994 getCollapseNumberExpr(Clauses), 13995 nullptr /*ordered not a clause on distribute*/, CS, *this, 13996 *DSAStack, VarsWithImplicitDSA, B); 13997 if (NestedLoopCount == 0) 13998 return StmtError(); 13999 14000 assert((CurContext->isDependentContext() || B.builtAll()) && 14001 "omp target teams distribute parallel for simd loop exprs were not " 14002 "built"); 14003 14004 if (!CurContext->isDependentContext()) { 14005 // Finalize the clauses that need pre-built expressions for CodeGen. 14006 for (OMPClause *C : Clauses) { 14007 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 14008 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 14009 B.NumIterations, *this, CurScope, 14010 DSAStack)) 14011 return StmtError(); 14012 } 14013 } 14014 14015 if (checkSimdlenSafelenSpecified(*this, Clauses)) 14016 return StmtError(); 14017 14018 setFunctionHasBranchProtectedScope(); 14019 return OMPTargetTeamsDistributeParallelForSimdDirective::Create( 14020 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 14021 } 14022 14023 StmtResult Sema::ActOnOpenMPTargetTeamsDistributeSimdDirective( 14024 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 14025 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 14026 if (!AStmt) 14027 return StmtError(); 14028 14029 auto *CS = cast<CapturedStmt>(AStmt); 14030 // 1.2.2 OpenMP Language Terminology 14031 // Structured block - An executable statement with a single entry at the 14032 // top and a single exit at the bottom. 14033 // The point of exit cannot be a branch out of the structured block. 14034 // longjmp() and throw() must not violate the entry/exit criteria. 14035 CS->getCapturedDecl()->setNothrow(); 14036 for (int ThisCaptureLevel = 14037 getOpenMPCaptureLevels(OMPD_target_teams_distribute_simd); 14038 ThisCaptureLevel > 1; --ThisCaptureLevel) { 14039 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 14040 // 1.2.2 OpenMP Language Terminology 14041 // Structured block - An executable statement with a single entry at the 14042 // top and a single exit at the bottom. 14043 // The point of exit cannot be a branch out of the structured block. 14044 // longjmp() and throw() must not violate the entry/exit criteria. 14045 CS->getCapturedDecl()->setNothrow(); 14046 } 14047 14048 OMPLoopBasedDirective::HelperExprs B; 14049 // In presence of clause 'collapse' with number of loops, it will 14050 // define the nested loops number. 14051 unsigned NestedLoopCount = checkOpenMPLoop( 14052 OMPD_target_teams_distribute_simd, getCollapseNumberExpr(Clauses), 14053 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 14054 VarsWithImplicitDSA, B); 14055 if (NestedLoopCount == 0) 14056 return StmtError(); 14057 14058 assert((CurContext->isDependentContext() || B.builtAll()) && 14059 "omp target teams distribute simd loop exprs were not built"); 14060 14061 if (!CurContext->isDependentContext()) { 14062 // Finalize the clauses that need pre-built expressions for CodeGen. 14063 for (OMPClause *C : Clauses) { 14064 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 14065 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 14066 B.NumIterations, *this, CurScope, 14067 DSAStack)) 14068 return StmtError(); 14069 } 14070 } 14071 14072 if (checkSimdlenSafelenSpecified(*this, Clauses)) 14073 return StmtError(); 14074 14075 setFunctionHasBranchProtectedScope(); 14076 return OMPTargetTeamsDistributeSimdDirective::Create( 14077 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 14078 } 14079 14080 bool Sema::checkTransformableLoopNest( 14081 OpenMPDirectiveKind Kind, Stmt *AStmt, int NumLoops, 14082 SmallVectorImpl<OMPLoopBasedDirective::HelperExprs> &LoopHelpers, 14083 Stmt *&Body, 14084 SmallVectorImpl<SmallVector<llvm::PointerUnion<Stmt *, Decl *>, 0>> 14085 &OriginalInits) { 14086 OriginalInits.emplace_back(); 14087 bool Result = OMPLoopBasedDirective::doForAllLoops( 14088 AStmt->IgnoreContainers(), /*TryImperfectlyNestedLoops=*/false, NumLoops, 14089 [this, &LoopHelpers, &Body, &OriginalInits, Kind](unsigned Cnt, 14090 Stmt *CurStmt) { 14091 VarsWithInheritedDSAType TmpDSA; 14092 unsigned SingleNumLoops = 14093 checkOpenMPLoop(Kind, nullptr, nullptr, CurStmt, *this, *DSAStack, 14094 TmpDSA, LoopHelpers[Cnt]); 14095 if (SingleNumLoops == 0) 14096 return true; 14097 assert(SingleNumLoops == 1 && "Expect single loop iteration space"); 14098 if (auto *For = dyn_cast<ForStmt>(CurStmt)) { 14099 OriginalInits.back().push_back(For->getInit()); 14100 Body = For->getBody(); 14101 } else { 14102 assert(isa<CXXForRangeStmt>(CurStmt) && 14103 "Expected canonical for or range-based for loops."); 14104 auto *CXXFor = cast<CXXForRangeStmt>(CurStmt); 14105 OriginalInits.back().push_back(CXXFor->getBeginStmt()); 14106 Body = CXXFor->getBody(); 14107 } 14108 OriginalInits.emplace_back(); 14109 return false; 14110 }, 14111 [&OriginalInits](OMPLoopBasedDirective *Transform) { 14112 Stmt *DependentPreInits; 14113 if (auto *Dir = dyn_cast<OMPTileDirective>(Transform)) 14114 DependentPreInits = Dir->getPreInits(); 14115 else if (auto *Dir = dyn_cast<OMPUnrollDirective>(Transform)) 14116 DependentPreInits = Dir->getPreInits(); 14117 else 14118 llvm_unreachable("Unhandled loop transformation"); 14119 if (!DependentPreInits) 14120 return; 14121 llvm::append_range(OriginalInits.back(), 14122 cast<DeclStmt>(DependentPreInits)->getDeclGroup()); 14123 }); 14124 assert(OriginalInits.back().empty() && "No preinit after innermost loop"); 14125 OriginalInits.pop_back(); 14126 return Result; 14127 } 14128 14129 StmtResult Sema::ActOnOpenMPTileDirective(ArrayRef<OMPClause *> Clauses, 14130 Stmt *AStmt, SourceLocation StartLoc, 14131 SourceLocation EndLoc) { 14132 auto SizesClauses = 14133 OMPExecutableDirective::getClausesOfKind<OMPSizesClause>(Clauses); 14134 if (SizesClauses.empty()) { 14135 // A missing 'sizes' clause is already reported by the parser. 14136 return StmtError(); 14137 } 14138 const OMPSizesClause *SizesClause = *SizesClauses.begin(); 14139 unsigned NumLoops = SizesClause->getNumSizes(); 14140 14141 // Empty statement should only be possible if there already was an error. 14142 if (!AStmt) 14143 return StmtError(); 14144 14145 // Verify and diagnose loop nest. 14146 SmallVector<OMPLoopBasedDirective::HelperExprs, 4> LoopHelpers(NumLoops); 14147 Stmt *Body = nullptr; 14148 SmallVector<SmallVector<llvm::PointerUnion<Stmt *, Decl *>, 0>, 4> 14149 OriginalInits; 14150 if (!checkTransformableLoopNest(OMPD_tile, AStmt, NumLoops, LoopHelpers, Body, 14151 OriginalInits)) 14152 return StmtError(); 14153 14154 // Delay tiling to when template is completely instantiated. 14155 if (CurContext->isDependentContext()) 14156 return OMPTileDirective::Create(Context, StartLoc, EndLoc, Clauses, 14157 NumLoops, AStmt, nullptr, nullptr); 14158 14159 SmallVector<Decl *, 4> PreInits; 14160 14161 // Create iteration variables for the generated loops. 14162 SmallVector<VarDecl *, 4> FloorIndVars; 14163 SmallVector<VarDecl *, 4> TileIndVars; 14164 FloorIndVars.resize(NumLoops); 14165 TileIndVars.resize(NumLoops); 14166 for (unsigned I = 0; I < NumLoops; ++I) { 14167 OMPLoopBasedDirective::HelperExprs &LoopHelper = LoopHelpers[I]; 14168 14169 assert(LoopHelper.Counters.size() == 1 && 14170 "Expect single-dimensional loop iteration space"); 14171 auto *OrigCntVar = cast<DeclRefExpr>(LoopHelper.Counters.front()); 14172 std::string OrigVarName = OrigCntVar->getNameInfo().getAsString(); 14173 DeclRefExpr *IterVarRef = cast<DeclRefExpr>(LoopHelper.IterationVarRef); 14174 QualType CntTy = IterVarRef->getType(); 14175 14176 // Iteration variable for the floor (i.e. outer) loop. 14177 { 14178 std::string FloorCntName = 14179 (Twine(".floor_") + llvm::utostr(I) + ".iv." + OrigVarName).str(); 14180 VarDecl *FloorCntDecl = 14181 buildVarDecl(*this, {}, CntTy, FloorCntName, nullptr, OrigCntVar); 14182 FloorIndVars[I] = FloorCntDecl; 14183 } 14184 14185 // Iteration variable for the tile (i.e. inner) loop. 14186 { 14187 std::string TileCntName = 14188 (Twine(".tile_") + llvm::utostr(I) + ".iv." + OrigVarName).str(); 14189 14190 // Reuse the iteration variable created by checkOpenMPLoop. It is also 14191 // used by the expressions to derive the original iteration variable's 14192 // value from the logical iteration number. 14193 auto *TileCntDecl = cast<VarDecl>(IterVarRef->getDecl()); 14194 TileCntDecl->setDeclName(&PP.getIdentifierTable().get(TileCntName)); 14195 TileIndVars[I] = TileCntDecl; 14196 } 14197 for (auto &P : OriginalInits[I]) { 14198 if (auto *D = P.dyn_cast<Decl *>()) 14199 PreInits.push_back(D); 14200 else if (auto *PI = dyn_cast_or_null<DeclStmt>(P.dyn_cast<Stmt *>())) 14201 PreInits.append(PI->decl_begin(), PI->decl_end()); 14202 } 14203 if (auto *PI = cast_or_null<DeclStmt>(LoopHelper.PreInits)) 14204 PreInits.append(PI->decl_begin(), PI->decl_end()); 14205 // Gather declarations for the data members used as counters. 14206 for (Expr *CounterRef : LoopHelper.Counters) { 14207 auto *CounterDecl = cast<DeclRefExpr>(CounterRef)->getDecl(); 14208 if (isa<OMPCapturedExprDecl>(CounterDecl)) 14209 PreInits.push_back(CounterDecl); 14210 } 14211 } 14212 14213 // Once the original iteration values are set, append the innermost body. 14214 Stmt *Inner = Body; 14215 14216 // Create tile loops from the inside to the outside. 14217 for (int I = NumLoops - 1; I >= 0; --I) { 14218 OMPLoopBasedDirective::HelperExprs &LoopHelper = LoopHelpers[I]; 14219 Expr *NumIterations = LoopHelper.NumIterations; 14220 auto *OrigCntVar = cast<DeclRefExpr>(LoopHelper.Counters[0]); 14221 QualType CntTy = OrigCntVar->getType(); 14222 Expr *DimTileSize = SizesClause->getSizesRefs()[I]; 14223 Scope *CurScope = getCurScope(); 14224 14225 // Commonly used variables. 14226 DeclRefExpr *TileIV = buildDeclRefExpr(*this, TileIndVars[I], CntTy, 14227 OrigCntVar->getExprLoc()); 14228 DeclRefExpr *FloorIV = buildDeclRefExpr(*this, FloorIndVars[I], CntTy, 14229 OrigCntVar->getExprLoc()); 14230 14231 // For init-statement: auto .tile.iv = .floor.iv 14232 AddInitializerToDecl(TileIndVars[I], DefaultLvalueConversion(FloorIV).get(), 14233 /*DirectInit=*/false); 14234 Decl *CounterDecl = TileIndVars[I]; 14235 StmtResult InitStmt = new (Context) 14236 DeclStmt(DeclGroupRef::Create(Context, &CounterDecl, 1), 14237 OrigCntVar->getBeginLoc(), OrigCntVar->getEndLoc()); 14238 if (!InitStmt.isUsable()) 14239 return StmtError(); 14240 14241 // For cond-expression: .tile.iv < min(.floor.iv + DimTileSize, 14242 // NumIterations) 14243 ExprResult EndOfTile = BuildBinOp(CurScope, LoopHelper.Cond->getExprLoc(), 14244 BO_Add, FloorIV, DimTileSize); 14245 if (!EndOfTile.isUsable()) 14246 return StmtError(); 14247 ExprResult IsPartialTile = 14248 BuildBinOp(CurScope, LoopHelper.Cond->getExprLoc(), BO_LT, 14249 NumIterations, EndOfTile.get()); 14250 if (!IsPartialTile.isUsable()) 14251 return StmtError(); 14252 ExprResult MinTileAndIterSpace = ActOnConditionalOp( 14253 LoopHelper.Cond->getBeginLoc(), LoopHelper.Cond->getEndLoc(), 14254 IsPartialTile.get(), NumIterations, EndOfTile.get()); 14255 if (!MinTileAndIterSpace.isUsable()) 14256 return StmtError(); 14257 ExprResult CondExpr = BuildBinOp(CurScope, LoopHelper.Cond->getExprLoc(), 14258 BO_LT, TileIV, MinTileAndIterSpace.get()); 14259 if (!CondExpr.isUsable()) 14260 return StmtError(); 14261 14262 // For incr-statement: ++.tile.iv 14263 ExprResult IncrStmt = 14264 BuildUnaryOp(CurScope, LoopHelper.Inc->getExprLoc(), UO_PreInc, TileIV); 14265 if (!IncrStmt.isUsable()) 14266 return StmtError(); 14267 14268 // Statements to set the original iteration variable's value from the 14269 // logical iteration number. 14270 // Generated for loop is: 14271 // Original_for_init; 14272 // for (auto .tile.iv = .floor.iv; .tile.iv < min(.floor.iv + DimTileSize, 14273 // NumIterations); ++.tile.iv) { 14274 // Original_Body; 14275 // Original_counter_update; 14276 // } 14277 // FIXME: If the innermost body is an loop itself, inserting these 14278 // statements stops it being recognized as a perfectly nested loop (e.g. 14279 // for applying tiling again). If this is the case, sink the expressions 14280 // further into the inner loop. 14281 SmallVector<Stmt *, 4> BodyParts; 14282 BodyParts.append(LoopHelper.Updates.begin(), LoopHelper.Updates.end()); 14283 BodyParts.push_back(Inner); 14284 Inner = CompoundStmt::Create(Context, BodyParts, Inner->getBeginLoc(), 14285 Inner->getEndLoc()); 14286 Inner = new (Context) 14287 ForStmt(Context, InitStmt.get(), CondExpr.get(), nullptr, 14288 IncrStmt.get(), Inner, LoopHelper.Init->getBeginLoc(), 14289 LoopHelper.Init->getBeginLoc(), LoopHelper.Inc->getEndLoc()); 14290 } 14291 14292 // Create floor loops from the inside to the outside. 14293 for (int I = NumLoops - 1; I >= 0; --I) { 14294 auto &LoopHelper = LoopHelpers[I]; 14295 Expr *NumIterations = LoopHelper.NumIterations; 14296 DeclRefExpr *OrigCntVar = cast<DeclRefExpr>(LoopHelper.Counters[0]); 14297 QualType CntTy = OrigCntVar->getType(); 14298 Expr *DimTileSize = SizesClause->getSizesRefs()[I]; 14299 Scope *CurScope = getCurScope(); 14300 14301 // Commonly used variables. 14302 DeclRefExpr *FloorIV = buildDeclRefExpr(*this, FloorIndVars[I], CntTy, 14303 OrigCntVar->getExprLoc()); 14304 14305 // For init-statement: auto .floor.iv = 0 14306 AddInitializerToDecl( 14307 FloorIndVars[I], 14308 ActOnIntegerConstant(LoopHelper.Init->getExprLoc(), 0).get(), 14309 /*DirectInit=*/false); 14310 Decl *CounterDecl = FloorIndVars[I]; 14311 StmtResult InitStmt = new (Context) 14312 DeclStmt(DeclGroupRef::Create(Context, &CounterDecl, 1), 14313 OrigCntVar->getBeginLoc(), OrigCntVar->getEndLoc()); 14314 if (!InitStmt.isUsable()) 14315 return StmtError(); 14316 14317 // For cond-expression: .floor.iv < NumIterations 14318 ExprResult CondExpr = BuildBinOp(CurScope, LoopHelper.Cond->getExprLoc(), 14319 BO_LT, FloorIV, NumIterations); 14320 if (!CondExpr.isUsable()) 14321 return StmtError(); 14322 14323 // For incr-statement: .floor.iv += DimTileSize 14324 ExprResult IncrStmt = BuildBinOp(CurScope, LoopHelper.Inc->getExprLoc(), 14325 BO_AddAssign, FloorIV, DimTileSize); 14326 if (!IncrStmt.isUsable()) 14327 return StmtError(); 14328 14329 Inner = new (Context) 14330 ForStmt(Context, InitStmt.get(), CondExpr.get(), nullptr, 14331 IncrStmt.get(), Inner, LoopHelper.Init->getBeginLoc(), 14332 LoopHelper.Init->getBeginLoc(), LoopHelper.Inc->getEndLoc()); 14333 } 14334 14335 return OMPTileDirective::Create(Context, StartLoc, EndLoc, Clauses, NumLoops, 14336 AStmt, Inner, 14337 buildPreInits(Context, PreInits)); 14338 } 14339 14340 StmtResult Sema::ActOnOpenMPUnrollDirective(ArrayRef<OMPClause *> Clauses, 14341 Stmt *AStmt, 14342 SourceLocation StartLoc, 14343 SourceLocation EndLoc) { 14344 // Empty statement should only be possible if there already was an error. 14345 if (!AStmt) 14346 return StmtError(); 14347 14348 if (checkMutuallyExclusiveClauses(*this, Clauses, {OMPC_partial, OMPC_full})) 14349 return StmtError(); 14350 14351 const OMPFullClause *FullClause = 14352 OMPExecutableDirective::getSingleClause<OMPFullClause>(Clauses); 14353 const OMPPartialClause *PartialClause = 14354 OMPExecutableDirective::getSingleClause<OMPPartialClause>(Clauses); 14355 assert(!(FullClause && PartialClause) && 14356 "mutual exclusivity must have been checked before"); 14357 14358 constexpr unsigned NumLoops = 1; 14359 Stmt *Body = nullptr; 14360 SmallVector<OMPLoopBasedDirective::HelperExprs, NumLoops> LoopHelpers( 14361 NumLoops); 14362 SmallVector<SmallVector<llvm::PointerUnion<Stmt *, Decl *>, 0>, NumLoops + 1> 14363 OriginalInits; 14364 if (!checkTransformableLoopNest(OMPD_unroll, AStmt, NumLoops, LoopHelpers, 14365 Body, OriginalInits)) 14366 return StmtError(); 14367 14368 unsigned NumGeneratedLoops = PartialClause ? 1 : 0; 14369 14370 // Delay unrolling to when template is completely instantiated. 14371 if (CurContext->isDependentContext()) 14372 return OMPUnrollDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt, 14373 NumGeneratedLoops, nullptr, nullptr); 14374 14375 OMPLoopBasedDirective::HelperExprs &LoopHelper = LoopHelpers.front(); 14376 14377 if (FullClause) { 14378 if (!VerifyPositiveIntegerConstantInClause( 14379 LoopHelper.NumIterations, OMPC_full, /*StrictlyPositive=*/false, 14380 /*SuppressExprDiags=*/true) 14381 .isUsable()) { 14382 Diag(AStmt->getBeginLoc(), diag::err_omp_unroll_full_variable_trip_count); 14383 Diag(FullClause->getBeginLoc(), diag::note_omp_directive_here) 14384 << "#pragma omp unroll full"; 14385 return StmtError(); 14386 } 14387 } 14388 14389 // The generated loop may only be passed to other loop-associated directive 14390 // when a partial clause is specified. Without the requirement it is 14391 // sufficient to generate loop unroll metadata at code-generation. 14392 if (NumGeneratedLoops == 0) 14393 return OMPUnrollDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt, 14394 NumGeneratedLoops, nullptr, nullptr); 14395 14396 // Otherwise, we need to provide a de-sugared/transformed AST that can be 14397 // associated with another loop directive. 14398 // 14399 // The canonical loop analysis return by checkTransformableLoopNest assumes 14400 // the following structure to be the same loop without transformations or 14401 // directives applied: \code OriginalInits; LoopHelper.PreInits; 14402 // LoopHelper.Counters; 14403 // for (; IV < LoopHelper.NumIterations; ++IV) { 14404 // LoopHelper.Updates; 14405 // Body; 14406 // } 14407 // \endcode 14408 // where IV is a variable declared and initialized to 0 in LoopHelper.PreInits 14409 // and referenced by LoopHelper.IterationVarRef. 14410 // 14411 // The unrolling directive transforms this into the following loop: 14412 // \code 14413 // OriginalInits; \ 14414 // LoopHelper.PreInits; > NewPreInits 14415 // LoopHelper.Counters; / 14416 // for (auto UIV = 0; UIV < LoopHelper.NumIterations; UIV+=Factor) { 14417 // #pragma clang loop unroll_count(Factor) 14418 // for (IV = UIV; IV < UIV + Factor && UIV < LoopHelper.NumIterations; ++IV) 14419 // { 14420 // LoopHelper.Updates; 14421 // Body; 14422 // } 14423 // } 14424 // \endcode 14425 // where UIV is a new logical iteration counter. IV must be the same VarDecl 14426 // as the original LoopHelper.IterationVarRef because LoopHelper.Updates 14427 // references it. If the partially unrolled loop is associated with another 14428 // loop directive (like an OMPForDirective), it will use checkOpenMPLoop to 14429 // analyze this loop, i.e. the outer loop must fulfill the constraints of an 14430 // OpenMP canonical loop. The inner loop is not an associable canonical loop 14431 // and only exists to defer its unrolling to LLVM's LoopUnroll instead of 14432 // doing it in the frontend (by adding loop metadata). NewPreInits becomes a 14433 // property of the OMPLoopBasedDirective instead of statements in 14434 // CompoundStatement. This is to allow the loop to become a non-outermost loop 14435 // of a canonical loop nest where these PreInits are emitted before the 14436 // outermost directive. 14437 14438 // Determine the PreInit declarations. 14439 SmallVector<Decl *, 4> PreInits; 14440 assert(OriginalInits.size() == 1 && 14441 "Expecting a single-dimensional loop iteration space"); 14442 for (auto &P : OriginalInits[0]) { 14443 if (auto *D = P.dyn_cast<Decl *>()) 14444 PreInits.push_back(D); 14445 else if (auto *PI = dyn_cast_or_null<DeclStmt>(P.dyn_cast<Stmt *>())) 14446 PreInits.append(PI->decl_begin(), PI->decl_end()); 14447 } 14448 if (auto *PI = cast_or_null<DeclStmt>(LoopHelper.PreInits)) 14449 PreInits.append(PI->decl_begin(), PI->decl_end()); 14450 // Gather declarations for the data members used as counters. 14451 for (Expr *CounterRef : LoopHelper.Counters) { 14452 auto *CounterDecl = cast<DeclRefExpr>(CounterRef)->getDecl(); 14453 if (isa<OMPCapturedExprDecl>(CounterDecl)) 14454 PreInits.push_back(CounterDecl); 14455 } 14456 14457 auto *IterationVarRef = cast<DeclRefExpr>(LoopHelper.IterationVarRef); 14458 QualType IVTy = IterationVarRef->getType(); 14459 assert(LoopHelper.Counters.size() == 1 && 14460 "Expecting a single-dimensional loop iteration space"); 14461 auto *OrigVar = cast<DeclRefExpr>(LoopHelper.Counters.front()); 14462 14463 // Determine the unroll factor. 14464 uint64_t Factor; 14465 SourceLocation FactorLoc; 14466 if (Expr *FactorVal = PartialClause->getFactor()) { 14467 Factor = FactorVal->getIntegerConstantExpr(Context)->getZExtValue(); 14468 FactorLoc = FactorVal->getExprLoc(); 14469 } else { 14470 // TODO: Use a better profitability model. 14471 Factor = 2; 14472 } 14473 assert(Factor > 0 && "Expected positive unroll factor"); 14474 auto MakeFactorExpr = [this, Factor, IVTy, FactorLoc]() { 14475 return IntegerLiteral::Create( 14476 Context, llvm::APInt(Context.getIntWidth(IVTy), Factor), IVTy, 14477 FactorLoc); 14478 }; 14479 14480 // Iteration variable SourceLocations. 14481 SourceLocation OrigVarLoc = OrigVar->getExprLoc(); 14482 SourceLocation OrigVarLocBegin = OrigVar->getBeginLoc(); 14483 SourceLocation OrigVarLocEnd = OrigVar->getEndLoc(); 14484 14485 // Internal variable names. 14486 std::string OrigVarName = OrigVar->getNameInfo().getAsString(); 14487 std::string OuterIVName = (Twine(".unrolled.iv.") + OrigVarName).str(); 14488 std::string InnerIVName = (Twine(".unroll_inner.iv.") + OrigVarName).str(); 14489 std::string InnerTripCountName = 14490 (Twine(".unroll_inner.tripcount.") + OrigVarName).str(); 14491 14492 // Create the iteration variable for the unrolled loop. 14493 VarDecl *OuterIVDecl = 14494 buildVarDecl(*this, {}, IVTy, OuterIVName, nullptr, OrigVar); 14495 auto MakeOuterRef = [this, OuterIVDecl, IVTy, OrigVarLoc]() { 14496 return buildDeclRefExpr(*this, OuterIVDecl, IVTy, OrigVarLoc); 14497 }; 14498 14499 // Iteration variable for the inner loop: Reuse the iteration variable created 14500 // by checkOpenMPLoop. 14501 auto *InnerIVDecl = cast<VarDecl>(IterationVarRef->getDecl()); 14502 InnerIVDecl->setDeclName(&PP.getIdentifierTable().get(InnerIVName)); 14503 auto MakeInnerRef = [this, InnerIVDecl, IVTy, OrigVarLoc]() { 14504 return buildDeclRefExpr(*this, InnerIVDecl, IVTy, OrigVarLoc); 14505 }; 14506 14507 // Make a copy of the NumIterations expression for each use: By the AST 14508 // constraints, every expression object in a DeclContext must be unique. 14509 CaptureVars CopyTransformer(*this); 14510 auto MakeNumIterations = [&CopyTransformer, &LoopHelper]() -> Expr * { 14511 return AssertSuccess( 14512 CopyTransformer.TransformExpr(LoopHelper.NumIterations)); 14513 }; 14514 14515 // Inner For init-statement: auto .unroll_inner.iv = .unrolled.iv 14516 ExprResult LValueConv = DefaultLvalueConversion(MakeOuterRef()); 14517 AddInitializerToDecl(InnerIVDecl, LValueConv.get(), /*DirectInit=*/false); 14518 StmtResult InnerInit = new (Context) 14519 DeclStmt(DeclGroupRef(InnerIVDecl), OrigVarLocBegin, OrigVarLocEnd); 14520 if (!InnerInit.isUsable()) 14521 return StmtError(); 14522 14523 // Inner For cond-expression: 14524 // \code 14525 // .unroll_inner.iv < .unrolled.iv + Factor && 14526 // .unroll_inner.iv < NumIterations 14527 // \endcode 14528 // This conjunction of two conditions allows ScalarEvolution to derive the 14529 // maximum trip count of the inner loop. 14530 ExprResult EndOfTile = BuildBinOp(CurScope, LoopHelper.Cond->getExprLoc(), 14531 BO_Add, MakeOuterRef(), MakeFactorExpr()); 14532 if (!EndOfTile.isUsable()) 14533 return StmtError(); 14534 ExprResult InnerCond1 = BuildBinOp(CurScope, LoopHelper.Cond->getExprLoc(), 14535 BO_LT, MakeInnerRef(), EndOfTile.get()); 14536 if (!InnerCond1.isUsable()) 14537 return StmtError(); 14538 ExprResult InnerCond2 = 14539 BuildBinOp(CurScope, LoopHelper.Cond->getExprLoc(), BO_LT, MakeInnerRef(), 14540 MakeNumIterations()); 14541 if (!InnerCond2.isUsable()) 14542 return StmtError(); 14543 ExprResult InnerCond = 14544 BuildBinOp(CurScope, LoopHelper.Cond->getExprLoc(), BO_LAnd, 14545 InnerCond1.get(), InnerCond2.get()); 14546 if (!InnerCond.isUsable()) 14547 return StmtError(); 14548 14549 // Inner For incr-statement: ++.unroll_inner.iv 14550 ExprResult InnerIncr = BuildUnaryOp(CurScope, LoopHelper.Inc->getExprLoc(), 14551 UO_PreInc, MakeInnerRef()); 14552 if (!InnerIncr.isUsable()) 14553 return StmtError(); 14554 14555 // Inner For statement. 14556 SmallVector<Stmt *> InnerBodyStmts; 14557 InnerBodyStmts.append(LoopHelper.Updates.begin(), LoopHelper.Updates.end()); 14558 InnerBodyStmts.push_back(Body); 14559 CompoundStmt *InnerBody = CompoundStmt::Create( 14560 Context, InnerBodyStmts, Body->getBeginLoc(), Body->getEndLoc()); 14561 ForStmt *InnerFor = new (Context) 14562 ForStmt(Context, InnerInit.get(), InnerCond.get(), nullptr, 14563 InnerIncr.get(), InnerBody, LoopHelper.Init->getBeginLoc(), 14564 LoopHelper.Init->getBeginLoc(), LoopHelper.Inc->getEndLoc()); 14565 14566 // Unroll metadata for the inner loop. 14567 // This needs to take into account the remainder portion of the unrolled loop, 14568 // hence `unroll(full)` does not apply here, even though the LoopUnroll pass 14569 // supports multiple loop exits. Instead, unroll using a factor equivalent to 14570 // the maximum trip count, which will also generate a remainder loop. Just 14571 // `unroll(enable)` (which could have been useful if the user has not 14572 // specified a concrete factor; even though the outer loop cannot be 14573 // influenced anymore, would avoid more code bloat than necessary) will refuse 14574 // the loop because "Won't unroll; remainder loop could not be generated when 14575 // assuming runtime trip count". Even if it did work, it must not choose a 14576 // larger unroll factor than the maximum loop length, or it would always just 14577 // execute the remainder loop. 14578 LoopHintAttr *UnrollHintAttr = 14579 LoopHintAttr::CreateImplicit(Context, LoopHintAttr::UnrollCount, 14580 LoopHintAttr::Numeric, MakeFactorExpr()); 14581 AttributedStmt *InnerUnrolled = 14582 AttributedStmt::Create(Context, StartLoc, {UnrollHintAttr}, InnerFor); 14583 14584 // Outer For init-statement: auto .unrolled.iv = 0 14585 AddInitializerToDecl( 14586 OuterIVDecl, ActOnIntegerConstant(LoopHelper.Init->getExprLoc(), 0).get(), 14587 /*DirectInit=*/false); 14588 StmtResult OuterInit = new (Context) 14589 DeclStmt(DeclGroupRef(OuterIVDecl), OrigVarLocBegin, OrigVarLocEnd); 14590 if (!OuterInit.isUsable()) 14591 return StmtError(); 14592 14593 // Outer For cond-expression: .unrolled.iv < NumIterations 14594 ExprResult OuterConde = 14595 BuildBinOp(CurScope, LoopHelper.Cond->getExprLoc(), BO_LT, MakeOuterRef(), 14596 MakeNumIterations()); 14597 if (!OuterConde.isUsable()) 14598 return StmtError(); 14599 14600 // Outer For incr-statement: .unrolled.iv += Factor 14601 ExprResult OuterIncr = 14602 BuildBinOp(CurScope, LoopHelper.Inc->getExprLoc(), BO_AddAssign, 14603 MakeOuterRef(), MakeFactorExpr()); 14604 if (!OuterIncr.isUsable()) 14605 return StmtError(); 14606 14607 // Outer For statement. 14608 ForStmt *OuterFor = new (Context) 14609 ForStmt(Context, OuterInit.get(), OuterConde.get(), nullptr, 14610 OuterIncr.get(), InnerUnrolled, LoopHelper.Init->getBeginLoc(), 14611 LoopHelper.Init->getBeginLoc(), LoopHelper.Inc->getEndLoc()); 14612 14613 return OMPUnrollDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt, 14614 NumGeneratedLoops, OuterFor, 14615 buildPreInits(Context, PreInits)); 14616 } 14617 14618 OMPClause *Sema::ActOnOpenMPSingleExprClause(OpenMPClauseKind Kind, Expr *Expr, 14619 SourceLocation StartLoc, 14620 SourceLocation LParenLoc, 14621 SourceLocation EndLoc) { 14622 OMPClause *Res = nullptr; 14623 switch (Kind) { 14624 case OMPC_final: 14625 Res = ActOnOpenMPFinalClause(Expr, StartLoc, LParenLoc, EndLoc); 14626 break; 14627 case OMPC_num_threads: 14628 Res = ActOnOpenMPNumThreadsClause(Expr, StartLoc, LParenLoc, EndLoc); 14629 break; 14630 case OMPC_safelen: 14631 Res = ActOnOpenMPSafelenClause(Expr, StartLoc, LParenLoc, EndLoc); 14632 break; 14633 case OMPC_simdlen: 14634 Res = ActOnOpenMPSimdlenClause(Expr, StartLoc, LParenLoc, EndLoc); 14635 break; 14636 case OMPC_allocator: 14637 Res = ActOnOpenMPAllocatorClause(Expr, StartLoc, LParenLoc, EndLoc); 14638 break; 14639 case OMPC_collapse: 14640 Res = ActOnOpenMPCollapseClause(Expr, StartLoc, LParenLoc, EndLoc); 14641 break; 14642 case OMPC_ordered: 14643 Res = ActOnOpenMPOrderedClause(StartLoc, EndLoc, LParenLoc, Expr); 14644 break; 14645 case OMPC_num_teams: 14646 Res = ActOnOpenMPNumTeamsClause(Expr, StartLoc, LParenLoc, EndLoc); 14647 break; 14648 case OMPC_thread_limit: 14649 Res = ActOnOpenMPThreadLimitClause(Expr, StartLoc, LParenLoc, EndLoc); 14650 break; 14651 case OMPC_priority: 14652 Res = ActOnOpenMPPriorityClause(Expr, StartLoc, LParenLoc, EndLoc); 14653 break; 14654 case OMPC_grainsize: 14655 Res = ActOnOpenMPGrainsizeClause(Expr, StartLoc, LParenLoc, EndLoc); 14656 break; 14657 case OMPC_num_tasks: 14658 Res = ActOnOpenMPNumTasksClause(Expr, StartLoc, LParenLoc, EndLoc); 14659 break; 14660 case OMPC_hint: 14661 Res = ActOnOpenMPHintClause(Expr, StartLoc, LParenLoc, EndLoc); 14662 break; 14663 case OMPC_depobj: 14664 Res = ActOnOpenMPDepobjClause(Expr, StartLoc, LParenLoc, EndLoc); 14665 break; 14666 case OMPC_detach: 14667 Res = ActOnOpenMPDetachClause(Expr, StartLoc, LParenLoc, EndLoc); 14668 break; 14669 case OMPC_novariants: 14670 Res = ActOnOpenMPNovariantsClause(Expr, StartLoc, LParenLoc, EndLoc); 14671 break; 14672 case OMPC_nocontext: 14673 Res = ActOnOpenMPNocontextClause(Expr, StartLoc, LParenLoc, EndLoc); 14674 break; 14675 case OMPC_filter: 14676 Res = ActOnOpenMPFilterClause(Expr, StartLoc, LParenLoc, EndLoc); 14677 break; 14678 case OMPC_partial: 14679 Res = ActOnOpenMPPartialClause(Expr, StartLoc, LParenLoc, EndLoc); 14680 break; 14681 case OMPC_align: 14682 Res = ActOnOpenMPAlignClause(Expr, StartLoc, LParenLoc, EndLoc); 14683 break; 14684 case OMPC_device: 14685 case OMPC_if: 14686 case OMPC_default: 14687 case OMPC_proc_bind: 14688 case OMPC_schedule: 14689 case OMPC_private: 14690 case OMPC_firstprivate: 14691 case OMPC_lastprivate: 14692 case OMPC_shared: 14693 case OMPC_reduction: 14694 case OMPC_task_reduction: 14695 case OMPC_in_reduction: 14696 case OMPC_linear: 14697 case OMPC_aligned: 14698 case OMPC_copyin: 14699 case OMPC_copyprivate: 14700 case OMPC_nowait: 14701 case OMPC_untied: 14702 case OMPC_mergeable: 14703 case OMPC_threadprivate: 14704 case OMPC_sizes: 14705 case OMPC_allocate: 14706 case OMPC_flush: 14707 case OMPC_read: 14708 case OMPC_write: 14709 case OMPC_update: 14710 case OMPC_capture: 14711 case OMPC_compare: 14712 case OMPC_seq_cst: 14713 case OMPC_acq_rel: 14714 case OMPC_acquire: 14715 case OMPC_release: 14716 case OMPC_relaxed: 14717 case OMPC_depend: 14718 case OMPC_threads: 14719 case OMPC_simd: 14720 case OMPC_map: 14721 case OMPC_nogroup: 14722 case OMPC_dist_schedule: 14723 case OMPC_defaultmap: 14724 case OMPC_unknown: 14725 case OMPC_uniform: 14726 case OMPC_to: 14727 case OMPC_from: 14728 case OMPC_use_device_ptr: 14729 case OMPC_use_device_addr: 14730 case OMPC_is_device_ptr: 14731 case OMPC_unified_address: 14732 case OMPC_unified_shared_memory: 14733 case OMPC_reverse_offload: 14734 case OMPC_dynamic_allocators: 14735 case OMPC_atomic_default_mem_order: 14736 case OMPC_device_type: 14737 case OMPC_match: 14738 case OMPC_nontemporal: 14739 case OMPC_order: 14740 case OMPC_destroy: 14741 case OMPC_inclusive: 14742 case OMPC_exclusive: 14743 case OMPC_uses_allocators: 14744 case OMPC_affinity: 14745 case OMPC_when: 14746 case OMPC_bind: 14747 default: 14748 llvm_unreachable("Clause is not allowed."); 14749 } 14750 return Res; 14751 } 14752 14753 // An OpenMP directive such as 'target parallel' has two captured regions: 14754 // for the 'target' and 'parallel' respectively. This function returns 14755 // the region in which to capture expressions associated with a clause. 14756 // A return value of OMPD_unknown signifies that the expression should not 14757 // be captured. 14758 static OpenMPDirectiveKind getOpenMPCaptureRegionForClause( 14759 OpenMPDirectiveKind DKind, OpenMPClauseKind CKind, unsigned OpenMPVersion, 14760 OpenMPDirectiveKind NameModifier = OMPD_unknown) { 14761 OpenMPDirectiveKind CaptureRegion = OMPD_unknown; 14762 switch (CKind) { 14763 case OMPC_if: 14764 switch (DKind) { 14765 case OMPD_target_parallel_for_simd: 14766 if (OpenMPVersion >= 50 && 14767 (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)) { 14768 CaptureRegion = OMPD_parallel; 14769 break; 14770 } 14771 LLVM_FALLTHROUGH; 14772 case OMPD_target_parallel: 14773 case OMPD_target_parallel_for: 14774 case OMPD_target_parallel_loop: 14775 // If this clause applies to the nested 'parallel' region, capture within 14776 // the 'target' region, otherwise do not capture. 14777 if (NameModifier == OMPD_unknown || NameModifier == OMPD_parallel) 14778 CaptureRegion = OMPD_target; 14779 break; 14780 case OMPD_target_teams_distribute_parallel_for_simd: 14781 if (OpenMPVersion >= 50 && 14782 (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)) { 14783 CaptureRegion = OMPD_parallel; 14784 break; 14785 } 14786 LLVM_FALLTHROUGH; 14787 case OMPD_target_teams_distribute_parallel_for: 14788 // If this clause applies to the nested 'parallel' region, capture within 14789 // the 'teams' region, otherwise do not capture. 14790 if (NameModifier == OMPD_unknown || NameModifier == OMPD_parallel) 14791 CaptureRegion = OMPD_teams; 14792 break; 14793 case OMPD_teams_distribute_parallel_for_simd: 14794 if (OpenMPVersion >= 50 && 14795 (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)) { 14796 CaptureRegion = OMPD_parallel; 14797 break; 14798 } 14799 LLVM_FALLTHROUGH; 14800 case OMPD_teams_distribute_parallel_for: 14801 CaptureRegion = OMPD_teams; 14802 break; 14803 case OMPD_target_update: 14804 case OMPD_target_enter_data: 14805 case OMPD_target_exit_data: 14806 CaptureRegion = OMPD_task; 14807 break; 14808 case OMPD_parallel_master_taskloop: 14809 if (NameModifier == OMPD_unknown || NameModifier == OMPD_taskloop) 14810 CaptureRegion = OMPD_parallel; 14811 break; 14812 case OMPD_parallel_master_taskloop_simd: 14813 if ((OpenMPVersion <= 45 && NameModifier == OMPD_unknown) || 14814 NameModifier == OMPD_taskloop) { 14815 CaptureRegion = OMPD_parallel; 14816 break; 14817 } 14818 if (OpenMPVersion <= 45) 14819 break; 14820 if (NameModifier == OMPD_unknown || NameModifier == OMPD_simd) 14821 CaptureRegion = OMPD_taskloop; 14822 break; 14823 case OMPD_parallel_for_simd: 14824 if (OpenMPVersion <= 45) 14825 break; 14826 if (NameModifier == OMPD_unknown || NameModifier == OMPD_simd) 14827 CaptureRegion = OMPD_parallel; 14828 break; 14829 case OMPD_taskloop_simd: 14830 case OMPD_master_taskloop_simd: 14831 if (OpenMPVersion <= 45) 14832 break; 14833 if (NameModifier == OMPD_unknown || NameModifier == OMPD_simd) 14834 CaptureRegion = OMPD_taskloop; 14835 break; 14836 case OMPD_distribute_parallel_for_simd: 14837 if (OpenMPVersion <= 45) 14838 break; 14839 if (NameModifier == OMPD_unknown || NameModifier == OMPD_simd) 14840 CaptureRegion = OMPD_parallel; 14841 break; 14842 case OMPD_target_simd: 14843 if (OpenMPVersion >= 50 && 14844 (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)) 14845 CaptureRegion = OMPD_target; 14846 break; 14847 case OMPD_teams_distribute_simd: 14848 case OMPD_target_teams_distribute_simd: 14849 if (OpenMPVersion >= 50 && 14850 (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)) 14851 CaptureRegion = OMPD_teams; 14852 break; 14853 case OMPD_cancel: 14854 case OMPD_parallel: 14855 case OMPD_parallel_master: 14856 case OMPD_parallel_masked: 14857 case OMPD_parallel_sections: 14858 case OMPD_parallel_for: 14859 case OMPD_parallel_loop: 14860 case OMPD_target: 14861 case OMPD_target_teams: 14862 case OMPD_target_teams_distribute: 14863 case OMPD_target_teams_loop: 14864 case OMPD_distribute_parallel_for: 14865 case OMPD_task: 14866 case OMPD_taskloop: 14867 case OMPD_master_taskloop: 14868 case OMPD_target_data: 14869 case OMPD_simd: 14870 case OMPD_for_simd: 14871 case OMPD_distribute_simd: 14872 // Do not capture if-clause expressions. 14873 break; 14874 case OMPD_threadprivate: 14875 case OMPD_allocate: 14876 case OMPD_taskyield: 14877 case OMPD_barrier: 14878 case OMPD_taskwait: 14879 case OMPD_cancellation_point: 14880 case OMPD_flush: 14881 case OMPD_depobj: 14882 case OMPD_scan: 14883 case OMPD_declare_reduction: 14884 case OMPD_declare_mapper: 14885 case OMPD_declare_simd: 14886 case OMPD_declare_variant: 14887 case OMPD_begin_declare_variant: 14888 case OMPD_end_declare_variant: 14889 case OMPD_declare_target: 14890 case OMPD_end_declare_target: 14891 case OMPD_loop: 14892 case OMPD_teams_loop: 14893 case OMPD_teams: 14894 case OMPD_tile: 14895 case OMPD_unroll: 14896 case OMPD_for: 14897 case OMPD_sections: 14898 case OMPD_section: 14899 case OMPD_single: 14900 case OMPD_master: 14901 case OMPD_masked: 14902 case OMPD_critical: 14903 case OMPD_taskgroup: 14904 case OMPD_distribute: 14905 case OMPD_ordered: 14906 case OMPD_atomic: 14907 case OMPD_teams_distribute: 14908 case OMPD_requires: 14909 case OMPD_metadirective: 14910 llvm_unreachable("Unexpected OpenMP directive with if-clause"); 14911 case OMPD_unknown: 14912 default: 14913 llvm_unreachable("Unknown OpenMP directive"); 14914 } 14915 break; 14916 case OMPC_num_threads: 14917 switch (DKind) { 14918 case OMPD_target_parallel: 14919 case OMPD_target_parallel_for: 14920 case OMPD_target_parallel_for_simd: 14921 case OMPD_target_parallel_loop: 14922 CaptureRegion = OMPD_target; 14923 break; 14924 case OMPD_teams_distribute_parallel_for: 14925 case OMPD_teams_distribute_parallel_for_simd: 14926 case OMPD_target_teams_distribute_parallel_for: 14927 case OMPD_target_teams_distribute_parallel_for_simd: 14928 CaptureRegion = OMPD_teams; 14929 break; 14930 case OMPD_parallel: 14931 case OMPD_parallel_master: 14932 case OMPD_parallel_masked: 14933 case OMPD_parallel_sections: 14934 case OMPD_parallel_for: 14935 case OMPD_parallel_for_simd: 14936 case OMPD_parallel_loop: 14937 case OMPD_distribute_parallel_for: 14938 case OMPD_distribute_parallel_for_simd: 14939 case OMPD_parallel_master_taskloop: 14940 case OMPD_parallel_master_taskloop_simd: 14941 // Do not capture num_threads-clause expressions. 14942 break; 14943 case OMPD_target_data: 14944 case OMPD_target_enter_data: 14945 case OMPD_target_exit_data: 14946 case OMPD_target_update: 14947 case OMPD_target: 14948 case OMPD_target_simd: 14949 case OMPD_target_teams: 14950 case OMPD_target_teams_distribute: 14951 case OMPD_target_teams_distribute_simd: 14952 case OMPD_cancel: 14953 case OMPD_task: 14954 case OMPD_taskloop: 14955 case OMPD_taskloop_simd: 14956 case OMPD_master_taskloop: 14957 case OMPD_master_taskloop_simd: 14958 case OMPD_threadprivate: 14959 case OMPD_allocate: 14960 case OMPD_taskyield: 14961 case OMPD_barrier: 14962 case OMPD_taskwait: 14963 case OMPD_cancellation_point: 14964 case OMPD_flush: 14965 case OMPD_depobj: 14966 case OMPD_scan: 14967 case OMPD_declare_reduction: 14968 case OMPD_declare_mapper: 14969 case OMPD_declare_simd: 14970 case OMPD_declare_variant: 14971 case OMPD_begin_declare_variant: 14972 case OMPD_end_declare_variant: 14973 case OMPD_declare_target: 14974 case OMPD_end_declare_target: 14975 case OMPD_loop: 14976 case OMPD_teams_loop: 14977 case OMPD_target_teams_loop: 14978 case OMPD_teams: 14979 case OMPD_simd: 14980 case OMPD_tile: 14981 case OMPD_unroll: 14982 case OMPD_for: 14983 case OMPD_for_simd: 14984 case OMPD_sections: 14985 case OMPD_section: 14986 case OMPD_single: 14987 case OMPD_master: 14988 case OMPD_masked: 14989 case OMPD_critical: 14990 case OMPD_taskgroup: 14991 case OMPD_distribute: 14992 case OMPD_ordered: 14993 case OMPD_atomic: 14994 case OMPD_distribute_simd: 14995 case OMPD_teams_distribute: 14996 case OMPD_teams_distribute_simd: 14997 case OMPD_requires: 14998 case OMPD_metadirective: 14999 llvm_unreachable("Unexpected OpenMP directive with num_threads-clause"); 15000 case OMPD_unknown: 15001 default: 15002 llvm_unreachable("Unknown OpenMP directive"); 15003 } 15004 break; 15005 case OMPC_num_teams: 15006 switch (DKind) { 15007 case OMPD_target_teams: 15008 case OMPD_target_teams_distribute: 15009 case OMPD_target_teams_distribute_simd: 15010 case OMPD_target_teams_distribute_parallel_for: 15011 case OMPD_target_teams_distribute_parallel_for_simd: 15012 case OMPD_target_teams_loop: 15013 CaptureRegion = OMPD_target; 15014 break; 15015 case OMPD_teams_distribute_parallel_for: 15016 case OMPD_teams_distribute_parallel_for_simd: 15017 case OMPD_teams: 15018 case OMPD_teams_distribute: 15019 case OMPD_teams_distribute_simd: 15020 case OMPD_teams_loop: 15021 // Do not capture num_teams-clause expressions. 15022 break; 15023 case OMPD_distribute_parallel_for: 15024 case OMPD_distribute_parallel_for_simd: 15025 case OMPD_task: 15026 case OMPD_taskloop: 15027 case OMPD_taskloop_simd: 15028 case OMPD_master_taskloop: 15029 case OMPD_master_taskloop_simd: 15030 case OMPD_parallel_master_taskloop: 15031 case OMPD_parallel_master_taskloop_simd: 15032 case OMPD_target_data: 15033 case OMPD_target_enter_data: 15034 case OMPD_target_exit_data: 15035 case OMPD_target_update: 15036 case OMPD_cancel: 15037 case OMPD_parallel: 15038 case OMPD_parallel_master: 15039 case OMPD_parallel_masked: 15040 case OMPD_parallel_sections: 15041 case OMPD_parallel_for: 15042 case OMPD_parallel_for_simd: 15043 case OMPD_parallel_loop: 15044 case OMPD_target: 15045 case OMPD_target_simd: 15046 case OMPD_target_parallel: 15047 case OMPD_target_parallel_for: 15048 case OMPD_target_parallel_for_simd: 15049 case OMPD_target_parallel_loop: 15050 case OMPD_threadprivate: 15051 case OMPD_allocate: 15052 case OMPD_taskyield: 15053 case OMPD_barrier: 15054 case OMPD_taskwait: 15055 case OMPD_cancellation_point: 15056 case OMPD_flush: 15057 case OMPD_depobj: 15058 case OMPD_scan: 15059 case OMPD_declare_reduction: 15060 case OMPD_declare_mapper: 15061 case OMPD_declare_simd: 15062 case OMPD_declare_variant: 15063 case OMPD_begin_declare_variant: 15064 case OMPD_end_declare_variant: 15065 case OMPD_declare_target: 15066 case OMPD_end_declare_target: 15067 case OMPD_loop: 15068 case OMPD_simd: 15069 case OMPD_tile: 15070 case OMPD_unroll: 15071 case OMPD_for: 15072 case OMPD_for_simd: 15073 case OMPD_sections: 15074 case OMPD_section: 15075 case OMPD_single: 15076 case OMPD_master: 15077 case OMPD_masked: 15078 case OMPD_critical: 15079 case OMPD_taskgroup: 15080 case OMPD_distribute: 15081 case OMPD_ordered: 15082 case OMPD_atomic: 15083 case OMPD_distribute_simd: 15084 case OMPD_requires: 15085 case OMPD_metadirective: 15086 llvm_unreachable("Unexpected OpenMP directive with num_teams-clause"); 15087 case OMPD_unknown: 15088 default: 15089 llvm_unreachable("Unknown OpenMP directive"); 15090 } 15091 break; 15092 case OMPC_thread_limit: 15093 switch (DKind) { 15094 case OMPD_target_teams: 15095 case OMPD_target_teams_distribute: 15096 case OMPD_target_teams_distribute_simd: 15097 case OMPD_target_teams_distribute_parallel_for: 15098 case OMPD_target_teams_distribute_parallel_for_simd: 15099 case OMPD_target_teams_loop: 15100 CaptureRegion = OMPD_target; 15101 break; 15102 case OMPD_teams_distribute_parallel_for: 15103 case OMPD_teams_distribute_parallel_for_simd: 15104 case OMPD_teams: 15105 case OMPD_teams_distribute: 15106 case OMPD_teams_distribute_simd: 15107 case OMPD_teams_loop: 15108 // Do not capture thread_limit-clause expressions. 15109 break; 15110 case OMPD_distribute_parallel_for: 15111 case OMPD_distribute_parallel_for_simd: 15112 case OMPD_task: 15113 case OMPD_taskloop: 15114 case OMPD_taskloop_simd: 15115 case OMPD_master_taskloop: 15116 case OMPD_master_taskloop_simd: 15117 case OMPD_parallel_master_taskloop: 15118 case OMPD_parallel_master_taskloop_simd: 15119 case OMPD_target_data: 15120 case OMPD_target_enter_data: 15121 case OMPD_target_exit_data: 15122 case OMPD_target_update: 15123 case OMPD_cancel: 15124 case OMPD_parallel: 15125 case OMPD_parallel_master: 15126 case OMPD_parallel_masked: 15127 case OMPD_parallel_sections: 15128 case OMPD_parallel_for: 15129 case OMPD_parallel_for_simd: 15130 case OMPD_parallel_loop: 15131 case OMPD_target: 15132 case OMPD_target_simd: 15133 case OMPD_target_parallel: 15134 case OMPD_target_parallel_for: 15135 case OMPD_target_parallel_for_simd: 15136 case OMPD_target_parallel_loop: 15137 case OMPD_threadprivate: 15138 case OMPD_allocate: 15139 case OMPD_taskyield: 15140 case OMPD_barrier: 15141 case OMPD_taskwait: 15142 case OMPD_cancellation_point: 15143 case OMPD_flush: 15144 case OMPD_depobj: 15145 case OMPD_scan: 15146 case OMPD_declare_reduction: 15147 case OMPD_declare_mapper: 15148 case OMPD_declare_simd: 15149 case OMPD_declare_variant: 15150 case OMPD_begin_declare_variant: 15151 case OMPD_end_declare_variant: 15152 case OMPD_declare_target: 15153 case OMPD_end_declare_target: 15154 case OMPD_loop: 15155 case OMPD_simd: 15156 case OMPD_tile: 15157 case OMPD_unroll: 15158 case OMPD_for: 15159 case OMPD_for_simd: 15160 case OMPD_sections: 15161 case OMPD_section: 15162 case OMPD_single: 15163 case OMPD_master: 15164 case OMPD_masked: 15165 case OMPD_critical: 15166 case OMPD_taskgroup: 15167 case OMPD_distribute: 15168 case OMPD_ordered: 15169 case OMPD_atomic: 15170 case OMPD_distribute_simd: 15171 case OMPD_requires: 15172 case OMPD_metadirective: 15173 llvm_unreachable("Unexpected OpenMP directive with thread_limit-clause"); 15174 case OMPD_unknown: 15175 default: 15176 llvm_unreachable("Unknown OpenMP directive"); 15177 } 15178 break; 15179 case OMPC_schedule: 15180 switch (DKind) { 15181 case OMPD_parallel_for: 15182 case OMPD_parallel_for_simd: 15183 case OMPD_distribute_parallel_for: 15184 case OMPD_distribute_parallel_for_simd: 15185 case OMPD_teams_distribute_parallel_for: 15186 case OMPD_teams_distribute_parallel_for_simd: 15187 case OMPD_target_parallel_for: 15188 case OMPD_target_parallel_for_simd: 15189 case OMPD_target_teams_distribute_parallel_for: 15190 case OMPD_target_teams_distribute_parallel_for_simd: 15191 CaptureRegion = OMPD_parallel; 15192 break; 15193 case OMPD_for: 15194 case OMPD_for_simd: 15195 // Do not capture schedule-clause expressions. 15196 break; 15197 case OMPD_task: 15198 case OMPD_taskloop: 15199 case OMPD_taskloop_simd: 15200 case OMPD_master_taskloop: 15201 case OMPD_master_taskloop_simd: 15202 case OMPD_parallel_master_taskloop: 15203 case OMPD_parallel_master_taskloop_simd: 15204 case OMPD_target_data: 15205 case OMPD_target_enter_data: 15206 case OMPD_target_exit_data: 15207 case OMPD_target_update: 15208 case OMPD_teams: 15209 case OMPD_teams_distribute: 15210 case OMPD_teams_distribute_simd: 15211 case OMPD_target_teams_distribute: 15212 case OMPD_target_teams_distribute_simd: 15213 case OMPD_target: 15214 case OMPD_target_simd: 15215 case OMPD_target_parallel: 15216 case OMPD_cancel: 15217 case OMPD_parallel: 15218 case OMPD_parallel_master: 15219 case OMPD_parallel_masked: 15220 case OMPD_parallel_sections: 15221 case OMPD_threadprivate: 15222 case OMPD_allocate: 15223 case OMPD_taskyield: 15224 case OMPD_barrier: 15225 case OMPD_taskwait: 15226 case OMPD_cancellation_point: 15227 case OMPD_flush: 15228 case OMPD_depobj: 15229 case OMPD_scan: 15230 case OMPD_declare_reduction: 15231 case OMPD_declare_mapper: 15232 case OMPD_declare_simd: 15233 case OMPD_declare_variant: 15234 case OMPD_begin_declare_variant: 15235 case OMPD_end_declare_variant: 15236 case OMPD_declare_target: 15237 case OMPD_end_declare_target: 15238 case OMPD_loop: 15239 case OMPD_teams_loop: 15240 case OMPD_target_teams_loop: 15241 case OMPD_parallel_loop: 15242 case OMPD_target_parallel_loop: 15243 case OMPD_simd: 15244 case OMPD_tile: 15245 case OMPD_unroll: 15246 case OMPD_sections: 15247 case OMPD_section: 15248 case OMPD_single: 15249 case OMPD_master: 15250 case OMPD_masked: 15251 case OMPD_critical: 15252 case OMPD_taskgroup: 15253 case OMPD_distribute: 15254 case OMPD_ordered: 15255 case OMPD_atomic: 15256 case OMPD_distribute_simd: 15257 case OMPD_target_teams: 15258 case OMPD_requires: 15259 case OMPD_metadirective: 15260 llvm_unreachable("Unexpected OpenMP directive with schedule clause"); 15261 case OMPD_unknown: 15262 default: 15263 llvm_unreachable("Unknown OpenMP directive"); 15264 } 15265 break; 15266 case OMPC_dist_schedule: 15267 switch (DKind) { 15268 case OMPD_teams_distribute_parallel_for: 15269 case OMPD_teams_distribute_parallel_for_simd: 15270 case OMPD_teams_distribute: 15271 case OMPD_teams_distribute_simd: 15272 case OMPD_target_teams_distribute_parallel_for: 15273 case OMPD_target_teams_distribute_parallel_for_simd: 15274 case OMPD_target_teams_distribute: 15275 case OMPD_target_teams_distribute_simd: 15276 CaptureRegion = OMPD_teams; 15277 break; 15278 case OMPD_distribute_parallel_for: 15279 case OMPD_distribute_parallel_for_simd: 15280 case OMPD_distribute: 15281 case OMPD_distribute_simd: 15282 // Do not capture dist_schedule-clause expressions. 15283 break; 15284 case OMPD_parallel_for: 15285 case OMPD_parallel_for_simd: 15286 case OMPD_target_parallel_for_simd: 15287 case OMPD_target_parallel_for: 15288 case OMPD_task: 15289 case OMPD_taskloop: 15290 case OMPD_taskloop_simd: 15291 case OMPD_master_taskloop: 15292 case OMPD_master_taskloop_simd: 15293 case OMPD_parallel_master_taskloop: 15294 case OMPD_parallel_master_taskloop_simd: 15295 case OMPD_target_data: 15296 case OMPD_target_enter_data: 15297 case OMPD_target_exit_data: 15298 case OMPD_target_update: 15299 case OMPD_teams: 15300 case OMPD_target: 15301 case OMPD_target_simd: 15302 case OMPD_target_parallel: 15303 case OMPD_cancel: 15304 case OMPD_parallel: 15305 case OMPD_parallel_master: 15306 case OMPD_parallel_masked: 15307 case OMPD_parallel_sections: 15308 case OMPD_threadprivate: 15309 case OMPD_allocate: 15310 case OMPD_taskyield: 15311 case OMPD_barrier: 15312 case OMPD_taskwait: 15313 case OMPD_cancellation_point: 15314 case OMPD_flush: 15315 case OMPD_depobj: 15316 case OMPD_scan: 15317 case OMPD_declare_reduction: 15318 case OMPD_declare_mapper: 15319 case OMPD_declare_simd: 15320 case OMPD_declare_variant: 15321 case OMPD_begin_declare_variant: 15322 case OMPD_end_declare_variant: 15323 case OMPD_declare_target: 15324 case OMPD_end_declare_target: 15325 case OMPD_loop: 15326 case OMPD_teams_loop: 15327 case OMPD_target_teams_loop: 15328 case OMPD_parallel_loop: 15329 case OMPD_target_parallel_loop: 15330 case OMPD_simd: 15331 case OMPD_tile: 15332 case OMPD_unroll: 15333 case OMPD_for: 15334 case OMPD_for_simd: 15335 case OMPD_sections: 15336 case OMPD_section: 15337 case OMPD_single: 15338 case OMPD_master: 15339 case OMPD_masked: 15340 case OMPD_critical: 15341 case OMPD_taskgroup: 15342 case OMPD_ordered: 15343 case OMPD_atomic: 15344 case OMPD_target_teams: 15345 case OMPD_requires: 15346 case OMPD_metadirective: 15347 llvm_unreachable("Unexpected OpenMP directive with dist_schedule clause"); 15348 case OMPD_unknown: 15349 default: 15350 llvm_unreachable("Unknown OpenMP directive"); 15351 } 15352 break; 15353 case OMPC_device: 15354 switch (DKind) { 15355 case OMPD_target_update: 15356 case OMPD_target_enter_data: 15357 case OMPD_target_exit_data: 15358 case OMPD_target: 15359 case OMPD_target_simd: 15360 case OMPD_target_teams: 15361 case OMPD_target_parallel: 15362 case OMPD_target_teams_distribute: 15363 case OMPD_target_teams_distribute_simd: 15364 case OMPD_target_parallel_for: 15365 case OMPD_target_parallel_for_simd: 15366 case OMPD_target_parallel_loop: 15367 case OMPD_target_teams_distribute_parallel_for: 15368 case OMPD_target_teams_distribute_parallel_for_simd: 15369 case OMPD_target_teams_loop: 15370 case OMPD_dispatch: 15371 CaptureRegion = OMPD_task; 15372 break; 15373 case OMPD_target_data: 15374 case OMPD_interop: 15375 // Do not capture device-clause expressions. 15376 break; 15377 case OMPD_teams_distribute_parallel_for: 15378 case OMPD_teams_distribute_parallel_for_simd: 15379 case OMPD_teams: 15380 case OMPD_teams_distribute: 15381 case OMPD_teams_distribute_simd: 15382 case OMPD_distribute_parallel_for: 15383 case OMPD_distribute_parallel_for_simd: 15384 case OMPD_task: 15385 case OMPD_taskloop: 15386 case OMPD_taskloop_simd: 15387 case OMPD_master_taskloop: 15388 case OMPD_master_taskloop_simd: 15389 case OMPD_parallel_master_taskloop: 15390 case OMPD_parallel_master_taskloop_simd: 15391 case OMPD_cancel: 15392 case OMPD_parallel: 15393 case OMPD_parallel_master: 15394 case OMPD_parallel_masked: 15395 case OMPD_parallel_sections: 15396 case OMPD_parallel_for: 15397 case OMPD_parallel_for_simd: 15398 case OMPD_threadprivate: 15399 case OMPD_allocate: 15400 case OMPD_taskyield: 15401 case OMPD_barrier: 15402 case OMPD_taskwait: 15403 case OMPD_cancellation_point: 15404 case OMPD_flush: 15405 case OMPD_depobj: 15406 case OMPD_scan: 15407 case OMPD_declare_reduction: 15408 case OMPD_declare_mapper: 15409 case OMPD_declare_simd: 15410 case OMPD_declare_variant: 15411 case OMPD_begin_declare_variant: 15412 case OMPD_end_declare_variant: 15413 case OMPD_declare_target: 15414 case OMPD_end_declare_target: 15415 case OMPD_loop: 15416 case OMPD_teams_loop: 15417 case OMPD_parallel_loop: 15418 case OMPD_simd: 15419 case OMPD_tile: 15420 case OMPD_unroll: 15421 case OMPD_for: 15422 case OMPD_for_simd: 15423 case OMPD_sections: 15424 case OMPD_section: 15425 case OMPD_single: 15426 case OMPD_master: 15427 case OMPD_masked: 15428 case OMPD_critical: 15429 case OMPD_taskgroup: 15430 case OMPD_distribute: 15431 case OMPD_ordered: 15432 case OMPD_atomic: 15433 case OMPD_distribute_simd: 15434 case OMPD_requires: 15435 case OMPD_metadirective: 15436 llvm_unreachable("Unexpected OpenMP directive with device-clause"); 15437 case OMPD_unknown: 15438 default: 15439 llvm_unreachable("Unknown OpenMP directive"); 15440 } 15441 break; 15442 case OMPC_grainsize: 15443 case OMPC_num_tasks: 15444 case OMPC_final: 15445 case OMPC_priority: 15446 switch (DKind) { 15447 case OMPD_task: 15448 case OMPD_taskloop: 15449 case OMPD_taskloop_simd: 15450 case OMPD_master_taskloop: 15451 case OMPD_master_taskloop_simd: 15452 break; 15453 case OMPD_parallel_master_taskloop: 15454 case OMPD_parallel_master_taskloop_simd: 15455 CaptureRegion = OMPD_parallel; 15456 break; 15457 case OMPD_target_update: 15458 case OMPD_target_enter_data: 15459 case OMPD_target_exit_data: 15460 case OMPD_target: 15461 case OMPD_target_simd: 15462 case OMPD_target_teams: 15463 case OMPD_target_parallel: 15464 case OMPD_target_teams_distribute: 15465 case OMPD_target_teams_distribute_simd: 15466 case OMPD_target_parallel_for: 15467 case OMPD_target_parallel_for_simd: 15468 case OMPD_target_teams_distribute_parallel_for: 15469 case OMPD_target_teams_distribute_parallel_for_simd: 15470 case OMPD_target_data: 15471 case OMPD_teams_distribute_parallel_for: 15472 case OMPD_teams_distribute_parallel_for_simd: 15473 case OMPD_teams: 15474 case OMPD_teams_distribute: 15475 case OMPD_teams_distribute_simd: 15476 case OMPD_distribute_parallel_for: 15477 case OMPD_distribute_parallel_for_simd: 15478 case OMPD_cancel: 15479 case OMPD_parallel: 15480 case OMPD_parallel_master: 15481 case OMPD_parallel_masked: 15482 case OMPD_parallel_sections: 15483 case OMPD_parallel_for: 15484 case OMPD_parallel_for_simd: 15485 case OMPD_threadprivate: 15486 case OMPD_allocate: 15487 case OMPD_taskyield: 15488 case OMPD_barrier: 15489 case OMPD_taskwait: 15490 case OMPD_cancellation_point: 15491 case OMPD_flush: 15492 case OMPD_depobj: 15493 case OMPD_scan: 15494 case OMPD_declare_reduction: 15495 case OMPD_declare_mapper: 15496 case OMPD_declare_simd: 15497 case OMPD_declare_variant: 15498 case OMPD_begin_declare_variant: 15499 case OMPD_end_declare_variant: 15500 case OMPD_declare_target: 15501 case OMPD_end_declare_target: 15502 case OMPD_loop: 15503 case OMPD_teams_loop: 15504 case OMPD_target_teams_loop: 15505 case OMPD_parallel_loop: 15506 case OMPD_target_parallel_loop: 15507 case OMPD_simd: 15508 case OMPD_tile: 15509 case OMPD_unroll: 15510 case OMPD_for: 15511 case OMPD_for_simd: 15512 case OMPD_sections: 15513 case OMPD_section: 15514 case OMPD_single: 15515 case OMPD_master: 15516 case OMPD_masked: 15517 case OMPD_critical: 15518 case OMPD_taskgroup: 15519 case OMPD_distribute: 15520 case OMPD_ordered: 15521 case OMPD_atomic: 15522 case OMPD_distribute_simd: 15523 case OMPD_requires: 15524 case OMPD_metadirective: 15525 llvm_unreachable("Unexpected OpenMP directive with grainsize-clause"); 15526 case OMPD_unknown: 15527 default: 15528 llvm_unreachable("Unknown OpenMP directive"); 15529 } 15530 break; 15531 case OMPC_novariants: 15532 case OMPC_nocontext: 15533 switch (DKind) { 15534 case OMPD_dispatch: 15535 CaptureRegion = OMPD_task; 15536 break; 15537 default: 15538 llvm_unreachable("Unexpected OpenMP directive"); 15539 } 15540 break; 15541 case OMPC_filter: 15542 // Do not capture filter-clause expressions. 15543 break; 15544 case OMPC_when: 15545 if (DKind == OMPD_metadirective) { 15546 CaptureRegion = OMPD_metadirective; 15547 } else if (DKind == OMPD_unknown) { 15548 llvm_unreachable("Unknown OpenMP directive"); 15549 } else { 15550 llvm_unreachable("Unexpected OpenMP directive with when clause"); 15551 } 15552 break; 15553 case OMPC_firstprivate: 15554 case OMPC_lastprivate: 15555 case OMPC_reduction: 15556 case OMPC_task_reduction: 15557 case OMPC_in_reduction: 15558 case OMPC_linear: 15559 case OMPC_default: 15560 case OMPC_proc_bind: 15561 case OMPC_safelen: 15562 case OMPC_simdlen: 15563 case OMPC_sizes: 15564 case OMPC_allocator: 15565 case OMPC_collapse: 15566 case OMPC_private: 15567 case OMPC_shared: 15568 case OMPC_aligned: 15569 case OMPC_copyin: 15570 case OMPC_copyprivate: 15571 case OMPC_ordered: 15572 case OMPC_nowait: 15573 case OMPC_untied: 15574 case OMPC_mergeable: 15575 case OMPC_threadprivate: 15576 case OMPC_allocate: 15577 case OMPC_flush: 15578 case OMPC_depobj: 15579 case OMPC_read: 15580 case OMPC_write: 15581 case OMPC_update: 15582 case OMPC_capture: 15583 case OMPC_compare: 15584 case OMPC_seq_cst: 15585 case OMPC_acq_rel: 15586 case OMPC_acquire: 15587 case OMPC_release: 15588 case OMPC_relaxed: 15589 case OMPC_depend: 15590 case OMPC_threads: 15591 case OMPC_simd: 15592 case OMPC_map: 15593 case OMPC_nogroup: 15594 case OMPC_hint: 15595 case OMPC_defaultmap: 15596 case OMPC_unknown: 15597 case OMPC_uniform: 15598 case OMPC_to: 15599 case OMPC_from: 15600 case OMPC_use_device_ptr: 15601 case OMPC_use_device_addr: 15602 case OMPC_is_device_ptr: 15603 case OMPC_unified_address: 15604 case OMPC_unified_shared_memory: 15605 case OMPC_reverse_offload: 15606 case OMPC_dynamic_allocators: 15607 case OMPC_atomic_default_mem_order: 15608 case OMPC_device_type: 15609 case OMPC_match: 15610 case OMPC_nontemporal: 15611 case OMPC_order: 15612 case OMPC_destroy: 15613 case OMPC_detach: 15614 case OMPC_inclusive: 15615 case OMPC_exclusive: 15616 case OMPC_uses_allocators: 15617 case OMPC_affinity: 15618 case OMPC_bind: 15619 default: 15620 llvm_unreachable("Unexpected OpenMP clause."); 15621 } 15622 return CaptureRegion; 15623 } 15624 15625 OMPClause *Sema::ActOnOpenMPIfClause(OpenMPDirectiveKind NameModifier, 15626 Expr *Condition, SourceLocation StartLoc, 15627 SourceLocation LParenLoc, 15628 SourceLocation NameModifierLoc, 15629 SourceLocation ColonLoc, 15630 SourceLocation EndLoc) { 15631 Expr *ValExpr = Condition; 15632 Stmt *HelperValStmt = nullptr; 15633 OpenMPDirectiveKind CaptureRegion = OMPD_unknown; 15634 if (!Condition->isValueDependent() && !Condition->isTypeDependent() && 15635 !Condition->isInstantiationDependent() && 15636 !Condition->containsUnexpandedParameterPack()) { 15637 ExprResult Val = CheckBooleanCondition(StartLoc, Condition); 15638 if (Val.isInvalid()) 15639 return nullptr; 15640 15641 ValExpr = Val.get(); 15642 15643 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 15644 CaptureRegion = getOpenMPCaptureRegionForClause( 15645 DKind, OMPC_if, LangOpts.OpenMP, NameModifier); 15646 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 15647 ValExpr = MakeFullExpr(ValExpr).get(); 15648 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 15649 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 15650 HelperValStmt = buildPreInits(Context, Captures); 15651 } 15652 } 15653 15654 return new (Context) 15655 OMPIfClause(NameModifier, ValExpr, HelperValStmt, CaptureRegion, StartLoc, 15656 LParenLoc, NameModifierLoc, ColonLoc, EndLoc); 15657 } 15658 15659 OMPClause *Sema::ActOnOpenMPFinalClause(Expr *Condition, 15660 SourceLocation StartLoc, 15661 SourceLocation LParenLoc, 15662 SourceLocation EndLoc) { 15663 Expr *ValExpr = Condition; 15664 Stmt *HelperValStmt = nullptr; 15665 OpenMPDirectiveKind CaptureRegion = OMPD_unknown; 15666 if (!Condition->isValueDependent() && !Condition->isTypeDependent() && 15667 !Condition->isInstantiationDependent() && 15668 !Condition->containsUnexpandedParameterPack()) { 15669 ExprResult Val = CheckBooleanCondition(StartLoc, Condition); 15670 if (Val.isInvalid()) 15671 return nullptr; 15672 15673 ValExpr = MakeFullExpr(Val.get()).get(); 15674 15675 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 15676 CaptureRegion = 15677 getOpenMPCaptureRegionForClause(DKind, OMPC_final, LangOpts.OpenMP); 15678 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 15679 ValExpr = MakeFullExpr(ValExpr).get(); 15680 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 15681 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 15682 HelperValStmt = buildPreInits(Context, Captures); 15683 } 15684 } 15685 15686 return new (Context) OMPFinalClause(ValExpr, HelperValStmt, CaptureRegion, 15687 StartLoc, LParenLoc, EndLoc); 15688 } 15689 15690 ExprResult Sema::PerformOpenMPImplicitIntegerConversion(SourceLocation Loc, 15691 Expr *Op) { 15692 if (!Op) 15693 return ExprError(); 15694 15695 class IntConvertDiagnoser : public ICEConvertDiagnoser { 15696 public: 15697 IntConvertDiagnoser() 15698 : ICEConvertDiagnoser(/*AllowScopedEnumerations*/ false, false, true) {} 15699 SemaDiagnosticBuilder diagnoseNotInt(Sema &S, SourceLocation Loc, 15700 QualType T) override { 15701 return S.Diag(Loc, diag::err_omp_not_integral) << T; 15702 } 15703 SemaDiagnosticBuilder diagnoseIncomplete(Sema &S, SourceLocation Loc, 15704 QualType T) override { 15705 return S.Diag(Loc, diag::err_omp_incomplete_type) << T; 15706 } 15707 SemaDiagnosticBuilder diagnoseExplicitConv(Sema &S, SourceLocation Loc, 15708 QualType T, 15709 QualType ConvTy) override { 15710 return S.Diag(Loc, diag::err_omp_explicit_conversion) << T << ConvTy; 15711 } 15712 SemaDiagnosticBuilder noteExplicitConv(Sema &S, CXXConversionDecl *Conv, 15713 QualType ConvTy) override { 15714 return S.Diag(Conv->getLocation(), diag::note_omp_conversion_here) 15715 << ConvTy->isEnumeralType() << ConvTy; 15716 } 15717 SemaDiagnosticBuilder diagnoseAmbiguous(Sema &S, SourceLocation Loc, 15718 QualType T) override { 15719 return S.Diag(Loc, diag::err_omp_ambiguous_conversion) << T; 15720 } 15721 SemaDiagnosticBuilder noteAmbiguous(Sema &S, CXXConversionDecl *Conv, 15722 QualType ConvTy) override { 15723 return S.Diag(Conv->getLocation(), diag::note_omp_conversion_here) 15724 << ConvTy->isEnumeralType() << ConvTy; 15725 } 15726 SemaDiagnosticBuilder diagnoseConversion(Sema &, SourceLocation, QualType, 15727 QualType) override { 15728 llvm_unreachable("conversion functions are permitted"); 15729 } 15730 } ConvertDiagnoser; 15731 return PerformContextualImplicitConversion(Loc, Op, ConvertDiagnoser); 15732 } 15733 15734 static bool 15735 isNonNegativeIntegerValue(Expr *&ValExpr, Sema &SemaRef, OpenMPClauseKind CKind, 15736 bool StrictlyPositive, bool BuildCapture = false, 15737 OpenMPDirectiveKind DKind = OMPD_unknown, 15738 OpenMPDirectiveKind *CaptureRegion = nullptr, 15739 Stmt **HelperValStmt = nullptr) { 15740 if (!ValExpr->isTypeDependent() && !ValExpr->isValueDependent() && 15741 !ValExpr->isInstantiationDependent()) { 15742 SourceLocation Loc = ValExpr->getExprLoc(); 15743 ExprResult Value = 15744 SemaRef.PerformOpenMPImplicitIntegerConversion(Loc, ValExpr); 15745 if (Value.isInvalid()) 15746 return false; 15747 15748 ValExpr = Value.get(); 15749 // The expression must evaluate to a non-negative integer value. 15750 if (Optional<llvm::APSInt> Result = 15751 ValExpr->getIntegerConstantExpr(SemaRef.Context)) { 15752 if (Result->isSigned() && 15753 !((!StrictlyPositive && Result->isNonNegative()) || 15754 (StrictlyPositive && Result->isStrictlyPositive()))) { 15755 SemaRef.Diag(Loc, diag::err_omp_negative_expression_in_clause) 15756 << getOpenMPClauseName(CKind) << (StrictlyPositive ? 1 : 0) 15757 << ValExpr->getSourceRange(); 15758 return false; 15759 } 15760 } 15761 if (!BuildCapture) 15762 return true; 15763 *CaptureRegion = 15764 getOpenMPCaptureRegionForClause(DKind, CKind, SemaRef.LangOpts.OpenMP); 15765 if (*CaptureRegion != OMPD_unknown && 15766 !SemaRef.CurContext->isDependentContext()) { 15767 ValExpr = SemaRef.MakeFullExpr(ValExpr).get(); 15768 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 15769 ValExpr = tryBuildCapture(SemaRef, ValExpr, Captures).get(); 15770 *HelperValStmt = buildPreInits(SemaRef.Context, Captures); 15771 } 15772 } 15773 return true; 15774 } 15775 15776 OMPClause *Sema::ActOnOpenMPNumThreadsClause(Expr *NumThreads, 15777 SourceLocation StartLoc, 15778 SourceLocation LParenLoc, 15779 SourceLocation EndLoc) { 15780 Expr *ValExpr = NumThreads; 15781 Stmt *HelperValStmt = nullptr; 15782 15783 // OpenMP [2.5, Restrictions] 15784 // The num_threads expression must evaluate to a positive integer value. 15785 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_num_threads, 15786 /*StrictlyPositive=*/true)) 15787 return nullptr; 15788 15789 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 15790 OpenMPDirectiveKind CaptureRegion = 15791 getOpenMPCaptureRegionForClause(DKind, OMPC_num_threads, LangOpts.OpenMP); 15792 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 15793 ValExpr = MakeFullExpr(ValExpr).get(); 15794 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 15795 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 15796 HelperValStmt = buildPreInits(Context, Captures); 15797 } 15798 15799 return new (Context) OMPNumThreadsClause( 15800 ValExpr, HelperValStmt, CaptureRegion, StartLoc, LParenLoc, EndLoc); 15801 } 15802 15803 ExprResult Sema::VerifyPositiveIntegerConstantInClause(Expr *E, 15804 OpenMPClauseKind CKind, 15805 bool StrictlyPositive, 15806 bool SuppressExprDiags) { 15807 if (!E) 15808 return ExprError(); 15809 if (E->isValueDependent() || E->isTypeDependent() || 15810 E->isInstantiationDependent() || E->containsUnexpandedParameterPack()) 15811 return E; 15812 15813 llvm::APSInt Result; 15814 ExprResult ICE; 15815 if (SuppressExprDiags) { 15816 // Use a custom diagnoser that suppresses 'note' diagnostics about the 15817 // expression. 15818 struct SuppressedDiagnoser : public Sema::VerifyICEDiagnoser { 15819 SuppressedDiagnoser() : VerifyICEDiagnoser(/*Suppress=*/true) {} 15820 Sema::SemaDiagnosticBuilder diagnoseNotICE(Sema &S, 15821 SourceLocation Loc) override { 15822 llvm_unreachable("Diagnostic suppressed"); 15823 } 15824 } Diagnoser; 15825 ICE = VerifyIntegerConstantExpression(E, &Result, Diagnoser, AllowFold); 15826 } else { 15827 ICE = VerifyIntegerConstantExpression(E, &Result, /*FIXME*/ AllowFold); 15828 } 15829 if (ICE.isInvalid()) 15830 return ExprError(); 15831 15832 if ((StrictlyPositive && !Result.isStrictlyPositive()) || 15833 (!StrictlyPositive && !Result.isNonNegative())) { 15834 Diag(E->getExprLoc(), diag::err_omp_negative_expression_in_clause) 15835 << getOpenMPClauseName(CKind) << (StrictlyPositive ? 1 : 0) 15836 << E->getSourceRange(); 15837 return ExprError(); 15838 } 15839 if ((CKind == OMPC_aligned || CKind == OMPC_align) && !Result.isPowerOf2()) { 15840 Diag(E->getExprLoc(), diag::warn_omp_alignment_not_power_of_two) 15841 << E->getSourceRange(); 15842 return ExprError(); 15843 } 15844 if (CKind == OMPC_collapse && DSAStack->getAssociatedLoops() == 1) 15845 DSAStack->setAssociatedLoops(Result.getExtValue()); 15846 else if (CKind == OMPC_ordered) 15847 DSAStack->setAssociatedLoops(Result.getExtValue()); 15848 return ICE; 15849 } 15850 15851 OMPClause *Sema::ActOnOpenMPSafelenClause(Expr *Len, SourceLocation StartLoc, 15852 SourceLocation LParenLoc, 15853 SourceLocation EndLoc) { 15854 // OpenMP [2.8.1, simd construct, Description] 15855 // The parameter of the safelen clause must be a constant 15856 // positive integer expression. 15857 ExprResult Safelen = VerifyPositiveIntegerConstantInClause(Len, OMPC_safelen); 15858 if (Safelen.isInvalid()) 15859 return nullptr; 15860 return new (Context) 15861 OMPSafelenClause(Safelen.get(), StartLoc, LParenLoc, EndLoc); 15862 } 15863 15864 OMPClause *Sema::ActOnOpenMPSimdlenClause(Expr *Len, SourceLocation StartLoc, 15865 SourceLocation LParenLoc, 15866 SourceLocation EndLoc) { 15867 // OpenMP [2.8.1, simd construct, Description] 15868 // The parameter of the simdlen clause must be a constant 15869 // positive integer expression. 15870 ExprResult Simdlen = VerifyPositiveIntegerConstantInClause(Len, OMPC_simdlen); 15871 if (Simdlen.isInvalid()) 15872 return nullptr; 15873 return new (Context) 15874 OMPSimdlenClause(Simdlen.get(), StartLoc, LParenLoc, EndLoc); 15875 } 15876 15877 /// Tries to find omp_allocator_handle_t type. 15878 static bool findOMPAllocatorHandleT(Sema &S, SourceLocation Loc, 15879 DSAStackTy *Stack) { 15880 QualType OMPAllocatorHandleT = Stack->getOMPAllocatorHandleT(); 15881 if (!OMPAllocatorHandleT.isNull()) 15882 return true; 15883 // Build the predefined allocator expressions. 15884 bool ErrorFound = false; 15885 for (int I = 0; I < OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; ++I) { 15886 auto AllocatorKind = static_cast<OMPAllocateDeclAttr::AllocatorTypeTy>(I); 15887 StringRef Allocator = 15888 OMPAllocateDeclAttr::ConvertAllocatorTypeTyToStr(AllocatorKind); 15889 DeclarationName AllocatorName = &S.getASTContext().Idents.get(Allocator); 15890 auto *VD = dyn_cast_or_null<ValueDecl>( 15891 S.LookupSingleName(S.TUScope, AllocatorName, Loc, Sema::LookupAnyName)); 15892 if (!VD) { 15893 ErrorFound = true; 15894 break; 15895 } 15896 QualType AllocatorType = 15897 VD->getType().getNonLValueExprType(S.getASTContext()); 15898 ExprResult Res = S.BuildDeclRefExpr(VD, AllocatorType, VK_LValue, Loc); 15899 if (!Res.isUsable()) { 15900 ErrorFound = true; 15901 break; 15902 } 15903 if (OMPAllocatorHandleT.isNull()) 15904 OMPAllocatorHandleT = AllocatorType; 15905 if (!S.getASTContext().hasSameType(OMPAllocatorHandleT, AllocatorType)) { 15906 ErrorFound = true; 15907 break; 15908 } 15909 Stack->setAllocator(AllocatorKind, Res.get()); 15910 } 15911 if (ErrorFound) { 15912 S.Diag(Loc, diag::err_omp_implied_type_not_found) 15913 << "omp_allocator_handle_t"; 15914 return false; 15915 } 15916 OMPAllocatorHandleT.addConst(); 15917 Stack->setOMPAllocatorHandleT(OMPAllocatorHandleT); 15918 return true; 15919 } 15920 15921 OMPClause *Sema::ActOnOpenMPAllocatorClause(Expr *A, SourceLocation StartLoc, 15922 SourceLocation LParenLoc, 15923 SourceLocation EndLoc) { 15924 // OpenMP [2.11.3, allocate Directive, Description] 15925 // allocator is an expression of omp_allocator_handle_t type. 15926 if (!findOMPAllocatorHandleT(*this, A->getExprLoc(), DSAStack)) 15927 return nullptr; 15928 15929 ExprResult Allocator = DefaultLvalueConversion(A); 15930 if (Allocator.isInvalid()) 15931 return nullptr; 15932 Allocator = PerformImplicitConversion(Allocator.get(), 15933 DSAStack->getOMPAllocatorHandleT(), 15934 Sema::AA_Initializing, 15935 /*AllowExplicit=*/true); 15936 if (Allocator.isInvalid()) 15937 return nullptr; 15938 return new (Context) 15939 OMPAllocatorClause(Allocator.get(), StartLoc, LParenLoc, EndLoc); 15940 } 15941 15942 OMPClause *Sema::ActOnOpenMPCollapseClause(Expr *NumForLoops, 15943 SourceLocation StartLoc, 15944 SourceLocation LParenLoc, 15945 SourceLocation EndLoc) { 15946 // OpenMP [2.7.1, loop construct, Description] 15947 // OpenMP [2.8.1, simd construct, Description] 15948 // OpenMP [2.9.6, distribute construct, Description] 15949 // The parameter of the collapse clause must be a constant 15950 // positive integer expression. 15951 ExprResult NumForLoopsResult = 15952 VerifyPositiveIntegerConstantInClause(NumForLoops, OMPC_collapse); 15953 if (NumForLoopsResult.isInvalid()) 15954 return nullptr; 15955 return new (Context) 15956 OMPCollapseClause(NumForLoopsResult.get(), StartLoc, LParenLoc, EndLoc); 15957 } 15958 15959 OMPClause *Sema::ActOnOpenMPOrderedClause(SourceLocation StartLoc, 15960 SourceLocation EndLoc, 15961 SourceLocation LParenLoc, 15962 Expr *NumForLoops) { 15963 // OpenMP [2.7.1, loop construct, Description] 15964 // OpenMP [2.8.1, simd construct, Description] 15965 // OpenMP [2.9.6, distribute construct, Description] 15966 // The parameter of the ordered clause must be a constant 15967 // positive integer expression if any. 15968 if (NumForLoops && LParenLoc.isValid()) { 15969 ExprResult NumForLoopsResult = 15970 VerifyPositiveIntegerConstantInClause(NumForLoops, OMPC_ordered); 15971 if (NumForLoopsResult.isInvalid()) 15972 return nullptr; 15973 NumForLoops = NumForLoopsResult.get(); 15974 } else { 15975 NumForLoops = nullptr; 15976 } 15977 auto *Clause = OMPOrderedClause::Create( 15978 Context, NumForLoops, NumForLoops ? DSAStack->getAssociatedLoops() : 0, 15979 StartLoc, LParenLoc, EndLoc); 15980 DSAStack->setOrderedRegion(/*IsOrdered=*/true, NumForLoops, Clause); 15981 return Clause; 15982 } 15983 15984 OMPClause *Sema::ActOnOpenMPSimpleClause( 15985 OpenMPClauseKind Kind, unsigned Argument, SourceLocation ArgumentLoc, 15986 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) { 15987 OMPClause *Res = nullptr; 15988 switch (Kind) { 15989 case OMPC_default: 15990 Res = ActOnOpenMPDefaultClause(static_cast<DefaultKind>(Argument), 15991 ArgumentLoc, StartLoc, LParenLoc, EndLoc); 15992 break; 15993 case OMPC_proc_bind: 15994 Res = ActOnOpenMPProcBindClause(static_cast<ProcBindKind>(Argument), 15995 ArgumentLoc, StartLoc, LParenLoc, EndLoc); 15996 break; 15997 case OMPC_atomic_default_mem_order: 15998 Res = ActOnOpenMPAtomicDefaultMemOrderClause( 15999 static_cast<OpenMPAtomicDefaultMemOrderClauseKind>(Argument), 16000 ArgumentLoc, StartLoc, LParenLoc, EndLoc); 16001 break; 16002 case OMPC_order: 16003 Res = ActOnOpenMPOrderClause(static_cast<OpenMPOrderClauseKind>(Argument), 16004 ArgumentLoc, StartLoc, LParenLoc, EndLoc); 16005 break; 16006 case OMPC_update: 16007 Res = ActOnOpenMPUpdateClause(static_cast<OpenMPDependClauseKind>(Argument), 16008 ArgumentLoc, StartLoc, LParenLoc, EndLoc); 16009 break; 16010 case OMPC_bind: 16011 Res = ActOnOpenMPBindClause(static_cast<OpenMPBindClauseKind>(Argument), 16012 ArgumentLoc, StartLoc, LParenLoc, EndLoc); 16013 break; 16014 case OMPC_if: 16015 case OMPC_final: 16016 case OMPC_num_threads: 16017 case OMPC_safelen: 16018 case OMPC_simdlen: 16019 case OMPC_sizes: 16020 case OMPC_allocator: 16021 case OMPC_collapse: 16022 case OMPC_schedule: 16023 case OMPC_private: 16024 case OMPC_firstprivate: 16025 case OMPC_lastprivate: 16026 case OMPC_shared: 16027 case OMPC_reduction: 16028 case OMPC_task_reduction: 16029 case OMPC_in_reduction: 16030 case OMPC_linear: 16031 case OMPC_aligned: 16032 case OMPC_copyin: 16033 case OMPC_copyprivate: 16034 case OMPC_ordered: 16035 case OMPC_nowait: 16036 case OMPC_untied: 16037 case OMPC_mergeable: 16038 case OMPC_threadprivate: 16039 case OMPC_allocate: 16040 case OMPC_flush: 16041 case OMPC_depobj: 16042 case OMPC_read: 16043 case OMPC_write: 16044 case OMPC_capture: 16045 case OMPC_compare: 16046 case OMPC_seq_cst: 16047 case OMPC_acq_rel: 16048 case OMPC_acquire: 16049 case OMPC_release: 16050 case OMPC_relaxed: 16051 case OMPC_depend: 16052 case OMPC_device: 16053 case OMPC_threads: 16054 case OMPC_simd: 16055 case OMPC_map: 16056 case OMPC_num_teams: 16057 case OMPC_thread_limit: 16058 case OMPC_priority: 16059 case OMPC_grainsize: 16060 case OMPC_nogroup: 16061 case OMPC_num_tasks: 16062 case OMPC_hint: 16063 case OMPC_dist_schedule: 16064 case OMPC_defaultmap: 16065 case OMPC_unknown: 16066 case OMPC_uniform: 16067 case OMPC_to: 16068 case OMPC_from: 16069 case OMPC_use_device_ptr: 16070 case OMPC_use_device_addr: 16071 case OMPC_is_device_ptr: 16072 case OMPC_has_device_addr: 16073 case OMPC_unified_address: 16074 case OMPC_unified_shared_memory: 16075 case OMPC_reverse_offload: 16076 case OMPC_dynamic_allocators: 16077 case OMPC_device_type: 16078 case OMPC_match: 16079 case OMPC_nontemporal: 16080 case OMPC_destroy: 16081 case OMPC_novariants: 16082 case OMPC_nocontext: 16083 case OMPC_detach: 16084 case OMPC_inclusive: 16085 case OMPC_exclusive: 16086 case OMPC_uses_allocators: 16087 case OMPC_affinity: 16088 case OMPC_when: 16089 default: 16090 llvm_unreachable("Clause is not allowed."); 16091 } 16092 return Res; 16093 } 16094 16095 static std::string 16096 getListOfPossibleValues(OpenMPClauseKind K, unsigned First, unsigned Last, 16097 ArrayRef<unsigned> Exclude = llvm::None) { 16098 SmallString<256> Buffer; 16099 llvm::raw_svector_ostream Out(Buffer); 16100 unsigned Skipped = Exclude.size(); 16101 auto S = Exclude.begin(), E = Exclude.end(); 16102 for (unsigned I = First; I < Last; ++I) { 16103 if (std::find(S, E, I) != E) { 16104 --Skipped; 16105 continue; 16106 } 16107 Out << "'" << getOpenMPSimpleClauseTypeName(K, I) << "'"; 16108 if (I + Skipped + 2 == Last) 16109 Out << " or "; 16110 else if (I + Skipped + 1 != Last) 16111 Out << ", "; 16112 } 16113 return std::string(Out.str()); 16114 } 16115 16116 OMPClause *Sema::ActOnOpenMPDefaultClause(DefaultKind Kind, 16117 SourceLocation KindKwLoc, 16118 SourceLocation StartLoc, 16119 SourceLocation LParenLoc, 16120 SourceLocation EndLoc) { 16121 if (Kind == OMP_DEFAULT_unknown) { 16122 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value) 16123 << getListOfPossibleValues(OMPC_default, /*First=*/0, 16124 /*Last=*/unsigned(OMP_DEFAULT_unknown)) 16125 << getOpenMPClauseName(OMPC_default); 16126 return nullptr; 16127 } 16128 16129 switch (Kind) { 16130 case OMP_DEFAULT_none: 16131 DSAStack->setDefaultDSANone(KindKwLoc); 16132 break; 16133 case OMP_DEFAULT_shared: 16134 DSAStack->setDefaultDSAShared(KindKwLoc); 16135 break; 16136 case OMP_DEFAULT_firstprivate: 16137 DSAStack->setDefaultDSAFirstPrivate(KindKwLoc); 16138 break; 16139 case OMP_DEFAULT_private: 16140 DSAStack->setDefaultDSAPrivate(KindKwLoc); 16141 break; 16142 default: 16143 llvm_unreachable("DSA unexpected in OpenMP default clause"); 16144 } 16145 16146 return new (Context) 16147 OMPDefaultClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc); 16148 } 16149 16150 OMPClause *Sema::ActOnOpenMPProcBindClause(ProcBindKind Kind, 16151 SourceLocation KindKwLoc, 16152 SourceLocation StartLoc, 16153 SourceLocation LParenLoc, 16154 SourceLocation EndLoc) { 16155 if (Kind == OMP_PROC_BIND_unknown) { 16156 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value) 16157 << getListOfPossibleValues(OMPC_proc_bind, 16158 /*First=*/unsigned(OMP_PROC_BIND_master), 16159 /*Last=*/ 16160 unsigned(LangOpts.OpenMP > 50 16161 ? OMP_PROC_BIND_primary 16162 : OMP_PROC_BIND_spread) + 16163 1) 16164 << getOpenMPClauseName(OMPC_proc_bind); 16165 return nullptr; 16166 } 16167 if (Kind == OMP_PROC_BIND_primary && LangOpts.OpenMP < 51) 16168 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value) 16169 << getListOfPossibleValues(OMPC_proc_bind, 16170 /*First=*/unsigned(OMP_PROC_BIND_master), 16171 /*Last=*/ 16172 unsigned(OMP_PROC_BIND_spread) + 1) 16173 << getOpenMPClauseName(OMPC_proc_bind); 16174 return new (Context) 16175 OMPProcBindClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc); 16176 } 16177 16178 OMPClause *Sema::ActOnOpenMPAtomicDefaultMemOrderClause( 16179 OpenMPAtomicDefaultMemOrderClauseKind Kind, SourceLocation KindKwLoc, 16180 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) { 16181 if (Kind == OMPC_ATOMIC_DEFAULT_MEM_ORDER_unknown) { 16182 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value) 16183 << getListOfPossibleValues( 16184 OMPC_atomic_default_mem_order, /*First=*/0, 16185 /*Last=*/OMPC_ATOMIC_DEFAULT_MEM_ORDER_unknown) 16186 << getOpenMPClauseName(OMPC_atomic_default_mem_order); 16187 return nullptr; 16188 } 16189 return new (Context) OMPAtomicDefaultMemOrderClause(Kind, KindKwLoc, StartLoc, 16190 LParenLoc, EndLoc); 16191 } 16192 16193 OMPClause *Sema::ActOnOpenMPOrderClause(OpenMPOrderClauseKind Kind, 16194 SourceLocation KindKwLoc, 16195 SourceLocation StartLoc, 16196 SourceLocation LParenLoc, 16197 SourceLocation EndLoc) { 16198 if (Kind == OMPC_ORDER_unknown) { 16199 static_assert(OMPC_ORDER_unknown > 0, 16200 "OMPC_ORDER_unknown not greater than 0"); 16201 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value) 16202 << getListOfPossibleValues(OMPC_order, /*First=*/0, 16203 /*Last=*/OMPC_ORDER_unknown) 16204 << getOpenMPClauseName(OMPC_order); 16205 return nullptr; 16206 } 16207 return new (Context) 16208 OMPOrderClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc); 16209 } 16210 16211 OMPClause *Sema::ActOnOpenMPUpdateClause(OpenMPDependClauseKind Kind, 16212 SourceLocation KindKwLoc, 16213 SourceLocation StartLoc, 16214 SourceLocation LParenLoc, 16215 SourceLocation EndLoc) { 16216 if (Kind == OMPC_DEPEND_unknown || Kind == OMPC_DEPEND_source || 16217 Kind == OMPC_DEPEND_sink || Kind == OMPC_DEPEND_depobj) { 16218 SmallVector<unsigned> Except = { 16219 OMPC_DEPEND_source, OMPC_DEPEND_sink, OMPC_DEPEND_depobj, 16220 OMPC_DEPEND_outallmemory, OMPC_DEPEND_inoutallmemory}; 16221 if (LangOpts.OpenMP < 51) 16222 Except.push_back(OMPC_DEPEND_inoutset); 16223 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value) 16224 << getListOfPossibleValues(OMPC_depend, /*First=*/0, 16225 /*Last=*/OMPC_DEPEND_unknown, Except) 16226 << getOpenMPClauseName(OMPC_update); 16227 return nullptr; 16228 } 16229 return OMPUpdateClause::Create(Context, StartLoc, LParenLoc, KindKwLoc, Kind, 16230 EndLoc); 16231 } 16232 16233 OMPClause *Sema::ActOnOpenMPSizesClause(ArrayRef<Expr *> SizeExprs, 16234 SourceLocation StartLoc, 16235 SourceLocation LParenLoc, 16236 SourceLocation EndLoc) { 16237 for (Expr *SizeExpr : SizeExprs) { 16238 ExprResult NumForLoopsResult = VerifyPositiveIntegerConstantInClause( 16239 SizeExpr, OMPC_sizes, /*StrictlyPositive=*/true); 16240 if (!NumForLoopsResult.isUsable()) 16241 return nullptr; 16242 } 16243 16244 DSAStack->setAssociatedLoops(SizeExprs.size()); 16245 return OMPSizesClause::Create(Context, StartLoc, LParenLoc, EndLoc, 16246 SizeExprs); 16247 } 16248 16249 OMPClause *Sema::ActOnOpenMPFullClause(SourceLocation StartLoc, 16250 SourceLocation EndLoc) { 16251 return OMPFullClause::Create(Context, StartLoc, EndLoc); 16252 } 16253 16254 OMPClause *Sema::ActOnOpenMPPartialClause(Expr *FactorExpr, 16255 SourceLocation StartLoc, 16256 SourceLocation LParenLoc, 16257 SourceLocation EndLoc) { 16258 if (FactorExpr) { 16259 // If an argument is specified, it must be a constant (or an unevaluated 16260 // template expression). 16261 ExprResult FactorResult = VerifyPositiveIntegerConstantInClause( 16262 FactorExpr, OMPC_partial, /*StrictlyPositive=*/true); 16263 if (FactorResult.isInvalid()) 16264 return nullptr; 16265 FactorExpr = FactorResult.get(); 16266 } 16267 16268 return OMPPartialClause::Create(Context, StartLoc, LParenLoc, EndLoc, 16269 FactorExpr); 16270 } 16271 16272 OMPClause *Sema::ActOnOpenMPAlignClause(Expr *A, SourceLocation StartLoc, 16273 SourceLocation LParenLoc, 16274 SourceLocation EndLoc) { 16275 ExprResult AlignVal; 16276 AlignVal = VerifyPositiveIntegerConstantInClause(A, OMPC_align); 16277 if (AlignVal.isInvalid()) 16278 return nullptr; 16279 return OMPAlignClause::Create(Context, AlignVal.get(), StartLoc, LParenLoc, 16280 EndLoc); 16281 } 16282 16283 OMPClause *Sema::ActOnOpenMPSingleExprWithArgClause( 16284 OpenMPClauseKind Kind, ArrayRef<unsigned> Argument, Expr *Expr, 16285 SourceLocation StartLoc, SourceLocation LParenLoc, 16286 ArrayRef<SourceLocation> ArgumentLoc, SourceLocation DelimLoc, 16287 SourceLocation EndLoc) { 16288 OMPClause *Res = nullptr; 16289 switch (Kind) { 16290 case OMPC_schedule: 16291 enum { Modifier1, Modifier2, ScheduleKind, NumberOfElements }; 16292 assert(Argument.size() == NumberOfElements && 16293 ArgumentLoc.size() == NumberOfElements); 16294 Res = ActOnOpenMPScheduleClause( 16295 static_cast<OpenMPScheduleClauseModifier>(Argument[Modifier1]), 16296 static_cast<OpenMPScheduleClauseModifier>(Argument[Modifier2]), 16297 static_cast<OpenMPScheduleClauseKind>(Argument[ScheduleKind]), Expr, 16298 StartLoc, LParenLoc, ArgumentLoc[Modifier1], ArgumentLoc[Modifier2], 16299 ArgumentLoc[ScheduleKind], DelimLoc, EndLoc); 16300 break; 16301 case OMPC_if: 16302 assert(Argument.size() == 1 && ArgumentLoc.size() == 1); 16303 Res = ActOnOpenMPIfClause(static_cast<OpenMPDirectiveKind>(Argument.back()), 16304 Expr, StartLoc, LParenLoc, ArgumentLoc.back(), 16305 DelimLoc, EndLoc); 16306 break; 16307 case OMPC_dist_schedule: 16308 Res = ActOnOpenMPDistScheduleClause( 16309 static_cast<OpenMPDistScheduleClauseKind>(Argument.back()), Expr, 16310 StartLoc, LParenLoc, ArgumentLoc.back(), DelimLoc, EndLoc); 16311 break; 16312 case OMPC_defaultmap: 16313 enum { Modifier, DefaultmapKind }; 16314 Res = ActOnOpenMPDefaultmapClause( 16315 static_cast<OpenMPDefaultmapClauseModifier>(Argument[Modifier]), 16316 static_cast<OpenMPDefaultmapClauseKind>(Argument[DefaultmapKind]), 16317 StartLoc, LParenLoc, ArgumentLoc[Modifier], ArgumentLoc[DefaultmapKind], 16318 EndLoc); 16319 break; 16320 case OMPC_device: 16321 assert(Argument.size() == 1 && ArgumentLoc.size() == 1); 16322 Res = ActOnOpenMPDeviceClause( 16323 static_cast<OpenMPDeviceClauseModifier>(Argument.back()), Expr, 16324 StartLoc, LParenLoc, ArgumentLoc.back(), EndLoc); 16325 break; 16326 case OMPC_final: 16327 case OMPC_num_threads: 16328 case OMPC_safelen: 16329 case OMPC_simdlen: 16330 case OMPC_sizes: 16331 case OMPC_allocator: 16332 case OMPC_collapse: 16333 case OMPC_default: 16334 case OMPC_proc_bind: 16335 case OMPC_private: 16336 case OMPC_firstprivate: 16337 case OMPC_lastprivate: 16338 case OMPC_shared: 16339 case OMPC_reduction: 16340 case OMPC_task_reduction: 16341 case OMPC_in_reduction: 16342 case OMPC_linear: 16343 case OMPC_aligned: 16344 case OMPC_copyin: 16345 case OMPC_copyprivate: 16346 case OMPC_ordered: 16347 case OMPC_nowait: 16348 case OMPC_untied: 16349 case OMPC_mergeable: 16350 case OMPC_threadprivate: 16351 case OMPC_allocate: 16352 case OMPC_flush: 16353 case OMPC_depobj: 16354 case OMPC_read: 16355 case OMPC_write: 16356 case OMPC_update: 16357 case OMPC_capture: 16358 case OMPC_compare: 16359 case OMPC_seq_cst: 16360 case OMPC_acq_rel: 16361 case OMPC_acquire: 16362 case OMPC_release: 16363 case OMPC_relaxed: 16364 case OMPC_depend: 16365 case OMPC_threads: 16366 case OMPC_simd: 16367 case OMPC_map: 16368 case OMPC_num_teams: 16369 case OMPC_thread_limit: 16370 case OMPC_priority: 16371 case OMPC_grainsize: 16372 case OMPC_nogroup: 16373 case OMPC_num_tasks: 16374 case OMPC_hint: 16375 case OMPC_unknown: 16376 case OMPC_uniform: 16377 case OMPC_to: 16378 case OMPC_from: 16379 case OMPC_use_device_ptr: 16380 case OMPC_use_device_addr: 16381 case OMPC_is_device_ptr: 16382 case OMPC_has_device_addr: 16383 case OMPC_unified_address: 16384 case OMPC_unified_shared_memory: 16385 case OMPC_reverse_offload: 16386 case OMPC_dynamic_allocators: 16387 case OMPC_atomic_default_mem_order: 16388 case OMPC_device_type: 16389 case OMPC_match: 16390 case OMPC_nontemporal: 16391 case OMPC_order: 16392 case OMPC_destroy: 16393 case OMPC_novariants: 16394 case OMPC_nocontext: 16395 case OMPC_detach: 16396 case OMPC_inclusive: 16397 case OMPC_exclusive: 16398 case OMPC_uses_allocators: 16399 case OMPC_affinity: 16400 case OMPC_when: 16401 case OMPC_bind: 16402 default: 16403 llvm_unreachable("Clause is not allowed."); 16404 } 16405 return Res; 16406 } 16407 16408 static bool checkScheduleModifiers(Sema &S, OpenMPScheduleClauseModifier M1, 16409 OpenMPScheduleClauseModifier M2, 16410 SourceLocation M1Loc, SourceLocation M2Loc) { 16411 if (M1 == OMPC_SCHEDULE_MODIFIER_unknown && M1Loc.isValid()) { 16412 SmallVector<unsigned, 2> Excluded; 16413 if (M2 != OMPC_SCHEDULE_MODIFIER_unknown) 16414 Excluded.push_back(M2); 16415 if (M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) 16416 Excluded.push_back(OMPC_SCHEDULE_MODIFIER_monotonic); 16417 if (M2 == OMPC_SCHEDULE_MODIFIER_monotonic) 16418 Excluded.push_back(OMPC_SCHEDULE_MODIFIER_nonmonotonic); 16419 S.Diag(M1Loc, diag::err_omp_unexpected_clause_value) 16420 << getListOfPossibleValues(OMPC_schedule, 16421 /*First=*/OMPC_SCHEDULE_MODIFIER_unknown + 1, 16422 /*Last=*/OMPC_SCHEDULE_MODIFIER_last, 16423 Excluded) 16424 << getOpenMPClauseName(OMPC_schedule); 16425 return true; 16426 } 16427 return false; 16428 } 16429 16430 OMPClause *Sema::ActOnOpenMPScheduleClause( 16431 OpenMPScheduleClauseModifier M1, OpenMPScheduleClauseModifier M2, 16432 OpenMPScheduleClauseKind Kind, Expr *ChunkSize, SourceLocation StartLoc, 16433 SourceLocation LParenLoc, SourceLocation M1Loc, SourceLocation M2Loc, 16434 SourceLocation KindLoc, SourceLocation CommaLoc, SourceLocation EndLoc) { 16435 if (checkScheduleModifiers(*this, M1, M2, M1Loc, M2Loc) || 16436 checkScheduleModifiers(*this, M2, M1, M2Loc, M1Loc)) 16437 return nullptr; 16438 // OpenMP, 2.7.1, Loop Construct, Restrictions 16439 // Either the monotonic modifier or the nonmonotonic modifier can be specified 16440 // but not both. 16441 if ((M1 == M2 && M1 != OMPC_SCHEDULE_MODIFIER_unknown) || 16442 (M1 == OMPC_SCHEDULE_MODIFIER_monotonic && 16443 M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) || 16444 (M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic && 16445 M2 == OMPC_SCHEDULE_MODIFIER_monotonic)) { 16446 Diag(M2Loc, diag::err_omp_unexpected_schedule_modifier) 16447 << getOpenMPSimpleClauseTypeName(OMPC_schedule, M2) 16448 << getOpenMPSimpleClauseTypeName(OMPC_schedule, M1); 16449 return nullptr; 16450 } 16451 if (Kind == OMPC_SCHEDULE_unknown) { 16452 std::string Values; 16453 if (M1Loc.isInvalid() && M2Loc.isInvalid()) { 16454 unsigned Exclude[] = {OMPC_SCHEDULE_unknown}; 16455 Values = getListOfPossibleValues(OMPC_schedule, /*First=*/0, 16456 /*Last=*/OMPC_SCHEDULE_MODIFIER_last, 16457 Exclude); 16458 } else { 16459 Values = getListOfPossibleValues(OMPC_schedule, /*First=*/0, 16460 /*Last=*/OMPC_SCHEDULE_unknown); 16461 } 16462 Diag(KindLoc, diag::err_omp_unexpected_clause_value) 16463 << Values << getOpenMPClauseName(OMPC_schedule); 16464 return nullptr; 16465 } 16466 // OpenMP, 2.7.1, Loop Construct, Restrictions 16467 // The nonmonotonic modifier can only be specified with schedule(dynamic) or 16468 // schedule(guided). 16469 // OpenMP 5.0 does not have this restriction. 16470 if (LangOpts.OpenMP < 50 && 16471 (M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic || 16472 M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) && 16473 Kind != OMPC_SCHEDULE_dynamic && Kind != OMPC_SCHEDULE_guided) { 16474 Diag(M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic ? M1Loc : M2Loc, 16475 diag::err_omp_schedule_nonmonotonic_static); 16476 return nullptr; 16477 } 16478 Expr *ValExpr = ChunkSize; 16479 Stmt *HelperValStmt = nullptr; 16480 if (ChunkSize) { 16481 if (!ChunkSize->isValueDependent() && !ChunkSize->isTypeDependent() && 16482 !ChunkSize->isInstantiationDependent() && 16483 !ChunkSize->containsUnexpandedParameterPack()) { 16484 SourceLocation ChunkSizeLoc = ChunkSize->getBeginLoc(); 16485 ExprResult Val = 16486 PerformOpenMPImplicitIntegerConversion(ChunkSizeLoc, ChunkSize); 16487 if (Val.isInvalid()) 16488 return nullptr; 16489 16490 ValExpr = Val.get(); 16491 16492 // OpenMP [2.7.1, Restrictions] 16493 // chunk_size must be a loop invariant integer expression with a positive 16494 // value. 16495 if (Optional<llvm::APSInt> Result = 16496 ValExpr->getIntegerConstantExpr(Context)) { 16497 if (Result->isSigned() && !Result->isStrictlyPositive()) { 16498 Diag(ChunkSizeLoc, diag::err_omp_negative_expression_in_clause) 16499 << "schedule" << 1 << ChunkSize->getSourceRange(); 16500 return nullptr; 16501 } 16502 } else if (getOpenMPCaptureRegionForClause( 16503 DSAStack->getCurrentDirective(), OMPC_schedule, 16504 LangOpts.OpenMP) != OMPD_unknown && 16505 !CurContext->isDependentContext()) { 16506 ValExpr = MakeFullExpr(ValExpr).get(); 16507 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 16508 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 16509 HelperValStmt = buildPreInits(Context, Captures); 16510 } 16511 } 16512 } 16513 16514 return new (Context) 16515 OMPScheduleClause(StartLoc, LParenLoc, KindLoc, CommaLoc, EndLoc, Kind, 16516 ValExpr, HelperValStmt, M1, M1Loc, M2, M2Loc); 16517 } 16518 16519 OMPClause *Sema::ActOnOpenMPClause(OpenMPClauseKind Kind, 16520 SourceLocation StartLoc, 16521 SourceLocation EndLoc) { 16522 OMPClause *Res = nullptr; 16523 switch (Kind) { 16524 case OMPC_ordered: 16525 Res = ActOnOpenMPOrderedClause(StartLoc, EndLoc); 16526 break; 16527 case OMPC_nowait: 16528 Res = ActOnOpenMPNowaitClause(StartLoc, EndLoc); 16529 break; 16530 case OMPC_untied: 16531 Res = ActOnOpenMPUntiedClause(StartLoc, EndLoc); 16532 break; 16533 case OMPC_mergeable: 16534 Res = ActOnOpenMPMergeableClause(StartLoc, EndLoc); 16535 break; 16536 case OMPC_read: 16537 Res = ActOnOpenMPReadClause(StartLoc, EndLoc); 16538 break; 16539 case OMPC_write: 16540 Res = ActOnOpenMPWriteClause(StartLoc, EndLoc); 16541 break; 16542 case OMPC_update: 16543 Res = ActOnOpenMPUpdateClause(StartLoc, EndLoc); 16544 break; 16545 case OMPC_capture: 16546 Res = ActOnOpenMPCaptureClause(StartLoc, EndLoc); 16547 break; 16548 case OMPC_compare: 16549 Res = ActOnOpenMPCompareClause(StartLoc, EndLoc); 16550 break; 16551 case OMPC_seq_cst: 16552 Res = ActOnOpenMPSeqCstClause(StartLoc, EndLoc); 16553 break; 16554 case OMPC_acq_rel: 16555 Res = ActOnOpenMPAcqRelClause(StartLoc, EndLoc); 16556 break; 16557 case OMPC_acquire: 16558 Res = ActOnOpenMPAcquireClause(StartLoc, EndLoc); 16559 break; 16560 case OMPC_release: 16561 Res = ActOnOpenMPReleaseClause(StartLoc, EndLoc); 16562 break; 16563 case OMPC_relaxed: 16564 Res = ActOnOpenMPRelaxedClause(StartLoc, EndLoc); 16565 break; 16566 case OMPC_threads: 16567 Res = ActOnOpenMPThreadsClause(StartLoc, EndLoc); 16568 break; 16569 case OMPC_simd: 16570 Res = ActOnOpenMPSIMDClause(StartLoc, EndLoc); 16571 break; 16572 case OMPC_nogroup: 16573 Res = ActOnOpenMPNogroupClause(StartLoc, EndLoc); 16574 break; 16575 case OMPC_unified_address: 16576 Res = ActOnOpenMPUnifiedAddressClause(StartLoc, EndLoc); 16577 break; 16578 case OMPC_unified_shared_memory: 16579 Res = ActOnOpenMPUnifiedSharedMemoryClause(StartLoc, EndLoc); 16580 break; 16581 case OMPC_reverse_offload: 16582 Res = ActOnOpenMPReverseOffloadClause(StartLoc, EndLoc); 16583 break; 16584 case OMPC_dynamic_allocators: 16585 Res = ActOnOpenMPDynamicAllocatorsClause(StartLoc, EndLoc); 16586 break; 16587 case OMPC_destroy: 16588 Res = ActOnOpenMPDestroyClause(/*InteropVar=*/nullptr, StartLoc, 16589 /*LParenLoc=*/SourceLocation(), 16590 /*VarLoc=*/SourceLocation(), EndLoc); 16591 break; 16592 case OMPC_full: 16593 Res = ActOnOpenMPFullClause(StartLoc, EndLoc); 16594 break; 16595 case OMPC_partial: 16596 Res = ActOnOpenMPPartialClause(nullptr, StartLoc, /*LParenLoc=*/{}, EndLoc); 16597 break; 16598 case OMPC_if: 16599 case OMPC_final: 16600 case OMPC_num_threads: 16601 case OMPC_safelen: 16602 case OMPC_simdlen: 16603 case OMPC_sizes: 16604 case OMPC_allocator: 16605 case OMPC_collapse: 16606 case OMPC_schedule: 16607 case OMPC_private: 16608 case OMPC_firstprivate: 16609 case OMPC_lastprivate: 16610 case OMPC_shared: 16611 case OMPC_reduction: 16612 case OMPC_task_reduction: 16613 case OMPC_in_reduction: 16614 case OMPC_linear: 16615 case OMPC_aligned: 16616 case OMPC_copyin: 16617 case OMPC_copyprivate: 16618 case OMPC_default: 16619 case OMPC_proc_bind: 16620 case OMPC_threadprivate: 16621 case OMPC_allocate: 16622 case OMPC_flush: 16623 case OMPC_depobj: 16624 case OMPC_depend: 16625 case OMPC_device: 16626 case OMPC_map: 16627 case OMPC_num_teams: 16628 case OMPC_thread_limit: 16629 case OMPC_priority: 16630 case OMPC_grainsize: 16631 case OMPC_num_tasks: 16632 case OMPC_hint: 16633 case OMPC_dist_schedule: 16634 case OMPC_defaultmap: 16635 case OMPC_unknown: 16636 case OMPC_uniform: 16637 case OMPC_to: 16638 case OMPC_from: 16639 case OMPC_use_device_ptr: 16640 case OMPC_use_device_addr: 16641 case OMPC_is_device_ptr: 16642 case OMPC_has_device_addr: 16643 case OMPC_atomic_default_mem_order: 16644 case OMPC_device_type: 16645 case OMPC_match: 16646 case OMPC_nontemporal: 16647 case OMPC_order: 16648 case OMPC_novariants: 16649 case OMPC_nocontext: 16650 case OMPC_detach: 16651 case OMPC_inclusive: 16652 case OMPC_exclusive: 16653 case OMPC_uses_allocators: 16654 case OMPC_affinity: 16655 case OMPC_when: 16656 default: 16657 llvm_unreachable("Clause is not allowed."); 16658 } 16659 return Res; 16660 } 16661 16662 OMPClause *Sema::ActOnOpenMPNowaitClause(SourceLocation StartLoc, 16663 SourceLocation EndLoc) { 16664 DSAStack->setNowaitRegion(); 16665 return new (Context) OMPNowaitClause(StartLoc, EndLoc); 16666 } 16667 16668 OMPClause *Sema::ActOnOpenMPUntiedClause(SourceLocation StartLoc, 16669 SourceLocation EndLoc) { 16670 DSAStack->setUntiedRegion(); 16671 return new (Context) OMPUntiedClause(StartLoc, EndLoc); 16672 } 16673 16674 OMPClause *Sema::ActOnOpenMPMergeableClause(SourceLocation StartLoc, 16675 SourceLocation EndLoc) { 16676 return new (Context) OMPMergeableClause(StartLoc, EndLoc); 16677 } 16678 16679 OMPClause *Sema::ActOnOpenMPReadClause(SourceLocation StartLoc, 16680 SourceLocation EndLoc) { 16681 return new (Context) OMPReadClause(StartLoc, EndLoc); 16682 } 16683 16684 OMPClause *Sema::ActOnOpenMPWriteClause(SourceLocation StartLoc, 16685 SourceLocation EndLoc) { 16686 return new (Context) OMPWriteClause(StartLoc, EndLoc); 16687 } 16688 16689 OMPClause *Sema::ActOnOpenMPUpdateClause(SourceLocation StartLoc, 16690 SourceLocation EndLoc) { 16691 return OMPUpdateClause::Create(Context, StartLoc, EndLoc); 16692 } 16693 16694 OMPClause *Sema::ActOnOpenMPCaptureClause(SourceLocation StartLoc, 16695 SourceLocation EndLoc) { 16696 return new (Context) OMPCaptureClause(StartLoc, EndLoc); 16697 } 16698 16699 OMPClause *Sema::ActOnOpenMPCompareClause(SourceLocation StartLoc, 16700 SourceLocation EndLoc) { 16701 return new (Context) OMPCompareClause(StartLoc, EndLoc); 16702 } 16703 16704 OMPClause *Sema::ActOnOpenMPSeqCstClause(SourceLocation StartLoc, 16705 SourceLocation EndLoc) { 16706 return new (Context) OMPSeqCstClause(StartLoc, EndLoc); 16707 } 16708 16709 OMPClause *Sema::ActOnOpenMPAcqRelClause(SourceLocation StartLoc, 16710 SourceLocation EndLoc) { 16711 return new (Context) OMPAcqRelClause(StartLoc, EndLoc); 16712 } 16713 16714 OMPClause *Sema::ActOnOpenMPAcquireClause(SourceLocation StartLoc, 16715 SourceLocation EndLoc) { 16716 return new (Context) OMPAcquireClause(StartLoc, EndLoc); 16717 } 16718 16719 OMPClause *Sema::ActOnOpenMPReleaseClause(SourceLocation StartLoc, 16720 SourceLocation EndLoc) { 16721 return new (Context) OMPReleaseClause(StartLoc, EndLoc); 16722 } 16723 16724 OMPClause *Sema::ActOnOpenMPRelaxedClause(SourceLocation StartLoc, 16725 SourceLocation EndLoc) { 16726 return new (Context) OMPRelaxedClause(StartLoc, EndLoc); 16727 } 16728 16729 OMPClause *Sema::ActOnOpenMPThreadsClause(SourceLocation StartLoc, 16730 SourceLocation EndLoc) { 16731 return new (Context) OMPThreadsClause(StartLoc, EndLoc); 16732 } 16733 16734 OMPClause *Sema::ActOnOpenMPSIMDClause(SourceLocation StartLoc, 16735 SourceLocation EndLoc) { 16736 return new (Context) OMPSIMDClause(StartLoc, EndLoc); 16737 } 16738 16739 OMPClause *Sema::ActOnOpenMPNogroupClause(SourceLocation StartLoc, 16740 SourceLocation EndLoc) { 16741 return new (Context) OMPNogroupClause(StartLoc, EndLoc); 16742 } 16743 16744 OMPClause *Sema::ActOnOpenMPUnifiedAddressClause(SourceLocation StartLoc, 16745 SourceLocation EndLoc) { 16746 return new (Context) OMPUnifiedAddressClause(StartLoc, EndLoc); 16747 } 16748 16749 OMPClause *Sema::ActOnOpenMPUnifiedSharedMemoryClause(SourceLocation StartLoc, 16750 SourceLocation EndLoc) { 16751 return new (Context) OMPUnifiedSharedMemoryClause(StartLoc, EndLoc); 16752 } 16753 16754 OMPClause *Sema::ActOnOpenMPReverseOffloadClause(SourceLocation StartLoc, 16755 SourceLocation EndLoc) { 16756 return new (Context) OMPReverseOffloadClause(StartLoc, EndLoc); 16757 } 16758 16759 OMPClause *Sema::ActOnOpenMPDynamicAllocatorsClause(SourceLocation StartLoc, 16760 SourceLocation EndLoc) { 16761 return new (Context) OMPDynamicAllocatorsClause(StartLoc, EndLoc); 16762 } 16763 16764 StmtResult Sema::ActOnOpenMPInteropDirective(ArrayRef<OMPClause *> Clauses, 16765 SourceLocation StartLoc, 16766 SourceLocation EndLoc) { 16767 16768 // OpenMP 5.1 [2.15.1, interop Construct, Restrictions] 16769 // At least one action-clause must appear on a directive. 16770 if (!hasClauses(Clauses, OMPC_init, OMPC_use, OMPC_destroy, OMPC_nowait)) { 16771 StringRef Expected = "'init', 'use', 'destroy', or 'nowait'"; 16772 Diag(StartLoc, diag::err_omp_no_clause_for_directive) 16773 << Expected << getOpenMPDirectiveName(OMPD_interop); 16774 return StmtError(); 16775 } 16776 16777 // OpenMP 5.1 [2.15.1, interop Construct, Restrictions] 16778 // A depend clause can only appear on the directive if a targetsync 16779 // interop-type is present or the interop-var was initialized with 16780 // the targetsync interop-type. 16781 16782 // If there is any 'init' clause diagnose if there is no 'init' clause with 16783 // interop-type of 'targetsync'. Cases involving other directives cannot be 16784 // diagnosed. 16785 const OMPDependClause *DependClause = nullptr; 16786 bool HasInitClause = false; 16787 bool IsTargetSync = false; 16788 for (const OMPClause *C : Clauses) { 16789 if (IsTargetSync) 16790 break; 16791 if (const auto *InitClause = dyn_cast<OMPInitClause>(C)) { 16792 HasInitClause = true; 16793 if (InitClause->getIsTargetSync()) 16794 IsTargetSync = true; 16795 } else if (const auto *DC = dyn_cast<OMPDependClause>(C)) { 16796 DependClause = DC; 16797 } 16798 } 16799 if (DependClause && HasInitClause && !IsTargetSync) { 16800 Diag(DependClause->getBeginLoc(), diag::err_omp_interop_bad_depend_clause); 16801 return StmtError(); 16802 } 16803 16804 // OpenMP 5.1 [2.15.1, interop Construct, Restrictions] 16805 // Each interop-var may be specified for at most one action-clause of each 16806 // interop construct. 16807 llvm::SmallPtrSet<const VarDecl *, 4> InteropVars; 16808 for (const OMPClause *C : Clauses) { 16809 OpenMPClauseKind ClauseKind = C->getClauseKind(); 16810 const DeclRefExpr *DRE = nullptr; 16811 SourceLocation VarLoc; 16812 16813 if (ClauseKind == OMPC_init) { 16814 const auto *IC = cast<OMPInitClause>(C); 16815 VarLoc = IC->getVarLoc(); 16816 DRE = dyn_cast_or_null<DeclRefExpr>(IC->getInteropVar()); 16817 } else if (ClauseKind == OMPC_use) { 16818 const auto *UC = cast<OMPUseClause>(C); 16819 VarLoc = UC->getVarLoc(); 16820 DRE = dyn_cast_or_null<DeclRefExpr>(UC->getInteropVar()); 16821 } else if (ClauseKind == OMPC_destroy) { 16822 const auto *DC = cast<OMPDestroyClause>(C); 16823 VarLoc = DC->getVarLoc(); 16824 DRE = dyn_cast_or_null<DeclRefExpr>(DC->getInteropVar()); 16825 } 16826 16827 if (!DRE) 16828 continue; 16829 16830 if (const auto *VD = dyn_cast<VarDecl>(DRE->getDecl())) { 16831 if (!InteropVars.insert(VD->getCanonicalDecl()).second) { 16832 Diag(VarLoc, diag::err_omp_interop_var_multiple_actions) << VD; 16833 return StmtError(); 16834 } 16835 } 16836 } 16837 16838 return OMPInteropDirective::Create(Context, StartLoc, EndLoc, Clauses); 16839 } 16840 16841 static bool isValidInteropVariable(Sema &SemaRef, Expr *InteropVarExpr, 16842 SourceLocation VarLoc, 16843 OpenMPClauseKind Kind) { 16844 if (InteropVarExpr->isValueDependent() || InteropVarExpr->isTypeDependent() || 16845 InteropVarExpr->isInstantiationDependent() || 16846 InteropVarExpr->containsUnexpandedParameterPack()) 16847 return true; 16848 16849 const auto *DRE = dyn_cast<DeclRefExpr>(InteropVarExpr); 16850 if (!DRE || !isa<VarDecl>(DRE->getDecl())) { 16851 SemaRef.Diag(VarLoc, diag::err_omp_interop_variable_expected) << 0; 16852 return false; 16853 } 16854 16855 // Interop variable should be of type omp_interop_t. 16856 bool HasError = false; 16857 QualType InteropType; 16858 LookupResult Result(SemaRef, &SemaRef.Context.Idents.get("omp_interop_t"), 16859 VarLoc, Sema::LookupOrdinaryName); 16860 if (SemaRef.LookupName(Result, SemaRef.getCurScope())) { 16861 NamedDecl *ND = Result.getFoundDecl(); 16862 if (const auto *TD = dyn_cast<TypeDecl>(ND)) { 16863 InteropType = QualType(TD->getTypeForDecl(), 0); 16864 } else { 16865 HasError = true; 16866 } 16867 } else { 16868 HasError = true; 16869 } 16870 16871 if (HasError) { 16872 SemaRef.Diag(VarLoc, diag::err_omp_implied_type_not_found) 16873 << "omp_interop_t"; 16874 return false; 16875 } 16876 16877 QualType VarType = InteropVarExpr->getType().getUnqualifiedType(); 16878 if (!SemaRef.Context.hasSameType(InteropType, VarType)) { 16879 SemaRef.Diag(VarLoc, diag::err_omp_interop_variable_wrong_type); 16880 return false; 16881 } 16882 16883 // OpenMP 5.1 [2.15.1, interop Construct, Restrictions] 16884 // The interop-var passed to init or destroy must be non-const. 16885 if ((Kind == OMPC_init || Kind == OMPC_destroy) && 16886 isConstNotMutableType(SemaRef, InteropVarExpr->getType())) { 16887 SemaRef.Diag(VarLoc, diag::err_omp_interop_variable_expected) 16888 << /*non-const*/ 1; 16889 return false; 16890 } 16891 return true; 16892 } 16893 16894 OMPClause * 16895 Sema::ActOnOpenMPInitClause(Expr *InteropVar, ArrayRef<Expr *> PrefExprs, 16896 bool IsTarget, bool IsTargetSync, 16897 SourceLocation StartLoc, SourceLocation LParenLoc, 16898 SourceLocation VarLoc, SourceLocation EndLoc) { 16899 16900 if (!isValidInteropVariable(*this, InteropVar, VarLoc, OMPC_init)) 16901 return nullptr; 16902 16903 // Check prefer_type values. These foreign-runtime-id values are either 16904 // string literals or constant integral expressions. 16905 for (const Expr *E : PrefExprs) { 16906 if (E->isValueDependent() || E->isTypeDependent() || 16907 E->isInstantiationDependent() || E->containsUnexpandedParameterPack()) 16908 continue; 16909 if (E->isIntegerConstantExpr(Context)) 16910 continue; 16911 if (isa<StringLiteral>(E)) 16912 continue; 16913 Diag(E->getExprLoc(), diag::err_omp_interop_prefer_type); 16914 return nullptr; 16915 } 16916 16917 return OMPInitClause::Create(Context, InteropVar, PrefExprs, IsTarget, 16918 IsTargetSync, StartLoc, LParenLoc, VarLoc, 16919 EndLoc); 16920 } 16921 16922 OMPClause *Sema::ActOnOpenMPUseClause(Expr *InteropVar, SourceLocation StartLoc, 16923 SourceLocation LParenLoc, 16924 SourceLocation VarLoc, 16925 SourceLocation EndLoc) { 16926 16927 if (!isValidInteropVariable(*this, InteropVar, VarLoc, OMPC_use)) 16928 return nullptr; 16929 16930 return new (Context) 16931 OMPUseClause(InteropVar, StartLoc, LParenLoc, VarLoc, EndLoc); 16932 } 16933 16934 OMPClause *Sema::ActOnOpenMPDestroyClause(Expr *InteropVar, 16935 SourceLocation StartLoc, 16936 SourceLocation LParenLoc, 16937 SourceLocation VarLoc, 16938 SourceLocation EndLoc) { 16939 if (InteropVar && 16940 !isValidInteropVariable(*this, InteropVar, VarLoc, OMPC_destroy)) 16941 return nullptr; 16942 16943 return new (Context) 16944 OMPDestroyClause(InteropVar, StartLoc, LParenLoc, VarLoc, EndLoc); 16945 } 16946 16947 OMPClause *Sema::ActOnOpenMPNovariantsClause(Expr *Condition, 16948 SourceLocation StartLoc, 16949 SourceLocation LParenLoc, 16950 SourceLocation EndLoc) { 16951 Expr *ValExpr = Condition; 16952 Stmt *HelperValStmt = nullptr; 16953 OpenMPDirectiveKind CaptureRegion = OMPD_unknown; 16954 if (!Condition->isValueDependent() && !Condition->isTypeDependent() && 16955 !Condition->isInstantiationDependent() && 16956 !Condition->containsUnexpandedParameterPack()) { 16957 ExprResult Val = CheckBooleanCondition(StartLoc, Condition); 16958 if (Val.isInvalid()) 16959 return nullptr; 16960 16961 ValExpr = MakeFullExpr(Val.get()).get(); 16962 16963 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 16964 CaptureRegion = getOpenMPCaptureRegionForClause(DKind, OMPC_novariants, 16965 LangOpts.OpenMP); 16966 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 16967 ValExpr = MakeFullExpr(ValExpr).get(); 16968 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 16969 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 16970 HelperValStmt = buildPreInits(Context, Captures); 16971 } 16972 } 16973 16974 return new (Context) OMPNovariantsClause( 16975 ValExpr, HelperValStmt, CaptureRegion, StartLoc, LParenLoc, EndLoc); 16976 } 16977 16978 OMPClause *Sema::ActOnOpenMPNocontextClause(Expr *Condition, 16979 SourceLocation StartLoc, 16980 SourceLocation LParenLoc, 16981 SourceLocation EndLoc) { 16982 Expr *ValExpr = Condition; 16983 Stmt *HelperValStmt = nullptr; 16984 OpenMPDirectiveKind CaptureRegion = OMPD_unknown; 16985 if (!Condition->isValueDependent() && !Condition->isTypeDependent() && 16986 !Condition->isInstantiationDependent() && 16987 !Condition->containsUnexpandedParameterPack()) { 16988 ExprResult Val = CheckBooleanCondition(StartLoc, Condition); 16989 if (Val.isInvalid()) 16990 return nullptr; 16991 16992 ValExpr = MakeFullExpr(Val.get()).get(); 16993 16994 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 16995 CaptureRegion = 16996 getOpenMPCaptureRegionForClause(DKind, OMPC_nocontext, LangOpts.OpenMP); 16997 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 16998 ValExpr = MakeFullExpr(ValExpr).get(); 16999 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 17000 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 17001 HelperValStmt = buildPreInits(Context, Captures); 17002 } 17003 } 17004 17005 return new (Context) OMPNocontextClause(ValExpr, HelperValStmt, CaptureRegion, 17006 StartLoc, LParenLoc, EndLoc); 17007 } 17008 17009 OMPClause *Sema::ActOnOpenMPFilterClause(Expr *ThreadID, 17010 SourceLocation StartLoc, 17011 SourceLocation LParenLoc, 17012 SourceLocation EndLoc) { 17013 Expr *ValExpr = ThreadID; 17014 Stmt *HelperValStmt = nullptr; 17015 17016 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 17017 OpenMPDirectiveKind CaptureRegion = 17018 getOpenMPCaptureRegionForClause(DKind, OMPC_filter, LangOpts.OpenMP); 17019 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 17020 ValExpr = MakeFullExpr(ValExpr).get(); 17021 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 17022 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 17023 HelperValStmt = buildPreInits(Context, Captures); 17024 } 17025 17026 return new (Context) OMPFilterClause(ValExpr, HelperValStmt, CaptureRegion, 17027 StartLoc, LParenLoc, EndLoc); 17028 } 17029 17030 OMPClause *Sema::ActOnOpenMPVarListClause(OpenMPClauseKind Kind, 17031 ArrayRef<Expr *> VarList, 17032 const OMPVarListLocTy &Locs, 17033 OpenMPVarListDataTy &Data) { 17034 SourceLocation StartLoc = Locs.StartLoc; 17035 SourceLocation LParenLoc = Locs.LParenLoc; 17036 SourceLocation EndLoc = Locs.EndLoc; 17037 OMPClause *Res = nullptr; 17038 int ExtraModifier = Data.ExtraModifier; 17039 SourceLocation ExtraModifierLoc = Data.ExtraModifierLoc; 17040 SourceLocation ColonLoc = Data.ColonLoc; 17041 switch (Kind) { 17042 case OMPC_private: 17043 Res = ActOnOpenMPPrivateClause(VarList, StartLoc, LParenLoc, EndLoc); 17044 break; 17045 case OMPC_firstprivate: 17046 Res = ActOnOpenMPFirstprivateClause(VarList, StartLoc, LParenLoc, EndLoc); 17047 break; 17048 case OMPC_lastprivate: 17049 assert(0 <= ExtraModifier && ExtraModifier <= OMPC_LASTPRIVATE_unknown && 17050 "Unexpected lastprivate modifier."); 17051 Res = ActOnOpenMPLastprivateClause( 17052 VarList, static_cast<OpenMPLastprivateModifier>(ExtraModifier), 17053 ExtraModifierLoc, ColonLoc, StartLoc, LParenLoc, EndLoc); 17054 break; 17055 case OMPC_shared: 17056 Res = ActOnOpenMPSharedClause(VarList, StartLoc, LParenLoc, EndLoc); 17057 break; 17058 case OMPC_reduction: 17059 assert(0 <= ExtraModifier && ExtraModifier <= OMPC_REDUCTION_unknown && 17060 "Unexpected lastprivate modifier."); 17061 Res = ActOnOpenMPReductionClause( 17062 VarList, static_cast<OpenMPReductionClauseModifier>(ExtraModifier), 17063 StartLoc, LParenLoc, ExtraModifierLoc, ColonLoc, EndLoc, 17064 Data.ReductionOrMapperIdScopeSpec, Data.ReductionOrMapperId); 17065 break; 17066 case OMPC_task_reduction: 17067 Res = ActOnOpenMPTaskReductionClause( 17068 VarList, StartLoc, LParenLoc, ColonLoc, EndLoc, 17069 Data.ReductionOrMapperIdScopeSpec, Data.ReductionOrMapperId); 17070 break; 17071 case OMPC_in_reduction: 17072 Res = ActOnOpenMPInReductionClause( 17073 VarList, StartLoc, LParenLoc, ColonLoc, EndLoc, 17074 Data.ReductionOrMapperIdScopeSpec, Data.ReductionOrMapperId); 17075 break; 17076 case OMPC_linear: 17077 assert(0 <= ExtraModifier && ExtraModifier <= OMPC_LINEAR_unknown && 17078 "Unexpected linear modifier."); 17079 Res = ActOnOpenMPLinearClause( 17080 VarList, Data.DepModOrTailExpr, StartLoc, LParenLoc, 17081 static_cast<OpenMPLinearClauseKind>(ExtraModifier), ExtraModifierLoc, 17082 ColonLoc, EndLoc); 17083 break; 17084 case OMPC_aligned: 17085 Res = ActOnOpenMPAlignedClause(VarList, Data.DepModOrTailExpr, StartLoc, 17086 LParenLoc, ColonLoc, EndLoc); 17087 break; 17088 case OMPC_copyin: 17089 Res = ActOnOpenMPCopyinClause(VarList, StartLoc, LParenLoc, EndLoc); 17090 break; 17091 case OMPC_copyprivate: 17092 Res = ActOnOpenMPCopyprivateClause(VarList, StartLoc, LParenLoc, EndLoc); 17093 break; 17094 case OMPC_flush: 17095 Res = ActOnOpenMPFlushClause(VarList, StartLoc, LParenLoc, EndLoc); 17096 break; 17097 case OMPC_depend: 17098 assert(0 <= ExtraModifier && ExtraModifier <= OMPC_DEPEND_unknown && 17099 "Unexpected depend modifier."); 17100 Res = ActOnOpenMPDependClause( 17101 {static_cast<OpenMPDependClauseKind>(ExtraModifier), ExtraModifierLoc, 17102 ColonLoc, Data.OmpAllMemoryLoc}, 17103 Data.DepModOrTailExpr, VarList, StartLoc, LParenLoc, EndLoc); 17104 break; 17105 case OMPC_map: 17106 assert(0 <= ExtraModifier && ExtraModifier <= OMPC_MAP_unknown && 17107 "Unexpected map modifier."); 17108 Res = ActOnOpenMPMapClause( 17109 Data.MapTypeModifiers, Data.MapTypeModifiersLoc, 17110 Data.ReductionOrMapperIdScopeSpec, Data.ReductionOrMapperId, 17111 static_cast<OpenMPMapClauseKind>(ExtraModifier), Data.IsMapTypeImplicit, 17112 ExtraModifierLoc, ColonLoc, VarList, Locs); 17113 break; 17114 case OMPC_to: 17115 Res = 17116 ActOnOpenMPToClause(Data.MotionModifiers, Data.MotionModifiersLoc, 17117 Data.ReductionOrMapperIdScopeSpec, 17118 Data.ReductionOrMapperId, ColonLoc, VarList, Locs); 17119 break; 17120 case OMPC_from: 17121 Res = ActOnOpenMPFromClause(Data.MotionModifiers, Data.MotionModifiersLoc, 17122 Data.ReductionOrMapperIdScopeSpec, 17123 Data.ReductionOrMapperId, ColonLoc, VarList, 17124 Locs); 17125 break; 17126 case OMPC_use_device_ptr: 17127 Res = ActOnOpenMPUseDevicePtrClause(VarList, Locs); 17128 break; 17129 case OMPC_use_device_addr: 17130 Res = ActOnOpenMPUseDeviceAddrClause(VarList, Locs); 17131 break; 17132 case OMPC_is_device_ptr: 17133 Res = ActOnOpenMPIsDevicePtrClause(VarList, Locs); 17134 break; 17135 case OMPC_has_device_addr: 17136 Res = ActOnOpenMPHasDeviceAddrClause(VarList, Locs); 17137 break; 17138 case OMPC_allocate: 17139 Res = ActOnOpenMPAllocateClause(Data.DepModOrTailExpr, VarList, StartLoc, 17140 LParenLoc, ColonLoc, EndLoc); 17141 break; 17142 case OMPC_nontemporal: 17143 Res = ActOnOpenMPNontemporalClause(VarList, StartLoc, LParenLoc, EndLoc); 17144 break; 17145 case OMPC_inclusive: 17146 Res = ActOnOpenMPInclusiveClause(VarList, StartLoc, LParenLoc, EndLoc); 17147 break; 17148 case OMPC_exclusive: 17149 Res = ActOnOpenMPExclusiveClause(VarList, StartLoc, LParenLoc, EndLoc); 17150 break; 17151 case OMPC_affinity: 17152 Res = ActOnOpenMPAffinityClause(StartLoc, LParenLoc, ColonLoc, EndLoc, 17153 Data.DepModOrTailExpr, VarList); 17154 break; 17155 case OMPC_if: 17156 case OMPC_depobj: 17157 case OMPC_final: 17158 case OMPC_num_threads: 17159 case OMPC_safelen: 17160 case OMPC_simdlen: 17161 case OMPC_sizes: 17162 case OMPC_allocator: 17163 case OMPC_collapse: 17164 case OMPC_default: 17165 case OMPC_proc_bind: 17166 case OMPC_schedule: 17167 case OMPC_ordered: 17168 case OMPC_nowait: 17169 case OMPC_untied: 17170 case OMPC_mergeable: 17171 case OMPC_threadprivate: 17172 case OMPC_read: 17173 case OMPC_write: 17174 case OMPC_update: 17175 case OMPC_capture: 17176 case OMPC_compare: 17177 case OMPC_seq_cst: 17178 case OMPC_acq_rel: 17179 case OMPC_acquire: 17180 case OMPC_release: 17181 case OMPC_relaxed: 17182 case OMPC_device: 17183 case OMPC_threads: 17184 case OMPC_simd: 17185 case OMPC_num_teams: 17186 case OMPC_thread_limit: 17187 case OMPC_priority: 17188 case OMPC_grainsize: 17189 case OMPC_nogroup: 17190 case OMPC_num_tasks: 17191 case OMPC_hint: 17192 case OMPC_dist_schedule: 17193 case OMPC_defaultmap: 17194 case OMPC_unknown: 17195 case OMPC_uniform: 17196 case OMPC_unified_address: 17197 case OMPC_unified_shared_memory: 17198 case OMPC_reverse_offload: 17199 case OMPC_dynamic_allocators: 17200 case OMPC_atomic_default_mem_order: 17201 case OMPC_device_type: 17202 case OMPC_match: 17203 case OMPC_order: 17204 case OMPC_destroy: 17205 case OMPC_novariants: 17206 case OMPC_nocontext: 17207 case OMPC_detach: 17208 case OMPC_uses_allocators: 17209 case OMPC_when: 17210 case OMPC_bind: 17211 default: 17212 llvm_unreachable("Clause is not allowed."); 17213 } 17214 return Res; 17215 } 17216 17217 ExprResult Sema::getOpenMPCapturedExpr(VarDecl *Capture, ExprValueKind VK, 17218 ExprObjectKind OK, SourceLocation Loc) { 17219 ExprResult Res = BuildDeclRefExpr( 17220 Capture, Capture->getType().getNonReferenceType(), VK_LValue, Loc); 17221 if (!Res.isUsable()) 17222 return ExprError(); 17223 if (OK == OK_Ordinary && !getLangOpts().CPlusPlus) { 17224 Res = CreateBuiltinUnaryOp(Loc, UO_Deref, Res.get()); 17225 if (!Res.isUsable()) 17226 return ExprError(); 17227 } 17228 if (VK != VK_LValue && Res.get()->isGLValue()) { 17229 Res = DefaultLvalueConversion(Res.get()); 17230 if (!Res.isUsable()) 17231 return ExprError(); 17232 } 17233 return Res; 17234 } 17235 17236 OMPClause *Sema::ActOnOpenMPPrivateClause(ArrayRef<Expr *> VarList, 17237 SourceLocation StartLoc, 17238 SourceLocation LParenLoc, 17239 SourceLocation EndLoc) { 17240 SmallVector<Expr *, 8> Vars; 17241 SmallVector<Expr *, 8> PrivateCopies; 17242 for (Expr *RefExpr : VarList) { 17243 assert(RefExpr && "NULL expr in OpenMP private clause."); 17244 SourceLocation ELoc; 17245 SourceRange ERange; 17246 Expr *SimpleRefExpr = RefExpr; 17247 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 17248 if (Res.second) { 17249 // It will be analyzed later. 17250 Vars.push_back(RefExpr); 17251 PrivateCopies.push_back(nullptr); 17252 } 17253 ValueDecl *D = Res.first; 17254 if (!D) 17255 continue; 17256 17257 QualType Type = D->getType(); 17258 auto *VD = dyn_cast<VarDecl>(D); 17259 17260 // OpenMP [2.9.3.3, Restrictions, C/C++, p.3] 17261 // A variable that appears in a private clause must not have an incomplete 17262 // type or a reference type. 17263 if (RequireCompleteType(ELoc, Type, diag::err_omp_private_incomplete_type)) 17264 continue; 17265 Type = Type.getNonReferenceType(); 17266 17267 // OpenMP 5.0 [2.19.3, List Item Privatization, Restrictions] 17268 // A variable that is privatized must not have a const-qualified type 17269 // unless it is of class type with a mutable member. This restriction does 17270 // not apply to the firstprivate clause. 17271 // 17272 // OpenMP 3.1 [2.9.3.3, private clause, Restrictions] 17273 // A variable that appears in a private clause must not have a 17274 // const-qualified type unless it is of class type with a mutable member. 17275 if (rejectConstNotMutableType(*this, D, Type, OMPC_private, ELoc)) 17276 continue; 17277 17278 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 17279 // in a Construct] 17280 // Variables with the predetermined data-sharing attributes may not be 17281 // listed in data-sharing attributes clauses, except for the cases 17282 // listed below. For these exceptions only, listing a predetermined 17283 // variable in a data-sharing attribute clause is allowed and overrides 17284 // the variable's predetermined data-sharing attributes. 17285 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false); 17286 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_private) { 17287 Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind) 17288 << getOpenMPClauseName(OMPC_private); 17289 reportOriginalDsa(*this, DSAStack, D, DVar); 17290 continue; 17291 } 17292 17293 OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective(); 17294 // Variably modified types are not supported for tasks. 17295 if (!Type->isAnyPointerType() && Type->isVariablyModifiedType() && 17296 isOpenMPTaskingDirective(CurrDir)) { 17297 Diag(ELoc, diag::err_omp_variably_modified_type_not_supported) 17298 << getOpenMPClauseName(OMPC_private) << Type 17299 << getOpenMPDirectiveName(CurrDir); 17300 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) == 17301 VarDecl::DeclarationOnly; 17302 Diag(D->getLocation(), 17303 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 17304 << D; 17305 continue; 17306 } 17307 17308 // OpenMP 4.5 [2.15.5.1, Restrictions, p.3] 17309 // A list item cannot appear in both a map clause and a data-sharing 17310 // attribute clause on the same construct 17311 // 17312 // OpenMP 5.0 [2.19.7.1, Restrictions, p.7] 17313 // A list item cannot appear in both a map clause and a data-sharing 17314 // attribute clause on the same construct unless the construct is a 17315 // combined construct. 17316 if ((LangOpts.OpenMP <= 45 && isOpenMPTargetExecutionDirective(CurrDir)) || 17317 CurrDir == OMPD_target) { 17318 OpenMPClauseKind ConflictKind; 17319 if (DSAStack->checkMappableExprComponentListsForDecl( 17320 VD, /*CurrentRegionOnly=*/true, 17321 [&](OMPClauseMappableExprCommon::MappableExprComponentListRef, 17322 OpenMPClauseKind WhereFoundClauseKind) -> bool { 17323 ConflictKind = WhereFoundClauseKind; 17324 return true; 17325 })) { 17326 Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa) 17327 << getOpenMPClauseName(OMPC_private) 17328 << getOpenMPClauseName(ConflictKind) 17329 << getOpenMPDirectiveName(CurrDir); 17330 reportOriginalDsa(*this, DSAStack, D, DVar); 17331 continue; 17332 } 17333 } 17334 17335 // OpenMP [2.9.3.3, Restrictions, C/C++, p.1] 17336 // A variable of class type (or array thereof) that appears in a private 17337 // clause requires an accessible, unambiguous default constructor for the 17338 // class type. 17339 // Generate helper private variable and initialize it with the default 17340 // value. The address of the original variable is replaced by the address of 17341 // the new private variable in CodeGen. This new variable is not added to 17342 // IdResolver, so the code in the OpenMP region uses original variable for 17343 // proper diagnostics. 17344 Type = Type.getUnqualifiedType(); 17345 VarDecl *VDPrivate = 17346 buildVarDecl(*this, ELoc, Type, D->getName(), 17347 D->hasAttrs() ? &D->getAttrs() : nullptr, 17348 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr); 17349 ActOnUninitializedDecl(VDPrivate); 17350 if (VDPrivate->isInvalidDecl()) 17351 continue; 17352 DeclRefExpr *VDPrivateRefExpr = buildDeclRefExpr( 17353 *this, VDPrivate, RefExpr->getType().getUnqualifiedType(), ELoc); 17354 17355 DeclRefExpr *Ref = nullptr; 17356 if (!VD && !CurContext->isDependentContext()) 17357 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false); 17358 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_private, Ref); 17359 Vars.push_back((VD || CurContext->isDependentContext()) 17360 ? RefExpr->IgnoreParens() 17361 : Ref); 17362 PrivateCopies.push_back(VDPrivateRefExpr); 17363 } 17364 17365 if (Vars.empty()) 17366 return nullptr; 17367 17368 return OMPPrivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars, 17369 PrivateCopies); 17370 } 17371 17372 OMPClause *Sema::ActOnOpenMPFirstprivateClause(ArrayRef<Expr *> VarList, 17373 SourceLocation StartLoc, 17374 SourceLocation LParenLoc, 17375 SourceLocation EndLoc) { 17376 SmallVector<Expr *, 8> Vars; 17377 SmallVector<Expr *, 8> PrivateCopies; 17378 SmallVector<Expr *, 8> Inits; 17379 SmallVector<Decl *, 4> ExprCaptures; 17380 bool IsImplicitClause = 17381 StartLoc.isInvalid() && LParenLoc.isInvalid() && EndLoc.isInvalid(); 17382 SourceLocation ImplicitClauseLoc = DSAStack->getConstructLoc(); 17383 17384 for (Expr *RefExpr : VarList) { 17385 assert(RefExpr && "NULL expr in OpenMP firstprivate clause."); 17386 SourceLocation ELoc; 17387 SourceRange ERange; 17388 Expr *SimpleRefExpr = RefExpr; 17389 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 17390 if (Res.second) { 17391 // It will be analyzed later. 17392 Vars.push_back(RefExpr); 17393 PrivateCopies.push_back(nullptr); 17394 Inits.push_back(nullptr); 17395 } 17396 ValueDecl *D = Res.first; 17397 if (!D) 17398 continue; 17399 17400 ELoc = IsImplicitClause ? ImplicitClauseLoc : ELoc; 17401 QualType Type = D->getType(); 17402 auto *VD = dyn_cast<VarDecl>(D); 17403 17404 // OpenMP [2.9.3.3, Restrictions, C/C++, p.3] 17405 // A variable that appears in a private clause must not have an incomplete 17406 // type or a reference type. 17407 if (RequireCompleteType(ELoc, Type, 17408 diag::err_omp_firstprivate_incomplete_type)) 17409 continue; 17410 Type = Type.getNonReferenceType(); 17411 17412 // OpenMP [2.9.3.4, Restrictions, C/C++, p.1] 17413 // A variable of class type (or array thereof) that appears in a private 17414 // clause requires an accessible, unambiguous copy constructor for the 17415 // class type. 17416 QualType ElemType = Context.getBaseElementType(Type).getNonReferenceType(); 17417 17418 // If an implicit firstprivate variable found it was checked already. 17419 DSAStackTy::DSAVarData TopDVar; 17420 if (!IsImplicitClause) { 17421 DSAStackTy::DSAVarData DVar = 17422 DSAStack->getTopDSA(D, /*FromParent=*/false); 17423 TopDVar = DVar; 17424 OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective(); 17425 bool IsConstant = ElemType.isConstant(Context); 17426 // OpenMP [2.4.13, Data-sharing Attribute Clauses] 17427 // A list item that specifies a given variable may not appear in more 17428 // than one clause on the same directive, except that a variable may be 17429 // specified in both firstprivate and lastprivate clauses. 17430 // OpenMP 4.5 [2.10.8, Distribute Construct, p.3] 17431 // A list item may appear in a firstprivate or lastprivate clause but not 17432 // both. 17433 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_firstprivate && 17434 (isOpenMPDistributeDirective(CurrDir) || 17435 DVar.CKind != OMPC_lastprivate) && 17436 DVar.RefExpr) { 17437 Diag(ELoc, diag::err_omp_wrong_dsa) 17438 << getOpenMPClauseName(DVar.CKind) 17439 << getOpenMPClauseName(OMPC_firstprivate); 17440 reportOriginalDsa(*this, DSAStack, D, DVar); 17441 continue; 17442 } 17443 17444 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 17445 // in a Construct] 17446 // Variables with the predetermined data-sharing attributes may not be 17447 // listed in data-sharing attributes clauses, except for the cases 17448 // listed below. For these exceptions only, listing a predetermined 17449 // variable in a data-sharing attribute clause is allowed and overrides 17450 // the variable's predetermined data-sharing attributes. 17451 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 17452 // in a Construct, C/C++, p.2] 17453 // Variables with const-qualified type having no mutable member may be 17454 // listed in a firstprivate clause, even if they are static data members. 17455 if (!(IsConstant || (VD && VD->isStaticDataMember())) && !DVar.RefExpr && 17456 DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_shared) { 17457 Diag(ELoc, diag::err_omp_wrong_dsa) 17458 << getOpenMPClauseName(DVar.CKind) 17459 << getOpenMPClauseName(OMPC_firstprivate); 17460 reportOriginalDsa(*this, DSAStack, D, DVar); 17461 continue; 17462 } 17463 17464 // OpenMP [2.9.3.4, Restrictions, p.2] 17465 // A list item that is private within a parallel region must not appear 17466 // in a firstprivate clause on a worksharing construct if any of the 17467 // worksharing regions arising from the worksharing construct ever bind 17468 // to any of the parallel regions arising from the parallel construct. 17469 // OpenMP 4.5 [2.15.3.4, Restrictions, p.3] 17470 // A list item that is private within a teams region must not appear in a 17471 // firstprivate clause on a distribute construct if any of the distribute 17472 // regions arising from the distribute construct ever bind to any of the 17473 // teams regions arising from the teams construct. 17474 // OpenMP 4.5 [2.15.3.4, Restrictions, p.3] 17475 // A list item that appears in a reduction clause of a teams construct 17476 // must not appear in a firstprivate clause on a distribute construct if 17477 // any of the distribute regions arising from the distribute construct 17478 // ever bind to any of the teams regions arising from the teams construct. 17479 if ((isOpenMPWorksharingDirective(CurrDir) || 17480 isOpenMPDistributeDirective(CurrDir)) && 17481 !isOpenMPParallelDirective(CurrDir) && 17482 !isOpenMPTeamsDirective(CurrDir)) { 17483 DVar = DSAStack->getImplicitDSA(D, true); 17484 if (DVar.CKind != OMPC_shared && 17485 (isOpenMPParallelDirective(DVar.DKind) || 17486 isOpenMPTeamsDirective(DVar.DKind) || 17487 DVar.DKind == OMPD_unknown)) { 17488 Diag(ELoc, diag::err_omp_required_access) 17489 << getOpenMPClauseName(OMPC_firstprivate) 17490 << getOpenMPClauseName(OMPC_shared); 17491 reportOriginalDsa(*this, DSAStack, D, DVar); 17492 continue; 17493 } 17494 } 17495 // OpenMP [2.9.3.4, Restrictions, p.3] 17496 // A list item that appears in a reduction clause of a parallel construct 17497 // must not appear in a firstprivate clause on a worksharing or task 17498 // construct if any of the worksharing or task regions arising from the 17499 // worksharing or task construct ever bind to any of the parallel regions 17500 // arising from the parallel construct. 17501 // OpenMP [2.9.3.4, Restrictions, p.4] 17502 // A list item that appears in a reduction clause in worksharing 17503 // construct must not appear in a firstprivate clause in a task construct 17504 // encountered during execution of any of the worksharing regions arising 17505 // from the worksharing construct. 17506 if (isOpenMPTaskingDirective(CurrDir)) { 17507 DVar = DSAStack->hasInnermostDSA( 17508 D, 17509 [](OpenMPClauseKind C, bool AppliedToPointee) { 17510 return C == OMPC_reduction && !AppliedToPointee; 17511 }, 17512 [](OpenMPDirectiveKind K) { 17513 return isOpenMPParallelDirective(K) || 17514 isOpenMPWorksharingDirective(K) || 17515 isOpenMPTeamsDirective(K); 17516 }, 17517 /*FromParent=*/true); 17518 if (DVar.CKind == OMPC_reduction && 17519 (isOpenMPParallelDirective(DVar.DKind) || 17520 isOpenMPWorksharingDirective(DVar.DKind) || 17521 isOpenMPTeamsDirective(DVar.DKind))) { 17522 Diag(ELoc, diag::err_omp_parallel_reduction_in_task_firstprivate) 17523 << getOpenMPDirectiveName(DVar.DKind); 17524 reportOriginalDsa(*this, DSAStack, D, DVar); 17525 continue; 17526 } 17527 } 17528 17529 // OpenMP 4.5 [2.15.5.1, Restrictions, p.3] 17530 // A list item cannot appear in both a map clause and a data-sharing 17531 // attribute clause on the same construct 17532 // 17533 // OpenMP 5.0 [2.19.7.1, Restrictions, p.7] 17534 // A list item cannot appear in both a map clause and a data-sharing 17535 // attribute clause on the same construct unless the construct is a 17536 // combined construct. 17537 if ((LangOpts.OpenMP <= 45 && 17538 isOpenMPTargetExecutionDirective(CurrDir)) || 17539 CurrDir == OMPD_target) { 17540 OpenMPClauseKind ConflictKind; 17541 if (DSAStack->checkMappableExprComponentListsForDecl( 17542 VD, /*CurrentRegionOnly=*/true, 17543 [&ConflictKind]( 17544 OMPClauseMappableExprCommon::MappableExprComponentListRef, 17545 OpenMPClauseKind WhereFoundClauseKind) { 17546 ConflictKind = WhereFoundClauseKind; 17547 return true; 17548 })) { 17549 Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa) 17550 << getOpenMPClauseName(OMPC_firstprivate) 17551 << getOpenMPClauseName(ConflictKind) 17552 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 17553 reportOriginalDsa(*this, DSAStack, D, DVar); 17554 continue; 17555 } 17556 } 17557 } 17558 17559 // Variably modified types are not supported for tasks. 17560 if (!Type->isAnyPointerType() && Type->isVariablyModifiedType() && 17561 isOpenMPTaskingDirective(DSAStack->getCurrentDirective())) { 17562 Diag(ELoc, diag::err_omp_variably_modified_type_not_supported) 17563 << getOpenMPClauseName(OMPC_firstprivate) << Type 17564 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 17565 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) == 17566 VarDecl::DeclarationOnly; 17567 Diag(D->getLocation(), 17568 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 17569 << D; 17570 continue; 17571 } 17572 17573 Type = Type.getUnqualifiedType(); 17574 VarDecl *VDPrivate = 17575 buildVarDecl(*this, ELoc, Type, D->getName(), 17576 D->hasAttrs() ? &D->getAttrs() : nullptr, 17577 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr); 17578 // Generate helper private variable and initialize it with the value of the 17579 // original variable. The address of the original variable is replaced by 17580 // the address of the new private variable in the CodeGen. This new variable 17581 // is not added to IdResolver, so the code in the OpenMP region uses 17582 // original variable for proper diagnostics and variable capturing. 17583 Expr *VDInitRefExpr = nullptr; 17584 // For arrays generate initializer for single element and replace it by the 17585 // original array element in CodeGen. 17586 if (Type->isArrayType()) { 17587 VarDecl *VDInit = 17588 buildVarDecl(*this, RefExpr->getExprLoc(), ElemType, D->getName()); 17589 VDInitRefExpr = buildDeclRefExpr(*this, VDInit, ElemType, ELoc); 17590 Expr *Init = DefaultLvalueConversion(VDInitRefExpr).get(); 17591 ElemType = ElemType.getUnqualifiedType(); 17592 VarDecl *VDInitTemp = buildVarDecl(*this, RefExpr->getExprLoc(), ElemType, 17593 ".firstprivate.temp"); 17594 InitializedEntity Entity = 17595 InitializedEntity::InitializeVariable(VDInitTemp); 17596 InitializationKind Kind = InitializationKind::CreateCopy(ELoc, ELoc); 17597 17598 InitializationSequence InitSeq(*this, Entity, Kind, Init); 17599 ExprResult Result = InitSeq.Perform(*this, Entity, Kind, Init); 17600 if (Result.isInvalid()) 17601 VDPrivate->setInvalidDecl(); 17602 else 17603 VDPrivate->setInit(Result.getAs<Expr>()); 17604 // Remove temp variable declaration. 17605 Context.Deallocate(VDInitTemp); 17606 } else { 17607 VarDecl *VDInit = buildVarDecl(*this, RefExpr->getExprLoc(), Type, 17608 ".firstprivate.temp"); 17609 VDInitRefExpr = buildDeclRefExpr(*this, VDInit, RefExpr->getType(), 17610 RefExpr->getExprLoc()); 17611 AddInitializerToDecl(VDPrivate, 17612 DefaultLvalueConversion(VDInitRefExpr).get(), 17613 /*DirectInit=*/false); 17614 } 17615 if (VDPrivate->isInvalidDecl()) { 17616 if (IsImplicitClause) { 17617 Diag(RefExpr->getExprLoc(), 17618 diag::note_omp_task_predetermined_firstprivate_here); 17619 } 17620 continue; 17621 } 17622 CurContext->addDecl(VDPrivate); 17623 DeclRefExpr *VDPrivateRefExpr = buildDeclRefExpr( 17624 *this, VDPrivate, RefExpr->getType().getUnqualifiedType(), 17625 RefExpr->getExprLoc()); 17626 DeclRefExpr *Ref = nullptr; 17627 if (!VD && !CurContext->isDependentContext()) { 17628 if (TopDVar.CKind == OMPC_lastprivate) { 17629 Ref = TopDVar.PrivateCopy; 17630 } else { 17631 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true); 17632 if (!isOpenMPCapturedDecl(D)) 17633 ExprCaptures.push_back(Ref->getDecl()); 17634 } 17635 } 17636 if (!IsImplicitClause) 17637 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_firstprivate, Ref); 17638 Vars.push_back((VD || CurContext->isDependentContext()) 17639 ? RefExpr->IgnoreParens() 17640 : Ref); 17641 PrivateCopies.push_back(VDPrivateRefExpr); 17642 Inits.push_back(VDInitRefExpr); 17643 } 17644 17645 if (Vars.empty()) 17646 return nullptr; 17647 17648 return OMPFirstprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, 17649 Vars, PrivateCopies, Inits, 17650 buildPreInits(Context, ExprCaptures)); 17651 } 17652 17653 OMPClause *Sema::ActOnOpenMPLastprivateClause( 17654 ArrayRef<Expr *> VarList, OpenMPLastprivateModifier LPKind, 17655 SourceLocation LPKindLoc, SourceLocation ColonLoc, SourceLocation StartLoc, 17656 SourceLocation LParenLoc, SourceLocation EndLoc) { 17657 if (LPKind == OMPC_LASTPRIVATE_unknown && LPKindLoc.isValid()) { 17658 assert(ColonLoc.isValid() && "Colon location must be valid."); 17659 Diag(LPKindLoc, diag::err_omp_unexpected_clause_value) 17660 << getListOfPossibleValues(OMPC_lastprivate, /*First=*/0, 17661 /*Last=*/OMPC_LASTPRIVATE_unknown) 17662 << getOpenMPClauseName(OMPC_lastprivate); 17663 return nullptr; 17664 } 17665 17666 SmallVector<Expr *, 8> Vars; 17667 SmallVector<Expr *, 8> SrcExprs; 17668 SmallVector<Expr *, 8> DstExprs; 17669 SmallVector<Expr *, 8> AssignmentOps; 17670 SmallVector<Decl *, 4> ExprCaptures; 17671 SmallVector<Expr *, 4> ExprPostUpdates; 17672 for (Expr *RefExpr : VarList) { 17673 assert(RefExpr && "NULL expr in OpenMP lastprivate clause."); 17674 SourceLocation ELoc; 17675 SourceRange ERange; 17676 Expr *SimpleRefExpr = RefExpr; 17677 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 17678 if (Res.second) { 17679 // It will be analyzed later. 17680 Vars.push_back(RefExpr); 17681 SrcExprs.push_back(nullptr); 17682 DstExprs.push_back(nullptr); 17683 AssignmentOps.push_back(nullptr); 17684 } 17685 ValueDecl *D = Res.first; 17686 if (!D) 17687 continue; 17688 17689 QualType Type = D->getType(); 17690 auto *VD = dyn_cast<VarDecl>(D); 17691 17692 // OpenMP [2.14.3.5, Restrictions, C/C++, p.2] 17693 // A variable that appears in a lastprivate clause must not have an 17694 // incomplete type or a reference type. 17695 if (RequireCompleteType(ELoc, Type, 17696 diag::err_omp_lastprivate_incomplete_type)) 17697 continue; 17698 Type = Type.getNonReferenceType(); 17699 17700 // OpenMP 5.0 [2.19.3, List Item Privatization, Restrictions] 17701 // A variable that is privatized must not have a const-qualified type 17702 // unless it is of class type with a mutable member. This restriction does 17703 // not apply to the firstprivate clause. 17704 // 17705 // OpenMP 3.1 [2.9.3.5, lastprivate clause, Restrictions] 17706 // A variable that appears in a lastprivate clause must not have a 17707 // const-qualified type unless it is of class type with a mutable member. 17708 if (rejectConstNotMutableType(*this, D, Type, OMPC_lastprivate, ELoc)) 17709 continue; 17710 17711 // OpenMP 5.0 [2.19.4.5 lastprivate Clause, Restrictions] 17712 // A list item that appears in a lastprivate clause with the conditional 17713 // modifier must be a scalar variable. 17714 if (LPKind == OMPC_LASTPRIVATE_conditional && !Type->isScalarType()) { 17715 Diag(ELoc, diag::err_omp_lastprivate_conditional_non_scalar); 17716 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) == 17717 VarDecl::DeclarationOnly; 17718 Diag(D->getLocation(), 17719 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 17720 << D; 17721 continue; 17722 } 17723 17724 OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective(); 17725 // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables Referenced 17726 // in a Construct] 17727 // Variables with the predetermined data-sharing attributes may not be 17728 // listed in data-sharing attributes clauses, except for the cases 17729 // listed below. 17730 // OpenMP 4.5 [2.10.8, Distribute Construct, p.3] 17731 // A list item may appear in a firstprivate or lastprivate clause but not 17732 // both. 17733 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false); 17734 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_lastprivate && 17735 (isOpenMPDistributeDirective(CurrDir) || 17736 DVar.CKind != OMPC_firstprivate) && 17737 (DVar.CKind != OMPC_private || DVar.RefExpr != nullptr)) { 17738 Diag(ELoc, diag::err_omp_wrong_dsa) 17739 << getOpenMPClauseName(DVar.CKind) 17740 << getOpenMPClauseName(OMPC_lastprivate); 17741 reportOriginalDsa(*this, DSAStack, D, DVar); 17742 continue; 17743 } 17744 17745 // OpenMP [2.14.3.5, Restrictions, p.2] 17746 // A list item that is private within a parallel region, or that appears in 17747 // the reduction clause of a parallel construct, must not appear in a 17748 // lastprivate clause on a worksharing construct if any of the corresponding 17749 // worksharing regions ever binds to any of the corresponding parallel 17750 // regions. 17751 DSAStackTy::DSAVarData TopDVar = DVar; 17752 if (isOpenMPWorksharingDirective(CurrDir) && 17753 !isOpenMPParallelDirective(CurrDir) && 17754 !isOpenMPTeamsDirective(CurrDir)) { 17755 DVar = DSAStack->getImplicitDSA(D, true); 17756 if (DVar.CKind != OMPC_shared) { 17757 Diag(ELoc, diag::err_omp_required_access) 17758 << getOpenMPClauseName(OMPC_lastprivate) 17759 << getOpenMPClauseName(OMPC_shared); 17760 reportOriginalDsa(*this, DSAStack, D, DVar); 17761 continue; 17762 } 17763 } 17764 17765 // OpenMP [2.14.3.5, Restrictions, C++, p.1,2] 17766 // A variable of class type (or array thereof) that appears in a 17767 // lastprivate clause requires an accessible, unambiguous default 17768 // constructor for the class type, unless the list item is also specified 17769 // in a firstprivate clause. 17770 // A variable of class type (or array thereof) that appears in a 17771 // lastprivate clause requires an accessible, unambiguous copy assignment 17772 // operator for the class type. 17773 Type = Context.getBaseElementType(Type).getNonReferenceType(); 17774 VarDecl *SrcVD = buildVarDecl(*this, ERange.getBegin(), 17775 Type.getUnqualifiedType(), ".lastprivate.src", 17776 D->hasAttrs() ? &D->getAttrs() : nullptr); 17777 DeclRefExpr *PseudoSrcExpr = 17778 buildDeclRefExpr(*this, SrcVD, Type.getUnqualifiedType(), ELoc); 17779 VarDecl *DstVD = 17780 buildVarDecl(*this, ERange.getBegin(), Type, ".lastprivate.dst", 17781 D->hasAttrs() ? &D->getAttrs() : nullptr); 17782 DeclRefExpr *PseudoDstExpr = buildDeclRefExpr(*this, DstVD, Type, ELoc); 17783 // For arrays generate assignment operation for single element and replace 17784 // it by the original array element in CodeGen. 17785 ExprResult AssignmentOp = BuildBinOp(/*S=*/nullptr, ELoc, BO_Assign, 17786 PseudoDstExpr, PseudoSrcExpr); 17787 if (AssignmentOp.isInvalid()) 17788 continue; 17789 AssignmentOp = 17790 ActOnFinishFullExpr(AssignmentOp.get(), ELoc, /*DiscardedValue*/ false); 17791 if (AssignmentOp.isInvalid()) 17792 continue; 17793 17794 DeclRefExpr *Ref = nullptr; 17795 if (!VD && !CurContext->isDependentContext()) { 17796 if (TopDVar.CKind == OMPC_firstprivate) { 17797 Ref = TopDVar.PrivateCopy; 17798 } else { 17799 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false); 17800 if (!isOpenMPCapturedDecl(D)) 17801 ExprCaptures.push_back(Ref->getDecl()); 17802 } 17803 if ((TopDVar.CKind == OMPC_firstprivate && !TopDVar.PrivateCopy) || 17804 (!isOpenMPCapturedDecl(D) && 17805 Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>())) { 17806 ExprResult RefRes = DefaultLvalueConversion(Ref); 17807 if (!RefRes.isUsable()) 17808 continue; 17809 ExprResult PostUpdateRes = 17810 BuildBinOp(DSAStack->getCurScope(), ELoc, BO_Assign, SimpleRefExpr, 17811 RefRes.get()); 17812 if (!PostUpdateRes.isUsable()) 17813 continue; 17814 ExprPostUpdates.push_back( 17815 IgnoredValueConversions(PostUpdateRes.get()).get()); 17816 } 17817 } 17818 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_lastprivate, Ref); 17819 Vars.push_back((VD || CurContext->isDependentContext()) 17820 ? RefExpr->IgnoreParens() 17821 : Ref); 17822 SrcExprs.push_back(PseudoSrcExpr); 17823 DstExprs.push_back(PseudoDstExpr); 17824 AssignmentOps.push_back(AssignmentOp.get()); 17825 } 17826 17827 if (Vars.empty()) 17828 return nullptr; 17829 17830 return OMPLastprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, 17831 Vars, SrcExprs, DstExprs, AssignmentOps, 17832 LPKind, LPKindLoc, ColonLoc, 17833 buildPreInits(Context, ExprCaptures), 17834 buildPostUpdate(*this, ExprPostUpdates)); 17835 } 17836 17837 OMPClause *Sema::ActOnOpenMPSharedClause(ArrayRef<Expr *> VarList, 17838 SourceLocation StartLoc, 17839 SourceLocation LParenLoc, 17840 SourceLocation EndLoc) { 17841 SmallVector<Expr *, 8> Vars; 17842 for (Expr *RefExpr : VarList) { 17843 assert(RefExpr && "NULL expr in OpenMP lastprivate clause."); 17844 SourceLocation ELoc; 17845 SourceRange ERange; 17846 Expr *SimpleRefExpr = RefExpr; 17847 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 17848 if (Res.second) { 17849 // It will be analyzed later. 17850 Vars.push_back(RefExpr); 17851 } 17852 ValueDecl *D = Res.first; 17853 if (!D) 17854 continue; 17855 17856 auto *VD = dyn_cast<VarDecl>(D); 17857 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 17858 // in a Construct] 17859 // Variables with the predetermined data-sharing attributes may not be 17860 // listed in data-sharing attributes clauses, except for the cases 17861 // listed below. For these exceptions only, listing a predetermined 17862 // variable in a data-sharing attribute clause is allowed and overrides 17863 // the variable's predetermined data-sharing attributes. 17864 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false); 17865 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_shared && 17866 DVar.RefExpr) { 17867 Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind) 17868 << getOpenMPClauseName(OMPC_shared); 17869 reportOriginalDsa(*this, DSAStack, D, DVar); 17870 continue; 17871 } 17872 17873 DeclRefExpr *Ref = nullptr; 17874 if (!VD && isOpenMPCapturedDecl(D) && !CurContext->isDependentContext()) 17875 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true); 17876 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_shared, Ref); 17877 Vars.push_back((VD || !Ref || CurContext->isDependentContext()) 17878 ? RefExpr->IgnoreParens() 17879 : Ref); 17880 } 17881 17882 if (Vars.empty()) 17883 return nullptr; 17884 17885 return OMPSharedClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars); 17886 } 17887 17888 namespace { 17889 class DSARefChecker : public StmtVisitor<DSARefChecker, bool> { 17890 DSAStackTy *Stack; 17891 17892 public: 17893 bool VisitDeclRefExpr(DeclRefExpr *E) { 17894 if (auto *VD = dyn_cast<VarDecl>(E->getDecl())) { 17895 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(VD, /*FromParent=*/false); 17896 if (DVar.CKind == OMPC_shared && !DVar.RefExpr) 17897 return false; 17898 if (DVar.CKind != OMPC_unknown) 17899 return true; 17900 DSAStackTy::DSAVarData DVarPrivate = Stack->hasDSA( 17901 VD, 17902 [](OpenMPClauseKind C, bool AppliedToPointee) { 17903 return isOpenMPPrivate(C) && !AppliedToPointee; 17904 }, 17905 [](OpenMPDirectiveKind) { return true; }, 17906 /*FromParent=*/true); 17907 return DVarPrivate.CKind != OMPC_unknown; 17908 } 17909 return false; 17910 } 17911 bool VisitStmt(Stmt *S) { 17912 for (Stmt *Child : S->children()) { 17913 if (Child && Visit(Child)) 17914 return true; 17915 } 17916 return false; 17917 } 17918 explicit DSARefChecker(DSAStackTy *S) : Stack(S) {} 17919 }; 17920 } // namespace 17921 17922 namespace { 17923 // Transform MemberExpression for specified FieldDecl of current class to 17924 // DeclRefExpr to specified OMPCapturedExprDecl. 17925 class TransformExprToCaptures : public TreeTransform<TransformExprToCaptures> { 17926 typedef TreeTransform<TransformExprToCaptures> BaseTransform; 17927 ValueDecl *Field = nullptr; 17928 DeclRefExpr *CapturedExpr = nullptr; 17929 17930 public: 17931 TransformExprToCaptures(Sema &SemaRef, ValueDecl *FieldDecl) 17932 : BaseTransform(SemaRef), Field(FieldDecl), CapturedExpr(nullptr) {} 17933 17934 ExprResult TransformMemberExpr(MemberExpr *E) { 17935 if (isa<CXXThisExpr>(E->getBase()->IgnoreParenImpCasts()) && 17936 E->getMemberDecl() == Field) { 17937 CapturedExpr = buildCapture(SemaRef, Field, E, /*WithInit=*/false); 17938 return CapturedExpr; 17939 } 17940 return BaseTransform::TransformMemberExpr(E); 17941 } 17942 DeclRefExpr *getCapturedExpr() { return CapturedExpr; } 17943 }; 17944 } // namespace 17945 17946 template <typename T, typename U> 17947 static T filterLookupForUDReductionAndMapper( 17948 SmallVectorImpl<U> &Lookups, const llvm::function_ref<T(ValueDecl *)> Gen) { 17949 for (U &Set : Lookups) { 17950 for (auto *D : Set) { 17951 if (T Res = Gen(cast<ValueDecl>(D))) 17952 return Res; 17953 } 17954 } 17955 return T(); 17956 } 17957 17958 static NamedDecl *findAcceptableDecl(Sema &SemaRef, NamedDecl *D) { 17959 assert(!LookupResult::isVisible(SemaRef, D) && "not in slow case"); 17960 17961 for (auto RD : D->redecls()) { 17962 // Don't bother with extra checks if we already know this one isn't visible. 17963 if (RD == D) 17964 continue; 17965 17966 auto ND = cast<NamedDecl>(RD); 17967 if (LookupResult::isVisible(SemaRef, ND)) 17968 return ND; 17969 } 17970 17971 return nullptr; 17972 } 17973 17974 static void 17975 argumentDependentLookup(Sema &SemaRef, const DeclarationNameInfo &Id, 17976 SourceLocation Loc, QualType Ty, 17977 SmallVectorImpl<UnresolvedSet<8>> &Lookups) { 17978 // Find all of the associated namespaces and classes based on the 17979 // arguments we have. 17980 Sema::AssociatedNamespaceSet AssociatedNamespaces; 17981 Sema::AssociatedClassSet AssociatedClasses; 17982 OpaqueValueExpr OVE(Loc, Ty, VK_LValue); 17983 SemaRef.FindAssociatedClassesAndNamespaces(Loc, &OVE, AssociatedNamespaces, 17984 AssociatedClasses); 17985 17986 // C++ [basic.lookup.argdep]p3: 17987 // Let X be the lookup set produced by unqualified lookup (3.4.1) 17988 // and let Y be the lookup set produced by argument dependent 17989 // lookup (defined as follows). If X contains [...] then Y is 17990 // empty. Otherwise Y is the set of declarations found in the 17991 // namespaces associated with the argument types as described 17992 // below. The set of declarations found by the lookup of the name 17993 // is the union of X and Y. 17994 // 17995 // Here, we compute Y and add its members to the overloaded 17996 // candidate set. 17997 for (auto *NS : AssociatedNamespaces) { 17998 // When considering an associated namespace, the lookup is the 17999 // same as the lookup performed when the associated namespace is 18000 // used as a qualifier (3.4.3.2) except that: 18001 // 18002 // -- Any using-directives in the associated namespace are 18003 // ignored. 18004 // 18005 // -- Any namespace-scope friend functions declared in 18006 // associated classes are visible within their respective 18007 // namespaces even if they are not visible during an ordinary 18008 // lookup (11.4). 18009 DeclContext::lookup_result R = NS->lookup(Id.getName()); 18010 for (auto *D : R) { 18011 auto *Underlying = D; 18012 if (auto *USD = dyn_cast<UsingShadowDecl>(D)) 18013 Underlying = USD->getTargetDecl(); 18014 18015 if (!isa<OMPDeclareReductionDecl>(Underlying) && 18016 !isa<OMPDeclareMapperDecl>(Underlying)) 18017 continue; 18018 18019 if (!SemaRef.isVisible(D)) { 18020 D = findAcceptableDecl(SemaRef, D); 18021 if (!D) 18022 continue; 18023 if (auto *USD = dyn_cast<UsingShadowDecl>(D)) 18024 Underlying = USD->getTargetDecl(); 18025 } 18026 Lookups.emplace_back(); 18027 Lookups.back().addDecl(Underlying); 18028 } 18029 } 18030 } 18031 18032 static ExprResult 18033 buildDeclareReductionRef(Sema &SemaRef, SourceLocation Loc, SourceRange Range, 18034 Scope *S, CXXScopeSpec &ReductionIdScopeSpec, 18035 const DeclarationNameInfo &ReductionId, QualType Ty, 18036 CXXCastPath &BasePath, Expr *UnresolvedReduction) { 18037 if (ReductionIdScopeSpec.isInvalid()) 18038 return ExprError(); 18039 SmallVector<UnresolvedSet<8>, 4> Lookups; 18040 if (S) { 18041 LookupResult Lookup(SemaRef, ReductionId, Sema::LookupOMPReductionName); 18042 Lookup.suppressDiagnostics(); 18043 while (S && SemaRef.LookupParsedName(Lookup, S, &ReductionIdScopeSpec)) { 18044 NamedDecl *D = Lookup.getRepresentativeDecl(); 18045 do { 18046 S = S->getParent(); 18047 } while (S && !S->isDeclScope(D)); 18048 if (S) 18049 S = S->getParent(); 18050 Lookups.emplace_back(); 18051 Lookups.back().append(Lookup.begin(), Lookup.end()); 18052 Lookup.clear(); 18053 } 18054 } else if (auto *ULE = 18055 cast_or_null<UnresolvedLookupExpr>(UnresolvedReduction)) { 18056 Lookups.push_back(UnresolvedSet<8>()); 18057 Decl *PrevD = nullptr; 18058 for (NamedDecl *D : ULE->decls()) { 18059 if (D == PrevD) 18060 Lookups.push_back(UnresolvedSet<8>()); 18061 else if (auto *DRD = dyn_cast<OMPDeclareReductionDecl>(D)) 18062 Lookups.back().addDecl(DRD); 18063 PrevD = D; 18064 } 18065 } 18066 if (SemaRef.CurContext->isDependentContext() || Ty->isDependentType() || 18067 Ty->isInstantiationDependentType() || 18068 Ty->containsUnexpandedParameterPack() || 18069 filterLookupForUDReductionAndMapper<bool>(Lookups, [](ValueDecl *D) { 18070 return !D->isInvalidDecl() && 18071 (D->getType()->isDependentType() || 18072 D->getType()->isInstantiationDependentType() || 18073 D->getType()->containsUnexpandedParameterPack()); 18074 })) { 18075 UnresolvedSet<8> ResSet; 18076 for (const UnresolvedSet<8> &Set : Lookups) { 18077 if (Set.empty()) 18078 continue; 18079 ResSet.append(Set.begin(), Set.end()); 18080 // The last item marks the end of all declarations at the specified scope. 18081 ResSet.addDecl(Set[Set.size() - 1]); 18082 } 18083 return UnresolvedLookupExpr::Create( 18084 SemaRef.Context, /*NamingClass=*/nullptr, 18085 ReductionIdScopeSpec.getWithLocInContext(SemaRef.Context), ReductionId, 18086 /*ADL=*/true, /*Overloaded=*/true, ResSet.begin(), ResSet.end()); 18087 } 18088 // Lookup inside the classes. 18089 // C++ [over.match.oper]p3: 18090 // For a unary operator @ with an operand of a type whose 18091 // cv-unqualified version is T1, and for a binary operator @ with 18092 // a left operand of a type whose cv-unqualified version is T1 and 18093 // a right operand of a type whose cv-unqualified version is T2, 18094 // three sets of candidate functions, designated member 18095 // candidates, non-member candidates and built-in candidates, are 18096 // constructed as follows: 18097 // -- If T1 is a complete class type or a class currently being 18098 // defined, the set of member candidates is the result of the 18099 // qualified lookup of T1::operator@ (13.3.1.1.1); otherwise, 18100 // the set of member candidates is empty. 18101 LookupResult Lookup(SemaRef, ReductionId, Sema::LookupOMPReductionName); 18102 Lookup.suppressDiagnostics(); 18103 if (const auto *TyRec = Ty->getAs<RecordType>()) { 18104 // Complete the type if it can be completed. 18105 // If the type is neither complete nor being defined, bail out now. 18106 if (SemaRef.isCompleteType(Loc, Ty) || TyRec->isBeingDefined() || 18107 TyRec->getDecl()->getDefinition()) { 18108 Lookup.clear(); 18109 SemaRef.LookupQualifiedName(Lookup, TyRec->getDecl()); 18110 if (Lookup.empty()) { 18111 Lookups.emplace_back(); 18112 Lookups.back().append(Lookup.begin(), Lookup.end()); 18113 } 18114 } 18115 } 18116 // Perform ADL. 18117 if (SemaRef.getLangOpts().CPlusPlus) 18118 argumentDependentLookup(SemaRef, ReductionId, Loc, Ty, Lookups); 18119 if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>( 18120 Lookups, [&SemaRef, Ty](ValueDecl *D) -> ValueDecl * { 18121 if (!D->isInvalidDecl() && 18122 SemaRef.Context.hasSameType(D->getType(), Ty)) 18123 return D; 18124 return nullptr; 18125 })) 18126 return SemaRef.BuildDeclRefExpr(VD, VD->getType().getNonReferenceType(), 18127 VK_LValue, Loc); 18128 if (SemaRef.getLangOpts().CPlusPlus) { 18129 if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>( 18130 Lookups, [&SemaRef, Ty, Loc](ValueDecl *D) -> ValueDecl * { 18131 if (!D->isInvalidDecl() && 18132 SemaRef.IsDerivedFrom(Loc, Ty, D->getType()) && 18133 !Ty.isMoreQualifiedThan(D->getType())) 18134 return D; 18135 return nullptr; 18136 })) { 18137 CXXBasePaths Paths(/*FindAmbiguities=*/true, /*RecordPaths=*/true, 18138 /*DetectVirtual=*/false); 18139 if (SemaRef.IsDerivedFrom(Loc, Ty, VD->getType(), Paths)) { 18140 if (!Paths.isAmbiguous(SemaRef.Context.getCanonicalType( 18141 VD->getType().getUnqualifiedType()))) { 18142 if (SemaRef.CheckBaseClassAccess( 18143 Loc, VD->getType(), Ty, Paths.front(), 18144 /*DiagID=*/0) != Sema::AR_inaccessible) { 18145 SemaRef.BuildBasePathArray(Paths, BasePath); 18146 return SemaRef.BuildDeclRefExpr( 18147 VD, VD->getType().getNonReferenceType(), VK_LValue, Loc); 18148 } 18149 } 18150 } 18151 } 18152 } 18153 if (ReductionIdScopeSpec.isSet()) { 18154 SemaRef.Diag(Loc, diag::err_omp_not_resolved_reduction_identifier) 18155 << Ty << Range; 18156 return ExprError(); 18157 } 18158 return ExprEmpty(); 18159 } 18160 18161 namespace { 18162 /// Data for the reduction-based clauses. 18163 struct ReductionData { 18164 /// List of original reduction items. 18165 SmallVector<Expr *, 8> Vars; 18166 /// List of private copies of the reduction items. 18167 SmallVector<Expr *, 8> Privates; 18168 /// LHS expressions for the reduction_op expressions. 18169 SmallVector<Expr *, 8> LHSs; 18170 /// RHS expressions for the reduction_op expressions. 18171 SmallVector<Expr *, 8> RHSs; 18172 /// Reduction operation expression. 18173 SmallVector<Expr *, 8> ReductionOps; 18174 /// inscan copy operation expressions. 18175 SmallVector<Expr *, 8> InscanCopyOps; 18176 /// inscan copy temp array expressions for prefix sums. 18177 SmallVector<Expr *, 8> InscanCopyArrayTemps; 18178 /// inscan copy temp array element expressions for prefix sums. 18179 SmallVector<Expr *, 8> InscanCopyArrayElems; 18180 /// Taskgroup descriptors for the corresponding reduction items in 18181 /// in_reduction clauses. 18182 SmallVector<Expr *, 8> TaskgroupDescriptors; 18183 /// List of captures for clause. 18184 SmallVector<Decl *, 4> ExprCaptures; 18185 /// List of postupdate expressions. 18186 SmallVector<Expr *, 4> ExprPostUpdates; 18187 /// Reduction modifier. 18188 unsigned RedModifier = 0; 18189 ReductionData() = delete; 18190 /// Reserves required memory for the reduction data. 18191 ReductionData(unsigned Size, unsigned Modifier = 0) : RedModifier(Modifier) { 18192 Vars.reserve(Size); 18193 Privates.reserve(Size); 18194 LHSs.reserve(Size); 18195 RHSs.reserve(Size); 18196 ReductionOps.reserve(Size); 18197 if (RedModifier == OMPC_REDUCTION_inscan) { 18198 InscanCopyOps.reserve(Size); 18199 InscanCopyArrayTemps.reserve(Size); 18200 InscanCopyArrayElems.reserve(Size); 18201 } 18202 TaskgroupDescriptors.reserve(Size); 18203 ExprCaptures.reserve(Size); 18204 ExprPostUpdates.reserve(Size); 18205 } 18206 /// Stores reduction item and reduction operation only (required for dependent 18207 /// reduction item). 18208 void push(Expr *Item, Expr *ReductionOp) { 18209 Vars.emplace_back(Item); 18210 Privates.emplace_back(nullptr); 18211 LHSs.emplace_back(nullptr); 18212 RHSs.emplace_back(nullptr); 18213 ReductionOps.emplace_back(ReductionOp); 18214 TaskgroupDescriptors.emplace_back(nullptr); 18215 if (RedModifier == OMPC_REDUCTION_inscan) { 18216 InscanCopyOps.push_back(nullptr); 18217 InscanCopyArrayTemps.push_back(nullptr); 18218 InscanCopyArrayElems.push_back(nullptr); 18219 } 18220 } 18221 /// Stores reduction data. 18222 void push(Expr *Item, Expr *Private, Expr *LHS, Expr *RHS, Expr *ReductionOp, 18223 Expr *TaskgroupDescriptor, Expr *CopyOp, Expr *CopyArrayTemp, 18224 Expr *CopyArrayElem) { 18225 Vars.emplace_back(Item); 18226 Privates.emplace_back(Private); 18227 LHSs.emplace_back(LHS); 18228 RHSs.emplace_back(RHS); 18229 ReductionOps.emplace_back(ReductionOp); 18230 TaskgroupDescriptors.emplace_back(TaskgroupDescriptor); 18231 if (RedModifier == OMPC_REDUCTION_inscan) { 18232 InscanCopyOps.push_back(CopyOp); 18233 InscanCopyArrayTemps.push_back(CopyArrayTemp); 18234 InscanCopyArrayElems.push_back(CopyArrayElem); 18235 } else { 18236 assert(CopyOp == nullptr && CopyArrayTemp == nullptr && 18237 CopyArrayElem == nullptr && 18238 "Copy operation must be used for inscan reductions only."); 18239 } 18240 } 18241 }; 18242 } // namespace 18243 18244 static bool checkOMPArraySectionConstantForReduction( 18245 ASTContext &Context, const OMPArraySectionExpr *OASE, bool &SingleElement, 18246 SmallVectorImpl<llvm::APSInt> &ArraySizes) { 18247 const Expr *Length = OASE->getLength(); 18248 if (Length == nullptr) { 18249 // For array sections of the form [1:] or [:], we would need to analyze 18250 // the lower bound... 18251 if (OASE->getColonLocFirst().isValid()) 18252 return false; 18253 18254 // This is an array subscript which has implicit length 1! 18255 SingleElement = true; 18256 ArraySizes.push_back(llvm::APSInt::get(1)); 18257 } else { 18258 Expr::EvalResult Result; 18259 if (!Length->EvaluateAsInt(Result, Context)) 18260 return false; 18261 18262 llvm::APSInt ConstantLengthValue = Result.Val.getInt(); 18263 SingleElement = (ConstantLengthValue.getSExtValue() == 1); 18264 ArraySizes.push_back(ConstantLengthValue); 18265 } 18266 18267 // Get the base of this array section and walk up from there. 18268 const Expr *Base = OASE->getBase()->IgnoreParenImpCasts(); 18269 18270 // We require length = 1 for all array sections except the right-most to 18271 // guarantee that the memory region is contiguous and has no holes in it. 18272 while (const auto *TempOASE = dyn_cast<OMPArraySectionExpr>(Base)) { 18273 Length = TempOASE->getLength(); 18274 if (Length == nullptr) { 18275 // For array sections of the form [1:] or [:], we would need to analyze 18276 // the lower bound... 18277 if (OASE->getColonLocFirst().isValid()) 18278 return false; 18279 18280 // This is an array subscript which has implicit length 1! 18281 ArraySizes.push_back(llvm::APSInt::get(1)); 18282 } else { 18283 Expr::EvalResult Result; 18284 if (!Length->EvaluateAsInt(Result, Context)) 18285 return false; 18286 18287 llvm::APSInt ConstantLengthValue = Result.Val.getInt(); 18288 if (ConstantLengthValue.getSExtValue() != 1) 18289 return false; 18290 18291 ArraySizes.push_back(ConstantLengthValue); 18292 } 18293 Base = TempOASE->getBase()->IgnoreParenImpCasts(); 18294 } 18295 18296 // If we have a single element, we don't need to add the implicit lengths. 18297 if (!SingleElement) { 18298 while (const auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base)) { 18299 // Has implicit length 1! 18300 ArraySizes.push_back(llvm::APSInt::get(1)); 18301 Base = TempASE->getBase()->IgnoreParenImpCasts(); 18302 } 18303 } 18304 18305 // This array section can be privatized as a single value or as a constant 18306 // sized array. 18307 return true; 18308 } 18309 18310 static BinaryOperatorKind 18311 getRelatedCompoundReductionOp(BinaryOperatorKind BOK) { 18312 if (BOK == BO_Add) 18313 return BO_AddAssign; 18314 if (BOK == BO_Mul) 18315 return BO_MulAssign; 18316 if (BOK == BO_And) 18317 return BO_AndAssign; 18318 if (BOK == BO_Or) 18319 return BO_OrAssign; 18320 if (BOK == BO_Xor) 18321 return BO_XorAssign; 18322 return BOK; 18323 } 18324 18325 static bool actOnOMPReductionKindClause( 18326 Sema &S, DSAStackTy *Stack, OpenMPClauseKind ClauseKind, 18327 ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, 18328 SourceLocation ColonLoc, SourceLocation EndLoc, 18329 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, 18330 ArrayRef<Expr *> UnresolvedReductions, ReductionData &RD) { 18331 DeclarationName DN = ReductionId.getName(); 18332 OverloadedOperatorKind OOK = DN.getCXXOverloadedOperator(); 18333 BinaryOperatorKind BOK = BO_Comma; 18334 18335 ASTContext &Context = S.Context; 18336 // OpenMP [2.14.3.6, reduction clause] 18337 // C 18338 // reduction-identifier is either an identifier or one of the following 18339 // operators: +, -, *, &, |, ^, && and || 18340 // C++ 18341 // reduction-identifier is either an id-expression or one of the following 18342 // operators: +, -, *, &, |, ^, && and || 18343 switch (OOK) { 18344 case OO_Plus: 18345 case OO_Minus: 18346 BOK = BO_Add; 18347 break; 18348 case OO_Star: 18349 BOK = BO_Mul; 18350 break; 18351 case OO_Amp: 18352 BOK = BO_And; 18353 break; 18354 case OO_Pipe: 18355 BOK = BO_Or; 18356 break; 18357 case OO_Caret: 18358 BOK = BO_Xor; 18359 break; 18360 case OO_AmpAmp: 18361 BOK = BO_LAnd; 18362 break; 18363 case OO_PipePipe: 18364 BOK = BO_LOr; 18365 break; 18366 case OO_New: 18367 case OO_Delete: 18368 case OO_Array_New: 18369 case OO_Array_Delete: 18370 case OO_Slash: 18371 case OO_Percent: 18372 case OO_Tilde: 18373 case OO_Exclaim: 18374 case OO_Equal: 18375 case OO_Less: 18376 case OO_Greater: 18377 case OO_LessEqual: 18378 case OO_GreaterEqual: 18379 case OO_PlusEqual: 18380 case OO_MinusEqual: 18381 case OO_StarEqual: 18382 case OO_SlashEqual: 18383 case OO_PercentEqual: 18384 case OO_CaretEqual: 18385 case OO_AmpEqual: 18386 case OO_PipeEqual: 18387 case OO_LessLess: 18388 case OO_GreaterGreater: 18389 case OO_LessLessEqual: 18390 case OO_GreaterGreaterEqual: 18391 case OO_EqualEqual: 18392 case OO_ExclaimEqual: 18393 case OO_Spaceship: 18394 case OO_PlusPlus: 18395 case OO_MinusMinus: 18396 case OO_Comma: 18397 case OO_ArrowStar: 18398 case OO_Arrow: 18399 case OO_Call: 18400 case OO_Subscript: 18401 case OO_Conditional: 18402 case OO_Coawait: 18403 case NUM_OVERLOADED_OPERATORS: 18404 llvm_unreachable("Unexpected reduction identifier"); 18405 case OO_None: 18406 if (IdentifierInfo *II = DN.getAsIdentifierInfo()) { 18407 if (II->isStr("max")) 18408 BOK = BO_GT; 18409 else if (II->isStr("min")) 18410 BOK = BO_LT; 18411 } 18412 break; 18413 } 18414 SourceRange ReductionIdRange; 18415 if (ReductionIdScopeSpec.isValid()) 18416 ReductionIdRange.setBegin(ReductionIdScopeSpec.getBeginLoc()); 18417 else 18418 ReductionIdRange.setBegin(ReductionId.getBeginLoc()); 18419 ReductionIdRange.setEnd(ReductionId.getEndLoc()); 18420 18421 auto IR = UnresolvedReductions.begin(), ER = UnresolvedReductions.end(); 18422 bool FirstIter = true; 18423 for (Expr *RefExpr : VarList) { 18424 assert(RefExpr && "nullptr expr in OpenMP reduction clause."); 18425 // OpenMP [2.1, C/C++] 18426 // A list item is a variable or array section, subject to the restrictions 18427 // specified in Section 2.4 on page 42 and in each of the sections 18428 // describing clauses and directives for which a list appears. 18429 // OpenMP [2.14.3.3, Restrictions, p.1] 18430 // A variable that is part of another variable (as an array or 18431 // structure element) cannot appear in a private clause. 18432 if (!FirstIter && IR != ER) 18433 ++IR; 18434 FirstIter = false; 18435 SourceLocation ELoc; 18436 SourceRange ERange; 18437 Expr *SimpleRefExpr = RefExpr; 18438 auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange, 18439 /*AllowArraySection=*/true); 18440 if (Res.second) { 18441 // Try to find 'declare reduction' corresponding construct before using 18442 // builtin/overloaded operators. 18443 QualType Type = Context.DependentTy; 18444 CXXCastPath BasePath; 18445 ExprResult DeclareReductionRef = buildDeclareReductionRef( 18446 S, ELoc, ERange, Stack->getCurScope(), ReductionIdScopeSpec, 18447 ReductionId, Type, BasePath, IR == ER ? nullptr : *IR); 18448 Expr *ReductionOp = nullptr; 18449 if (S.CurContext->isDependentContext() && 18450 (DeclareReductionRef.isUnset() || 18451 isa<UnresolvedLookupExpr>(DeclareReductionRef.get()))) 18452 ReductionOp = DeclareReductionRef.get(); 18453 // It will be analyzed later. 18454 RD.push(RefExpr, ReductionOp); 18455 } 18456 ValueDecl *D = Res.first; 18457 if (!D) 18458 continue; 18459 18460 Expr *TaskgroupDescriptor = nullptr; 18461 QualType Type; 18462 auto *ASE = dyn_cast<ArraySubscriptExpr>(RefExpr->IgnoreParens()); 18463 auto *OASE = dyn_cast<OMPArraySectionExpr>(RefExpr->IgnoreParens()); 18464 if (ASE) { 18465 Type = ASE->getType().getNonReferenceType(); 18466 } else if (OASE) { 18467 QualType BaseType = 18468 OMPArraySectionExpr::getBaseOriginalType(OASE->getBase()); 18469 if (const auto *ATy = BaseType->getAsArrayTypeUnsafe()) 18470 Type = ATy->getElementType(); 18471 else 18472 Type = BaseType->getPointeeType(); 18473 Type = Type.getNonReferenceType(); 18474 } else { 18475 Type = Context.getBaseElementType(D->getType().getNonReferenceType()); 18476 } 18477 auto *VD = dyn_cast<VarDecl>(D); 18478 18479 // OpenMP [2.9.3.3, Restrictions, C/C++, p.3] 18480 // A variable that appears in a private clause must not have an incomplete 18481 // type or a reference type. 18482 if (S.RequireCompleteType(ELoc, D->getType(), 18483 diag::err_omp_reduction_incomplete_type)) 18484 continue; 18485 // OpenMP [2.14.3.6, reduction clause, Restrictions] 18486 // A list item that appears in a reduction clause must not be 18487 // const-qualified. 18488 if (rejectConstNotMutableType(S, D, Type, ClauseKind, ELoc, 18489 /*AcceptIfMutable*/ false, ASE || OASE)) 18490 continue; 18491 18492 OpenMPDirectiveKind CurrDir = Stack->getCurrentDirective(); 18493 // OpenMP [2.9.3.6, Restrictions, C/C++, p.4] 18494 // If a list-item is a reference type then it must bind to the same object 18495 // for all threads of the team. 18496 if (!ASE && !OASE) { 18497 if (VD) { 18498 VarDecl *VDDef = VD->getDefinition(); 18499 if (VD->getType()->isReferenceType() && VDDef && VDDef->hasInit()) { 18500 DSARefChecker Check(Stack); 18501 if (Check.Visit(VDDef->getInit())) { 18502 S.Diag(ELoc, diag::err_omp_reduction_ref_type_arg) 18503 << getOpenMPClauseName(ClauseKind) << ERange; 18504 S.Diag(VDDef->getLocation(), diag::note_defined_here) << VDDef; 18505 continue; 18506 } 18507 } 18508 } 18509 18510 // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables Referenced 18511 // in a Construct] 18512 // Variables with the predetermined data-sharing attributes may not be 18513 // listed in data-sharing attributes clauses, except for the cases 18514 // listed below. For these exceptions only, listing a predetermined 18515 // variable in a data-sharing attribute clause is allowed and overrides 18516 // the variable's predetermined data-sharing attributes. 18517 // OpenMP [2.14.3.6, Restrictions, p.3] 18518 // Any number of reduction clauses can be specified on the directive, 18519 // but a list item can appear only once in the reduction clauses for that 18520 // directive. 18521 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(D, /*FromParent=*/false); 18522 if (DVar.CKind == OMPC_reduction) { 18523 S.Diag(ELoc, diag::err_omp_once_referenced) 18524 << getOpenMPClauseName(ClauseKind); 18525 if (DVar.RefExpr) 18526 S.Diag(DVar.RefExpr->getExprLoc(), diag::note_omp_referenced); 18527 continue; 18528 } 18529 if (DVar.CKind != OMPC_unknown) { 18530 S.Diag(ELoc, diag::err_omp_wrong_dsa) 18531 << getOpenMPClauseName(DVar.CKind) 18532 << getOpenMPClauseName(OMPC_reduction); 18533 reportOriginalDsa(S, Stack, D, DVar); 18534 continue; 18535 } 18536 18537 // OpenMP [2.14.3.6, Restrictions, p.1] 18538 // A list item that appears in a reduction clause of a worksharing 18539 // construct must be shared in the parallel regions to which any of the 18540 // worksharing regions arising from the worksharing construct bind. 18541 if (isOpenMPWorksharingDirective(CurrDir) && 18542 !isOpenMPParallelDirective(CurrDir) && 18543 !isOpenMPTeamsDirective(CurrDir)) { 18544 DVar = Stack->getImplicitDSA(D, true); 18545 if (DVar.CKind != OMPC_shared) { 18546 S.Diag(ELoc, diag::err_omp_required_access) 18547 << getOpenMPClauseName(OMPC_reduction) 18548 << getOpenMPClauseName(OMPC_shared); 18549 reportOriginalDsa(S, Stack, D, DVar); 18550 continue; 18551 } 18552 } 18553 } else { 18554 // Threadprivates cannot be shared between threads, so dignose if the base 18555 // is a threadprivate variable. 18556 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(D, /*FromParent=*/false); 18557 if (DVar.CKind == OMPC_threadprivate) { 18558 S.Diag(ELoc, diag::err_omp_wrong_dsa) 18559 << getOpenMPClauseName(DVar.CKind) 18560 << getOpenMPClauseName(OMPC_reduction); 18561 reportOriginalDsa(S, Stack, D, DVar); 18562 continue; 18563 } 18564 } 18565 18566 // Try to find 'declare reduction' corresponding construct before using 18567 // builtin/overloaded operators. 18568 CXXCastPath BasePath; 18569 ExprResult DeclareReductionRef = buildDeclareReductionRef( 18570 S, ELoc, ERange, Stack->getCurScope(), ReductionIdScopeSpec, 18571 ReductionId, Type, BasePath, IR == ER ? nullptr : *IR); 18572 if (DeclareReductionRef.isInvalid()) 18573 continue; 18574 if (S.CurContext->isDependentContext() && 18575 (DeclareReductionRef.isUnset() || 18576 isa<UnresolvedLookupExpr>(DeclareReductionRef.get()))) { 18577 RD.push(RefExpr, DeclareReductionRef.get()); 18578 continue; 18579 } 18580 if (BOK == BO_Comma && DeclareReductionRef.isUnset()) { 18581 // Not allowed reduction identifier is found. 18582 S.Diag(ReductionId.getBeginLoc(), 18583 diag::err_omp_unknown_reduction_identifier) 18584 << Type << ReductionIdRange; 18585 continue; 18586 } 18587 18588 // OpenMP [2.14.3.6, reduction clause, Restrictions] 18589 // The type of a list item that appears in a reduction clause must be valid 18590 // for the reduction-identifier. For a max or min reduction in C, the type 18591 // of the list item must be an allowed arithmetic data type: char, int, 18592 // float, double, or _Bool, possibly modified with long, short, signed, or 18593 // unsigned. For a max or min reduction in C++, the type of the list item 18594 // must be an allowed arithmetic data type: char, wchar_t, int, float, 18595 // double, or bool, possibly modified with long, short, signed, or unsigned. 18596 if (DeclareReductionRef.isUnset()) { 18597 if ((BOK == BO_GT || BOK == BO_LT) && 18598 !(Type->isScalarType() || 18599 (S.getLangOpts().CPlusPlus && Type->isArithmeticType()))) { 18600 S.Diag(ELoc, diag::err_omp_clause_not_arithmetic_type_arg) 18601 << getOpenMPClauseName(ClauseKind) << S.getLangOpts().CPlusPlus; 18602 if (!ASE && !OASE) { 18603 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) == 18604 VarDecl::DeclarationOnly; 18605 S.Diag(D->getLocation(), 18606 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 18607 << D; 18608 } 18609 continue; 18610 } 18611 if ((BOK == BO_OrAssign || BOK == BO_AndAssign || BOK == BO_XorAssign) && 18612 !S.getLangOpts().CPlusPlus && Type->isFloatingType()) { 18613 S.Diag(ELoc, diag::err_omp_clause_floating_type_arg) 18614 << getOpenMPClauseName(ClauseKind); 18615 if (!ASE && !OASE) { 18616 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) == 18617 VarDecl::DeclarationOnly; 18618 S.Diag(D->getLocation(), 18619 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 18620 << D; 18621 } 18622 continue; 18623 } 18624 } 18625 18626 Type = Type.getNonLValueExprType(Context).getUnqualifiedType(); 18627 VarDecl *LHSVD = buildVarDecl(S, ELoc, Type, ".reduction.lhs", 18628 D->hasAttrs() ? &D->getAttrs() : nullptr); 18629 VarDecl *RHSVD = buildVarDecl(S, ELoc, Type, D->getName(), 18630 D->hasAttrs() ? &D->getAttrs() : nullptr); 18631 QualType PrivateTy = Type; 18632 18633 // Try if we can determine constant lengths for all array sections and avoid 18634 // the VLA. 18635 bool ConstantLengthOASE = false; 18636 if (OASE) { 18637 bool SingleElement; 18638 llvm::SmallVector<llvm::APSInt, 4> ArraySizes; 18639 ConstantLengthOASE = checkOMPArraySectionConstantForReduction( 18640 Context, OASE, SingleElement, ArraySizes); 18641 18642 // If we don't have a single element, we must emit a constant array type. 18643 if (ConstantLengthOASE && !SingleElement) { 18644 for (llvm::APSInt &Size : ArraySizes) 18645 PrivateTy = Context.getConstantArrayType(PrivateTy, Size, nullptr, 18646 ArrayType::Normal, 18647 /*IndexTypeQuals=*/0); 18648 } 18649 } 18650 18651 if ((OASE && !ConstantLengthOASE) || 18652 (!OASE && !ASE && 18653 D->getType().getNonReferenceType()->isVariablyModifiedType())) { 18654 if (!Context.getTargetInfo().isVLASupported()) { 18655 if (isOpenMPTargetExecutionDirective(Stack->getCurrentDirective())) { 18656 S.Diag(ELoc, diag::err_omp_reduction_vla_unsupported) << !!OASE; 18657 S.Diag(ELoc, diag::note_vla_unsupported); 18658 continue; 18659 } else { 18660 S.targetDiag(ELoc, diag::err_omp_reduction_vla_unsupported) << !!OASE; 18661 S.targetDiag(ELoc, diag::note_vla_unsupported); 18662 } 18663 } 18664 // For arrays/array sections only: 18665 // Create pseudo array type for private copy. The size for this array will 18666 // be generated during codegen. 18667 // For array subscripts or single variables Private Ty is the same as Type 18668 // (type of the variable or single array element). 18669 PrivateTy = Context.getVariableArrayType( 18670 Type, 18671 new (Context) 18672 OpaqueValueExpr(ELoc, Context.getSizeType(), VK_PRValue), 18673 ArrayType::Normal, /*IndexTypeQuals=*/0, SourceRange()); 18674 } else if (!ASE && !OASE && 18675 Context.getAsArrayType(D->getType().getNonReferenceType())) { 18676 PrivateTy = D->getType().getNonReferenceType(); 18677 } 18678 // Private copy. 18679 VarDecl *PrivateVD = 18680 buildVarDecl(S, ELoc, PrivateTy, D->getName(), 18681 D->hasAttrs() ? &D->getAttrs() : nullptr, 18682 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr); 18683 // Add initializer for private variable. 18684 Expr *Init = nullptr; 18685 DeclRefExpr *LHSDRE = buildDeclRefExpr(S, LHSVD, Type, ELoc); 18686 DeclRefExpr *RHSDRE = buildDeclRefExpr(S, RHSVD, Type, ELoc); 18687 if (DeclareReductionRef.isUsable()) { 18688 auto *DRDRef = DeclareReductionRef.getAs<DeclRefExpr>(); 18689 auto *DRD = cast<OMPDeclareReductionDecl>(DRDRef->getDecl()); 18690 if (DRD->getInitializer()) { 18691 Init = DRDRef; 18692 RHSVD->setInit(DRDRef); 18693 RHSVD->setInitStyle(VarDecl::CallInit); 18694 } 18695 } else { 18696 switch (BOK) { 18697 case BO_Add: 18698 case BO_Xor: 18699 case BO_Or: 18700 case BO_LOr: 18701 // '+', '-', '^', '|', '||' reduction ops - initializer is '0'. 18702 if (Type->isScalarType() || Type->isAnyComplexType()) 18703 Init = S.ActOnIntegerConstant(ELoc, /*Val=*/0).get(); 18704 break; 18705 case BO_Mul: 18706 case BO_LAnd: 18707 if (Type->isScalarType() || Type->isAnyComplexType()) { 18708 // '*' and '&&' reduction ops - initializer is '1'. 18709 Init = S.ActOnIntegerConstant(ELoc, /*Val=*/1).get(); 18710 } 18711 break; 18712 case BO_And: { 18713 // '&' reduction op - initializer is '~0'. 18714 QualType OrigType = Type; 18715 if (auto *ComplexTy = OrigType->getAs<ComplexType>()) 18716 Type = ComplexTy->getElementType(); 18717 if (Type->isRealFloatingType()) { 18718 llvm::APFloat InitValue = llvm::APFloat::getAllOnesValue( 18719 Context.getFloatTypeSemantics(Type)); 18720 Init = FloatingLiteral::Create(Context, InitValue, /*isexact=*/true, 18721 Type, ELoc); 18722 } else if (Type->isScalarType()) { 18723 uint64_t Size = Context.getTypeSize(Type); 18724 QualType IntTy = Context.getIntTypeForBitwidth(Size, /*Signed=*/0); 18725 llvm::APInt InitValue = llvm::APInt::getAllOnes(Size); 18726 Init = IntegerLiteral::Create(Context, InitValue, IntTy, ELoc); 18727 } 18728 if (Init && OrigType->isAnyComplexType()) { 18729 // Init = 0xFFFF + 0xFFFFi; 18730 auto *Im = new (Context) ImaginaryLiteral(Init, OrigType); 18731 Init = S.CreateBuiltinBinOp(ELoc, BO_Add, Init, Im).get(); 18732 } 18733 Type = OrigType; 18734 break; 18735 } 18736 case BO_LT: 18737 case BO_GT: { 18738 // 'min' reduction op - initializer is 'Largest representable number in 18739 // the reduction list item type'. 18740 // 'max' reduction op - initializer is 'Least representable number in 18741 // the reduction list item type'. 18742 if (Type->isIntegerType() || Type->isPointerType()) { 18743 bool IsSigned = Type->hasSignedIntegerRepresentation(); 18744 uint64_t Size = Context.getTypeSize(Type); 18745 QualType IntTy = 18746 Context.getIntTypeForBitwidth(Size, /*Signed=*/IsSigned); 18747 llvm::APInt InitValue = 18748 (BOK != BO_LT) ? IsSigned ? llvm::APInt::getSignedMinValue(Size) 18749 : llvm::APInt::getMinValue(Size) 18750 : IsSigned ? llvm::APInt::getSignedMaxValue(Size) 18751 : llvm::APInt::getMaxValue(Size); 18752 Init = IntegerLiteral::Create(Context, InitValue, IntTy, ELoc); 18753 if (Type->isPointerType()) { 18754 // Cast to pointer type. 18755 ExprResult CastExpr = S.BuildCStyleCastExpr( 18756 ELoc, Context.getTrivialTypeSourceInfo(Type, ELoc), ELoc, Init); 18757 if (CastExpr.isInvalid()) 18758 continue; 18759 Init = CastExpr.get(); 18760 } 18761 } else if (Type->isRealFloatingType()) { 18762 llvm::APFloat InitValue = llvm::APFloat::getLargest( 18763 Context.getFloatTypeSemantics(Type), BOK != BO_LT); 18764 Init = FloatingLiteral::Create(Context, InitValue, /*isexact=*/true, 18765 Type, ELoc); 18766 } 18767 break; 18768 } 18769 case BO_PtrMemD: 18770 case BO_PtrMemI: 18771 case BO_MulAssign: 18772 case BO_Div: 18773 case BO_Rem: 18774 case BO_Sub: 18775 case BO_Shl: 18776 case BO_Shr: 18777 case BO_LE: 18778 case BO_GE: 18779 case BO_EQ: 18780 case BO_NE: 18781 case BO_Cmp: 18782 case BO_AndAssign: 18783 case BO_XorAssign: 18784 case BO_OrAssign: 18785 case BO_Assign: 18786 case BO_AddAssign: 18787 case BO_SubAssign: 18788 case BO_DivAssign: 18789 case BO_RemAssign: 18790 case BO_ShlAssign: 18791 case BO_ShrAssign: 18792 case BO_Comma: 18793 llvm_unreachable("Unexpected reduction operation"); 18794 } 18795 } 18796 if (Init && DeclareReductionRef.isUnset()) { 18797 S.AddInitializerToDecl(RHSVD, Init, /*DirectInit=*/false); 18798 // Store initializer for single element in private copy. Will be used 18799 // during codegen. 18800 PrivateVD->setInit(RHSVD->getInit()); 18801 PrivateVD->setInitStyle(RHSVD->getInitStyle()); 18802 } else if (!Init) { 18803 S.ActOnUninitializedDecl(RHSVD); 18804 // Store initializer for single element in private copy. Will be used 18805 // during codegen. 18806 PrivateVD->setInit(RHSVD->getInit()); 18807 PrivateVD->setInitStyle(RHSVD->getInitStyle()); 18808 } 18809 if (RHSVD->isInvalidDecl()) 18810 continue; 18811 if (!RHSVD->hasInit() && DeclareReductionRef.isUnset()) { 18812 S.Diag(ELoc, diag::err_omp_reduction_id_not_compatible) 18813 << Type << ReductionIdRange; 18814 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) == 18815 VarDecl::DeclarationOnly; 18816 S.Diag(D->getLocation(), 18817 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 18818 << D; 18819 continue; 18820 } 18821 DeclRefExpr *PrivateDRE = buildDeclRefExpr(S, PrivateVD, PrivateTy, ELoc); 18822 ExprResult ReductionOp; 18823 if (DeclareReductionRef.isUsable()) { 18824 QualType RedTy = DeclareReductionRef.get()->getType(); 18825 QualType PtrRedTy = Context.getPointerType(RedTy); 18826 ExprResult LHS = S.CreateBuiltinUnaryOp(ELoc, UO_AddrOf, LHSDRE); 18827 ExprResult RHS = S.CreateBuiltinUnaryOp(ELoc, UO_AddrOf, RHSDRE); 18828 if (!BasePath.empty()) { 18829 LHS = S.DefaultLvalueConversion(LHS.get()); 18830 RHS = S.DefaultLvalueConversion(RHS.get()); 18831 LHS = ImplicitCastExpr::Create( 18832 Context, PtrRedTy, CK_UncheckedDerivedToBase, LHS.get(), &BasePath, 18833 LHS.get()->getValueKind(), FPOptionsOverride()); 18834 RHS = ImplicitCastExpr::Create( 18835 Context, PtrRedTy, CK_UncheckedDerivedToBase, RHS.get(), &BasePath, 18836 RHS.get()->getValueKind(), FPOptionsOverride()); 18837 } 18838 FunctionProtoType::ExtProtoInfo EPI; 18839 QualType Params[] = {PtrRedTy, PtrRedTy}; 18840 QualType FnTy = Context.getFunctionType(Context.VoidTy, Params, EPI); 18841 auto *OVE = new (Context) OpaqueValueExpr( 18842 ELoc, Context.getPointerType(FnTy), VK_PRValue, OK_Ordinary, 18843 S.DefaultLvalueConversion(DeclareReductionRef.get()).get()); 18844 Expr *Args[] = {LHS.get(), RHS.get()}; 18845 ReductionOp = 18846 CallExpr::Create(Context, OVE, Args, Context.VoidTy, VK_PRValue, ELoc, 18847 S.CurFPFeatureOverrides()); 18848 } else { 18849 BinaryOperatorKind CombBOK = getRelatedCompoundReductionOp(BOK); 18850 if (Type->isRecordType() && CombBOK != BOK) { 18851 Sema::TentativeAnalysisScope Trap(S); 18852 ReductionOp = 18853 S.BuildBinOp(Stack->getCurScope(), ReductionId.getBeginLoc(), 18854 CombBOK, LHSDRE, RHSDRE); 18855 } 18856 if (!ReductionOp.isUsable()) { 18857 ReductionOp = 18858 S.BuildBinOp(Stack->getCurScope(), ReductionId.getBeginLoc(), BOK, 18859 LHSDRE, RHSDRE); 18860 if (ReductionOp.isUsable()) { 18861 if (BOK != BO_LT && BOK != BO_GT) { 18862 ReductionOp = 18863 S.BuildBinOp(Stack->getCurScope(), ReductionId.getBeginLoc(), 18864 BO_Assign, LHSDRE, ReductionOp.get()); 18865 } else { 18866 auto *ConditionalOp = new (Context) 18867 ConditionalOperator(ReductionOp.get(), ELoc, LHSDRE, ELoc, 18868 RHSDRE, Type, VK_LValue, OK_Ordinary); 18869 ReductionOp = 18870 S.BuildBinOp(Stack->getCurScope(), ReductionId.getBeginLoc(), 18871 BO_Assign, LHSDRE, ConditionalOp); 18872 } 18873 } 18874 } 18875 if (ReductionOp.isUsable()) 18876 ReductionOp = S.ActOnFinishFullExpr(ReductionOp.get(), 18877 /*DiscardedValue*/ false); 18878 if (!ReductionOp.isUsable()) 18879 continue; 18880 } 18881 18882 // Add copy operations for inscan reductions. 18883 // LHS = RHS; 18884 ExprResult CopyOpRes, TempArrayRes, TempArrayElem; 18885 if (ClauseKind == OMPC_reduction && 18886 RD.RedModifier == OMPC_REDUCTION_inscan) { 18887 ExprResult RHS = S.DefaultLvalueConversion(RHSDRE); 18888 CopyOpRes = S.BuildBinOp(Stack->getCurScope(), ELoc, BO_Assign, LHSDRE, 18889 RHS.get()); 18890 if (!CopyOpRes.isUsable()) 18891 continue; 18892 CopyOpRes = 18893 S.ActOnFinishFullExpr(CopyOpRes.get(), /*DiscardedValue=*/true); 18894 if (!CopyOpRes.isUsable()) 18895 continue; 18896 // For simd directive and simd-based directives in simd mode no need to 18897 // construct temp array, need just a single temp element. 18898 if (Stack->getCurrentDirective() == OMPD_simd || 18899 (S.getLangOpts().OpenMPSimd && 18900 isOpenMPSimdDirective(Stack->getCurrentDirective()))) { 18901 VarDecl *TempArrayVD = 18902 buildVarDecl(S, ELoc, PrivateTy, D->getName(), 18903 D->hasAttrs() ? &D->getAttrs() : nullptr); 18904 // Add a constructor to the temp decl. 18905 S.ActOnUninitializedDecl(TempArrayVD); 18906 TempArrayRes = buildDeclRefExpr(S, TempArrayVD, PrivateTy, ELoc); 18907 } else { 18908 // Build temp array for prefix sum. 18909 auto *Dim = new (S.Context) 18910 OpaqueValueExpr(ELoc, S.Context.getSizeType(), VK_PRValue); 18911 QualType ArrayTy = 18912 S.Context.getVariableArrayType(PrivateTy, Dim, ArrayType::Normal, 18913 /*IndexTypeQuals=*/0, {ELoc, ELoc}); 18914 VarDecl *TempArrayVD = 18915 buildVarDecl(S, ELoc, ArrayTy, D->getName(), 18916 D->hasAttrs() ? &D->getAttrs() : nullptr); 18917 // Add a constructor to the temp decl. 18918 S.ActOnUninitializedDecl(TempArrayVD); 18919 TempArrayRes = buildDeclRefExpr(S, TempArrayVD, ArrayTy, ELoc); 18920 TempArrayElem = 18921 S.DefaultFunctionArrayLvalueConversion(TempArrayRes.get()); 18922 auto *Idx = new (S.Context) 18923 OpaqueValueExpr(ELoc, S.Context.getSizeType(), VK_PRValue); 18924 TempArrayElem = S.CreateBuiltinArraySubscriptExpr(TempArrayElem.get(), 18925 ELoc, Idx, ELoc); 18926 } 18927 } 18928 18929 // OpenMP [2.15.4.6, Restrictions, p.2] 18930 // A list item that appears in an in_reduction clause of a task construct 18931 // must appear in a task_reduction clause of a construct associated with a 18932 // taskgroup region that includes the participating task in its taskgroup 18933 // set. The construct associated with the innermost region that meets this 18934 // condition must specify the same reduction-identifier as the in_reduction 18935 // clause. 18936 if (ClauseKind == OMPC_in_reduction) { 18937 SourceRange ParentSR; 18938 BinaryOperatorKind ParentBOK; 18939 const Expr *ParentReductionOp = nullptr; 18940 Expr *ParentBOKTD = nullptr, *ParentReductionOpTD = nullptr; 18941 DSAStackTy::DSAVarData ParentBOKDSA = 18942 Stack->getTopMostTaskgroupReductionData(D, ParentSR, ParentBOK, 18943 ParentBOKTD); 18944 DSAStackTy::DSAVarData ParentReductionOpDSA = 18945 Stack->getTopMostTaskgroupReductionData( 18946 D, ParentSR, ParentReductionOp, ParentReductionOpTD); 18947 bool IsParentBOK = ParentBOKDSA.DKind != OMPD_unknown; 18948 bool IsParentReductionOp = ParentReductionOpDSA.DKind != OMPD_unknown; 18949 if ((DeclareReductionRef.isUnset() && IsParentReductionOp) || 18950 (DeclareReductionRef.isUsable() && IsParentBOK) || 18951 (IsParentBOK && BOK != ParentBOK) || IsParentReductionOp) { 18952 bool EmitError = true; 18953 if (IsParentReductionOp && DeclareReductionRef.isUsable()) { 18954 llvm::FoldingSetNodeID RedId, ParentRedId; 18955 ParentReductionOp->Profile(ParentRedId, Context, /*Canonical=*/true); 18956 DeclareReductionRef.get()->Profile(RedId, Context, 18957 /*Canonical=*/true); 18958 EmitError = RedId != ParentRedId; 18959 } 18960 if (EmitError) { 18961 S.Diag(ReductionId.getBeginLoc(), 18962 diag::err_omp_reduction_identifier_mismatch) 18963 << ReductionIdRange << RefExpr->getSourceRange(); 18964 S.Diag(ParentSR.getBegin(), 18965 diag::note_omp_previous_reduction_identifier) 18966 << ParentSR 18967 << (IsParentBOK ? ParentBOKDSA.RefExpr 18968 : ParentReductionOpDSA.RefExpr) 18969 ->getSourceRange(); 18970 continue; 18971 } 18972 } 18973 TaskgroupDescriptor = IsParentBOK ? ParentBOKTD : ParentReductionOpTD; 18974 } 18975 18976 DeclRefExpr *Ref = nullptr; 18977 Expr *VarsExpr = RefExpr->IgnoreParens(); 18978 if (!VD && !S.CurContext->isDependentContext()) { 18979 if (ASE || OASE) { 18980 TransformExprToCaptures RebuildToCapture(S, D); 18981 VarsExpr = 18982 RebuildToCapture.TransformExpr(RefExpr->IgnoreParens()).get(); 18983 Ref = RebuildToCapture.getCapturedExpr(); 18984 } else { 18985 VarsExpr = Ref = buildCapture(S, D, SimpleRefExpr, /*WithInit=*/false); 18986 } 18987 if (!S.isOpenMPCapturedDecl(D)) { 18988 RD.ExprCaptures.emplace_back(Ref->getDecl()); 18989 if (Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>()) { 18990 ExprResult RefRes = S.DefaultLvalueConversion(Ref); 18991 if (!RefRes.isUsable()) 18992 continue; 18993 ExprResult PostUpdateRes = 18994 S.BuildBinOp(Stack->getCurScope(), ELoc, BO_Assign, SimpleRefExpr, 18995 RefRes.get()); 18996 if (!PostUpdateRes.isUsable()) 18997 continue; 18998 if (isOpenMPTaskingDirective(Stack->getCurrentDirective()) || 18999 Stack->getCurrentDirective() == OMPD_taskgroup) { 19000 S.Diag(RefExpr->getExprLoc(), 19001 diag::err_omp_reduction_non_addressable_expression) 19002 << RefExpr->getSourceRange(); 19003 continue; 19004 } 19005 RD.ExprPostUpdates.emplace_back( 19006 S.IgnoredValueConversions(PostUpdateRes.get()).get()); 19007 } 19008 } 19009 } 19010 // All reduction items are still marked as reduction (to do not increase 19011 // code base size). 19012 unsigned Modifier = RD.RedModifier; 19013 // Consider task_reductions as reductions with task modifier. Required for 19014 // correct analysis of in_reduction clauses. 19015 if (CurrDir == OMPD_taskgroup && ClauseKind == OMPC_task_reduction) 19016 Modifier = OMPC_REDUCTION_task; 19017 Stack->addDSA(D, RefExpr->IgnoreParens(), OMPC_reduction, Ref, Modifier, 19018 ASE || OASE); 19019 if (Modifier == OMPC_REDUCTION_task && 19020 (CurrDir == OMPD_taskgroup || 19021 ((isOpenMPParallelDirective(CurrDir) || 19022 isOpenMPWorksharingDirective(CurrDir)) && 19023 !isOpenMPSimdDirective(CurrDir)))) { 19024 if (DeclareReductionRef.isUsable()) 19025 Stack->addTaskgroupReductionData(D, ReductionIdRange, 19026 DeclareReductionRef.get()); 19027 else 19028 Stack->addTaskgroupReductionData(D, ReductionIdRange, BOK); 19029 } 19030 RD.push(VarsExpr, PrivateDRE, LHSDRE, RHSDRE, ReductionOp.get(), 19031 TaskgroupDescriptor, CopyOpRes.get(), TempArrayRes.get(), 19032 TempArrayElem.get()); 19033 } 19034 return RD.Vars.empty(); 19035 } 19036 19037 OMPClause *Sema::ActOnOpenMPReductionClause( 19038 ArrayRef<Expr *> VarList, OpenMPReductionClauseModifier Modifier, 19039 SourceLocation StartLoc, SourceLocation LParenLoc, 19040 SourceLocation ModifierLoc, SourceLocation ColonLoc, SourceLocation EndLoc, 19041 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, 19042 ArrayRef<Expr *> UnresolvedReductions) { 19043 if (ModifierLoc.isValid() && Modifier == OMPC_REDUCTION_unknown) { 19044 Diag(LParenLoc, diag::err_omp_unexpected_clause_value) 19045 << getListOfPossibleValues(OMPC_reduction, /*First=*/0, 19046 /*Last=*/OMPC_REDUCTION_unknown) 19047 << getOpenMPClauseName(OMPC_reduction); 19048 return nullptr; 19049 } 19050 // OpenMP 5.0, 2.19.5.4 reduction Clause, Restrictions 19051 // A reduction clause with the inscan reduction-modifier may only appear on a 19052 // worksharing-loop construct, a worksharing-loop SIMD construct, a simd 19053 // construct, a parallel worksharing-loop construct or a parallel 19054 // worksharing-loop SIMD construct. 19055 if (Modifier == OMPC_REDUCTION_inscan && 19056 (DSAStack->getCurrentDirective() != OMPD_for && 19057 DSAStack->getCurrentDirective() != OMPD_for_simd && 19058 DSAStack->getCurrentDirective() != OMPD_simd && 19059 DSAStack->getCurrentDirective() != OMPD_parallel_for && 19060 DSAStack->getCurrentDirective() != OMPD_parallel_for_simd)) { 19061 Diag(ModifierLoc, diag::err_omp_wrong_inscan_reduction); 19062 return nullptr; 19063 } 19064 19065 ReductionData RD(VarList.size(), Modifier); 19066 if (actOnOMPReductionKindClause(*this, DSAStack, OMPC_reduction, VarList, 19067 StartLoc, LParenLoc, ColonLoc, EndLoc, 19068 ReductionIdScopeSpec, ReductionId, 19069 UnresolvedReductions, RD)) 19070 return nullptr; 19071 19072 return OMPReductionClause::Create( 19073 Context, StartLoc, LParenLoc, ModifierLoc, ColonLoc, EndLoc, Modifier, 19074 RD.Vars, ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId, 19075 RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps, RD.InscanCopyOps, 19076 RD.InscanCopyArrayTemps, RD.InscanCopyArrayElems, 19077 buildPreInits(Context, RD.ExprCaptures), 19078 buildPostUpdate(*this, RD.ExprPostUpdates)); 19079 } 19080 19081 OMPClause *Sema::ActOnOpenMPTaskReductionClause( 19082 ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, 19083 SourceLocation ColonLoc, SourceLocation EndLoc, 19084 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, 19085 ArrayRef<Expr *> UnresolvedReductions) { 19086 ReductionData RD(VarList.size()); 19087 if (actOnOMPReductionKindClause(*this, DSAStack, OMPC_task_reduction, VarList, 19088 StartLoc, LParenLoc, ColonLoc, EndLoc, 19089 ReductionIdScopeSpec, ReductionId, 19090 UnresolvedReductions, RD)) 19091 return nullptr; 19092 19093 return OMPTaskReductionClause::Create( 19094 Context, StartLoc, LParenLoc, ColonLoc, EndLoc, RD.Vars, 19095 ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId, 19096 RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps, 19097 buildPreInits(Context, RD.ExprCaptures), 19098 buildPostUpdate(*this, RD.ExprPostUpdates)); 19099 } 19100 19101 OMPClause *Sema::ActOnOpenMPInReductionClause( 19102 ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, 19103 SourceLocation ColonLoc, SourceLocation EndLoc, 19104 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, 19105 ArrayRef<Expr *> UnresolvedReductions) { 19106 ReductionData RD(VarList.size()); 19107 if (actOnOMPReductionKindClause(*this, DSAStack, OMPC_in_reduction, VarList, 19108 StartLoc, LParenLoc, ColonLoc, EndLoc, 19109 ReductionIdScopeSpec, ReductionId, 19110 UnresolvedReductions, RD)) 19111 return nullptr; 19112 19113 return OMPInReductionClause::Create( 19114 Context, StartLoc, LParenLoc, ColonLoc, EndLoc, RD.Vars, 19115 ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId, 19116 RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps, RD.TaskgroupDescriptors, 19117 buildPreInits(Context, RD.ExprCaptures), 19118 buildPostUpdate(*this, RD.ExprPostUpdates)); 19119 } 19120 19121 bool Sema::CheckOpenMPLinearModifier(OpenMPLinearClauseKind LinKind, 19122 SourceLocation LinLoc) { 19123 if ((!LangOpts.CPlusPlus && LinKind != OMPC_LINEAR_val) || 19124 LinKind == OMPC_LINEAR_unknown) { 19125 Diag(LinLoc, diag::err_omp_wrong_linear_modifier) << LangOpts.CPlusPlus; 19126 return true; 19127 } 19128 return false; 19129 } 19130 19131 bool Sema::CheckOpenMPLinearDecl(const ValueDecl *D, SourceLocation ELoc, 19132 OpenMPLinearClauseKind LinKind, QualType Type, 19133 bool IsDeclareSimd) { 19134 const auto *VD = dyn_cast_or_null<VarDecl>(D); 19135 // A variable must not have an incomplete type or a reference type. 19136 if (RequireCompleteType(ELoc, Type, diag::err_omp_linear_incomplete_type)) 19137 return true; 19138 if ((LinKind == OMPC_LINEAR_uval || LinKind == OMPC_LINEAR_ref) && 19139 !Type->isReferenceType()) { 19140 Diag(ELoc, diag::err_omp_wrong_linear_modifier_non_reference) 19141 << Type << getOpenMPSimpleClauseTypeName(OMPC_linear, LinKind); 19142 return true; 19143 } 19144 Type = Type.getNonReferenceType(); 19145 19146 // OpenMP 5.0 [2.19.3, List Item Privatization, Restrictions] 19147 // A variable that is privatized must not have a const-qualified type 19148 // unless it is of class type with a mutable member. This restriction does 19149 // not apply to the firstprivate clause, nor to the linear clause on 19150 // declarative directives (like declare simd). 19151 if (!IsDeclareSimd && 19152 rejectConstNotMutableType(*this, D, Type, OMPC_linear, ELoc)) 19153 return true; 19154 19155 // A list item must be of integral or pointer type. 19156 Type = Type.getUnqualifiedType().getCanonicalType(); 19157 const auto *Ty = Type.getTypePtrOrNull(); 19158 if (!Ty || (LinKind != OMPC_LINEAR_ref && !Ty->isDependentType() && 19159 !Ty->isIntegralType(Context) && !Ty->isPointerType())) { 19160 Diag(ELoc, diag::err_omp_linear_expected_int_or_ptr) << Type; 19161 if (D) { 19162 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) == 19163 VarDecl::DeclarationOnly; 19164 Diag(D->getLocation(), 19165 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 19166 << D; 19167 } 19168 return true; 19169 } 19170 return false; 19171 } 19172 19173 OMPClause *Sema::ActOnOpenMPLinearClause( 19174 ArrayRef<Expr *> VarList, Expr *Step, SourceLocation StartLoc, 19175 SourceLocation LParenLoc, OpenMPLinearClauseKind LinKind, 19176 SourceLocation LinLoc, SourceLocation ColonLoc, SourceLocation EndLoc) { 19177 SmallVector<Expr *, 8> Vars; 19178 SmallVector<Expr *, 8> Privates; 19179 SmallVector<Expr *, 8> Inits; 19180 SmallVector<Decl *, 4> ExprCaptures; 19181 SmallVector<Expr *, 4> ExprPostUpdates; 19182 if (CheckOpenMPLinearModifier(LinKind, LinLoc)) 19183 LinKind = OMPC_LINEAR_val; 19184 for (Expr *RefExpr : VarList) { 19185 assert(RefExpr && "NULL expr in OpenMP linear clause."); 19186 SourceLocation ELoc; 19187 SourceRange ERange; 19188 Expr *SimpleRefExpr = RefExpr; 19189 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 19190 if (Res.second) { 19191 // It will be analyzed later. 19192 Vars.push_back(RefExpr); 19193 Privates.push_back(nullptr); 19194 Inits.push_back(nullptr); 19195 } 19196 ValueDecl *D = Res.first; 19197 if (!D) 19198 continue; 19199 19200 QualType Type = D->getType(); 19201 auto *VD = dyn_cast<VarDecl>(D); 19202 19203 // OpenMP [2.14.3.7, linear clause] 19204 // A list-item cannot appear in more than one linear clause. 19205 // A list-item that appears in a linear clause cannot appear in any 19206 // other data-sharing attribute clause. 19207 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false); 19208 if (DVar.RefExpr) { 19209 Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind) 19210 << getOpenMPClauseName(OMPC_linear); 19211 reportOriginalDsa(*this, DSAStack, D, DVar); 19212 continue; 19213 } 19214 19215 if (CheckOpenMPLinearDecl(D, ELoc, LinKind, Type)) 19216 continue; 19217 Type = Type.getNonReferenceType().getUnqualifiedType().getCanonicalType(); 19218 19219 // Build private copy of original var. 19220 VarDecl *Private = 19221 buildVarDecl(*this, ELoc, Type, D->getName(), 19222 D->hasAttrs() ? &D->getAttrs() : nullptr, 19223 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr); 19224 DeclRefExpr *PrivateRef = buildDeclRefExpr(*this, Private, Type, ELoc); 19225 // Build var to save initial value. 19226 VarDecl *Init = buildVarDecl(*this, ELoc, Type, ".linear.start"); 19227 Expr *InitExpr; 19228 DeclRefExpr *Ref = nullptr; 19229 if (!VD && !CurContext->isDependentContext()) { 19230 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false); 19231 if (!isOpenMPCapturedDecl(D)) { 19232 ExprCaptures.push_back(Ref->getDecl()); 19233 if (Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>()) { 19234 ExprResult RefRes = DefaultLvalueConversion(Ref); 19235 if (!RefRes.isUsable()) 19236 continue; 19237 ExprResult PostUpdateRes = 19238 BuildBinOp(DSAStack->getCurScope(), ELoc, BO_Assign, 19239 SimpleRefExpr, RefRes.get()); 19240 if (!PostUpdateRes.isUsable()) 19241 continue; 19242 ExprPostUpdates.push_back( 19243 IgnoredValueConversions(PostUpdateRes.get()).get()); 19244 } 19245 } 19246 } 19247 if (LinKind == OMPC_LINEAR_uval) 19248 InitExpr = VD ? VD->getInit() : SimpleRefExpr; 19249 else 19250 InitExpr = VD ? SimpleRefExpr : Ref; 19251 AddInitializerToDecl(Init, DefaultLvalueConversion(InitExpr).get(), 19252 /*DirectInit=*/false); 19253 DeclRefExpr *InitRef = buildDeclRefExpr(*this, Init, Type, ELoc); 19254 19255 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_linear, Ref); 19256 Vars.push_back((VD || CurContext->isDependentContext()) 19257 ? RefExpr->IgnoreParens() 19258 : Ref); 19259 Privates.push_back(PrivateRef); 19260 Inits.push_back(InitRef); 19261 } 19262 19263 if (Vars.empty()) 19264 return nullptr; 19265 19266 Expr *StepExpr = Step; 19267 Expr *CalcStepExpr = nullptr; 19268 if (Step && !Step->isValueDependent() && !Step->isTypeDependent() && 19269 !Step->isInstantiationDependent() && 19270 !Step->containsUnexpandedParameterPack()) { 19271 SourceLocation StepLoc = Step->getBeginLoc(); 19272 ExprResult Val = PerformOpenMPImplicitIntegerConversion(StepLoc, Step); 19273 if (Val.isInvalid()) 19274 return nullptr; 19275 StepExpr = Val.get(); 19276 19277 // Build var to save the step value. 19278 VarDecl *SaveVar = 19279 buildVarDecl(*this, StepLoc, StepExpr->getType(), ".linear.step"); 19280 ExprResult SaveRef = 19281 buildDeclRefExpr(*this, SaveVar, StepExpr->getType(), StepLoc); 19282 ExprResult CalcStep = 19283 BuildBinOp(CurScope, StepLoc, BO_Assign, SaveRef.get(), StepExpr); 19284 CalcStep = ActOnFinishFullExpr(CalcStep.get(), /*DiscardedValue*/ false); 19285 19286 // Warn about zero linear step (it would be probably better specified as 19287 // making corresponding variables 'const'). 19288 if (Optional<llvm::APSInt> Result = 19289 StepExpr->getIntegerConstantExpr(Context)) { 19290 if (!Result->isNegative() && !Result->isStrictlyPositive()) 19291 Diag(StepLoc, diag::warn_omp_linear_step_zero) 19292 << Vars[0] << (Vars.size() > 1); 19293 } else if (CalcStep.isUsable()) { 19294 // Calculate the step beforehand instead of doing this on each iteration. 19295 // (This is not used if the number of iterations may be kfold-ed). 19296 CalcStepExpr = CalcStep.get(); 19297 } 19298 } 19299 19300 return OMPLinearClause::Create(Context, StartLoc, LParenLoc, LinKind, LinLoc, 19301 ColonLoc, EndLoc, Vars, Privates, Inits, 19302 StepExpr, CalcStepExpr, 19303 buildPreInits(Context, ExprCaptures), 19304 buildPostUpdate(*this, ExprPostUpdates)); 19305 } 19306 19307 static bool FinishOpenMPLinearClause(OMPLinearClause &Clause, DeclRefExpr *IV, 19308 Expr *NumIterations, Sema &SemaRef, 19309 Scope *S, DSAStackTy *Stack) { 19310 // Walk the vars and build update/final expressions for the CodeGen. 19311 SmallVector<Expr *, 8> Updates; 19312 SmallVector<Expr *, 8> Finals; 19313 SmallVector<Expr *, 8> UsedExprs; 19314 Expr *Step = Clause.getStep(); 19315 Expr *CalcStep = Clause.getCalcStep(); 19316 // OpenMP [2.14.3.7, linear clause] 19317 // If linear-step is not specified it is assumed to be 1. 19318 if (!Step) 19319 Step = SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get(); 19320 else if (CalcStep) 19321 Step = cast<BinaryOperator>(CalcStep)->getLHS(); 19322 bool HasErrors = false; 19323 auto CurInit = Clause.inits().begin(); 19324 auto CurPrivate = Clause.privates().begin(); 19325 OpenMPLinearClauseKind LinKind = Clause.getModifier(); 19326 for (Expr *RefExpr : Clause.varlists()) { 19327 SourceLocation ELoc; 19328 SourceRange ERange; 19329 Expr *SimpleRefExpr = RefExpr; 19330 auto Res = getPrivateItem(SemaRef, SimpleRefExpr, ELoc, ERange); 19331 ValueDecl *D = Res.first; 19332 if (Res.second || !D) { 19333 Updates.push_back(nullptr); 19334 Finals.push_back(nullptr); 19335 HasErrors = true; 19336 continue; 19337 } 19338 auto &&Info = Stack->isLoopControlVariable(D); 19339 // OpenMP [2.15.11, distribute simd Construct] 19340 // A list item may not appear in a linear clause, unless it is the loop 19341 // iteration variable. 19342 if (isOpenMPDistributeDirective(Stack->getCurrentDirective()) && 19343 isOpenMPSimdDirective(Stack->getCurrentDirective()) && !Info.first) { 19344 SemaRef.Diag(ELoc, 19345 diag::err_omp_linear_distribute_var_non_loop_iteration); 19346 Updates.push_back(nullptr); 19347 Finals.push_back(nullptr); 19348 HasErrors = true; 19349 continue; 19350 } 19351 Expr *InitExpr = *CurInit; 19352 19353 // Build privatized reference to the current linear var. 19354 auto *DE = cast<DeclRefExpr>(SimpleRefExpr); 19355 Expr *CapturedRef; 19356 if (LinKind == OMPC_LINEAR_uval) 19357 CapturedRef = cast<VarDecl>(DE->getDecl())->getInit(); 19358 else 19359 CapturedRef = 19360 buildDeclRefExpr(SemaRef, cast<VarDecl>(DE->getDecl()), 19361 DE->getType().getUnqualifiedType(), DE->getExprLoc(), 19362 /*RefersToCapture=*/true); 19363 19364 // Build update: Var = InitExpr + IV * Step 19365 ExprResult Update; 19366 if (!Info.first) 19367 Update = buildCounterUpdate( 19368 SemaRef, S, RefExpr->getExprLoc(), *CurPrivate, InitExpr, IV, Step, 19369 /*Subtract=*/false, /*IsNonRectangularLB=*/false); 19370 else 19371 Update = *CurPrivate; 19372 Update = SemaRef.ActOnFinishFullExpr(Update.get(), DE->getBeginLoc(), 19373 /*DiscardedValue*/ false); 19374 19375 // Build final: Var = PrivCopy; 19376 ExprResult Final; 19377 if (!Info.first) 19378 Final = SemaRef.BuildBinOp( 19379 S, RefExpr->getExprLoc(), BO_Assign, CapturedRef, 19380 SemaRef.DefaultLvalueConversion(*CurPrivate).get()); 19381 else 19382 Final = *CurPrivate; 19383 Final = SemaRef.ActOnFinishFullExpr(Final.get(), DE->getBeginLoc(), 19384 /*DiscardedValue*/ false); 19385 19386 if (!Update.isUsable() || !Final.isUsable()) { 19387 Updates.push_back(nullptr); 19388 Finals.push_back(nullptr); 19389 UsedExprs.push_back(nullptr); 19390 HasErrors = true; 19391 } else { 19392 Updates.push_back(Update.get()); 19393 Finals.push_back(Final.get()); 19394 if (!Info.first) 19395 UsedExprs.push_back(SimpleRefExpr); 19396 } 19397 ++CurInit; 19398 ++CurPrivate; 19399 } 19400 if (Expr *S = Clause.getStep()) 19401 UsedExprs.push_back(S); 19402 // Fill the remaining part with the nullptr. 19403 UsedExprs.append(Clause.varlist_size() + 1 - UsedExprs.size(), nullptr); 19404 Clause.setUpdates(Updates); 19405 Clause.setFinals(Finals); 19406 Clause.setUsedExprs(UsedExprs); 19407 return HasErrors; 19408 } 19409 19410 OMPClause *Sema::ActOnOpenMPAlignedClause( 19411 ArrayRef<Expr *> VarList, Expr *Alignment, SourceLocation StartLoc, 19412 SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc) { 19413 SmallVector<Expr *, 8> Vars; 19414 for (Expr *RefExpr : VarList) { 19415 assert(RefExpr && "NULL expr in OpenMP linear clause."); 19416 SourceLocation ELoc; 19417 SourceRange ERange; 19418 Expr *SimpleRefExpr = RefExpr; 19419 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 19420 if (Res.second) { 19421 // It will be analyzed later. 19422 Vars.push_back(RefExpr); 19423 } 19424 ValueDecl *D = Res.first; 19425 if (!D) 19426 continue; 19427 19428 QualType QType = D->getType(); 19429 auto *VD = dyn_cast<VarDecl>(D); 19430 19431 // OpenMP [2.8.1, simd construct, Restrictions] 19432 // The type of list items appearing in the aligned clause must be 19433 // array, pointer, reference to array, or reference to pointer. 19434 QType = QType.getNonReferenceType().getUnqualifiedType().getCanonicalType(); 19435 const Type *Ty = QType.getTypePtrOrNull(); 19436 if (!Ty || (!Ty->isArrayType() && !Ty->isPointerType())) { 19437 Diag(ELoc, diag::err_omp_aligned_expected_array_or_ptr) 19438 << QType << getLangOpts().CPlusPlus << ERange; 19439 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) == 19440 VarDecl::DeclarationOnly; 19441 Diag(D->getLocation(), 19442 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 19443 << D; 19444 continue; 19445 } 19446 19447 // OpenMP [2.8.1, simd construct, Restrictions] 19448 // A list-item cannot appear in more than one aligned clause. 19449 if (const Expr *PrevRef = DSAStack->addUniqueAligned(D, SimpleRefExpr)) { 19450 Diag(ELoc, diag::err_omp_used_in_clause_twice) 19451 << 0 << getOpenMPClauseName(OMPC_aligned) << ERange; 19452 Diag(PrevRef->getExprLoc(), diag::note_omp_explicit_dsa) 19453 << getOpenMPClauseName(OMPC_aligned); 19454 continue; 19455 } 19456 19457 DeclRefExpr *Ref = nullptr; 19458 if (!VD && isOpenMPCapturedDecl(D)) 19459 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true); 19460 Vars.push_back(DefaultFunctionArrayConversion( 19461 (VD || !Ref) ? RefExpr->IgnoreParens() : Ref) 19462 .get()); 19463 } 19464 19465 // OpenMP [2.8.1, simd construct, Description] 19466 // The parameter of the aligned clause, alignment, must be a constant 19467 // positive integer expression. 19468 // If no optional parameter is specified, implementation-defined default 19469 // alignments for SIMD instructions on the target platforms are assumed. 19470 if (Alignment != nullptr) { 19471 ExprResult AlignResult = 19472 VerifyPositiveIntegerConstantInClause(Alignment, OMPC_aligned); 19473 if (AlignResult.isInvalid()) 19474 return nullptr; 19475 Alignment = AlignResult.get(); 19476 } 19477 if (Vars.empty()) 19478 return nullptr; 19479 19480 return OMPAlignedClause::Create(Context, StartLoc, LParenLoc, ColonLoc, 19481 EndLoc, Vars, Alignment); 19482 } 19483 19484 OMPClause *Sema::ActOnOpenMPCopyinClause(ArrayRef<Expr *> VarList, 19485 SourceLocation StartLoc, 19486 SourceLocation LParenLoc, 19487 SourceLocation EndLoc) { 19488 SmallVector<Expr *, 8> Vars; 19489 SmallVector<Expr *, 8> SrcExprs; 19490 SmallVector<Expr *, 8> DstExprs; 19491 SmallVector<Expr *, 8> AssignmentOps; 19492 for (Expr *RefExpr : VarList) { 19493 assert(RefExpr && "NULL expr in OpenMP copyin clause."); 19494 if (isa<DependentScopeDeclRefExpr>(RefExpr)) { 19495 // It will be analyzed later. 19496 Vars.push_back(RefExpr); 19497 SrcExprs.push_back(nullptr); 19498 DstExprs.push_back(nullptr); 19499 AssignmentOps.push_back(nullptr); 19500 continue; 19501 } 19502 19503 SourceLocation ELoc = RefExpr->getExprLoc(); 19504 // OpenMP [2.1, C/C++] 19505 // A list item is a variable name. 19506 // OpenMP [2.14.4.1, Restrictions, p.1] 19507 // A list item that appears in a copyin clause must be threadprivate. 19508 auto *DE = dyn_cast<DeclRefExpr>(RefExpr); 19509 if (!DE || !isa<VarDecl>(DE->getDecl())) { 19510 Diag(ELoc, diag::err_omp_expected_var_name_member_expr) 19511 << 0 << RefExpr->getSourceRange(); 19512 continue; 19513 } 19514 19515 Decl *D = DE->getDecl(); 19516 auto *VD = cast<VarDecl>(D); 19517 19518 QualType Type = VD->getType(); 19519 if (Type->isDependentType() || Type->isInstantiationDependentType()) { 19520 // It will be analyzed later. 19521 Vars.push_back(DE); 19522 SrcExprs.push_back(nullptr); 19523 DstExprs.push_back(nullptr); 19524 AssignmentOps.push_back(nullptr); 19525 continue; 19526 } 19527 19528 // OpenMP [2.14.4.1, Restrictions, C/C++, p.1] 19529 // A list item that appears in a copyin clause must be threadprivate. 19530 if (!DSAStack->isThreadPrivate(VD)) { 19531 Diag(ELoc, diag::err_omp_required_access) 19532 << getOpenMPClauseName(OMPC_copyin) 19533 << getOpenMPDirectiveName(OMPD_threadprivate); 19534 continue; 19535 } 19536 19537 // OpenMP [2.14.4.1, Restrictions, C/C++, p.2] 19538 // A variable of class type (or array thereof) that appears in a 19539 // copyin clause requires an accessible, unambiguous copy assignment 19540 // operator for the class type. 19541 QualType ElemType = Context.getBaseElementType(Type).getNonReferenceType(); 19542 VarDecl *SrcVD = 19543 buildVarDecl(*this, DE->getBeginLoc(), ElemType.getUnqualifiedType(), 19544 ".copyin.src", VD->hasAttrs() ? &VD->getAttrs() : nullptr); 19545 DeclRefExpr *PseudoSrcExpr = buildDeclRefExpr( 19546 *this, SrcVD, ElemType.getUnqualifiedType(), DE->getExprLoc()); 19547 VarDecl *DstVD = 19548 buildVarDecl(*this, DE->getBeginLoc(), ElemType, ".copyin.dst", 19549 VD->hasAttrs() ? &VD->getAttrs() : nullptr); 19550 DeclRefExpr *PseudoDstExpr = 19551 buildDeclRefExpr(*this, DstVD, ElemType, DE->getExprLoc()); 19552 // For arrays generate assignment operation for single element and replace 19553 // it by the original array element in CodeGen. 19554 ExprResult AssignmentOp = 19555 BuildBinOp(/*S=*/nullptr, DE->getExprLoc(), BO_Assign, PseudoDstExpr, 19556 PseudoSrcExpr); 19557 if (AssignmentOp.isInvalid()) 19558 continue; 19559 AssignmentOp = ActOnFinishFullExpr(AssignmentOp.get(), DE->getExprLoc(), 19560 /*DiscardedValue*/ false); 19561 if (AssignmentOp.isInvalid()) 19562 continue; 19563 19564 DSAStack->addDSA(VD, DE, OMPC_copyin); 19565 Vars.push_back(DE); 19566 SrcExprs.push_back(PseudoSrcExpr); 19567 DstExprs.push_back(PseudoDstExpr); 19568 AssignmentOps.push_back(AssignmentOp.get()); 19569 } 19570 19571 if (Vars.empty()) 19572 return nullptr; 19573 19574 return OMPCopyinClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars, 19575 SrcExprs, DstExprs, AssignmentOps); 19576 } 19577 19578 OMPClause *Sema::ActOnOpenMPCopyprivateClause(ArrayRef<Expr *> VarList, 19579 SourceLocation StartLoc, 19580 SourceLocation LParenLoc, 19581 SourceLocation EndLoc) { 19582 SmallVector<Expr *, 8> Vars; 19583 SmallVector<Expr *, 8> SrcExprs; 19584 SmallVector<Expr *, 8> DstExprs; 19585 SmallVector<Expr *, 8> AssignmentOps; 19586 for (Expr *RefExpr : VarList) { 19587 assert(RefExpr && "NULL expr in OpenMP linear clause."); 19588 SourceLocation ELoc; 19589 SourceRange ERange; 19590 Expr *SimpleRefExpr = RefExpr; 19591 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 19592 if (Res.second) { 19593 // It will be analyzed later. 19594 Vars.push_back(RefExpr); 19595 SrcExprs.push_back(nullptr); 19596 DstExprs.push_back(nullptr); 19597 AssignmentOps.push_back(nullptr); 19598 } 19599 ValueDecl *D = Res.first; 19600 if (!D) 19601 continue; 19602 19603 QualType Type = D->getType(); 19604 auto *VD = dyn_cast<VarDecl>(D); 19605 19606 // OpenMP [2.14.4.2, Restrictions, p.2] 19607 // A list item that appears in a copyprivate clause may not appear in a 19608 // private or firstprivate clause on the single construct. 19609 if (!VD || !DSAStack->isThreadPrivate(VD)) { 19610 DSAStackTy::DSAVarData DVar = 19611 DSAStack->getTopDSA(D, /*FromParent=*/false); 19612 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_copyprivate && 19613 DVar.RefExpr) { 19614 Diag(ELoc, diag::err_omp_wrong_dsa) 19615 << getOpenMPClauseName(DVar.CKind) 19616 << getOpenMPClauseName(OMPC_copyprivate); 19617 reportOriginalDsa(*this, DSAStack, D, DVar); 19618 continue; 19619 } 19620 19621 // OpenMP [2.11.4.2, Restrictions, p.1] 19622 // All list items that appear in a copyprivate clause must be either 19623 // threadprivate or private in the enclosing context. 19624 if (DVar.CKind == OMPC_unknown) { 19625 DVar = DSAStack->getImplicitDSA(D, false); 19626 if (DVar.CKind == OMPC_shared) { 19627 Diag(ELoc, diag::err_omp_required_access) 19628 << getOpenMPClauseName(OMPC_copyprivate) 19629 << "threadprivate or private in the enclosing context"; 19630 reportOriginalDsa(*this, DSAStack, D, DVar); 19631 continue; 19632 } 19633 } 19634 } 19635 19636 // Variably modified types are not supported. 19637 if (!Type->isAnyPointerType() && Type->isVariablyModifiedType()) { 19638 Diag(ELoc, diag::err_omp_variably_modified_type_not_supported) 19639 << getOpenMPClauseName(OMPC_copyprivate) << Type 19640 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 19641 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) == 19642 VarDecl::DeclarationOnly; 19643 Diag(D->getLocation(), 19644 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 19645 << D; 19646 continue; 19647 } 19648 19649 // OpenMP [2.14.4.1, Restrictions, C/C++, p.2] 19650 // A variable of class type (or array thereof) that appears in a 19651 // copyin clause requires an accessible, unambiguous copy assignment 19652 // operator for the class type. 19653 Type = Context.getBaseElementType(Type.getNonReferenceType()) 19654 .getUnqualifiedType(); 19655 VarDecl *SrcVD = 19656 buildVarDecl(*this, RefExpr->getBeginLoc(), Type, ".copyprivate.src", 19657 D->hasAttrs() ? &D->getAttrs() : nullptr); 19658 DeclRefExpr *PseudoSrcExpr = buildDeclRefExpr(*this, SrcVD, Type, ELoc); 19659 VarDecl *DstVD = 19660 buildVarDecl(*this, RefExpr->getBeginLoc(), Type, ".copyprivate.dst", 19661 D->hasAttrs() ? &D->getAttrs() : nullptr); 19662 DeclRefExpr *PseudoDstExpr = buildDeclRefExpr(*this, DstVD, Type, ELoc); 19663 ExprResult AssignmentOp = BuildBinOp( 19664 DSAStack->getCurScope(), ELoc, BO_Assign, PseudoDstExpr, PseudoSrcExpr); 19665 if (AssignmentOp.isInvalid()) 19666 continue; 19667 AssignmentOp = 19668 ActOnFinishFullExpr(AssignmentOp.get(), ELoc, /*DiscardedValue*/ false); 19669 if (AssignmentOp.isInvalid()) 19670 continue; 19671 19672 // No need to mark vars as copyprivate, they are already threadprivate or 19673 // implicitly private. 19674 assert(VD || isOpenMPCapturedDecl(D)); 19675 Vars.push_back( 19676 VD ? RefExpr->IgnoreParens() 19677 : buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false)); 19678 SrcExprs.push_back(PseudoSrcExpr); 19679 DstExprs.push_back(PseudoDstExpr); 19680 AssignmentOps.push_back(AssignmentOp.get()); 19681 } 19682 19683 if (Vars.empty()) 19684 return nullptr; 19685 19686 return OMPCopyprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, 19687 Vars, SrcExprs, DstExprs, AssignmentOps); 19688 } 19689 19690 OMPClause *Sema::ActOnOpenMPFlushClause(ArrayRef<Expr *> VarList, 19691 SourceLocation StartLoc, 19692 SourceLocation LParenLoc, 19693 SourceLocation EndLoc) { 19694 if (VarList.empty()) 19695 return nullptr; 19696 19697 return OMPFlushClause::Create(Context, StartLoc, LParenLoc, EndLoc, VarList); 19698 } 19699 19700 /// Tries to find omp_depend_t. type. 19701 static bool findOMPDependT(Sema &S, SourceLocation Loc, DSAStackTy *Stack, 19702 bool Diagnose = true) { 19703 QualType OMPDependT = Stack->getOMPDependT(); 19704 if (!OMPDependT.isNull()) 19705 return true; 19706 IdentifierInfo *II = &S.PP.getIdentifierTable().get("omp_depend_t"); 19707 ParsedType PT = S.getTypeName(*II, Loc, S.getCurScope()); 19708 if (!PT.getAsOpaquePtr() || PT.get().isNull()) { 19709 if (Diagnose) 19710 S.Diag(Loc, diag::err_omp_implied_type_not_found) << "omp_depend_t"; 19711 return false; 19712 } 19713 Stack->setOMPDependT(PT.get()); 19714 return true; 19715 } 19716 19717 OMPClause *Sema::ActOnOpenMPDepobjClause(Expr *Depobj, SourceLocation StartLoc, 19718 SourceLocation LParenLoc, 19719 SourceLocation EndLoc) { 19720 if (!Depobj) 19721 return nullptr; 19722 19723 bool OMPDependTFound = findOMPDependT(*this, StartLoc, DSAStack); 19724 19725 // OpenMP 5.0, 2.17.10.1 depobj Construct 19726 // depobj is an lvalue expression of type omp_depend_t. 19727 if (!Depobj->isTypeDependent() && !Depobj->isValueDependent() && 19728 !Depobj->isInstantiationDependent() && 19729 !Depobj->containsUnexpandedParameterPack() && 19730 (OMPDependTFound && 19731 !Context.typesAreCompatible(DSAStack->getOMPDependT(), Depobj->getType(), 19732 /*CompareUnqualified=*/true))) { 19733 Diag(Depobj->getExprLoc(), diag::err_omp_expected_omp_depend_t_lvalue) 19734 << 0 << Depobj->getType() << Depobj->getSourceRange(); 19735 } 19736 19737 if (!Depobj->isLValue()) { 19738 Diag(Depobj->getExprLoc(), diag::err_omp_expected_omp_depend_t_lvalue) 19739 << 1 << Depobj->getSourceRange(); 19740 } 19741 19742 return OMPDepobjClause::Create(Context, StartLoc, LParenLoc, EndLoc, Depobj); 19743 } 19744 19745 OMPClause * 19746 Sema::ActOnOpenMPDependClause(const OMPDependClause::DependDataTy &Data, 19747 Expr *DepModifier, ArrayRef<Expr *> VarList, 19748 SourceLocation StartLoc, SourceLocation LParenLoc, 19749 SourceLocation EndLoc) { 19750 OpenMPDependClauseKind DepKind = Data.DepKind; 19751 SourceLocation DepLoc = Data.DepLoc; 19752 if (DSAStack->getCurrentDirective() == OMPD_ordered && 19753 DepKind != OMPC_DEPEND_source && DepKind != OMPC_DEPEND_sink) { 19754 Diag(DepLoc, diag::err_omp_unexpected_clause_value) 19755 << "'source' or 'sink'" << getOpenMPClauseName(OMPC_depend); 19756 return nullptr; 19757 } 19758 if (DSAStack->getCurrentDirective() == OMPD_taskwait && 19759 DepKind == OMPC_DEPEND_mutexinoutset) { 19760 Diag(DepLoc, diag::err_omp_taskwait_depend_mutexinoutset_not_allowed); 19761 return nullptr; 19762 } 19763 if ((DSAStack->getCurrentDirective() != OMPD_ordered || 19764 DSAStack->getCurrentDirective() == OMPD_depobj) && 19765 (DepKind == OMPC_DEPEND_unknown || DepKind == OMPC_DEPEND_source || 19766 DepKind == OMPC_DEPEND_sink || 19767 ((LangOpts.OpenMP < 50 || 19768 DSAStack->getCurrentDirective() == OMPD_depobj) && 19769 DepKind == OMPC_DEPEND_depobj))) { 19770 SmallVector<unsigned, 6> Except = {OMPC_DEPEND_source, OMPC_DEPEND_sink, 19771 OMPC_DEPEND_outallmemory, 19772 OMPC_DEPEND_inoutallmemory}; 19773 if (LangOpts.OpenMP < 50 || DSAStack->getCurrentDirective() == OMPD_depobj) 19774 Except.push_back(OMPC_DEPEND_depobj); 19775 if (LangOpts.OpenMP < 51) 19776 Except.push_back(OMPC_DEPEND_inoutset); 19777 std::string Expected = (LangOpts.OpenMP >= 50 && !DepModifier) 19778 ? "depend modifier(iterator) or " 19779 : ""; 19780 Diag(DepLoc, diag::err_omp_unexpected_clause_value) 19781 << Expected + getListOfPossibleValues(OMPC_depend, /*First=*/0, 19782 /*Last=*/OMPC_DEPEND_unknown, 19783 Except) 19784 << getOpenMPClauseName(OMPC_depend); 19785 return nullptr; 19786 } 19787 if (DepModifier && 19788 (DepKind == OMPC_DEPEND_source || DepKind == OMPC_DEPEND_sink)) { 19789 Diag(DepModifier->getExprLoc(), 19790 diag::err_omp_depend_sink_source_with_modifier); 19791 return nullptr; 19792 } 19793 if (DepModifier && 19794 !DepModifier->getType()->isSpecificBuiltinType(BuiltinType::OMPIterator)) 19795 Diag(DepModifier->getExprLoc(), diag::err_omp_depend_modifier_not_iterator); 19796 19797 SmallVector<Expr *, 8> Vars; 19798 DSAStackTy::OperatorOffsetTy OpsOffs; 19799 llvm::APSInt DepCounter(/*BitWidth=*/32); 19800 llvm::APSInt TotalDepCount(/*BitWidth=*/32); 19801 if (DepKind == OMPC_DEPEND_sink || DepKind == OMPC_DEPEND_source) { 19802 if (const Expr *OrderedCountExpr = 19803 DSAStack->getParentOrderedRegionParam().first) { 19804 TotalDepCount = OrderedCountExpr->EvaluateKnownConstInt(Context); 19805 TotalDepCount.setIsUnsigned(/*Val=*/true); 19806 } 19807 } 19808 for (Expr *RefExpr : VarList) { 19809 assert(RefExpr && "NULL expr in OpenMP shared clause."); 19810 if (isa<DependentScopeDeclRefExpr>(RefExpr)) { 19811 // It will be analyzed later. 19812 Vars.push_back(RefExpr); 19813 continue; 19814 } 19815 19816 SourceLocation ELoc = RefExpr->getExprLoc(); 19817 Expr *SimpleExpr = RefExpr->IgnoreParenCasts(); 19818 if (DepKind == OMPC_DEPEND_sink) { 19819 if (DSAStack->getParentOrderedRegionParam().first && 19820 DepCounter >= TotalDepCount) { 19821 Diag(ELoc, diag::err_omp_depend_sink_unexpected_expr); 19822 continue; 19823 } 19824 ++DepCounter; 19825 // OpenMP [2.13.9, Summary] 19826 // depend(dependence-type : vec), where dependence-type is: 19827 // 'sink' and where vec is the iteration vector, which has the form: 19828 // x1 [+- d1], x2 [+- d2 ], . . . , xn [+- dn] 19829 // where n is the value specified by the ordered clause in the loop 19830 // directive, xi denotes the loop iteration variable of the i-th nested 19831 // loop associated with the loop directive, and di is a constant 19832 // non-negative integer. 19833 if (CurContext->isDependentContext()) { 19834 // It will be analyzed later. 19835 Vars.push_back(RefExpr); 19836 continue; 19837 } 19838 SimpleExpr = SimpleExpr->IgnoreImplicit(); 19839 OverloadedOperatorKind OOK = OO_None; 19840 SourceLocation OOLoc; 19841 Expr *LHS = SimpleExpr; 19842 Expr *RHS = nullptr; 19843 if (auto *BO = dyn_cast<BinaryOperator>(SimpleExpr)) { 19844 OOK = BinaryOperator::getOverloadedOperator(BO->getOpcode()); 19845 OOLoc = BO->getOperatorLoc(); 19846 LHS = BO->getLHS()->IgnoreParenImpCasts(); 19847 RHS = BO->getRHS()->IgnoreParenImpCasts(); 19848 } else if (auto *OCE = dyn_cast<CXXOperatorCallExpr>(SimpleExpr)) { 19849 OOK = OCE->getOperator(); 19850 OOLoc = OCE->getOperatorLoc(); 19851 LHS = OCE->getArg(/*Arg=*/0)->IgnoreParenImpCasts(); 19852 RHS = OCE->getArg(/*Arg=*/1)->IgnoreParenImpCasts(); 19853 } else if (auto *MCE = dyn_cast<CXXMemberCallExpr>(SimpleExpr)) { 19854 OOK = MCE->getMethodDecl() 19855 ->getNameInfo() 19856 .getName() 19857 .getCXXOverloadedOperator(); 19858 OOLoc = MCE->getCallee()->getExprLoc(); 19859 LHS = MCE->getImplicitObjectArgument()->IgnoreParenImpCasts(); 19860 RHS = MCE->getArg(/*Arg=*/0)->IgnoreParenImpCasts(); 19861 } 19862 SourceLocation ELoc; 19863 SourceRange ERange; 19864 auto Res = getPrivateItem(*this, LHS, ELoc, ERange); 19865 if (Res.second) { 19866 // It will be analyzed later. 19867 Vars.push_back(RefExpr); 19868 } 19869 ValueDecl *D = Res.first; 19870 if (!D) 19871 continue; 19872 19873 if (OOK != OO_Plus && OOK != OO_Minus && (RHS || OOK != OO_None)) { 19874 Diag(OOLoc, diag::err_omp_depend_sink_expected_plus_minus); 19875 continue; 19876 } 19877 if (RHS) { 19878 ExprResult RHSRes = VerifyPositiveIntegerConstantInClause( 19879 RHS, OMPC_depend, /*StrictlyPositive=*/false); 19880 if (RHSRes.isInvalid()) 19881 continue; 19882 } 19883 if (!CurContext->isDependentContext() && 19884 DSAStack->getParentOrderedRegionParam().first && 19885 DepCounter != DSAStack->isParentLoopControlVariable(D).first) { 19886 const ValueDecl *VD = 19887 DSAStack->getParentLoopControlVariable(DepCounter.getZExtValue()); 19888 if (VD) 19889 Diag(ELoc, diag::err_omp_depend_sink_expected_loop_iteration) 19890 << 1 << VD; 19891 else 19892 Diag(ELoc, diag::err_omp_depend_sink_expected_loop_iteration) << 0; 19893 continue; 19894 } 19895 OpsOffs.emplace_back(RHS, OOK); 19896 } else { 19897 bool OMPDependTFound = LangOpts.OpenMP >= 50; 19898 if (OMPDependTFound) 19899 OMPDependTFound = findOMPDependT(*this, StartLoc, DSAStack, 19900 DepKind == OMPC_DEPEND_depobj); 19901 if (DepKind == OMPC_DEPEND_depobj) { 19902 // OpenMP 5.0, 2.17.11 depend Clause, Restrictions, C/C++ 19903 // List items used in depend clauses with the depobj dependence type 19904 // must be expressions of the omp_depend_t type. 19905 if (!RefExpr->isValueDependent() && !RefExpr->isTypeDependent() && 19906 !RefExpr->isInstantiationDependent() && 19907 !RefExpr->containsUnexpandedParameterPack() && 19908 (OMPDependTFound && 19909 !Context.hasSameUnqualifiedType(DSAStack->getOMPDependT(), 19910 RefExpr->getType()))) { 19911 Diag(ELoc, diag::err_omp_expected_omp_depend_t_lvalue) 19912 << 0 << RefExpr->getType() << RefExpr->getSourceRange(); 19913 continue; 19914 } 19915 if (!RefExpr->isLValue()) { 19916 Diag(ELoc, diag::err_omp_expected_omp_depend_t_lvalue) 19917 << 1 << RefExpr->getType() << RefExpr->getSourceRange(); 19918 continue; 19919 } 19920 } else { 19921 // OpenMP 5.0 [2.17.11, Restrictions] 19922 // List items used in depend clauses cannot be zero-length array 19923 // sections. 19924 QualType ExprTy = RefExpr->getType().getNonReferenceType(); 19925 const auto *OASE = dyn_cast<OMPArraySectionExpr>(SimpleExpr); 19926 if (OASE) { 19927 QualType BaseType = 19928 OMPArraySectionExpr::getBaseOriginalType(OASE->getBase()); 19929 if (const auto *ATy = BaseType->getAsArrayTypeUnsafe()) 19930 ExprTy = ATy->getElementType(); 19931 else 19932 ExprTy = BaseType->getPointeeType(); 19933 ExprTy = ExprTy.getNonReferenceType(); 19934 const Expr *Length = OASE->getLength(); 19935 Expr::EvalResult Result; 19936 if (Length && !Length->isValueDependent() && 19937 Length->EvaluateAsInt(Result, Context) && 19938 Result.Val.getInt().isZero()) { 19939 Diag(ELoc, 19940 diag::err_omp_depend_zero_length_array_section_not_allowed) 19941 << SimpleExpr->getSourceRange(); 19942 continue; 19943 } 19944 } 19945 19946 // OpenMP 5.0, 2.17.11 depend Clause, Restrictions, C/C++ 19947 // List items used in depend clauses with the in, out, inout, 19948 // inoutset, or mutexinoutset dependence types cannot be 19949 // expressions of the omp_depend_t type. 19950 if (!RefExpr->isValueDependent() && !RefExpr->isTypeDependent() && 19951 !RefExpr->isInstantiationDependent() && 19952 !RefExpr->containsUnexpandedParameterPack() && 19953 (!RefExpr->IgnoreParenImpCasts()->isLValue() || 19954 (OMPDependTFound && 19955 DSAStack->getOMPDependT().getTypePtr() == ExprTy.getTypePtr()))) { 19956 Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item) 19957 << (LangOpts.OpenMP >= 50 ? 1 : 0) 19958 << (LangOpts.OpenMP >= 50 ? 1 : 0) << RefExpr->getSourceRange(); 19959 continue; 19960 } 19961 19962 auto *ASE = dyn_cast<ArraySubscriptExpr>(SimpleExpr); 19963 if (ASE && !ASE->getBase()->isTypeDependent() && 19964 !ASE->getBase()->getType().getNonReferenceType()->isPointerType() && 19965 !ASE->getBase()->getType().getNonReferenceType()->isArrayType()) { 19966 Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item) 19967 << (LangOpts.OpenMP >= 50 ? 1 : 0) 19968 << (LangOpts.OpenMP >= 50 ? 1 : 0) << RefExpr->getSourceRange(); 19969 continue; 19970 } 19971 19972 ExprResult Res; 19973 { 19974 Sema::TentativeAnalysisScope Trap(*this); 19975 Res = CreateBuiltinUnaryOp(ELoc, UO_AddrOf, 19976 RefExpr->IgnoreParenImpCasts()); 19977 } 19978 if (!Res.isUsable() && !isa<OMPArraySectionExpr>(SimpleExpr) && 19979 !isa<OMPArrayShapingExpr>(SimpleExpr)) { 19980 Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item) 19981 << (LangOpts.OpenMP >= 50 ? 1 : 0) 19982 << (LangOpts.OpenMP >= 50 ? 1 : 0) << RefExpr->getSourceRange(); 19983 continue; 19984 } 19985 } 19986 } 19987 Vars.push_back(RefExpr->IgnoreParenImpCasts()); 19988 } 19989 19990 if (!CurContext->isDependentContext() && DepKind == OMPC_DEPEND_sink && 19991 TotalDepCount > VarList.size() && 19992 DSAStack->getParentOrderedRegionParam().first && 19993 DSAStack->getParentLoopControlVariable(VarList.size() + 1)) { 19994 Diag(EndLoc, diag::err_omp_depend_sink_expected_loop_iteration) 19995 << 1 << DSAStack->getParentLoopControlVariable(VarList.size() + 1); 19996 } 19997 if (DepKind != OMPC_DEPEND_source && DepKind != OMPC_DEPEND_sink && 19998 DepKind != OMPC_DEPEND_outallmemory && 19999 DepKind != OMPC_DEPEND_inoutallmemory && Vars.empty()) 20000 return nullptr; 20001 20002 auto *C = OMPDependClause::Create( 20003 Context, StartLoc, LParenLoc, EndLoc, 20004 {DepKind, DepLoc, Data.ColonLoc, Data.OmpAllMemoryLoc}, DepModifier, Vars, 20005 TotalDepCount.getZExtValue()); 20006 if ((DepKind == OMPC_DEPEND_sink || DepKind == OMPC_DEPEND_source) && 20007 DSAStack->isParentOrderedRegion()) 20008 DSAStack->addDoacrossDependClause(C, OpsOffs); 20009 return C; 20010 } 20011 20012 OMPClause *Sema::ActOnOpenMPDeviceClause(OpenMPDeviceClauseModifier Modifier, 20013 Expr *Device, SourceLocation StartLoc, 20014 SourceLocation LParenLoc, 20015 SourceLocation ModifierLoc, 20016 SourceLocation EndLoc) { 20017 assert((ModifierLoc.isInvalid() || LangOpts.OpenMP >= 50) && 20018 "Unexpected device modifier in OpenMP < 50."); 20019 20020 bool ErrorFound = false; 20021 if (ModifierLoc.isValid() && Modifier == OMPC_DEVICE_unknown) { 20022 std::string Values = 20023 getListOfPossibleValues(OMPC_device, /*First=*/0, OMPC_DEVICE_unknown); 20024 Diag(ModifierLoc, diag::err_omp_unexpected_clause_value) 20025 << Values << getOpenMPClauseName(OMPC_device); 20026 ErrorFound = true; 20027 } 20028 20029 Expr *ValExpr = Device; 20030 Stmt *HelperValStmt = nullptr; 20031 20032 // OpenMP [2.9.1, Restrictions] 20033 // The device expression must evaluate to a non-negative integer value. 20034 ErrorFound = !isNonNegativeIntegerValue(ValExpr, *this, OMPC_device, 20035 /*StrictlyPositive=*/false) || 20036 ErrorFound; 20037 if (ErrorFound) 20038 return nullptr; 20039 20040 // OpenMP 5.0 [2.12.5, Restrictions] 20041 // In case of ancestor device-modifier, a requires directive with 20042 // the reverse_offload clause must be specified. 20043 if (Modifier == OMPC_DEVICE_ancestor) { 20044 if (!DSAStack->hasRequiresDeclWithClause<OMPReverseOffloadClause>()) { 20045 targetDiag( 20046 StartLoc, 20047 diag::err_omp_device_ancestor_without_requires_reverse_offload); 20048 ErrorFound = true; 20049 } 20050 } 20051 20052 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 20053 OpenMPDirectiveKind CaptureRegion = 20054 getOpenMPCaptureRegionForClause(DKind, OMPC_device, LangOpts.OpenMP); 20055 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 20056 ValExpr = MakeFullExpr(ValExpr).get(); 20057 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 20058 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 20059 HelperValStmt = buildPreInits(Context, Captures); 20060 } 20061 20062 return new (Context) 20063 OMPDeviceClause(Modifier, ValExpr, HelperValStmt, CaptureRegion, StartLoc, 20064 LParenLoc, ModifierLoc, EndLoc); 20065 } 20066 20067 static bool checkTypeMappable(SourceLocation SL, SourceRange SR, Sema &SemaRef, 20068 DSAStackTy *Stack, QualType QTy, 20069 bool FullCheck = true) { 20070 if (SemaRef.RequireCompleteType(SL, QTy, diag::err_incomplete_type)) 20071 return false; 20072 if (FullCheck && !SemaRef.CurContext->isDependentContext() && 20073 !QTy.isTriviallyCopyableType(SemaRef.Context)) 20074 SemaRef.Diag(SL, diag::warn_omp_non_trivial_type_mapped) << QTy << SR; 20075 return true; 20076 } 20077 20078 /// Return true if it can be proven that the provided array expression 20079 /// (array section or array subscript) does NOT specify the whole size of the 20080 /// array whose base type is \a BaseQTy. 20081 static bool checkArrayExpressionDoesNotReferToWholeSize(Sema &SemaRef, 20082 const Expr *E, 20083 QualType BaseQTy) { 20084 const auto *OASE = dyn_cast<OMPArraySectionExpr>(E); 20085 20086 // If this is an array subscript, it refers to the whole size if the size of 20087 // the dimension is constant and equals 1. Also, an array section assumes the 20088 // format of an array subscript if no colon is used. 20089 if (isa<ArraySubscriptExpr>(E) || 20090 (OASE && OASE->getColonLocFirst().isInvalid())) { 20091 if (const auto *ATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr())) 20092 return ATy->getSize().getSExtValue() != 1; 20093 // Size can't be evaluated statically. 20094 return false; 20095 } 20096 20097 assert(OASE && "Expecting array section if not an array subscript."); 20098 const Expr *LowerBound = OASE->getLowerBound(); 20099 const Expr *Length = OASE->getLength(); 20100 20101 // If there is a lower bound that does not evaluates to zero, we are not 20102 // covering the whole dimension. 20103 if (LowerBound) { 20104 Expr::EvalResult Result; 20105 if (!LowerBound->EvaluateAsInt(Result, SemaRef.getASTContext())) 20106 return false; // Can't get the integer value as a constant. 20107 20108 llvm::APSInt ConstLowerBound = Result.Val.getInt(); 20109 if (ConstLowerBound.getSExtValue()) 20110 return true; 20111 } 20112 20113 // If we don't have a length we covering the whole dimension. 20114 if (!Length) 20115 return false; 20116 20117 // If the base is a pointer, we don't have a way to get the size of the 20118 // pointee. 20119 if (BaseQTy->isPointerType()) 20120 return false; 20121 20122 // We can only check if the length is the same as the size of the dimension 20123 // if we have a constant array. 20124 const auto *CATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr()); 20125 if (!CATy) 20126 return false; 20127 20128 Expr::EvalResult Result; 20129 if (!Length->EvaluateAsInt(Result, SemaRef.getASTContext())) 20130 return false; // Can't get the integer value as a constant. 20131 20132 llvm::APSInt ConstLength = Result.Val.getInt(); 20133 return CATy->getSize().getSExtValue() != ConstLength.getSExtValue(); 20134 } 20135 20136 // Return true if it can be proven that the provided array expression (array 20137 // section or array subscript) does NOT specify a single element of the array 20138 // whose base type is \a BaseQTy. 20139 static bool checkArrayExpressionDoesNotReferToUnitySize(Sema &SemaRef, 20140 const Expr *E, 20141 QualType BaseQTy) { 20142 const auto *OASE = dyn_cast<OMPArraySectionExpr>(E); 20143 20144 // An array subscript always refer to a single element. Also, an array section 20145 // assumes the format of an array subscript if no colon is used. 20146 if (isa<ArraySubscriptExpr>(E) || 20147 (OASE && OASE->getColonLocFirst().isInvalid())) 20148 return false; 20149 20150 assert(OASE && "Expecting array section if not an array subscript."); 20151 const Expr *Length = OASE->getLength(); 20152 20153 // If we don't have a length we have to check if the array has unitary size 20154 // for this dimension. Also, we should always expect a length if the base type 20155 // is pointer. 20156 if (!Length) { 20157 if (const auto *ATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr())) 20158 return ATy->getSize().getSExtValue() != 1; 20159 // We cannot assume anything. 20160 return false; 20161 } 20162 20163 // Check if the length evaluates to 1. 20164 Expr::EvalResult Result; 20165 if (!Length->EvaluateAsInt(Result, SemaRef.getASTContext())) 20166 return false; // Can't get the integer value as a constant. 20167 20168 llvm::APSInt ConstLength = Result.Val.getInt(); 20169 return ConstLength.getSExtValue() != 1; 20170 } 20171 20172 // The base of elements of list in a map clause have to be either: 20173 // - a reference to variable or field. 20174 // - a member expression. 20175 // - an array expression. 20176 // 20177 // E.g. if we have the expression 'r.S.Arr[:12]', we want to retrieve the 20178 // reference to 'r'. 20179 // 20180 // If we have: 20181 // 20182 // struct SS { 20183 // Bla S; 20184 // foo() { 20185 // #pragma omp target map (S.Arr[:12]); 20186 // } 20187 // } 20188 // 20189 // We want to retrieve the member expression 'this->S'; 20190 20191 // OpenMP 5.0 [2.19.7.1, map Clause, Restrictions, p.2] 20192 // If a list item is an array section, it must specify contiguous storage. 20193 // 20194 // For this restriction it is sufficient that we make sure only references 20195 // to variables or fields and array expressions, and that no array sections 20196 // exist except in the rightmost expression (unless they cover the whole 20197 // dimension of the array). E.g. these would be invalid: 20198 // 20199 // r.ArrS[3:5].Arr[6:7] 20200 // 20201 // r.ArrS[3:5].x 20202 // 20203 // but these would be valid: 20204 // r.ArrS[3].Arr[6:7] 20205 // 20206 // r.ArrS[3].x 20207 namespace { 20208 class MapBaseChecker final : public StmtVisitor<MapBaseChecker, bool> { 20209 Sema &SemaRef; 20210 OpenMPClauseKind CKind = OMPC_unknown; 20211 OpenMPDirectiveKind DKind = OMPD_unknown; 20212 OMPClauseMappableExprCommon::MappableExprComponentList &Components; 20213 bool IsNonContiguous = false; 20214 bool NoDiagnose = false; 20215 const Expr *RelevantExpr = nullptr; 20216 bool AllowUnitySizeArraySection = true; 20217 bool AllowWholeSizeArraySection = true; 20218 bool AllowAnotherPtr = true; 20219 SourceLocation ELoc; 20220 SourceRange ERange; 20221 20222 void emitErrorMsg() { 20223 // If nothing else worked, this is not a valid map clause expression. 20224 if (SemaRef.getLangOpts().OpenMP < 50) { 20225 SemaRef.Diag(ELoc, 20226 diag::err_omp_expected_named_var_member_or_array_expression) 20227 << ERange; 20228 } else { 20229 SemaRef.Diag(ELoc, diag::err_omp_non_lvalue_in_map_or_motion_clauses) 20230 << getOpenMPClauseName(CKind) << ERange; 20231 } 20232 } 20233 20234 public: 20235 bool VisitDeclRefExpr(DeclRefExpr *DRE) { 20236 if (!isa<VarDecl>(DRE->getDecl())) { 20237 emitErrorMsg(); 20238 return false; 20239 } 20240 assert(!RelevantExpr && "RelevantExpr is expected to be nullptr"); 20241 RelevantExpr = DRE; 20242 // Record the component. 20243 Components.emplace_back(DRE, DRE->getDecl(), IsNonContiguous); 20244 return true; 20245 } 20246 20247 bool VisitMemberExpr(MemberExpr *ME) { 20248 Expr *E = ME; 20249 Expr *BaseE = ME->getBase()->IgnoreParenCasts(); 20250 20251 if (isa<CXXThisExpr>(BaseE)) { 20252 assert(!RelevantExpr && "RelevantExpr is expected to be nullptr"); 20253 // We found a base expression: this->Val. 20254 RelevantExpr = ME; 20255 } else { 20256 E = BaseE; 20257 } 20258 20259 if (!isa<FieldDecl>(ME->getMemberDecl())) { 20260 if (!NoDiagnose) { 20261 SemaRef.Diag(ELoc, diag::err_omp_expected_access_to_data_field) 20262 << ME->getSourceRange(); 20263 return false; 20264 } 20265 if (RelevantExpr) 20266 return false; 20267 return Visit(E); 20268 } 20269 20270 auto *FD = cast<FieldDecl>(ME->getMemberDecl()); 20271 20272 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.3] 20273 // A bit-field cannot appear in a map clause. 20274 // 20275 if (FD->isBitField()) { 20276 if (!NoDiagnose) { 20277 SemaRef.Diag(ELoc, diag::err_omp_bit_fields_forbidden_in_clause) 20278 << ME->getSourceRange() << getOpenMPClauseName(CKind); 20279 return false; 20280 } 20281 if (RelevantExpr) 20282 return false; 20283 return Visit(E); 20284 } 20285 20286 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1] 20287 // If the type of a list item is a reference to a type T then the type 20288 // will be considered to be T for all purposes of this clause. 20289 QualType CurType = BaseE->getType().getNonReferenceType(); 20290 20291 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.2] 20292 // A list item cannot be a variable that is a member of a structure with 20293 // a union type. 20294 // 20295 if (CurType->isUnionType()) { 20296 if (!NoDiagnose) { 20297 SemaRef.Diag(ELoc, diag::err_omp_union_type_not_allowed) 20298 << ME->getSourceRange(); 20299 return false; 20300 } 20301 return RelevantExpr || Visit(E); 20302 } 20303 20304 // If we got a member expression, we should not expect any array section 20305 // before that: 20306 // 20307 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.7] 20308 // If a list item is an element of a structure, only the rightmost symbol 20309 // of the variable reference can be an array section. 20310 // 20311 AllowUnitySizeArraySection = false; 20312 AllowWholeSizeArraySection = false; 20313 20314 // Record the component. 20315 Components.emplace_back(ME, FD, IsNonContiguous); 20316 return RelevantExpr || Visit(E); 20317 } 20318 20319 bool VisitArraySubscriptExpr(ArraySubscriptExpr *AE) { 20320 Expr *E = AE->getBase()->IgnoreParenImpCasts(); 20321 20322 if (!E->getType()->isAnyPointerType() && !E->getType()->isArrayType()) { 20323 if (!NoDiagnose) { 20324 SemaRef.Diag(ELoc, diag::err_omp_expected_base_var_name) 20325 << 0 << AE->getSourceRange(); 20326 return false; 20327 } 20328 return RelevantExpr || Visit(E); 20329 } 20330 20331 // If we got an array subscript that express the whole dimension we 20332 // can have any array expressions before. If it only expressing part of 20333 // the dimension, we can only have unitary-size array expressions. 20334 if (checkArrayExpressionDoesNotReferToWholeSize(SemaRef, AE, E->getType())) 20335 AllowWholeSizeArraySection = false; 20336 20337 if (const auto *TE = dyn_cast<CXXThisExpr>(E->IgnoreParenCasts())) { 20338 Expr::EvalResult Result; 20339 if (!AE->getIdx()->isValueDependent() && 20340 AE->getIdx()->EvaluateAsInt(Result, SemaRef.getASTContext()) && 20341 !Result.Val.getInt().isZero()) { 20342 SemaRef.Diag(AE->getIdx()->getExprLoc(), 20343 diag::err_omp_invalid_map_this_expr); 20344 SemaRef.Diag(AE->getIdx()->getExprLoc(), 20345 diag::note_omp_invalid_subscript_on_this_ptr_map); 20346 } 20347 assert(!RelevantExpr && "RelevantExpr is expected to be nullptr"); 20348 RelevantExpr = TE; 20349 } 20350 20351 // Record the component - we don't have any declaration associated. 20352 Components.emplace_back(AE, nullptr, IsNonContiguous); 20353 20354 return RelevantExpr || Visit(E); 20355 } 20356 20357 bool VisitOMPArraySectionExpr(OMPArraySectionExpr *OASE) { 20358 // After OMP 5.0 Array section in reduction clause will be implicitly 20359 // mapped 20360 assert(!(SemaRef.getLangOpts().OpenMP < 50 && NoDiagnose) && 20361 "Array sections cannot be implicitly mapped."); 20362 Expr *E = OASE->getBase()->IgnoreParenImpCasts(); 20363 QualType CurType = 20364 OMPArraySectionExpr::getBaseOriginalType(E).getCanonicalType(); 20365 20366 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1] 20367 // If the type of a list item is a reference to a type T then the type 20368 // will be considered to be T for all purposes of this clause. 20369 if (CurType->isReferenceType()) 20370 CurType = CurType->getPointeeType(); 20371 20372 bool IsPointer = CurType->isAnyPointerType(); 20373 20374 if (!IsPointer && !CurType->isArrayType()) { 20375 SemaRef.Diag(ELoc, diag::err_omp_expected_base_var_name) 20376 << 0 << OASE->getSourceRange(); 20377 return false; 20378 } 20379 20380 bool NotWhole = 20381 checkArrayExpressionDoesNotReferToWholeSize(SemaRef, OASE, CurType); 20382 bool NotUnity = 20383 checkArrayExpressionDoesNotReferToUnitySize(SemaRef, OASE, CurType); 20384 20385 if (AllowWholeSizeArraySection) { 20386 // Any array section is currently allowed. Allowing a whole size array 20387 // section implies allowing a unity array section as well. 20388 // 20389 // If this array section refers to the whole dimension we can still 20390 // accept other array sections before this one, except if the base is a 20391 // pointer. Otherwise, only unitary sections are accepted. 20392 if (NotWhole || IsPointer) 20393 AllowWholeSizeArraySection = false; 20394 } else if (DKind == OMPD_target_update && 20395 SemaRef.getLangOpts().OpenMP >= 50) { 20396 if (IsPointer && !AllowAnotherPtr) 20397 SemaRef.Diag(ELoc, diag::err_omp_section_length_undefined) 20398 << /*array of unknown bound */ 1; 20399 else 20400 IsNonContiguous = true; 20401 } else if (AllowUnitySizeArraySection && NotUnity) { 20402 // A unity or whole array section is not allowed and that is not 20403 // compatible with the properties of the current array section. 20404 if (NoDiagnose) 20405 return false; 20406 SemaRef.Diag(ELoc, 20407 diag::err_array_section_does_not_specify_contiguous_storage) 20408 << OASE->getSourceRange(); 20409 return false; 20410 } 20411 20412 if (IsPointer) 20413 AllowAnotherPtr = false; 20414 20415 if (const auto *TE = dyn_cast<CXXThisExpr>(E)) { 20416 Expr::EvalResult ResultR; 20417 Expr::EvalResult ResultL; 20418 if (!OASE->getLength()->isValueDependent() && 20419 OASE->getLength()->EvaluateAsInt(ResultR, SemaRef.getASTContext()) && 20420 !ResultR.Val.getInt().isOne()) { 20421 SemaRef.Diag(OASE->getLength()->getExprLoc(), 20422 diag::err_omp_invalid_map_this_expr); 20423 SemaRef.Diag(OASE->getLength()->getExprLoc(), 20424 diag::note_omp_invalid_length_on_this_ptr_mapping); 20425 } 20426 if (OASE->getLowerBound() && !OASE->getLowerBound()->isValueDependent() && 20427 OASE->getLowerBound()->EvaluateAsInt(ResultL, 20428 SemaRef.getASTContext()) && 20429 !ResultL.Val.getInt().isZero()) { 20430 SemaRef.Diag(OASE->getLowerBound()->getExprLoc(), 20431 diag::err_omp_invalid_map_this_expr); 20432 SemaRef.Diag(OASE->getLowerBound()->getExprLoc(), 20433 diag::note_omp_invalid_lower_bound_on_this_ptr_mapping); 20434 } 20435 assert(!RelevantExpr && "RelevantExpr is expected to be nullptr"); 20436 RelevantExpr = TE; 20437 } 20438 20439 // Record the component - we don't have any declaration associated. 20440 Components.emplace_back(OASE, nullptr, /*IsNonContiguous=*/false); 20441 return RelevantExpr || Visit(E); 20442 } 20443 bool VisitOMPArrayShapingExpr(OMPArrayShapingExpr *E) { 20444 Expr *Base = E->getBase(); 20445 20446 // Record the component - we don't have any declaration associated. 20447 Components.emplace_back(E, nullptr, IsNonContiguous); 20448 20449 return Visit(Base->IgnoreParenImpCasts()); 20450 } 20451 20452 bool VisitUnaryOperator(UnaryOperator *UO) { 20453 if (SemaRef.getLangOpts().OpenMP < 50 || !UO->isLValue() || 20454 UO->getOpcode() != UO_Deref) { 20455 emitErrorMsg(); 20456 return false; 20457 } 20458 if (!RelevantExpr) { 20459 // Record the component if haven't found base decl. 20460 Components.emplace_back(UO, nullptr, /*IsNonContiguous=*/false); 20461 } 20462 return RelevantExpr || Visit(UO->getSubExpr()->IgnoreParenImpCasts()); 20463 } 20464 bool VisitBinaryOperator(BinaryOperator *BO) { 20465 if (SemaRef.getLangOpts().OpenMP < 50 || !BO->getType()->isPointerType()) { 20466 emitErrorMsg(); 20467 return false; 20468 } 20469 20470 // Pointer arithmetic is the only thing we expect to happen here so after we 20471 // make sure the binary operator is a pointer type, the we only thing need 20472 // to to is to visit the subtree that has the same type as root (so that we 20473 // know the other subtree is just an offset) 20474 Expr *LE = BO->getLHS()->IgnoreParenImpCasts(); 20475 Expr *RE = BO->getRHS()->IgnoreParenImpCasts(); 20476 Components.emplace_back(BO, nullptr, false); 20477 assert((LE->getType().getTypePtr() == BO->getType().getTypePtr() || 20478 RE->getType().getTypePtr() == BO->getType().getTypePtr()) && 20479 "Either LHS or RHS have base decl inside"); 20480 if (BO->getType().getTypePtr() == LE->getType().getTypePtr()) 20481 return RelevantExpr || Visit(LE); 20482 return RelevantExpr || Visit(RE); 20483 } 20484 bool VisitCXXThisExpr(CXXThisExpr *CTE) { 20485 assert(!RelevantExpr && "RelevantExpr is expected to be nullptr"); 20486 RelevantExpr = CTE; 20487 Components.emplace_back(CTE, nullptr, IsNonContiguous); 20488 return true; 20489 } 20490 bool VisitCXXOperatorCallExpr(CXXOperatorCallExpr *COCE) { 20491 assert(!RelevantExpr && "RelevantExpr is expected to be nullptr"); 20492 Components.emplace_back(COCE, nullptr, IsNonContiguous); 20493 return true; 20494 } 20495 bool VisitOpaqueValueExpr(OpaqueValueExpr *E) { 20496 Expr *Source = E->getSourceExpr(); 20497 if (!Source) { 20498 emitErrorMsg(); 20499 return false; 20500 } 20501 return Visit(Source); 20502 } 20503 bool VisitStmt(Stmt *) { 20504 emitErrorMsg(); 20505 return false; 20506 } 20507 const Expr *getFoundBase() const { return RelevantExpr; } 20508 explicit MapBaseChecker( 20509 Sema &SemaRef, OpenMPClauseKind CKind, OpenMPDirectiveKind DKind, 20510 OMPClauseMappableExprCommon::MappableExprComponentList &Components, 20511 bool NoDiagnose, SourceLocation &ELoc, SourceRange &ERange) 20512 : SemaRef(SemaRef), CKind(CKind), DKind(DKind), Components(Components), 20513 NoDiagnose(NoDiagnose), ELoc(ELoc), ERange(ERange) {} 20514 }; 20515 } // namespace 20516 20517 /// Return the expression of the base of the mappable expression or null if it 20518 /// cannot be determined and do all the necessary checks to see if the 20519 /// expression is valid as a standalone mappable expression. In the process, 20520 /// record all the components of the expression. 20521 static const Expr *checkMapClauseExpressionBase( 20522 Sema &SemaRef, Expr *E, 20523 OMPClauseMappableExprCommon::MappableExprComponentList &CurComponents, 20524 OpenMPClauseKind CKind, OpenMPDirectiveKind DKind, bool NoDiagnose) { 20525 SourceLocation ELoc = E->getExprLoc(); 20526 SourceRange ERange = E->getSourceRange(); 20527 MapBaseChecker Checker(SemaRef, CKind, DKind, CurComponents, NoDiagnose, ELoc, 20528 ERange); 20529 if (Checker.Visit(E->IgnoreParens())) { 20530 // Check if the highest dimension array section has length specified 20531 if (SemaRef.getLangOpts().OpenMP >= 50 && !CurComponents.empty() && 20532 (CKind == OMPC_to || CKind == OMPC_from)) { 20533 auto CI = CurComponents.rbegin(); 20534 auto CE = CurComponents.rend(); 20535 for (; CI != CE; ++CI) { 20536 const auto *OASE = 20537 dyn_cast<OMPArraySectionExpr>(CI->getAssociatedExpression()); 20538 if (!OASE) 20539 continue; 20540 if (OASE && OASE->getLength()) 20541 break; 20542 SemaRef.Diag(ELoc, diag::err_array_section_does_not_specify_length) 20543 << ERange; 20544 } 20545 } 20546 return Checker.getFoundBase(); 20547 } 20548 return nullptr; 20549 } 20550 20551 // Return true if expression E associated with value VD has conflicts with other 20552 // map information. 20553 static bool checkMapConflicts( 20554 Sema &SemaRef, DSAStackTy *DSAS, const ValueDecl *VD, const Expr *E, 20555 bool CurrentRegionOnly, 20556 OMPClauseMappableExprCommon::MappableExprComponentListRef CurComponents, 20557 OpenMPClauseKind CKind) { 20558 assert(VD && E); 20559 SourceLocation ELoc = E->getExprLoc(); 20560 SourceRange ERange = E->getSourceRange(); 20561 20562 // In order to easily check the conflicts we need to match each component of 20563 // the expression under test with the components of the expressions that are 20564 // already in the stack. 20565 20566 assert(!CurComponents.empty() && "Map clause expression with no components!"); 20567 assert(CurComponents.back().getAssociatedDeclaration() == VD && 20568 "Map clause expression with unexpected base!"); 20569 20570 // Variables to help detecting enclosing problems in data environment nests. 20571 bool IsEnclosedByDataEnvironmentExpr = false; 20572 const Expr *EnclosingExpr = nullptr; 20573 20574 bool FoundError = DSAS->checkMappableExprComponentListsForDecl( 20575 VD, CurrentRegionOnly, 20576 [&IsEnclosedByDataEnvironmentExpr, &SemaRef, VD, CurrentRegionOnly, ELoc, 20577 ERange, CKind, &EnclosingExpr, 20578 CurComponents](OMPClauseMappableExprCommon::MappableExprComponentListRef 20579 StackComponents, 20580 OpenMPClauseKind Kind) { 20581 if (CKind == Kind && SemaRef.LangOpts.OpenMP >= 50) 20582 return false; 20583 assert(!StackComponents.empty() && 20584 "Map clause expression with no components!"); 20585 assert(StackComponents.back().getAssociatedDeclaration() == VD && 20586 "Map clause expression with unexpected base!"); 20587 (void)VD; 20588 20589 // The whole expression in the stack. 20590 const Expr *RE = StackComponents.front().getAssociatedExpression(); 20591 20592 // Expressions must start from the same base. Here we detect at which 20593 // point both expressions diverge from each other and see if we can 20594 // detect if the memory referred to both expressions is contiguous and 20595 // do not overlap. 20596 auto CI = CurComponents.rbegin(); 20597 auto CE = CurComponents.rend(); 20598 auto SI = StackComponents.rbegin(); 20599 auto SE = StackComponents.rend(); 20600 for (; CI != CE && SI != SE; ++CI, ++SI) { 20601 20602 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.3] 20603 // At most one list item can be an array item derived from a given 20604 // variable in map clauses of the same construct. 20605 if (CurrentRegionOnly && 20606 (isa<ArraySubscriptExpr>(CI->getAssociatedExpression()) || 20607 isa<OMPArraySectionExpr>(CI->getAssociatedExpression()) || 20608 isa<OMPArrayShapingExpr>(CI->getAssociatedExpression())) && 20609 (isa<ArraySubscriptExpr>(SI->getAssociatedExpression()) || 20610 isa<OMPArraySectionExpr>(SI->getAssociatedExpression()) || 20611 isa<OMPArrayShapingExpr>(SI->getAssociatedExpression()))) { 20612 SemaRef.Diag(CI->getAssociatedExpression()->getExprLoc(), 20613 diag::err_omp_multiple_array_items_in_map_clause) 20614 << CI->getAssociatedExpression()->getSourceRange(); 20615 SemaRef.Diag(SI->getAssociatedExpression()->getExprLoc(), 20616 diag::note_used_here) 20617 << SI->getAssociatedExpression()->getSourceRange(); 20618 return true; 20619 } 20620 20621 // Do both expressions have the same kind? 20622 if (CI->getAssociatedExpression()->getStmtClass() != 20623 SI->getAssociatedExpression()->getStmtClass()) 20624 break; 20625 20626 // Are we dealing with different variables/fields? 20627 if (CI->getAssociatedDeclaration() != SI->getAssociatedDeclaration()) 20628 break; 20629 } 20630 // Check if the extra components of the expressions in the enclosing 20631 // data environment are redundant for the current base declaration. 20632 // If they are, the maps completely overlap, which is legal. 20633 for (; SI != SE; ++SI) { 20634 QualType Type; 20635 if (const auto *ASE = 20636 dyn_cast<ArraySubscriptExpr>(SI->getAssociatedExpression())) { 20637 Type = ASE->getBase()->IgnoreParenImpCasts()->getType(); 20638 } else if (const auto *OASE = dyn_cast<OMPArraySectionExpr>( 20639 SI->getAssociatedExpression())) { 20640 const Expr *E = OASE->getBase()->IgnoreParenImpCasts(); 20641 Type = 20642 OMPArraySectionExpr::getBaseOriginalType(E).getCanonicalType(); 20643 } else if (const auto *OASE = dyn_cast<OMPArrayShapingExpr>( 20644 SI->getAssociatedExpression())) { 20645 Type = OASE->getBase()->getType()->getPointeeType(); 20646 } 20647 if (Type.isNull() || Type->isAnyPointerType() || 20648 checkArrayExpressionDoesNotReferToWholeSize( 20649 SemaRef, SI->getAssociatedExpression(), Type)) 20650 break; 20651 } 20652 20653 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.4] 20654 // List items of map clauses in the same construct must not share 20655 // original storage. 20656 // 20657 // If the expressions are exactly the same or one is a subset of the 20658 // other, it means they are sharing storage. 20659 if (CI == CE && SI == SE) { 20660 if (CurrentRegionOnly) { 20661 if (CKind == OMPC_map) { 20662 SemaRef.Diag(ELoc, diag::err_omp_map_shared_storage) << ERange; 20663 } else { 20664 assert(CKind == OMPC_to || CKind == OMPC_from); 20665 SemaRef.Diag(ELoc, diag::err_omp_once_referenced_in_target_update) 20666 << ERange; 20667 } 20668 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here) 20669 << RE->getSourceRange(); 20670 return true; 20671 } 20672 // If we find the same expression in the enclosing data environment, 20673 // that is legal. 20674 IsEnclosedByDataEnvironmentExpr = true; 20675 return false; 20676 } 20677 20678 QualType DerivedType = 20679 std::prev(CI)->getAssociatedDeclaration()->getType(); 20680 SourceLocation DerivedLoc = 20681 std::prev(CI)->getAssociatedExpression()->getExprLoc(); 20682 20683 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1] 20684 // If the type of a list item is a reference to a type T then the type 20685 // will be considered to be T for all purposes of this clause. 20686 DerivedType = DerivedType.getNonReferenceType(); 20687 20688 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.1] 20689 // A variable for which the type is pointer and an array section 20690 // derived from that variable must not appear as list items of map 20691 // clauses of the same construct. 20692 // 20693 // Also, cover one of the cases in: 20694 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.5] 20695 // If any part of the original storage of a list item has corresponding 20696 // storage in the device data environment, all of the original storage 20697 // must have corresponding storage in the device data environment. 20698 // 20699 if (DerivedType->isAnyPointerType()) { 20700 if (CI == CE || SI == SE) { 20701 SemaRef.Diag( 20702 DerivedLoc, 20703 diag::err_omp_pointer_mapped_along_with_derived_section) 20704 << DerivedLoc; 20705 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here) 20706 << RE->getSourceRange(); 20707 return true; 20708 } 20709 if (CI->getAssociatedExpression()->getStmtClass() != 20710 SI->getAssociatedExpression()->getStmtClass() || 20711 CI->getAssociatedDeclaration()->getCanonicalDecl() == 20712 SI->getAssociatedDeclaration()->getCanonicalDecl()) { 20713 assert(CI != CE && SI != SE); 20714 SemaRef.Diag(DerivedLoc, diag::err_omp_same_pointer_dereferenced) 20715 << DerivedLoc; 20716 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here) 20717 << RE->getSourceRange(); 20718 return true; 20719 } 20720 } 20721 20722 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.4] 20723 // List items of map clauses in the same construct must not share 20724 // original storage. 20725 // 20726 // An expression is a subset of the other. 20727 if (CurrentRegionOnly && (CI == CE || SI == SE)) { 20728 if (CKind == OMPC_map) { 20729 if (CI != CE || SI != SE) { 20730 // Allow constructs like this: map(s, s.ptr[0:1]), where s.ptr is 20731 // a pointer. 20732 auto Begin = 20733 CI != CE ? CurComponents.begin() : StackComponents.begin(); 20734 auto End = CI != CE ? CurComponents.end() : StackComponents.end(); 20735 auto It = Begin; 20736 while (It != End && !It->getAssociatedDeclaration()) 20737 std::advance(It, 1); 20738 assert(It != End && 20739 "Expected at least one component with the declaration."); 20740 if (It != Begin && It->getAssociatedDeclaration() 20741 ->getType() 20742 .getCanonicalType() 20743 ->isAnyPointerType()) { 20744 IsEnclosedByDataEnvironmentExpr = false; 20745 EnclosingExpr = nullptr; 20746 return false; 20747 } 20748 } 20749 SemaRef.Diag(ELoc, diag::err_omp_map_shared_storage) << ERange; 20750 } else { 20751 assert(CKind == OMPC_to || CKind == OMPC_from); 20752 SemaRef.Diag(ELoc, diag::err_omp_once_referenced_in_target_update) 20753 << ERange; 20754 } 20755 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here) 20756 << RE->getSourceRange(); 20757 return true; 20758 } 20759 20760 // The current expression uses the same base as other expression in the 20761 // data environment but does not contain it completely. 20762 if (!CurrentRegionOnly && SI != SE) 20763 EnclosingExpr = RE; 20764 20765 // The current expression is a subset of the expression in the data 20766 // environment. 20767 IsEnclosedByDataEnvironmentExpr |= 20768 (!CurrentRegionOnly && CI != CE && SI == SE); 20769 20770 return false; 20771 }); 20772 20773 if (CurrentRegionOnly) 20774 return FoundError; 20775 20776 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.5] 20777 // If any part of the original storage of a list item has corresponding 20778 // storage in the device data environment, all of the original storage must 20779 // have corresponding storage in the device data environment. 20780 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.6] 20781 // If a list item is an element of a structure, and a different element of 20782 // the structure has a corresponding list item in the device data environment 20783 // prior to a task encountering the construct associated with the map clause, 20784 // then the list item must also have a corresponding list item in the device 20785 // data environment prior to the task encountering the construct. 20786 // 20787 if (EnclosingExpr && !IsEnclosedByDataEnvironmentExpr) { 20788 SemaRef.Diag(ELoc, 20789 diag::err_omp_original_storage_is_shared_and_does_not_contain) 20790 << ERange; 20791 SemaRef.Diag(EnclosingExpr->getExprLoc(), diag::note_used_here) 20792 << EnclosingExpr->getSourceRange(); 20793 return true; 20794 } 20795 20796 return FoundError; 20797 } 20798 20799 // Look up the user-defined mapper given the mapper name and mapped type, and 20800 // build a reference to it. 20801 static ExprResult buildUserDefinedMapperRef(Sema &SemaRef, Scope *S, 20802 CXXScopeSpec &MapperIdScopeSpec, 20803 const DeclarationNameInfo &MapperId, 20804 QualType Type, 20805 Expr *UnresolvedMapper) { 20806 if (MapperIdScopeSpec.isInvalid()) 20807 return ExprError(); 20808 // Get the actual type for the array type. 20809 if (Type->isArrayType()) { 20810 assert(Type->getAsArrayTypeUnsafe() && "Expect to get a valid array type"); 20811 Type = Type->getAsArrayTypeUnsafe()->getElementType().getCanonicalType(); 20812 } 20813 // Find all user-defined mappers with the given MapperId. 20814 SmallVector<UnresolvedSet<8>, 4> Lookups; 20815 LookupResult Lookup(SemaRef, MapperId, Sema::LookupOMPMapperName); 20816 Lookup.suppressDiagnostics(); 20817 if (S) { 20818 while (S && SemaRef.LookupParsedName(Lookup, S, &MapperIdScopeSpec)) { 20819 NamedDecl *D = Lookup.getRepresentativeDecl(); 20820 while (S && !S->isDeclScope(D)) 20821 S = S->getParent(); 20822 if (S) 20823 S = S->getParent(); 20824 Lookups.emplace_back(); 20825 Lookups.back().append(Lookup.begin(), Lookup.end()); 20826 Lookup.clear(); 20827 } 20828 } else if (auto *ULE = cast_or_null<UnresolvedLookupExpr>(UnresolvedMapper)) { 20829 // Extract the user-defined mappers with the given MapperId. 20830 Lookups.push_back(UnresolvedSet<8>()); 20831 for (NamedDecl *D : ULE->decls()) { 20832 auto *DMD = cast<OMPDeclareMapperDecl>(D); 20833 assert(DMD && "Expect valid OMPDeclareMapperDecl during instantiation."); 20834 Lookups.back().addDecl(DMD); 20835 } 20836 } 20837 // Defer the lookup for dependent types. The results will be passed through 20838 // UnresolvedMapper on instantiation. 20839 if (SemaRef.CurContext->isDependentContext() || Type->isDependentType() || 20840 Type->isInstantiationDependentType() || 20841 Type->containsUnexpandedParameterPack() || 20842 filterLookupForUDReductionAndMapper<bool>(Lookups, [](ValueDecl *D) { 20843 return !D->isInvalidDecl() && 20844 (D->getType()->isDependentType() || 20845 D->getType()->isInstantiationDependentType() || 20846 D->getType()->containsUnexpandedParameterPack()); 20847 })) { 20848 UnresolvedSet<8> URS; 20849 for (const UnresolvedSet<8> &Set : Lookups) { 20850 if (Set.empty()) 20851 continue; 20852 URS.append(Set.begin(), Set.end()); 20853 } 20854 return UnresolvedLookupExpr::Create( 20855 SemaRef.Context, /*NamingClass=*/nullptr, 20856 MapperIdScopeSpec.getWithLocInContext(SemaRef.Context), MapperId, 20857 /*ADL=*/false, /*Overloaded=*/true, URS.begin(), URS.end()); 20858 } 20859 SourceLocation Loc = MapperId.getLoc(); 20860 // [OpenMP 5.0], 2.19.7.3 declare mapper Directive, Restrictions 20861 // The type must be of struct, union or class type in C and C++ 20862 if (!Type->isStructureOrClassType() && !Type->isUnionType() && 20863 (MapperIdScopeSpec.isSet() || MapperId.getAsString() != "default")) { 20864 SemaRef.Diag(Loc, diag::err_omp_mapper_wrong_type); 20865 return ExprError(); 20866 } 20867 // Perform argument dependent lookup. 20868 if (SemaRef.getLangOpts().CPlusPlus && !MapperIdScopeSpec.isSet()) 20869 argumentDependentLookup(SemaRef, MapperId, Loc, Type, Lookups); 20870 // Return the first user-defined mapper with the desired type. 20871 if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>( 20872 Lookups, [&SemaRef, Type](ValueDecl *D) -> ValueDecl * { 20873 if (!D->isInvalidDecl() && 20874 SemaRef.Context.hasSameType(D->getType(), Type)) 20875 return D; 20876 return nullptr; 20877 })) 20878 return SemaRef.BuildDeclRefExpr(VD, Type, VK_LValue, Loc); 20879 // Find the first user-defined mapper with a type derived from the desired 20880 // type. 20881 if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>( 20882 Lookups, [&SemaRef, Type, Loc](ValueDecl *D) -> ValueDecl * { 20883 if (!D->isInvalidDecl() && 20884 SemaRef.IsDerivedFrom(Loc, Type, D->getType()) && 20885 !Type.isMoreQualifiedThan(D->getType())) 20886 return D; 20887 return nullptr; 20888 })) { 20889 CXXBasePaths Paths(/*FindAmbiguities=*/true, /*RecordPaths=*/true, 20890 /*DetectVirtual=*/false); 20891 if (SemaRef.IsDerivedFrom(Loc, Type, VD->getType(), Paths)) { 20892 if (!Paths.isAmbiguous(SemaRef.Context.getCanonicalType( 20893 VD->getType().getUnqualifiedType()))) { 20894 if (SemaRef.CheckBaseClassAccess( 20895 Loc, VD->getType(), Type, Paths.front(), 20896 /*DiagID=*/0) != Sema::AR_inaccessible) { 20897 return SemaRef.BuildDeclRefExpr(VD, Type, VK_LValue, Loc); 20898 } 20899 } 20900 } 20901 } 20902 // Report error if a mapper is specified, but cannot be found. 20903 if (MapperIdScopeSpec.isSet() || MapperId.getAsString() != "default") { 20904 SemaRef.Diag(Loc, diag::err_omp_invalid_mapper) 20905 << Type << MapperId.getName(); 20906 return ExprError(); 20907 } 20908 return ExprEmpty(); 20909 } 20910 20911 namespace { 20912 // Utility struct that gathers all the related lists associated with a mappable 20913 // expression. 20914 struct MappableVarListInfo { 20915 // The list of expressions. 20916 ArrayRef<Expr *> VarList; 20917 // The list of processed expressions. 20918 SmallVector<Expr *, 16> ProcessedVarList; 20919 // The mappble components for each expression. 20920 OMPClauseMappableExprCommon::MappableExprComponentLists VarComponents; 20921 // The base declaration of the variable. 20922 SmallVector<ValueDecl *, 16> VarBaseDeclarations; 20923 // The reference to the user-defined mapper associated with every expression. 20924 SmallVector<Expr *, 16> UDMapperList; 20925 20926 MappableVarListInfo(ArrayRef<Expr *> VarList) : VarList(VarList) { 20927 // We have a list of components and base declarations for each entry in the 20928 // variable list. 20929 VarComponents.reserve(VarList.size()); 20930 VarBaseDeclarations.reserve(VarList.size()); 20931 } 20932 }; 20933 } // namespace 20934 20935 // Check the validity of the provided variable list for the provided clause kind 20936 // \a CKind. In the check process the valid expressions, mappable expression 20937 // components, variables, and user-defined mappers are extracted and used to 20938 // fill \a ProcessedVarList, \a VarComponents, \a VarBaseDeclarations, and \a 20939 // UDMapperList in MVLI. \a MapType, \a IsMapTypeImplicit, \a MapperIdScopeSpec, 20940 // and \a MapperId are expected to be valid if the clause kind is 'map'. 20941 static void checkMappableExpressionList( 20942 Sema &SemaRef, DSAStackTy *DSAS, OpenMPClauseKind CKind, 20943 MappableVarListInfo &MVLI, SourceLocation StartLoc, 20944 CXXScopeSpec &MapperIdScopeSpec, DeclarationNameInfo MapperId, 20945 ArrayRef<Expr *> UnresolvedMappers, 20946 OpenMPMapClauseKind MapType = OMPC_MAP_unknown, 20947 ArrayRef<OpenMPMapModifierKind> Modifiers = None, 20948 bool IsMapTypeImplicit = false, bool NoDiagnose = false) { 20949 // We only expect mappable expressions in 'to', 'from', and 'map' clauses. 20950 assert((CKind == OMPC_map || CKind == OMPC_to || CKind == OMPC_from) && 20951 "Unexpected clause kind with mappable expressions!"); 20952 20953 // If the identifier of user-defined mapper is not specified, it is "default". 20954 // We do not change the actual name in this clause to distinguish whether a 20955 // mapper is specified explicitly, i.e., it is not explicitly specified when 20956 // MapperId.getName() is empty. 20957 if (!MapperId.getName() || MapperId.getName().isEmpty()) { 20958 auto &DeclNames = SemaRef.getASTContext().DeclarationNames; 20959 MapperId.setName(DeclNames.getIdentifier( 20960 &SemaRef.getASTContext().Idents.get("default"))); 20961 MapperId.setLoc(StartLoc); 20962 } 20963 20964 // Iterators to find the current unresolved mapper expression. 20965 auto UMIt = UnresolvedMappers.begin(), UMEnd = UnresolvedMappers.end(); 20966 bool UpdateUMIt = false; 20967 Expr *UnresolvedMapper = nullptr; 20968 20969 bool HasHoldModifier = 20970 llvm::is_contained(Modifiers, OMPC_MAP_MODIFIER_ompx_hold); 20971 20972 // Keep track of the mappable components and base declarations in this clause. 20973 // Each entry in the list is going to have a list of components associated. We 20974 // record each set of the components so that we can build the clause later on. 20975 // In the end we should have the same amount of declarations and component 20976 // lists. 20977 20978 for (Expr *RE : MVLI.VarList) { 20979 assert(RE && "Null expr in omp to/from/map clause"); 20980 SourceLocation ELoc = RE->getExprLoc(); 20981 20982 // Find the current unresolved mapper expression. 20983 if (UpdateUMIt && UMIt != UMEnd) { 20984 UMIt++; 20985 assert( 20986 UMIt != UMEnd && 20987 "Expect the size of UnresolvedMappers to match with that of VarList"); 20988 } 20989 UpdateUMIt = true; 20990 if (UMIt != UMEnd) 20991 UnresolvedMapper = *UMIt; 20992 20993 const Expr *VE = RE->IgnoreParenLValueCasts(); 20994 20995 if (VE->isValueDependent() || VE->isTypeDependent() || 20996 VE->isInstantiationDependent() || 20997 VE->containsUnexpandedParameterPack()) { 20998 // Try to find the associated user-defined mapper. 20999 ExprResult ER = buildUserDefinedMapperRef( 21000 SemaRef, DSAS->getCurScope(), MapperIdScopeSpec, MapperId, 21001 VE->getType().getCanonicalType(), UnresolvedMapper); 21002 if (ER.isInvalid()) 21003 continue; 21004 MVLI.UDMapperList.push_back(ER.get()); 21005 // We can only analyze this information once the missing information is 21006 // resolved. 21007 MVLI.ProcessedVarList.push_back(RE); 21008 continue; 21009 } 21010 21011 Expr *SimpleExpr = RE->IgnoreParenCasts(); 21012 21013 if (!RE->isLValue()) { 21014 if (SemaRef.getLangOpts().OpenMP < 50) { 21015 SemaRef.Diag( 21016 ELoc, diag::err_omp_expected_named_var_member_or_array_expression) 21017 << RE->getSourceRange(); 21018 } else { 21019 SemaRef.Diag(ELoc, diag::err_omp_non_lvalue_in_map_or_motion_clauses) 21020 << getOpenMPClauseName(CKind) << RE->getSourceRange(); 21021 } 21022 continue; 21023 } 21024 21025 OMPClauseMappableExprCommon::MappableExprComponentList CurComponents; 21026 ValueDecl *CurDeclaration = nullptr; 21027 21028 // Obtain the array or member expression bases if required. Also, fill the 21029 // components array with all the components identified in the process. 21030 const Expr *BE = 21031 checkMapClauseExpressionBase(SemaRef, SimpleExpr, CurComponents, CKind, 21032 DSAS->getCurrentDirective(), NoDiagnose); 21033 if (!BE) 21034 continue; 21035 21036 assert(!CurComponents.empty() && 21037 "Invalid mappable expression information."); 21038 21039 if (const auto *TE = dyn_cast<CXXThisExpr>(BE)) { 21040 // Add store "this" pointer to class in DSAStackTy for future checking 21041 DSAS->addMappedClassesQualTypes(TE->getType()); 21042 // Try to find the associated user-defined mapper. 21043 ExprResult ER = buildUserDefinedMapperRef( 21044 SemaRef, DSAS->getCurScope(), MapperIdScopeSpec, MapperId, 21045 VE->getType().getCanonicalType(), UnresolvedMapper); 21046 if (ER.isInvalid()) 21047 continue; 21048 MVLI.UDMapperList.push_back(ER.get()); 21049 // Skip restriction checking for variable or field declarations 21050 MVLI.ProcessedVarList.push_back(RE); 21051 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1); 21052 MVLI.VarComponents.back().append(CurComponents.begin(), 21053 CurComponents.end()); 21054 MVLI.VarBaseDeclarations.push_back(nullptr); 21055 continue; 21056 } 21057 21058 // For the following checks, we rely on the base declaration which is 21059 // expected to be associated with the last component. The declaration is 21060 // expected to be a variable or a field (if 'this' is being mapped). 21061 CurDeclaration = CurComponents.back().getAssociatedDeclaration(); 21062 assert(CurDeclaration && "Null decl on map clause."); 21063 assert( 21064 CurDeclaration->isCanonicalDecl() && 21065 "Expecting components to have associated only canonical declarations."); 21066 21067 auto *VD = dyn_cast<VarDecl>(CurDeclaration); 21068 const auto *FD = dyn_cast<FieldDecl>(CurDeclaration); 21069 21070 assert((VD || FD) && "Only variables or fields are expected here!"); 21071 (void)FD; 21072 21073 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.10] 21074 // threadprivate variables cannot appear in a map clause. 21075 // OpenMP 4.5 [2.10.5, target update Construct] 21076 // threadprivate variables cannot appear in a from clause. 21077 if (VD && DSAS->isThreadPrivate(VD)) { 21078 if (NoDiagnose) 21079 continue; 21080 DSAStackTy::DSAVarData DVar = DSAS->getTopDSA(VD, /*FromParent=*/false); 21081 SemaRef.Diag(ELoc, diag::err_omp_threadprivate_in_clause) 21082 << getOpenMPClauseName(CKind); 21083 reportOriginalDsa(SemaRef, DSAS, VD, DVar); 21084 continue; 21085 } 21086 21087 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.9] 21088 // A list item cannot appear in both a map clause and a data-sharing 21089 // attribute clause on the same construct. 21090 21091 // Check conflicts with other map clause expressions. We check the conflicts 21092 // with the current construct separately from the enclosing data 21093 // environment, because the restrictions are different. We only have to 21094 // check conflicts across regions for the map clauses. 21095 if (checkMapConflicts(SemaRef, DSAS, CurDeclaration, SimpleExpr, 21096 /*CurrentRegionOnly=*/true, CurComponents, CKind)) 21097 break; 21098 if (CKind == OMPC_map && 21099 (SemaRef.getLangOpts().OpenMP <= 45 || StartLoc.isValid()) && 21100 checkMapConflicts(SemaRef, DSAS, CurDeclaration, SimpleExpr, 21101 /*CurrentRegionOnly=*/false, CurComponents, CKind)) 21102 break; 21103 21104 // OpenMP 4.5 [2.10.5, target update Construct] 21105 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1] 21106 // If the type of a list item is a reference to a type T then the type will 21107 // be considered to be T for all purposes of this clause. 21108 auto I = llvm::find_if( 21109 CurComponents, 21110 [](const OMPClauseMappableExprCommon::MappableComponent &MC) { 21111 return MC.getAssociatedDeclaration(); 21112 }); 21113 assert(I != CurComponents.end() && "Null decl on map clause."); 21114 (void)I; 21115 QualType Type; 21116 auto *ASE = dyn_cast<ArraySubscriptExpr>(VE->IgnoreParens()); 21117 auto *OASE = dyn_cast<OMPArraySectionExpr>(VE->IgnoreParens()); 21118 auto *OAShE = dyn_cast<OMPArrayShapingExpr>(VE->IgnoreParens()); 21119 if (ASE) { 21120 Type = ASE->getType().getNonReferenceType(); 21121 } else if (OASE) { 21122 QualType BaseType = 21123 OMPArraySectionExpr::getBaseOriginalType(OASE->getBase()); 21124 if (const auto *ATy = BaseType->getAsArrayTypeUnsafe()) 21125 Type = ATy->getElementType(); 21126 else 21127 Type = BaseType->getPointeeType(); 21128 Type = Type.getNonReferenceType(); 21129 } else if (OAShE) { 21130 Type = OAShE->getBase()->getType()->getPointeeType(); 21131 } else { 21132 Type = VE->getType(); 21133 } 21134 21135 // OpenMP 4.5 [2.10.5, target update Construct, Restrictions, p.4] 21136 // A list item in a to or from clause must have a mappable type. 21137 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.9] 21138 // A list item must have a mappable type. 21139 if (!checkTypeMappable(VE->getExprLoc(), VE->getSourceRange(), SemaRef, 21140 DSAS, Type, /*FullCheck=*/true)) 21141 continue; 21142 21143 if (CKind == OMPC_map) { 21144 // target enter data 21145 // OpenMP [2.10.2, Restrictions, p. 99] 21146 // A map-type must be specified in all map clauses and must be either 21147 // to or alloc. 21148 OpenMPDirectiveKind DKind = DSAS->getCurrentDirective(); 21149 if (DKind == OMPD_target_enter_data && 21150 !(MapType == OMPC_MAP_to || MapType == OMPC_MAP_alloc)) { 21151 SemaRef.Diag(StartLoc, diag::err_omp_invalid_map_type_for_directive) 21152 << (IsMapTypeImplicit ? 1 : 0) 21153 << getOpenMPSimpleClauseTypeName(OMPC_map, MapType) 21154 << getOpenMPDirectiveName(DKind); 21155 continue; 21156 } 21157 21158 // target exit_data 21159 // OpenMP [2.10.3, Restrictions, p. 102] 21160 // A map-type must be specified in all map clauses and must be either 21161 // from, release, or delete. 21162 if (DKind == OMPD_target_exit_data && 21163 !(MapType == OMPC_MAP_from || MapType == OMPC_MAP_release || 21164 MapType == OMPC_MAP_delete)) { 21165 SemaRef.Diag(StartLoc, diag::err_omp_invalid_map_type_for_directive) 21166 << (IsMapTypeImplicit ? 1 : 0) 21167 << getOpenMPSimpleClauseTypeName(OMPC_map, MapType) 21168 << getOpenMPDirectiveName(DKind); 21169 continue; 21170 } 21171 21172 // The 'ompx_hold' modifier is specifically intended to be used on a 21173 // 'target' or 'target data' directive to prevent data from being unmapped 21174 // during the associated statement. It is not permitted on a 'target 21175 // enter data' or 'target exit data' directive, which have no associated 21176 // statement. 21177 if ((DKind == OMPD_target_enter_data || DKind == OMPD_target_exit_data) && 21178 HasHoldModifier) { 21179 SemaRef.Diag(StartLoc, 21180 diag::err_omp_invalid_map_type_modifier_for_directive) 21181 << getOpenMPSimpleClauseTypeName(OMPC_map, 21182 OMPC_MAP_MODIFIER_ompx_hold) 21183 << getOpenMPDirectiveName(DKind); 21184 continue; 21185 } 21186 21187 // target, target data 21188 // OpenMP 5.0 [2.12.2, Restrictions, p. 163] 21189 // OpenMP 5.0 [2.12.5, Restrictions, p. 174] 21190 // A map-type in a map clause must be to, from, tofrom or alloc 21191 if ((DKind == OMPD_target_data || 21192 isOpenMPTargetExecutionDirective(DKind)) && 21193 !(MapType == OMPC_MAP_to || MapType == OMPC_MAP_from || 21194 MapType == OMPC_MAP_tofrom || MapType == OMPC_MAP_alloc)) { 21195 SemaRef.Diag(StartLoc, diag::err_omp_invalid_map_type_for_directive) 21196 << (IsMapTypeImplicit ? 1 : 0) 21197 << getOpenMPSimpleClauseTypeName(OMPC_map, MapType) 21198 << getOpenMPDirectiveName(DKind); 21199 continue; 21200 } 21201 21202 // OpenMP 4.5 [2.15.5.1, Restrictions, p.3] 21203 // A list item cannot appear in both a map clause and a data-sharing 21204 // attribute clause on the same construct 21205 // 21206 // OpenMP 5.0 [2.19.7.1, Restrictions, p.7] 21207 // A list item cannot appear in both a map clause and a data-sharing 21208 // attribute clause on the same construct unless the construct is a 21209 // combined construct. 21210 if (VD && ((SemaRef.LangOpts.OpenMP <= 45 && 21211 isOpenMPTargetExecutionDirective(DKind)) || 21212 DKind == OMPD_target)) { 21213 DSAStackTy::DSAVarData DVar = DSAS->getTopDSA(VD, /*FromParent=*/false); 21214 if (isOpenMPPrivate(DVar.CKind)) { 21215 SemaRef.Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa) 21216 << getOpenMPClauseName(DVar.CKind) 21217 << getOpenMPClauseName(OMPC_map) 21218 << getOpenMPDirectiveName(DSAS->getCurrentDirective()); 21219 reportOriginalDsa(SemaRef, DSAS, CurDeclaration, DVar); 21220 continue; 21221 } 21222 } 21223 } 21224 21225 // Try to find the associated user-defined mapper. 21226 ExprResult ER = buildUserDefinedMapperRef( 21227 SemaRef, DSAS->getCurScope(), MapperIdScopeSpec, MapperId, 21228 Type.getCanonicalType(), UnresolvedMapper); 21229 if (ER.isInvalid()) 21230 continue; 21231 MVLI.UDMapperList.push_back(ER.get()); 21232 21233 // Save the current expression. 21234 MVLI.ProcessedVarList.push_back(RE); 21235 21236 // Store the components in the stack so that they can be used to check 21237 // against other clauses later on. 21238 DSAS->addMappableExpressionComponents(CurDeclaration, CurComponents, 21239 /*WhereFoundClauseKind=*/OMPC_map); 21240 21241 // Save the components and declaration to create the clause. For purposes of 21242 // the clause creation, any component list that has has base 'this' uses 21243 // null as base declaration. 21244 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1); 21245 MVLI.VarComponents.back().append(CurComponents.begin(), 21246 CurComponents.end()); 21247 MVLI.VarBaseDeclarations.push_back(isa<MemberExpr>(BE) ? nullptr 21248 : CurDeclaration); 21249 } 21250 } 21251 21252 OMPClause *Sema::ActOnOpenMPMapClause( 21253 ArrayRef<OpenMPMapModifierKind> MapTypeModifiers, 21254 ArrayRef<SourceLocation> MapTypeModifiersLoc, 21255 CXXScopeSpec &MapperIdScopeSpec, DeclarationNameInfo &MapperId, 21256 OpenMPMapClauseKind MapType, bool IsMapTypeImplicit, SourceLocation MapLoc, 21257 SourceLocation ColonLoc, ArrayRef<Expr *> VarList, 21258 const OMPVarListLocTy &Locs, bool NoDiagnose, 21259 ArrayRef<Expr *> UnresolvedMappers) { 21260 OpenMPMapModifierKind Modifiers[] = { 21261 OMPC_MAP_MODIFIER_unknown, OMPC_MAP_MODIFIER_unknown, 21262 OMPC_MAP_MODIFIER_unknown, OMPC_MAP_MODIFIER_unknown, 21263 OMPC_MAP_MODIFIER_unknown}; 21264 SourceLocation ModifiersLoc[NumberOfOMPMapClauseModifiers]; 21265 21266 // Process map-type-modifiers, flag errors for duplicate modifiers. 21267 unsigned Count = 0; 21268 for (unsigned I = 0, E = MapTypeModifiers.size(); I < E; ++I) { 21269 if (MapTypeModifiers[I] != OMPC_MAP_MODIFIER_unknown && 21270 llvm::is_contained(Modifiers, MapTypeModifiers[I])) { 21271 Diag(MapTypeModifiersLoc[I], diag::err_omp_duplicate_map_type_modifier); 21272 continue; 21273 } 21274 assert(Count < NumberOfOMPMapClauseModifiers && 21275 "Modifiers exceed the allowed number of map type modifiers"); 21276 Modifiers[Count] = MapTypeModifiers[I]; 21277 ModifiersLoc[Count] = MapTypeModifiersLoc[I]; 21278 ++Count; 21279 } 21280 21281 MappableVarListInfo MVLI(VarList); 21282 checkMappableExpressionList(*this, DSAStack, OMPC_map, MVLI, Locs.StartLoc, 21283 MapperIdScopeSpec, MapperId, UnresolvedMappers, 21284 MapType, Modifiers, IsMapTypeImplicit, 21285 NoDiagnose); 21286 21287 // We need to produce a map clause even if we don't have variables so that 21288 // other diagnostics related with non-existing map clauses are accurate. 21289 return OMPMapClause::Create(Context, Locs, MVLI.ProcessedVarList, 21290 MVLI.VarBaseDeclarations, MVLI.VarComponents, 21291 MVLI.UDMapperList, Modifiers, ModifiersLoc, 21292 MapperIdScopeSpec.getWithLocInContext(Context), 21293 MapperId, MapType, IsMapTypeImplicit, MapLoc); 21294 } 21295 21296 QualType Sema::ActOnOpenMPDeclareReductionType(SourceLocation TyLoc, 21297 TypeResult ParsedType) { 21298 assert(ParsedType.isUsable()); 21299 21300 QualType ReductionType = GetTypeFromParser(ParsedType.get()); 21301 if (ReductionType.isNull()) 21302 return QualType(); 21303 21304 // [OpenMP 4.0], 2.15 declare reduction Directive, Restrictions, C\C++ 21305 // A type name in a declare reduction directive cannot be a function type, an 21306 // array type, a reference type, or a type qualified with const, volatile or 21307 // restrict. 21308 if (ReductionType.hasQualifiers()) { 21309 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 0; 21310 return QualType(); 21311 } 21312 21313 if (ReductionType->isFunctionType()) { 21314 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 1; 21315 return QualType(); 21316 } 21317 if (ReductionType->isReferenceType()) { 21318 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 2; 21319 return QualType(); 21320 } 21321 if (ReductionType->isArrayType()) { 21322 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 3; 21323 return QualType(); 21324 } 21325 return ReductionType; 21326 } 21327 21328 Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareReductionDirectiveStart( 21329 Scope *S, DeclContext *DC, DeclarationName Name, 21330 ArrayRef<std::pair<QualType, SourceLocation>> ReductionTypes, 21331 AccessSpecifier AS, Decl *PrevDeclInScope) { 21332 SmallVector<Decl *, 8> Decls; 21333 Decls.reserve(ReductionTypes.size()); 21334 21335 LookupResult Lookup(*this, Name, SourceLocation(), LookupOMPReductionName, 21336 forRedeclarationInCurContext()); 21337 // [OpenMP 4.0], 2.15 declare reduction Directive, Restrictions 21338 // A reduction-identifier may not be re-declared in the current scope for the 21339 // same type or for a type that is compatible according to the base language 21340 // rules. 21341 llvm::DenseMap<QualType, SourceLocation> PreviousRedeclTypes; 21342 OMPDeclareReductionDecl *PrevDRD = nullptr; 21343 bool InCompoundScope = true; 21344 if (S != nullptr) { 21345 // Find previous declaration with the same name not referenced in other 21346 // declarations. 21347 FunctionScopeInfo *ParentFn = getEnclosingFunction(); 21348 InCompoundScope = 21349 (ParentFn != nullptr) && !ParentFn->CompoundScopes.empty(); 21350 LookupName(Lookup, S); 21351 FilterLookupForScope(Lookup, DC, S, /*ConsiderLinkage=*/false, 21352 /*AllowInlineNamespace=*/false); 21353 llvm::DenseMap<OMPDeclareReductionDecl *, bool> UsedAsPrevious; 21354 LookupResult::Filter Filter = Lookup.makeFilter(); 21355 while (Filter.hasNext()) { 21356 auto *PrevDecl = cast<OMPDeclareReductionDecl>(Filter.next()); 21357 if (InCompoundScope) { 21358 auto I = UsedAsPrevious.find(PrevDecl); 21359 if (I == UsedAsPrevious.end()) 21360 UsedAsPrevious[PrevDecl] = false; 21361 if (OMPDeclareReductionDecl *D = PrevDecl->getPrevDeclInScope()) 21362 UsedAsPrevious[D] = true; 21363 } 21364 PreviousRedeclTypes[PrevDecl->getType().getCanonicalType()] = 21365 PrevDecl->getLocation(); 21366 } 21367 Filter.done(); 21368 if (InCompoundScope) { 21369 for (const auto &PrevData : UsedAsPrevious) { 21370 if (!PrevData.second) { 21371 PrevDRD = PrevData.first; 21372 break; 21373 } 21374 } 21375 } 21376 } else if (PrevDeclInScope != nullptr) { 21377 auto *PrevDRDInScope = PrevDRD = 21378 cast<OMPDeclareReductionDecl>(PrevDeclInScope); 21379 do { 21380 PreviousRedeclTypes[PrevDRDInScope->getType().getCanonicalType()] = 21381 PrevDRDInScope->getLocation(); 21382 PrevDRDInScope = PrevDRDInScope->getPrevDeclInScope(); 21383 } while (PrevDRDInScope != nullptr); 21384 } 21385 for (const auto &TyData : ReductionTypes) { 21386 const auto I = PreviousRedeclTypes.find(TyData.first.getCanonicalType()); 21387 bool Invalid = false; 21388 if (I != PreviousRedeclTypes.end()) { 21389 Diag(TyData.second, diag::err_omp_declare_reduction_redefinition) 21390 << TyData.first; 21391 Diag(I->second, diag::note_previous_definition); 21392 Invalid = true; 21393 } 21394 PreviousRedeclTypes[TyData.first.getCanonicalType()] = TyData.second; 21395 auto *DRD = OMPDeclareReductionDecl::Create(Context, DC, TyData.second, 21396 Name, TyData.first, PrevDRD); 21397 DC->addDecl(DRD); 21398 DRD->setAccess(AS); 21399 Decls.push_back(DRD); 21400 if (Invalid) 21401 DRD->setInvalidDecl(); 21402 else 21403 PrevDRD = DRD; 21404 } 21405 21406 return DeclGroupPtrTy::make( 21407 DeclGroupRef::Create(Context, Decls.begin(), Decls.size())); 21408 } 21409 21410 void Sema::ActOnOpenMPDeclareReductionCombinerStart(Scope *S, Decl *D) { 21411 auto *DRD = cast<OMPDeclareReductionDecl>(D); 21412 21413 // Enter new function scope. 21414 PushFunctionScope(); 21415 setFunctionHasBranchProtectedScope(); 21416 getCurFunction()->setHasOMPDeclareReductionCombiner(); 21417 21418 if (S != nullptr) 21419 PushDeclContext(S, DRD); 21420 else 21421 CurContext = DRD; 21422 21423 PushExpressionEvaluationContext( 21424 ExpressionEvaluationContext::PotentiallyEvaluated); 21425 21426 QualType ReductionType = DRD->getType(); 21427 // Create 'T* omp_parm;T omp_in;'. All references to 'omp_in' will 21428 // be replaced by '*omp_parm' during codegen. This required because 'omp_in' 21429 // uses semantics of argument handles by value, but it should be passed by 21430 // reference. C lang does not support references, so pass all parameters as 21431 // pointers. 21432 // Create 'T omp_in;' variable. 21433 VarDecl *OmpInParm = 21434 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_in"); 21435 // Create 'T* omp_parm;T omp_out;'. All references to 'omp_out' will 21436 // be replaced by '*omp_parm' during codegen. This required because 'omp_out' 21437 // uses semantics of argument handles by value, but it should be passed by 21438 // reference. C lang does not support references, so pass all parameters as 21439 // pointers. 21440 // Create 'T omp_out;' variable. 21441 VarDecl *OmpOutParm = 21442 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_out"); 21443 if (S != nullptr) { 21444 PushOnScopeChains(OmpInParm, S); 21445 PushOnScopeChains(OmpOutParm, S); 21446 } else { 21447 DRD->addDecl(OmpInParm); 21448 DRD->addDecl(OmpOutParm); 21449 } 21450 Expr *InE = 21451 ::buildDeclRefExpr(*this, OmpInParm, ReductionType, D->getLocation()); 21452 Expr *OutE = 21453 ::buildDeclRefExpr(*this, OmpOutParm, ReductionType, D->getLocation()); 21454 DRD->setCombinerData(InE, OutE); 21455 } 21456 21457 void Sema::ActOnOpenMPDeclareReductionCombinerEnd(Decl *D, Expr *Combiner) { 21458 auto *DRD = cast<OMPDeclareReductionDecl>(D); 21459 DiscardCleanupsInEvaluationContext(); 21460 PopExpressionEvaluationContext(); 21461 21462 PopDeclContext(); 21463 PopFunctionScopeInfo(); 21464 21465 if (Combiner != nullptr) 21466 DRD->setCombiner(Combiner); 21467 else 21468 DRD->setInvalidDecl(); 21469 } 21470 21471 VarDecl *Sema::ActOnOpenMPDeclareReductionInitializerStart(Scope *S, Decl *D) { 21472 auto *DRD = cast<OMPDeclareReductionDecl>(D); 21473 21474 // Enter new function scope. 21475 PushFunctionScope(); 21476 setFunctionHasBranchProtectedScope(); 21477 21478 if (S != nullptr) 21479 PushDeclContext(S, DRD); 21480 else 21481 CurContext = DRD; 21482 21483 PushExpressionEvaluationContext( 21484 ExpressionEvaluationContext::PotentiallyEvaluated); 21485 21486 QualType ReductionType = DRD->getType(); 21487 // Create 'T* omp_parm;T omp_priv;'. All references to 'omp_priv' will 21488 // be replaced by '*omp_parm' during codegen. This required because 'omp_priv' 21489 // uses semantics of argument handles by value, but it should be passed by 21490 // reference. C lang does not support references, so pass all parameters as 21491 // pointers. 21492 // Create 'T omp_priv;' variable. 21493 VarDecl *OmpPrivParm = 21494 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_priv"); 21495 // Create 'T* omp_parm;T omp_orig;'. All references to 'omp_orig' will 21496 // be replaced by '*omp_parm' during codegen. This required because 'omp_orig' 21497 // uses semantics of argument handles by value, but it should be passed by 21498 // reference. C lang does not support references, so pass all parameters as 21499 // pointers. 21500 // Create 'T omp_orig;' variable. 21501 VarDecl *OmpOrigParm = 21502 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_orig"); 21503 if (S != nullptr) { 21504 PushOnScopeChains(OmpPrivParm, S); 21505 PushOnScopeChains(OmpOrigParm, S); 21506 } else { 21507 DRD->addDecl(OmpPrivParm); 21508 DRD->addDecl(OmpOrigParm); 21509 } 21510 Expr *OrigE = 21511 ::buildDeclRefExpr(*this, OmpOrigParm, ReductionType, D->getLocation()); 21512 Expr *PrivE = 21513 ::buildDeclRefExpr(*this, OmpPrivParm, ReductionType, D->getLocation()); 21514 DRD->setInitializerData(OrigE, PrivE); 21515 return OmpPrivParm; 21516 } 21517 21518 void Sema::ActOnOpenMPDeclareReductionInitializerEnd(Decl *D, Expr *Initializer, 21519 VarDecl *OmpPrivParm) { 21520 auto *DRD = cast<OMPDeclareReductionDecl>(D); 21521 DiscardCleanupsInEvaluationContext(); 21522 PopExpressionEvaluationContext(); 21523 21524 PopDeclContext(); 21525 PopFunctionScopeInfo(); 21526 21527 if (Initializer != nullptr) { 21528 DRD->setInitializer(Initializer, OMPDeclareReductionDecl::CallInit); 21529 } else if (OmpPrivParm->hasInit()) { 21530 DRD->setInitializer(OmpPrivParm->getInit(), 21531 OmpPrivParm->isDirectInit() 21532 ? OMPDeclareReductionDecl::DirectInit 21533 : OMPDeclareReductionDecl::CopyInit); 21534 } else { 21535 DRD->setInvalidDecl(); 21536 } 21537 } 21538 21539 Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareReductionDirectiveEnd( 21540 Scope *S, DeclGroupPtrTy DeclReductions, bool IsValid) { 21541 for (Decl *D : DeclReductions.get()) { 21542 if (IsValid) { 21543 if (S) 21544 PushOnScopeChains(cast<OMPDeclareReductionDecl>(D), S, 21545 /*AddToContext=*/false); 21546 } else { 21547 D->setInvalidDecl(); 21548 } 21549 } 21550 return DeclReductions; 21551 } 21552 21553 TypeResult Sema::ActOnOpenMPDeclareMapperVarDecl(Scope *S, Declarator &D) { 21554 TypeSourceInfo *TInfo = GetTypeForDeclarator(D, S); 21555 QualType T = TInfo->getType(); 21556 if (D.isInvalidType()) 21557 return true; 21558 21559 if (getLangOpts().CPlusPlus) { 21560 // Check that there are no default arguments (C++ only). 21561 CheckExtraCXXDefaultArguments(D); 21562 } 21563 21564 return CreateParsedType(T, TInfo); 21565 } 21566 21567 QualType Sema::ActOnOpenMPDeclareMapperType(SourceLocation TyLoc, 21568 TypeResult ParsedType) { 21569 assert(ParsedType.isUsable() && "Expect usable parsed mapper type"); 21570 21571 QualType MapperType = GetTypeFromParser(ParsedType.get()); 21572 assert(!MapperType.isNull() && "Expect valid mapper type"); 21573 21574 // [OpenMP 5.0], 2.19.7.3 declare mapper Directive, Restrictions 21575 // The type must be of struct, union or class type in C and C++ 21576 if (!MapperType->isStructureOrClassType() && !MapperType->isUnionType()) { 21577 Diag(TyLoc, diag::err_omp_mapper_wrong_type); 21578 return QualType(); 21579 } 21580 return MapperType; 21581 } 21582 21583 Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareMapperDirective( 21584 Scope *S, DeclContext *DC, DeclarationName Name, QualType MapperType, 21585 SourceLocation StartLoc, DeclarationName VN, AccessSpecifier AS, 21586 Expr *MapperVarRef, ArrayRef<OMPClause *> Clauses, Decl *PrevDeclInScope) { 21587 LookupResult Lookup(*this, Name, SourceLocation(), LookupOMPMapperName, 21588 forRedeclarationInCurContext()); 21589 // [OpenMP 5.0], 2.19.7.3 declare mapper Directive, Restrictions 21590 // A mapper-identifier may not be redeclared in the current scope for the 21591 // same type or for a type that is compatible according to the base language 21592 // rules. 21593 llvm::DenseMap<QualType, SourceLocation> PreviousRedeclTypes; 21594 OMPDeclareMapperDecl *PrevDMD = nullptr; 21595 bool InCompoundScope = true; 21596 if (S != nullptr) { 21597 // Find previous declaration with the same name not referenced in other 21598 // declarations. 21599 FunctionScopeInfo *ParentFn = getEnclosingFunction(); 21600 InCompoundScope = 21601 (ParentFn != nullptr) && !ParentFn->CompoundScopes.empty(); 21602 LookupName(Lookup, S); 21603 FilterLookupForScope(Lookup, DC, S, /*ConsiderLinkage=*/false, 21604 /*AllowInlineNamespace=*/false); 21605 llvm::DenseMap<OMPDeclareMapperDecl *, bool> UsedAsPrevious; 21606 LookupResult::Filter Filter = Lookup.makeFilter(); 21607 while (Filter.hasNext()) { 21608 auto *PrevDecl = cast<OMPDeclareMapperDecl>(Filter.next()); 21609 if (InCompoundScope) { 21610 auto I = UsedAsPrevious.find(PrevDecl); 21611 if (I == UsedAsPrevious.end()) 21612 UsedAsPrevious[PrevDecl] = false; 21613 if (OMPDeclareMapperDecl *D = PrevDecl->getPrevDeclInScope()) 21614 UsedAsPrevious[D] = true; 21615 } 21616 PreviousRedeclTypes[PrevDecl->getType().getCanonicalType()] = 21617 PrevDecl->getLocation(); 21618 } 21619 Filter.done(); 21620 if (InCompoundScope) { 21621 for (const auto &PrevData : UsedAsPrevious) { 21622 if (!PrevData.second) { 21623 PrevDMD = PrevData.first; 21624 break; 21625 } 21626 } 21627 } 21628 } else if (PrevDeclInScope) { 21629 auto *PrevDMDInScope = PrevDMD = 21630 cast<OMPDeclareMapperDecl>(PrevDeclInScope); 21631 do { 21632 PreviousRedeclTypes[PrevDMDInScope->getType().getCanonicalType()] = 21633 PrevDMDInScope->getLocation(); 21634 PrevDMDInScope = PrevDMDInScope->getPrevDeclInScope(); 21635 } while (PrevDMDInScope != nullptr); 21636 } 21637 const auto I = PreviousRedeclTypes.find(MapperType.getCanonicalType()); 21638 bool Invalid = false; 21639 if (I != PreviousRedeclTypes.end()) { 21640 Diag(StartLoc, diag::err_omp_declare_mapper_redefinition) 21641 << MapperType << Name; 21642 Diag(I->second, diag::note_previous_definition); 21643 Invalid = true; 21644 } 21645 // Build expressions for implicit maps of data members with 'default' 21646 // mappers. 21647 SmallVector<OMPClause *, 4> ClausesWithImplicit(Clauses.begin(), 21648 Clauses.end()); 21649 if (LangOpts.OpenMP >= 50) 21650 processImplicitMapsWithDefaultMappers(*this, DSAStack, ClausesWithImplicit); 21651 auto *DMD = 21652 OMPDeclareMapperDecl::Create(Context, DC, StartLoc, Name, MapperType, VN, 21653 ClausesWithImplicit, PrevDMD); 21654 if (S) 21655 PushOnScopeChains(DMD, S); 21656 else 21657 DC->addDecl(DMD); 21658 DMD->setAccess(AS); 21659 if (Invalid) 21660 DMD->setInvalidDecl(); 21661 21662 auto *VD = cast<DeclRefExpr>(MapperVarRef)->getDecl(); 21663 VD->setDeclContext(DMD); 21664 VD->setLexicalDeclContext(DMD); 21665 DMD->addDecl(VD); 21666 DMD->setMapperVarRef(MapperVarRef); 21667 21668 return DeclGroupPtrTy::make(DeclGroupRef(DMD)); 21669 } 21670 21671 ExprResult 21672 Sema::ActOnOpenMPDeclareMapperDirectiveVarDecl(Scope *S, QualType MapperType, 21673 SourceLocation StartLoc, 21674 DeclarationName VN) { 21675 TypeSourceInfo *TInfo = 21676 Context.getTrivialTypeSourceInfo(MapperType, StartLoc); 21677 auto *VD = VarDecl::Create(Context, Context.getTranslationUnitDecl(), 21678 StartLoc, StartLoc, VN.getAsIdentifierInfo(), 21679 MapperType, TInfo, SC_None); 21680 if (S) 21681 PushOnScopeChains(VD, S, /*AddToContext=*/false); 21682 Expr *E = buildDeclRefExpr(*this, VD, MapperType, StartLoc); 21683 DSAStack->addDeclareMapperVarRef(E); 21684 return E; 21685 } 21686 21687 bool Sema::isOpenMPDeclareMapperVarDeclAllowed(const VarDecl *VD) const { 21688 assert(LangOpts.OpenMP && "Expected OpenMP mode."); 21689 const Expr *Ref = DSAStack->getDeclareMapperVarRef(); 21690 if (const auto *DRE = cast_or_null<DeclRefExpr>(Ref)) { 21691 if (VD->getCanonicalDecl() == DRE->getDecl()->getCanonicalDecl()) 21692 return true; 21693 if (VD->isUsableInConstantExpressions(Context)) 21694 return true; 21695 return false; 21696 } 21697 return true; 21698 } 21699 21700 const ValueDecl *Sema::getOpenMPDeclareMapperVarName() const { 21701 assert(LangOpts.OpenMP && "Expected OpenMP mode."); 21702 return cast<DeclRefExpr>(DSAStack->getDeclareMapperVarRef())->getDecl(); 21703 } 21704 21705 OMPClause *Sema::ActOnOpenMPNumTeamsClause(Expr *NumTeams, 21706 SourceLocation StartLoc, 21707 SourceLocation LParenLoc, 21708 SourceLocation EndLoc) { 21709 Expr *ValExpr = NumTeams; 21710 Stmt *HelperValStmt = nullptr; 21711 21712 // OpenMP [teams Constrcut, Restrictions] 21713 // The num_teams expression must evaluate to a positive integer value. 21714 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_num_teams, 21715 /*StrictlyPositive=*/true)) 21716 return nullptr; 21717 21718 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 21719 OpenMPDirectiveKind CaptureRegion = 21720 getOpenMPCaptureRegionForClause(DKind, OMPC_num_teams, LangOpts.OpenMP); 21721 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 21722 ValExpr = MakeFullExpr(ValExpr).get(); 21723 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 21724 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 21725 HelperValStmt = buildPreInits(Context, Captures); 21726 } 21727 21728 return new (Context) OMPNumTeamsClause(ValExpr, HelperValStmt, CaptureRegion, 21729 StartLoc, LParenLoc, EndLoc); 21730 } 21731 21732 OMPClause *Sema::ActOnOpenMPThreadLimitClause(Expr *ThreadLimit, 21733 SourceLocation StartLoc, 21734 SourceLocation LParenLoc, 21735 SourceLocation EndLoc) { 21736 Expr *ValExpr = ThreadLimit; 21737 Stmt *HelperValStmt = nullptr; 21738 21739 // OpenMP [teams Constrcut, Restrictions] 21740 // The thread_limit expression must evaluate to a positive integer value. 21741 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_thread_limit, 21742 /*StrictlyPositive=*/true)) 21743 return nullptr; 21744 21745 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 21746 OpenMPDirectiveKind CaptureRegion = getOpenMPCaptureRegionForClause( 21747 DKind, OMPC_thread_limit, LangOpts.OpenMP); 21748 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 21749 ValExpr = MakeFullExpr(ValExpr).get(); 21750 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 21751 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 21752 HelperValStmt = buildPreInits(Context, Captures); 21753 } 21754 21755 return new (Context) OMPThreadLimitClause( 21756 ValExpr, HelperValStmt, CaptureRegion, StartLoc, LParenLoc, EndLoc); 21757 } 21758 21759 OMPClause *Sema::ActOnOpenMPPriorityClause(Expr *Priority, 21760 SourceLocation StartLoc, 21761 SourceLocation LParenLoc, 21762 SourceLocation EndLoc) { 21763 Expr *ValExpr = Priority; 21764 Stmt *HelperValStmt = nullptr; 21765 OpenMPDirectiveKind CaptureRegion = OMPD_unknown; 21766 21767 // OpenMP [2.9.1, task Constrcut] 21768 // The priority-value is a non-negative numerical scalar expression. 21769 if (!isNonNegativeIntegerValue( 21770 ValExpr, *this, OMPC_priority, 21771 /*StrictlyPositive=*/false, /*BuildCapture=*/true, 21772 DSAStack->getCurrentDirective(), &CaptureRegion, &HelperValStmt)) 21773 return nullptr; 21774 21775 return new (Context) OMPPriorityClause(ValExpr, HelperValStmt, CaptureRegion, 21776 StartLoc, LParenLoc, EndLoc); 21777 } 21778 21779 OMPClause *Sema::ActOnOpenMPGrainsizeClause(Expr *Grainsize, 21780 SourceLocation StartLoc, 21781 SourceLocation LParenLoc, 21782 SourceLocation EndLoc) { 21783 Expr *ValExpr = Grainsize; 21784 Stmt *HelperValStmt = nullptr; 21785 OpenMPDirectiveKind CaptureRegion = OMPD_unknown; 21786 21787 // OpenMP [2.9.2, taskloop Constrcut] 21788 // The parameter of the grainsize clause must be a positive integer 21789 // expression. 21790 if (!isNonNegativeIntegerValue( 21791 ValExpr, *this, OMPC_grainsize, 21792 /*StrictlyPositive=*/true, /*BuildCapture=*/true, 21793 DSAStack->getCurrentDirective(), &CaptureRegion, &HelperValStmt)) 21794 return nullptr; 21795 21796 return new (Context) OMPGrainsizeClause(ValExpr, HelperValStmt, CaptureRegion, 21797 StartLoc, LParenLoc, EndLoc); 21798 } 21799 21800 OMPClause *Sema::ActOnOpenMPNumTasksClause(Expr *NumTasks, 21801 SourceLocation StartLoc, 21802 SourceLocation LParenLoc, 21803 SourceLocation EndLoc) { 21804 Expr *ValExpr = NumTasks; 21805 Stmt *HelperValStmt = nullptr; 21806 OpenMPDirectiveKind CaptureRegion = OMPD_unknown; 21807 21808 // OpenMP [2.9.2, taskloop Constrcut] 21809 // The parameter of the num_tasks clause must be a positive integer 21810 // expression. 21811 if (!isNonNegativeIntegerValue( 21812 ValExpr, *this, OMPC_num_tasks, 21813 /*StrictlyPositive=*/true, /*BuildCapture=*/true, 21814 DSAStack->getCurrentDirective(), &CaptureRegion, &HelperValStmt)) 21815 return nullptr; 21816 21817 return new (Context) OMPNumTasksClause(ValExpr, HelperValStmt, CaptureRegion, 21818 StartLoc, LParenLoc, EndLoc); 21819 } 21820 21821 OMPClause *Sema::ActOnOpenMPHintClause(Expr *Hint, SourceLocation StartLoc, 21822 SourceLocation LParenLoc, 21823 SourceLocation EndLoc) { 21824 // OpenMP [2.13.2, critical construct, Description] 21825 // ... where hint-expression is an integer constant expression that evaluates 21826 // to a valid lock hint. 21827 ExprResult HintExpr = 21828 VerifyPositiveIntegerConstantInClause(Hint, OMPC_hint, false); 21829 if (HintExpr.isInvalid()) 21830 return nullptr; 21831 return new (Context) 21832 OMPHintClause(HintExpr.get(), StartLoc, LParenLoc, EndLoc); 21833 } 21834 21835 /// Tries to find omp_event_handle_t type. 21836 static bool findOMPEventHandleT(Sema &S, SourceLocation Loc, 21837 DSAStackTy *Stack) { 21838 QualType OMPEventHandleT = Stack->getOMPEventHandleT(); 21839 if (!OMPEventHandleT.isNull()) 21840 return true; 21841 IdentifierInfo *II = &S.PP.getIdentifierTable().get("omp_event_handle_t"); 21842 ParsedType PT = S.getTypeName(*II, Loc, S.getCurScope()); 21843 if (!PT.getAsOpaquePtr() || PT.get().isNull()) { 21844 S.Diag(Loc, diag::err_omp_implied_type_not_found) << "omp_event_handle_t"; 21845 return false; 21846 } 21847 Stack->setOMPEventHandleT(PT.get()); 21848 return true; 21849 } 21850 21851 OMPClause *Sema::ActOnOpenMPDetachClause(Expr *Evt, SourceLocation StartLoc, 21852 SourceLocation LParenLoc, 21853 SourceLocation EndLoc) { 21854 if (!Evt->isValueDependent() && !Evt->isTypeDependent() && 21855 !Evt->isInstantiationDependent() && 21856 !Evt->containsUnexpandedParameterPack()) { 21857 if (!findOMPEventHandleT(*this, Evt->getExprLoc(), DSAStack)) 21858 return nullptr; 21859 // OpenMP 5.0, 2.10.1 task Construct. 21860 // event-handle is a variable of the omp_event_handle_t type. 21861 auto *Ref = dyn_cast<DeclRefExpr>(Evt->IgnoreParenImpCasts()); 21862 if (!Ref) { 21863 Diag(Evt->getExprLoc(), diag::err_omp_var_expected) 21864 << "omp_event_handle_t" << 0 << Evt->getSourceRange(); 21865 return nullptr; 21866 } 21867 auto *VD = dyn_cast_or_null<VarDecl>(Ref->getDecl()); 21868 if (!VD) { 21869 Diag(Evt->getExprLoc(), diag::err_omp_var_expected) 21870 << "omp_event_handle_t" << 0 << Evt->getSourceRange(); 21871 return nullptr; 21872 } 21873 if (!Context.hasSameUnqualifiedType(DSAStack->getOMPEventHandleT(), 21874 VD->getType()) || 21875 VD->getType().isConstant(Context)) { 21876 Diag(Evt->getExprLoc(), diag::err_omp_var_expected) 21877 << "omp_event_handle_t" << 1 << VD->getType() 21878 << Evt->getSourceRange(); 21879 return nullptr; 21880 } 21881 // OpenMP 5.0, 2.10.1 task Construct 21882 // [detach clause]... The event-handle will be considered as if it was 21883 // specified on a firstprivate clause. 21884 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(VD, /*FromParent=*/false); 21885 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_firstprivate && 21886 DVar.RefExpr) { 21887 Diag(Evt->getExprLoc(), diag::err_omp_wrong_dsa) 21888 << getOpenMPClauseName(DVar.CKind) 21889 << getOpenMPClauseName(OMPC_firstprivate); 21890 reportOriginalDsa(*this, DSAStack, VD, DVar); 21891 return nullptr; 21892 } 21893 } 21894 21895 return new (Context) OMPDetachClause(Evt, StartLoc, LParenLoc, EndLoc); 21896 } 21897 21898 OMPClause *Sema::ActOnOpenMPDistScheduleClause( 21899 OpenMPDistScheduleClauseKind Kind, Expr *ChunkSize, SourceLocation StartLoc, 21900 SourceLocation LParenLoc, SourceLocation KindLoc, SourceLocation CommaLoc, 21901 SourceLocation EndLoc) { 21902 if (Kind == OMPC_DIST_SCHEDULE_unknown) { 21903 std::string Values; 21904 Values += "'"; 21905 Values += getOpenMPSimpleClauseTypeName(OMPC_dist_schedule, 0); 21906 Values += "'"; 21907 Diag(KindLoc, diag::err_omp_unexpected_clause_value) 21908 << Values << getOpenMPClauseName(OMPC_dist_schedule); 21909 return nullptr; 21910 } 21911 Expr *ValExpr = ChunkSize; 21912 Stmt *HelperValStmt = nullptr; 21913 if (ChunkSize) { 21914 if (!ChunkSize->isValueDependent() && !ChunkSize->isTypeDependent() && 21915 !ChunkSize->isInstantiationDependent() && 21916 !ChunkSize->containsUnexpandedParameterPack()) { 21917 SourceLocation ChunkSizeLoc = ChunkSize->getBeginLoc(); 21918 ExprResult Val = 21919 PerformOpenMPImplicitIntegerConversion(ChunkSizeLoc, ChunkSize); 21920 if (Val.isInvalid()) 21921 return nullptr; 21922 21923 ValExpr = Val.get(); 21924 21925 // OpenMP [2.7.1, Restrictions] 21926 // chunk_size must be a loop invariant integer expression with a positive 21927 // value. 21928 if (Optional<llvm::APSInt> Result = 21929 ValExpr->getIntegerConstantExpr(Context)) { 21930 if (Result->isSigned() && !Result->isStrictlyPositive()) { 21931 Diag(ChunkSizeLoc, diag::err_omp_negative_expression_in_clause) 21932 << "dist_schedule" << ChunkSize->getSourceRange(); 21933 return nullptr; 21934 } 21935 } else if (getOpenMPCaptureRegionForClause( 21936 DSAStack->getCurrentDirective(), OMPC_dist_schedule, 21937 LangOpts.OpenMP) != OMPD_unknown && 21938 !CurContext->isDependentContext()) { 21939 ValExpr = MakeFullExpr(ValExpr).get(); 21940 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 21941 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 21942 HelperValStmt = buildPreInits(Context, Captures); 21943 } 21944 } 21945 } 21946 21947 return new (Context) 21948 OMPDistScheduleClause(StartLoc, LParenLoc, KindLoc, CommaLoc, EndLoc, 21949 Kind, ValExpr, HelperValStmt); 21950 } 21951 21952 OMPClause *Sema::ActOnOpenMPDefaultmapClause( 21953 OpenMPDefaultmapClauseModifier M, OpenMPDefaultmapClauseKind Kind, 21954 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation MLoc, 21955 SourceLocation KindLoc, SourceLocation EndLoc) { 21956 if (getLangOpts().OpenMP < 50) { 21957 if (M != OMPC_DEFAULTMAP_MODIFIER_tofrom || 21958 Kind != OMPC_DEFAULTMAP_scalar) { 21959 std::string Value; 21960 SourceLocation Loc; 21961 Value += "'"; 21962 if (M != OMPC_DEFAULTMAP_MODIFIER_tofrom) { 21963 Value += getOpenMPSimpleClauseTypeName(OMPC_defaultmap, 21964 OMPC_DEFAULTMAP_MODIFIER_tofrom); 21965 Loc = MLoc; 21966 } else { 21967 Value += getOpenMPSimpleClauseTypeName(OMPC_defaultmap, 21968 OMPC_DEFAULTMAP_scalar); 21969 Loc = KindLoc; 21970 } 21971 Value += "'"; 21972 Diag(Loc, diag::err_omp_unexpected_clause_value) 21973 << Value << getOpenMPClauseName(OMPC_defaultmap); 21974 return nullptr; 21975 } 21976 } else { 21977 bool isDefaultmapModifier = (M != OMPC_DEFAULTMAP_MODIFIER_unknown); 21978 bool isDefaultmapKind = (Kind != OMPC_DEFAULTMAP_unknown) || 21979 (LangOpts.OpenMP >= 50 && KindLoc.isInvalid()); 21980 if (!isDefaultmapKind || !isDefaultmapModifier) { 21981 StringRef KindValue = "'scalar', 'aggregate', 'pointer'"; 21982 if (LangOpts.OpenMP == 50) { 21983 StringRef ModifierValue = "'alloc', 'from', 'to', 'tofrom', " 21984 "'firstprivate', 'none', 'default'"; 21985 if (!isDefaultmapKind && isDefaultmapModifier) { 21986 Diag(KindLoc, diag::err_omp_unexpected_clause_value) 21987 << KindValue << getOpenMPClauseName(OMPC_defaultmap); 21988 } else if (isDefaultmapKind && !isDefaultmapModifier) { 21989 Diag(MLoc, diag::err_omp_unexpected_clause_value) 21990 << ModifierValue << getOpenMPClauseName(OMPC_defaultmap); 21991 } else { 21992 Diag(MLoc, diag::err_omp_unexpected_clause_value) 21993 << ModifierValue << getOpenMPClauseName(OMPC_defaultmap); 21994 Diag(KindLoc, diag::err_omp_unexpected_clause_value) 21995 << KindValue << getOpenMPClauseName(OMPC_defaultmap); 21996 } 21997 } else { 21998 StringRef ModifierValue = 21999 "'alloc', 'from', 'to', 'tofrom', " 22000 "'firstprivate', 'none', 'default', 'present'"; 22001 if (!isDefaultmapKind && isDefaultmapModifier) { 22002 Diag(KindLoc, diag::err_omp_unexpected_clause_value) 22003 << KindValue << getOpenMPClauseName(OMPC_defaultmap); 22004 } else if (isDefaultmapKind && !isDefaultmapModifier) { 22005 Diag(MLoc, diag::err_omp_unexpected_clause_value) 22006 << ModifierValue << getOpenMPClauseName(OMPC_defaultmap); 22007 } else { 22008 Diag(MLoc, diag::err_omp_unexpected_clause_value) 22009 << ModifierValue << getOpenMPClauseName(OMPC_defaultmap); 22010 Diag(KindLoc, diag::err_omp_unexpected_clause_value) 22011 << KindValue << getOpenMPClauseName(OMPC_defaultmap); 22012 } 22013 } 22014 return nullptr; 22015 } 22016 22017 // OpenMP [5.0, 2.12.5, Restrictions, p. 174] 22018 // At most one defaultmap clause for each category can appear on the 22019 // directive. 22020 if (DSAStack->checkDefaultmapCategory(Kind)) { 22021 Diag(StartLoc, diag::err_omp_one_defaultmap_each_category); 22022 return nullptr; 22023 } 22024 } 22025 if (Kind == OMPC_DEFAULTMAP_unknown) { 22026 // Variable category is not specified - mark all categories. 22027 DSAStack->setDefaultDMAAttr(M, OMPC_DEFAULTMAP_aggregate, StartLoc); 22028 DSAStack->setDefaultDMAAttr(M, OMPC_DEFAULTMAP_scalar, StartLoc); 22029 DSAStack->setDefaultDMAAttr(M, OMPC_DEFAULTMAP_pointer, StartLoc); 22030 } else { 22031 DSAStack->setDefaultDMAAttr(M, Kind, StartLoc); 22032 } 22033 22034 return new (Context) 22035 OMPDefaultmapClause(StartLoc, LParenLoc, MLoc, KindLoc, EndLoc, Kind, M); 22036 } 22037 22038 bool Sema::ActOnStartOpenMPDeclareTargetContext( 22039 DeclareTargetContextInfo &DTCI) { 22040 DeclContext *CurLexicalContext = getCurLexicalContext(); 22041 if (!CurLexicalContext->isFileContext() && 22042 !CurLexicalContext->isExternCContext() && 22043 !CurLexicalContext->isExternCXXContext() && 22044 !isa<CXXRecordDecl>(CurLexicalContext) && 22045 !isa<ClassTemplateDecl>(CurLexicalContext) && 22046 !isa<ClassTemplatePartialSpecializationDecl>(CurLexicalContext) && 22047 !isa<ClassTemplateSpecializationDecl>(CurLexicalContext)) { 22048 Diag(DTCI.Loc, diag::err_omp_region_not_file_context); 22049 return false; 22050 } 22051 DeclareTargetNesting.push_back(DTCI); 22052 return true; 22053 } 22054 22055 const Sema::DeclareTargetContextInfo 22056 Sema::ActOnOpenMPEndDeclareTargetDirective() { 22057 assert(!DeclareTargetNesting.empty() && 22058 "check isInOpenMPDeclareTargetContext() first!"); 22059 return DeclareTargetNesting.pop_back_val(); 22060 } 22061 22062 void Sema::ActOnFinishedOpenMPDeclareTargetContext( 22063 DeclareTargetContextInfo &DTCI) { 22064 for (auto &It : DTCI.ExplicitlyMapped) 22065 ActOnOpenMPDeclareTargetName(It.first, It.second.Loc, It.second.MT, DTCI); 22066 } 22067 22068 void Sema::DiagnoseUnterminatedOpenMPDeclareTarget() { 22069 if (DeclareTargetNesting.empty()) 22070 return; 22071 DeclareTargetContextInfo &DTCI = DeclareTargetNesting.back(); 22072 Diag(DTCI.Loc, diag::warn_omp_unterminated_declare_target) 22073 << getOpenMPDirectiveName(DTCI.Kind); 22074 } 22075 22076 NamedDecl *Sema::lookupOpenMPDeclareTargetName(Scope *CurScope, 22077 CXXScopeSpec &ScopeSpec, 22078 const DeclarationNameInfo &Id) { 22079 LookupResult Lookup(*this, Id, LookupOrdinaryName); 22080 LookupParsedName(Lookup, CurScope, &ScopeSpec, true); 22081 22082 if (Lookup.isAmbiguous()) 22083 return nullptr; 22084 Lookup.suppressDiagnostics(); 22085 22086 if (!Lookup.isSingleResult()) { 22087 VarOrFuncDeclFilterCCC CCC(*this); 22088 if (TypoCorrection Corrected = 22089 CorrectTypo(Id, LookupOrdinaryName, CurScope, nullptr, CCC, 22090 CTK_ErrorRecovery)) { 22091 diagnoseTypo(Corrected, PDiag(diag::err_undeclared_var_use_suggest) 22092 << Id.getName()); 22093 checkDeclIsAllowedInOpenMPTarget(nullptr, Corrected.getCorrectionDecl()); 22094 return nullptr; 22095 } 22096 22097 Diag(Id.getLoc(), diag::err_undeclared_var_use) << Id.getName(); 22098 return nullptr; 22099 } 22100 22101 NamedDecl *ND = Lookup.getAsSingle<NamedDecl>(); 22102 if (!isa<VarDecl>(ND) && !isa<FunctionDecl>(ND) && 22103 !isa<FunctionTemplateDecl>(ND)) { 22104 Diag(Id.getLoc(), diag::err_omp_invalid_target_decl) << Id.getName(); 22105 return nullptr; 22106 } 22107 return ND; 22108 } 22109 22110 void Sema::ActOnOpenMPDeclareTargetName(NamedDecl *ND, SourceLocation Loc, 22111 OMPDeclareTargetDeclAttr::MapTypeTy MT, 22112 DeclareTargetContextInfo &DTCI) { 22113 assert((isa<VarDecl>(ND) || isa<FunctionDecl>(ND) || 22114 isa<FunctionTemplateDecl>(ND)) && 22115 "Expected variable, function or function template."); 22116 22117 // Diagnose marking after use as it may lead to incorrect diagnosis and 22118 // codegen. 22119 if (LangOpts.OpenMP >= 50 && 22120 (ND->isUsed(/*CheckUsedAttr=*/false) || ND->isReferenced())) 22121 Diag(Loc, diag::warn_omp_declare_target_after_first_use); 22122 22123 // Explicit declare target lists have precedence. 22124 const unsigned Level = -1; 22125 22126 auto *VD = cast<ValueDecl>(ND); 22127 llvm::Optional<OMPDeclareTargetDeclAttr *> ActiveAttr = 22128 OMPDeclareTargetDeclAttr::getActiveAttr(VD); 22129 if (ActiveAttr.hasValue() && ActiveAttr.getValue()->getDevType() != DTCI.DT && 22130 ActiveAttr.getValue()->getLevel() == Level) { 22131 Diag(Loc, diag::err_omp_device_type_mismatch) 22132 << OMPDeclareTargetDeclAttr::ConvertDevTypeTyToStr(DTCI.DT) 22133 << OMPDeclareTargetDeclAttr::ConvertDevTypeTyToStr( 22134 ActiveAttr.getValue()->getDevType()); 22135 return; 22136 } 22137 if (ActiveAttr.hasValue() && ActiveAttr.getValue()->getMapType() != MT && 22138 ActiveAttr.getValue()->getLevel() == Level) { 22139 Diag(Loc, diag::err_omp_declare_target_to_and_link) << ND; 22140 return; 22141 } 22142 22143 if (ActiveAttr.hasValue() && ActiveAttr.getValue()->getLevel() == Level) 22144 return; 22145 22146 Expr *IndirectE = nullptr; 22147 bool IsIndirect = false; 22148 if (DTCI.Indirect.hasValue()) { 22149 IndirectE = DTCI.Indirect.getValue(); 22150 if (!IndirectE) 22151 IsIndirect = true; 22152 } 22153 auto *A = OMPDeclareTargetDeclAttr::CreateImplicit( 22154 Context, MT, DTCI.DT, IndirectE, IsIndirect, Level, 22155 SourceRange(Loc, Loc)); 22156 ND->addAttr(A); 22157 if (ASTMutationListener *ML = Context.getASTMutationListener()) 22158 ML->DeclarationMarkedOpenMPDeclareTarget(ND, A); 22159 checkDeclIsAllowedInOpenMPTarget(nullptr, ND, Loc); 22160 } 22161 22162 static void checkDeclInTargetContext(SourceLocation SL, SourceRange SR, 22163 Sema &SemaRef, Decl *D) { 22164 if (!D || !isa<VarDecl>(D)) 22165 return; 22166 auto *VD = cast<VarDecl>(D); 22167 Optional<OMPDeclareTargetDeclAttr::MapTypeTy> MapTy = 22168 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD); 22169 if (SemaRef.LangOpts.OpenMP >= 50 && 22170 (SemaRef.getCurLambda(/*IgnoreNonLambdaCapturingScope=*/true) || 22171 SemaRef.getCurBlock() || SemaRef.getCurCapturedRegion()) && 22172 VD->hasGlobalStorage()) { 22173 if (!MapTy || *MapTy != OMPDeclareTargetDeclAttr::MT_To) { 22174 // OpenMP 5.0, 2.12.7 declare target Directive, Restrictions 22175 // If a lambda declaration and definition appears between a 22176 // declare target directive and the matching end declare target 22177 // directive, all variables that are captured by the lambda 22178 // expression must also appear in a to clause. 22179 SemaRef.Diag(VD->getLocation(), 22180 diag::err_omp_lambda_capture_in_declare_target_not_to); 22181 SemaRef.Diag(SL, diag::note_var_explicitly_captured_here) 22182 << VD << 0 << SR; 22183 return; 22184 } 22185 } 22186 if (MapTy) 22187 return; 22188 SemaRef.Diag(VD->getLocation(), diag::warn_omp_not_in_target_context); 22189 SemaRef.Diag(SL, diag::note_used_here) << SR; 22190 } 22191 22192 static bool checkValueDeclInTarget(SourceLocation SL, SourceRange SR, 22193 Sema &SemaRef, DSAStackTy *Stack, 22194 ValueDecl *VD) { 22195 return OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD) || 22196 checkTypeMappable(SL, SR, SemaRef, Stack, VD->getType(), 22197 /*FullCheck=*/false); 22198 } 22199 22200 void Sema::checkDeclIsAllowedInOpenMPTarget(Expr *E, Decl *D, 22201 SourceLocation IdLoc) { 22202 if (!D || D->isInvalidDecl()) 22203 return; 22204 SourceRange SR = E ? E->getSourceRange() : D->getSourceRange(); 22205 SourceLocation SL = E ? E->getBeginLoc() : D->getLocation(); 22206 if (auto *VD = dyn_cast<VarDecl>(D)) { 22207 // Only global variables can be marked as declare target. 22208 if (!VD->isFileVarDecl() && !VD->isStaticLocal() && 22209 !VD->isStaticDataMember()) 22210 return; 22211 // 2.10.6: threadprivate variable cannot appear in a declare target 22212 // directive. 22213 if (DSAStack->isThreadPrivate(VD)) { 22214 Diag(SL, diag::err_omp_threadprivate_in_target); 22215 reportOriginalDsa(*this, DSAStack, VD, DSAStack->getTopDSA(VD, false)); 22216 return; 22217 } 22218 } 22219 if (const auto *FTD = dyn_cast<FunctionTemplateDecl>(D)) 22220 D = FTD->getTemplatedDecl(); 22221 if (auto *FD = dyn_cast<FunctionDecl>(D)) { 22222 llvm::Optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res = 22223 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(FD); 22224 if (IdLoc.isValid() && Res && *Res == OMPDeclareTargetDeclAttr::MT_Link) { 22225 Diag(IdLoc, diag::err_omp_function_in_link_clause); 22226 Diag(FD->getLocation(), diag::note_defined_here) << FD; 22227 return; 22228 } 22229 } 22230 if (auto *VD = dyn_cast<ValueDecl>(D)) { 22231 // Problem if any with var declared with incomplete type will be reported 22232 // as normal, so no need to check it here. 22233 if ((E || !VD->getType()->isIncompleteType()) && 22234 !checkValueDeclInTarget(SL, SR, *this, DSAStack, VD)) 22235 return; 22236 if (!E && isInOpenMPDeclareTargetContext()) { 22237 // Checking declaration inside declare target region. 22238 if (isa<VarDecl>(D) || isa<FunctionDecl>(D) || 22239 isa<FunctionTemplateDecl>(D)) { 22240 llvm::Optional<OMPDeclareTargetDeclAttr *> ActiveAttr = 22241 OMPDeclareTargetDeclAttr::getActiveAttr(VD); 22242 unsigned Level = DeclareTargetNesting.size(); 22243 if (ActiveAttr.hasValue() && ActiveAttr.getValue()->getLevel() >= Level) 22244 return; 22245 DeclareTargetContextInfo &DTCI = DeclareTargetNesting.back(); 22246 Expr *IndirectE = nullptr; 22247 bool IsIndirect = false; 22248 if (DTCI.Indirect.hasValue()) { 22249 IndirectE = DTCI.Indirect.getValue(); 22250 if (!IndirectE) 22251 IsIndirect = true; 22252 } 22253 auto *A = OMPDeclareTargetDeclAttr::CreateImplicit( 22254 Context, OMPDeclareTargetDeclAttr::MT_To, DTCI.DT, IndirectE, 22255 IsIndirect, Level, SourceRange(DTCI.Loc, DTCI.Loc)); 22256 D->addAttr(A); 22257 if (ASTMutationListener *ML = Context.getASTMutationListener()) 22258 ML->DeclarationMarkedOpenMPDeclareTarget(D, A); 22259 } 22260 return; 22261 } 22262 } 22263 if (!E) 22264 return; 22265 checkDeclInTargetContext(E->getExprLoc(), E->getSourceRange(), *this, D); 22266 } 22267 22268 OMPClause *Sema::ActOnOpenMPToClause( 22269 ArrayRef<OpenMPMotionModifierKind> MotionModifiers, 22270 ArrayRef<SourceLocation> MotionModifiersLoc, 22271 CXXScopeSpec &MapperIdScopeSpec, DeclarationNameInfo &MapperId, 22272 SourceLocation ColonLoc, ArrayRef<Expr *> VarList, 22273 const OMPVarListLocTy &Locs, ArrayRef<Expr *> UnresolvedMappers) { 22274 OpenMPMotionModifierKind Modifiers[] = {OMPC_MOTION_MODIFIER_unknown, 22275 OMPC_MOTION_MODIFIER_unknown}; 22276 SourceLocation ModifiersLoc[NumberOfOMPMotionModifiers]; 22277 22278 // Process motion-modifiers, flag errors for duplicate modifiers. 22279 unsigned Count = 0; 22280 for (unsigned I = 0, E = MotionModifiers.size(); I < E; ++I) { 22281 if (MotionModifiers[I] != OMPC_MOTION_MODIFIER_unknown && 22282 llvm::is_contained(Modifiers, MotionModifiers[I])) { 22283 Diag(MotionModifiersLoc[I], diag::err_omp_duplicate_motion_modifier); 22284 continue; 22285 } 22286 assert(Count < NumberOfOMPMotionModifiers && 22287 "Modifiers exceed the allowed number of motion modifiers"); 22288 Modifiers[Count] = MotionModifiers[I]; 22289 ModifiersLoc[Count] = MotionModifiersLoc[I]; 22290 ++Count; 22291 } 22292 22293 MappableVarListInfo MVLI(VarList); 22294 checkMappableExpressionList(*this, DSAStack, OMPC_to, MVLI, Locs.StartLoc, 22295 MapperIdScopeSpec, MapperId, UnresolvedMappers); 22296 if (MVLI.ProcessedVarList.empty()) 22297 return nullptr; 22298 22299 return OMPToClause::Create( 22300 Context, Locs, MVLI.ProcessedVarList, MVLI.VarBaseDeclarations, 22301 MVLI.VarComponents, MVLI.UDMapperList, Modifiers, ModifiersLoc, 22302 MapperIdScopeSpec.getWithLocInContext(Context), MapperId); 22303 } 22304 22305 OMPClause *Sema::ActOnOpenMPFromClause( 22306 ArrayRef<OpenMPMotionModifierKind> MotionModifiers, 22307 ArrayRef<SourceLocation> MotionModifiersLoc, 22308 CXXScopeSpec &MapperIdScopeSpec, DeclarationNameInfo &MapperId, 22309 SourceLocation ColonLoc, ArrayRef<Expr *> VarList, 22310 const OMPVarListLocTy &Locs, ArrayRef<Expr *> UnresolvedMappers) { 22311 OpenMPMotionModifierKind Modifiers[] = {OMPC_MOTION_MODIFIER_unknown, 22312 OMPC_MOTION_MODIFIER_unknown}; 22313 SourceLocation ModifiersLoc[NumberOfOMPMotionModifiers]; 22314 22315 // Process motion-modifiers, flag errors for duplicate modifiers. 22316 unsigned Count = 0; 22317 for (unsigned I = 0, E = MotionModifiers.size(); I < E; ++I) { 22318 if (MotionModifiers[I] != OMPC_MOTION_MODIFIER_unknown && 22319 llvm::is_contained(Modifiers, MotionModifiers[I])) { 22320 Diag(MotionModifiersLoc[I], diag::err_omp_duplicate_motion_modifier); 22321 continue; 22322 } 22323 assert(Count < NumberOfOMPMotionModifiers && 22324 "Modifiers exceed the allowed number of motion modifiers"); 22325 Modifiers[Count] = MotionModifiers[I]; 22326 ModifiersLoc[Count] = MotionModifiersLoc[I]; 22327 ++Count; 22328 } 22329 22330 MappableVarListInfo MVLI(VarList); 22331 checkMappableExpressionList(*this, DSAStack, OMPC_from, MVLI, Locs.StartLoc, 22332 MapperIdScopeSpec, MapperId, UnresolvedMappers); 22333 if (MVLI.ProcessedVarList.empty()) 22334 return nullptr; 22335 22336 return OMPFromClause::Create( 22337 Context, Locs, MVLI.ProcessedVarList, MVLI.VarBaseDeclarations, 22338 MVLI.VarComponents, MVLI.UDMapperList, Modifiers, ModifiersLoc, 22339 MapperIdScopeSpec.getWithLocInContext(Context), MapperId); 22340 } 22341 22342 OMPClause *Sema::ActOnOpenMPUseDevicePtrClause(ArrayRef<Expr *> VarList, 22343 const OMPVarListLocTy &Locs) { 22344 MappableVarListInfo MVLI(VarList); 22345 SmallVector<Expr *, 8> PrivateCopies; 22346 SmallVector<Expr *, 8> Inits; 22347 22348 for (Expr *RefExpr : VarList) { 22349 assert(RefExpr && "NULL expr in OpenMP use_device_ptr clause."); 22350 SourceLocation ELoc; 22351 SourceRange ERange; 22352 Expr *SimpleRefExpr = RefExpr; 22353 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 22354 if (Res.second) { 22355 // It will be analyzed later. 22356 MVLI.ProcessedVarList.push_back(RefExpr); 22357 PrivateCopies.push_back(nullptr); 22358 Inits.push_back(nullptr); 22359 } 22360 ValueDecl *D = Res.first; 22361 if (!D) 22362 continue; 22363 22364 QualType Type = D->getType(); 22365 Type = Type.getNonReferenceType().getUnqualifiedType(); 22366 22367 auto *VD = dyn_cast<VarDecl>(D); 22368 22369 // Item should be a pointer or reference to pointer. 22370 if (!Type->isPointerType()) { 22371 Diag(ELoc, diag::err_omp_usedeviceptr_not_a_pointer) 22372 << 0 << RefExpr->getSourceRange(); 22373 continue; 22374 } 22375 22376 // Build the private variable and the expression that refers to it. 22377 auto VDPrivate = 22378 buildVarDecl(*this, ELoc, Type, D->getName(), 22379 D->hasAttrs() ? &D->getAttrs() : nullptr, 22380 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr); 22381 if (VDPrivate->isInvalidDecl()) 22382 continue; 22383 22384 CurContext->addDecl(VDPrivate); 22385 DeclRefExpr *VDPrivateRefExpr = buildDeclRefExpr( 22386 *this, VDPrivate, RefExpr->getType().getUnqualifiedType(), ELoc); 22387 22388 // Add temporary variable to initialize the private copy of the pointer. 22389 VarDecl *VDInit = 22390 buildVarDecl(*this, RefExpr->getExprLoc(), Type, ".devptr.temp"); 22391 DeclRefExpr *VDInitRefExpr = buildDeclRefExpr( 22392 *this, VDInit, RefExpr->getType(), RefExpr->getExprLoc()); 22393 AddInitializerToDecl(VDPrivate, 22394 DefaultLvalueConversion(VDInitRefExpr).get(), 22395 /*DirectInit=*/false); 22396 22397 // If required, build a capture to implement the privatization initialized 22398 // with the current list item value. 22399 DeclRefExpr *Ref = nullptr; 22400 if (!VD) 22401 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true); 22402 MVLI.ProcessedVarList.push_back(VD ? RefExpr->IgnoreParens() : Ref); 22403 PrivateCopies.push_back(VDPrivateRefExpr); 22404 Inits.push_back(VDInitRefExpr); 22405 22406 // We need to add a data sharing attribute for this variable to make sure it 22407 // is correctly captured. A variable that shows up in a use_device_ptr has 22408 // similar properties of a first private variable. 22409 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_firstprivate, Ref); 22410 22411 // Create a mappable component for the list item. List items in this clause 22412 // only need a component. 22413 MVLI.VarBaseDeclarations.push_back(D); 22414 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1); 22415 MVLI.VarComponents.back().emplace_back(SimpleRefExpr, D, 22416 /*IsNonContiguous=*/false); 22417 } 22418 22419 if (MVLI.ProcessedVarList.empty()) 22420 return nullptr; 22421 22422 return OMPUseDevicePtrClause::Create( 22423 Context, Locs, MVLI.ProcessedVarList, PrivateCopies, Inits, 22424 MVLI.VarBaseDeclarations, MVLI.VarComponents); 22425 } 22426 22427 OMPClause *Sema::ActOnOpenMPUseDeviceAddrClause(ArrayRef<Expr *> VarList, 22428 const OMPVarListLocTy &Locs) { 22429 MappableVarListInfo MVLI(VarList); 22430 22431 for (Expr *RefExpr : VarList) { 22432 assert(RefExpr && "NULL expr in OpenMP use_device_addr clause."); 22433 SourceLocation ELoc; 22434 SourceRange ERange; 22435 Expr *SimpleRefExpr = RefExpr; 22436 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange, 22437 /*AllowArraySection=*/true); 22438 if (Res.second) { 22439 // It will be analyzed later. 22440 MVLI.ProcessedVarList.push_back(RefExpr); 22441 } 22442 ValueDecl *D = Res.first; 22443 if (!D) 22444 continue; 22445 auto *VD = dyn_cast<VarDecl>(D); 22446 22447 // If required, build a capture to implement the privatization initialized 22448 // with the current list item value. 22449 DeclRefExpr *Ref = nullptr; 22450 if (!VD) 22451 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true); 22452 MVLI.ProcessedVarList.push_back(VD ? RefExpr->IgnoreParens() : Ref); 22453 22454 // We need to add a data sharing attribute for this variable to make sure it 22455 // is correctly captured. A variable that shows up in a use_device_addr has 22456 // similar properties of a first private variable. 22457 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_firstprivate, Ref); 22458 22459 // Create a mappable component for the list item. List items in this clause 22460 // only need a component. 22461 MVLI.VarBaseDeclarations.push_back(D); 22462 MVLI.VarComponents.emplace_back(); 22463 Expr *Component = SimpleRefExpr; 22464 if (VD && (isa<OMPArraySectionExpr>(RefExpr->IgnoreParenImpCasts()) || 22465 isa<ArraySubscriptExpr>(RefExpr->IgnoreParenImpCasts()))) 22466 Component = DefaultFunctionArrayLvalueConversion(SimpleRefExpr).get(); 22467 MVLI.VarComponents.back().emplace_back(Component, D, 22468 /*IsNonContiguous=*/false); 22469 } 22470 22471 if (MVLI.ProcessedVarList.empty()) 22472 return nullptr; 22473 22474 return OMPUseDeviceAddrClause::Create(Context, Locs, MVLI.ProcessedVarList, 22475 MVLI.VarBaseDeclarations, 22476 MVLI.VarComponents); 22477 } 22478 22479 OMPClause *Sema::ActOnOpenMPIsDevicePtrClause(ArrayRef<Expr *> VarList, 22480 const OMPVarListLocTy &Locs) { 22481 MappableVarListInfo MVLI(VarList); 22482 for (Expr *RefExpr : VarList) { 22483 assert(RefExpr && "NULL expr in OpenMP is_device_ptr clause."); 22484 SourceLocation ELoc; 22485 SourceRange ERange; 22486 Expr *SimpleRefExpr = RefExpr; 22487 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 22488 if (Res.second) { 22489 // It will be analyzed later. 22490 MVLI.ProcessedVarList.push_back(RefExpr); 22491 } 22492 ValueDecl *D = Res.first; 22493 if (!D) 22494 continue; 22495 22496 QualType Type = D->getType(); 22497 // item should be a pointer or array or reference to pointer or array 22498 if (!Type.getNonReferenceType()->isPointerType() && 22499 !Type.getNonReferenceType()->isArrayType()) { 22500 Diag(ELoc, diag::err_omp_argument_type_isdeviceptr) 22501 << 0 << RefExpr->getSourceRange(); 22502 continue; 22503 } 22504 22505 // Check if the declaration in the clause does not show up in any data 22506 // sharing attribute. 22507 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false); 22508 if (isOpenMPPrivate(DVar.CKind)) { 22509 Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa) 22510 << getOpenMPClauseName(DVar.CKind) 22511 << getOpenMPClauseName(OMPC_is_device_ptr) 22512 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 22513 reportOriginalDsa(*this, DSAStack, D, DVar); 22514 continue; 22515 } 22516 22517 const Expr *ConflictExpr; 22518 if (DSAStack->checkMappableExprComponentListsForDecl( 22519 D, /*CurrentRegionOnly=*/true, 22520 [&ConflictExpr]( 22521 OMPClauseMappableExprCommon::MappableExprComponentListRef R, 22522 OpenMPClauseKind) -> bool { 22523 ConflictExpr = R.front().getAssociatedExpression(); 22524 return true; 22525 })) { 22526 Diag(ELoc, diag::err_omp_map_shared_storage) << RefExpr->getSourceRange(); 22527 Diag(ConflictExpr->getExprLoc(), diag::note_used_here) 22528 << ConflictExpr->getSourceRange(); 22529 continue; 22530 } 22531 22532 // Store the components in the stack so that they can be used to check 22533 // against other clauses later on. 22534 OMPClauseMappableExprCommon::MappableComponent MC( 22535 SimpleRefExpr, D, /*IsNonContiguous=*/false); 22536 DSAStack->addMappableExpressionComponents( 22537 D, MC, /*WhereFoundClauseKind=*/OMPC_is_device_ptr); 22538 22539 // Record the expression we've just processed. 22540 MVLI.ProcessedVarList.push_back(SimpleRefExpr); 22541 22542 // Create a mappable component for the list item. List items in this clause 22543 // only need a component. We use a null declaration to signal fields in 22544 // 'this'. 22545 assert((isa<DeclRefExpr>(SimpleRefExpr) || 22546 isa<CXXThisExpr>(cast<MemberExpr>(SimpleRefExpr)->getBase())) && 22547 "Unexpected device pointer expression!"); 22548 MVLI.VarBaseDeclarations.push_back( 22549 isa<DeclRefExpr>(SimpleRefExpr) ? D : nullptr); 22550 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1); 22551 MVLI.VarComponents.back().push_back(MC); 22552 } 22553 22554 if (MVLI.ProcessedVarList.empty()) 22555 return nullptr; 22556 22557 return OMPIsDevicePtrClause::Create(Context, Locs, MVLI.ProcessedVarList, 22558 MVLI.VarBaseDeclarations, 22559 MVLI.VarComponents); 22560 } 22561 22562 OMPClause *Sema::ActOnOpenMPHasDeviceAddrClause(ArrayRef<Expr *> VarList, 22563 const OMPVarListLocTy &Locs) { 22564 MappableVarListInfo MVLI(VarList); 22565 for (Expr *RefExpr : VarList) { 22566 assert(RefExpr && "NULL expr in OpenMP has_device_addr clause."); 22567 SourceLocation ELoc; 22568 SourceRange ERange; 22569 Expr *SimpleRefExpr = RefExpr; 22570 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange, 22571 /*AllowArraySection=*/true); 22572 if (Res.second) { 22573 // It will be analyzed later. 22574 MVLI.ProcessedVarList.push_back(RefExpr); 22575 } 22576 ValueDecl *D = Res.first; 22577 if (!D) 22578 continue; 22579 22580 // Check if the declaration in the clause does not show up in any data 22581 // sharing attribute. 22582 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false); 22583 if (isOpenMPPrivate(DVar.CKind)) { 22584 Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa) 22585 << getOpenMPClauseName(DVar.CKind) 22586 << getOpenMPClauseName(OMPC_has_device_addr) 22587 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 22588 reportOriginalDsa(*this, DSAStack, D, DVar); 22589 continue; 22590 } 22591 22592 const Expr *ConflictExpr; 22593 if (DSAStack->checkMappableExprComponentListsForDecl( 22594 D, /*CurrentRegionOnly=*/true, 22595 [&ConflictExpr]( 22596 OMPClauseMappableExprCommon::MappableExprComponentListRef R, 22597 OpenMPClauseKind) -> bool { 22598 ConflictExpr = R.front().getAssociatedExpression(); 22599 return true; 22600 })) { 22601 Diag(ELoc, diag::err_omp_map_shared_storage) << RefExpr->getSourceRange(); 22602 Diag(ConflictExpr->getExprLoc(), diag::note_used_here) 22603 << ConflictExpr->getSourceRange(); 22604 continue; 22605 } 22606 22607 // Store the components in the stack so that they can be used to check 22608 // against other clauses later on. 22609 OMPClauseMappableExprCommon::MappableComponent MC( 22610 SimpleRefExpr, D, /*IsNonContiguous=*/false); 22611 DSAStack->addMappableExpressionComponents( 22612 D, MC, /*WhereFoundClauseKind=*/OMPC_has_device_addr); 22613 22614 // Record the expression we've just processed. 22615 auto *VD = dyn_cast<VarDecl>(D); 22616 if (!VD && !CurContext->isDependentContext()) { 22617 DeclRefExpr *Ref = 22618 buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true); 22619 assert(Ref && "has_device_addr capture failed"); 22620 MVLI.ProcessedVarList.push_back(Ref); 22621 } else 22622 MVLI.ProcessedVarList.push_back(RefExpr->IgnoreParens()); 22623 22624 // Create a mappable component for the list item. List items in this clause 22625 // only need a component. We use a null declaration to signal fields in 22626 // 'this'. 22627 assert((isa<DeclRefExpr>(SimpleRefExpr) || 22628 isa<CXXThisExpr>(cast<MemberExpr>(SimpleRefExpr)->getBase())) && 22629 "Unexpected device pointer expression!"); 22630 MVLI.VarBaseDeclarations.push_back( 22631 isa<DeclRefExpr>(SimpleRefExpr) ? D : nullptr); 22632 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1); 22633 MVLI.VarComponents.back().push_back(MC); 22634 } 22635 22636 if (MVLI.ProcessedVarList.empty()) 22637 return nullptr; 22638 22639 return OMPHasDeviceAddrClause::Create(Context, Locs, MVLI.ProcessedVarList, 22640 MVLI.VarBaseDeclarations, 22641 MVLI.VarComponents); 22642 } 22643 22644 OMPClause *Sema::ActOnOpenMPAllocateClause( 22645 Expr *Allocator, ArrayRef<Expr *> VarList, SourceLocation StartLoc, 22646 SourceLocation ColonLoc, SourceLocation LParenLoc, SourceLocation EndLoc) { 22647 if (Allocator) { 22648 // OpenMP [2.11.4 allocate Clause, Description] 22649 // allocator is an expression of omp_allocator_handle_t type. 22650 if (!findOMPAllocatorHandleT(*this, Allocator->getExprLoc(), DSAStack)) 22651 return nullptr; 22652 22653 ExprResult AllocatorRes = DefaultLvalueConversion(Allocator); 22654 if (AllocatorRes.isInvalid()) 22655 return nullptr; 22656 AllocatorRes = PerformImplicitConversion(AllocatorRes.get(), 22657 DSAStack->getOMPAllocatorHandleT(), 22658 Sema::AA_Initializing, 22659 /*AllowExplicit=*/true); 22660 if (AllocatorRes.isInvalid()) 22661 return nullptr; 22662 Allocator = AllocatorRes.get(); 22663 } else { 22664 // OpenMP 5.0, 2.11.4 allocate Clause, Restrictions. 22665 // allocate clauses that appear on a target construct or on constructs in a 22666 // target region must specify an allocator expression unless a requires 22667 // directive with the dynamic_allocators clause is present in the same 22668 // compilation unit. 22669 if (LangOpts.OpenMPIsDevice && 22670 !DSAStack->hasRequiresDeclWithClause<OMPDynamicAllocatorsClause>()) 22671 targetDiag(StartLoc, diag::err_expected_allocator_expression); 22672 } 22673 // Analyze and build list of variables. 22674 SmallVector<Expr *, 8> Vars; 22675 for (Expr *RefExpr : VarList) { 22676 assert(RefExpr && "NULL expr in OpenMP private clause."); 22677 SourceLocation ELoc; 22678 SourceRange ERange; 22679 Expr *SimpleRefExpr = RefExpr; 22680 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 22681 if (Res.second) { 22682 // It will be analyzed later. 22683 Vars.push_back(RefExpr); 22684 } 22685 ValueDecl *D = Res.first; 22686 if (!D) 22687 continue; 22688 22689 auto *VD = dyn_cast<VarDecl>(D); 22690 DeclRefExpr *Ref = nullptr; 22691 if (!VD && !CurContext->isDependentContext()) 22692 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false); 22693 Vars.push_back((VD || CurContext->isDependentContext()) 22694 ? RefExpr->IgnoreParens() 22695 : Ref); 22696 } 22697 22698 if (Vars.empty()) 22699 return nullptr; 22700 22701 if (Allocator) 22702 DSAStack->addInnerAllocatorExpr(Allocator); 22703 return OMPAllocateClause::Create(Context, StartLoc, LParenLoc, Allocator, 22704 ColonLoc, EndLoc, Vars); 22705 } 22706 22707 OMPClause *Sema::ActOnOpenMPNontemporalClause(ArrayRef<Expr *> VarList, 22708 SourceLocation StartLoc, 22709 SourceLocation LParenLoc, 22710 SourceLocation EndLoc) { 22711 SmallVector<Expr *, 8> Vars; 22712 for (Expr *RefExpr : VarList) { 22713 assert(RefExpr && "NULL expr in OpenMP nontemporal clause."); 22714 SourceLocation ELoc; 22715 SourceRange ERange; 22716 Expr *SimpleRefExpr = RefExpr; 22717 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 22718 if (Res.second) 22719 // It will be analyzed later. 22720 Vars.push_back(RefExpr); 22721 ValueDecl *D = Res.first; 22722 if (!D) 22723 continue; 22724 22725 // OpenMP 5.0, 2.9.3.1 simd Construct, Restrictions. 22726 // A list-item cannot appear in more than one nontemporal clause. 22727 if (const Expr *PrevRef = 22728 DSAStack->addUniqueNontemporal(D, SimpleRefExpr)) { 22729 Diag(ELoc, diag::err_omp_used_in_clause_twice) 22730 << 0 << getOpenMPClauseName(OMPC_nontemporal) << ERange; 22731 Diag(PrevRef->getExprLoc(), diag::note_omp_explicit_dsa) 22732 << getOpenMPClauseName(OMPC_nontemporal); 22733 continue; 22734 } 22735 22736 Vars.push_back(RefExpr); 22737 } 22738 22739 if (Vars.empty()) 22740 return nullptr; 22741 22742 return OMPNontemporalClause::Create(Context, StartLoc, LParenLoc, EndLoc, 22743 Vars); 22744 } 22745 22746 OMPClause *Sema::ActOnOpenMPInclusiveClause(ArrayRef<Expr *> VarList, 22747 SourceLocation StartLoc, 22748 SourceLocation LParenLoc, 22749 SourceLocation EndLoc) { 22750 SmallVector<Expr *, 8> Vars; 22751 for (Expr *RefExpr : VarList) { 22752 assert(RefExpr && "NULL expr in OpenMP nontemporal clause."); 22753 SourceLocation ELoc; 22754 SourceRange ERange; 22755 Expr *SimpleRefExpr = RefExpr; 22756 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange, 22757 /*AllowArraySection=*/true); 22758 if (Res.second) 22759 // It will be analyzed later. 22760 Vars.push_back(RefExpr); 22761 ValueDecl *D = Res.first; 22762 if (!D) 22763 continue; 22764 22765 const DSAStackTy::DSAVarData DVar = 22766 DSAStack->getTopDSA(D, /*FromParent=*/true); 22767 // OpenMP 5.0, 2.9.6, scan Directive, Restrictions. 22768 // A list item that appears in the inclusive or exclusive clause must appear 22769 // in a reduction clause with the inscan modifier on the enclosing 22770 // worksharing-loop, worksharing-loop SIMD, or simd construct. 22771 if (DVar.CKind != OMPC_reduction || DVar.Modifier != OMPC_REDUCTION_inscan) 22772 Diag(ELoc, diag::err_omp_inclusive_exclusive_not_reduction) 22773 << RefExpr->getSourceRange(); 22774 22775 if (DSAStack->getParentDirective() != OMPD_unknown) 22776 DSAStack->markDeclAsUsedInScanDirective(D); 22777 Vars.push_back(RefExpr); 22778 } 22779 22780 if (Vars.empty()) 22781 return nullptr; 22782 22783 return OMPInclusiveClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars); 22784 } 22785 22786 OMPClause *Sema::ActOnOpenMPExclusiveClause(ArrayRef<Expr *> VarList, 22787 SourceLocation StartLoc, 22788 SourceLocation LParenLoc, 22789 SourceLocation EndLoc) { 22790 SmallVector<Expr *, 8> Vars; 22791 for (Expr *RefExpr : VarList) { 22792 assert(RefExpr && "NULL expr in OpenMP nontemporal clause."); 22793 SourceLocation ELoc; 22794 SourceRange ERange; 22795 Expr *SimpleRefExpr = RefExpr; 22796 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange, 22797 /*AllowArraySection=*/true); 22798 if (Res.second) 22799 // It will be analyzed later. 22800 Vars.push_back(RefExpr); 22801 ValueDecl *D = Res.first; 22802 if (!D) 22803 continue; 22804 22805 OpenMPDirectiveKind ParentDirective = DSAStack->getParentDirective(); 22806 DSAStackTy::DSAVarData DVar; 22807 if (ParentDirective != OMPD_unknown) 22808 DVar = DSAStack->getTopDSA(D, /*FromParent=*/true); 22809 // OpenMP 5.0, 2.9.6, scan Directive, Restrictions. 22810 // A list item that appears in the inclusive or exclusive clause must appear 22811 // in a reduction clause with the inscan modifier on the enclosing 22812 // worksharing-loop, worksharing-loop SIMD, or simd construct. 22813 if (ParentDirective == OMPD_unknown || DVar.CKind != OMPC_reduction || 22814 DVar.Modifier != OMPC_REDUCTION_inscan) { 22815 Diag(ELoc, diag::err_omp_inclusive_exclusive_not_reduction) 22816 << RefExpr->getSourceRange(); 22817 } else { 22818 DSAStack->markDeclAsUsedInScanDirective(D); 22819 } 22820 Vars.push_back(RefExpr); 22821 } 22822 22823 if (Vars.empty()) 22824 return nullptr; 22825 22826 return OMPExclusiveClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars); 22827 } 22828 22829 /// Tries to find omp_alloctrait_t type. 22830 static bool findOMPAlloctraitT(Sema &S, SourceLocation Loc, DSAStackTy *Stack) { 22831 QualType OMPAlloctraitT = Stack->getOMPAlloctraitT(); 22832 if (!OMPAlloctraitT.isNull()) 22833 return true; 22834 IdentifierInfo &II = S.PP.getIdentifierTable().get("omp_alloctrait_t"); 22835 ParsedType PT = S.getTypeName(II, Loc, S.getCurScope()); 22836 if (!PT.getAsOpaquePtr() || PT.get().isNull()) { 22837 S.Diag(Loc, diag::err_omp_implied_type_not_found) << "omp_alloctrait_t"; 22838 return false; 22839 } 22840 Stack->setOMPAlloctraitT(PT.get()); 22841 return true; 22842 } 22843 22844 OMPClause *Sema::ActOnOpenMPUsesAllocatorClause( 22845 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc, 22846 ArrayRef<UsesAllocatorsData> Data) { 22847 // OpenMP [2.12.5, target Construct] 22848 // allocator is an identifier of omp_allocator_handle_t type. 22849 if (!findOMPAllocatorHandleT(*this, StartLoc, DSAStack)) 22850 return nullptr; 22851 // OpenMP [2.12.5, target Construct] 22852 // allocator-traits-array is an identifier of const omp_alloctrait_t * type. 22853 if (llvm::any_of( 22854 Data, 22855 [](const UsesAllocatorsData &D) { return D.AllocatorTraits; }) && 22856 !findOMPAlloctraitT(*this, StartLoc, DSAStack)) 22857 return nullptr; 22858 llvm::SmallPtrSet<CanonicalDeclPtr<Decl>, 4> PredefinedAllocators; 22859 for (int I = 0; I < OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; ++I) { 22860 auto AllocatorKind = static_cast<OMPAllocateDeclAttr::AllocatorTypeTy>(I); 22861 StringRef Allocator = 22862 OMPAllocateDeclAttr::ConvertAllocatorTypeTyToStr(AllocatorKind); 22863 DeclarationName AllocatorName = &Context.Idents.get(Allocator); 22864 PredefinedAllocators.insert(LookupSingleName( 22865 TUScope, AllocatorName, StartLoc, Sema::LookupAnyName)); 22866 } 22867 22868 SmallVector<OMPUsesAllocatorsClause::Data, 4> NewData; 22869 for (const UsesAllocatorsData &D : Data) { 22870 Expr *AllocatorExpr = nullptr; 22871 // Check allocator expression. 22872 if (D.Allocator->isTypeDependent()) { 22873 AllocatorExpr = D.Allocator; 22874 } else { 22875 // Traits were specified - need to assign new allocator to the specified 22876 // allocator, so it must be an lvalue. 22877 AllocatorExpr = D.Allocator->IgnoreParenImpCasts(); 22878 auto *DRE = dyn_cast<DeclRefExpr>(AllocatorExpr); 22879 bool IsPredefinedAllocator = false; 22880 if (DRE) 22881 IsPredefinedAllocator = PredefinedAllocators.count(DRE->getDecl()); 22882 if (!DRE || 22883 !(Context.hasSameUnqualifiedType( 22884 AllocatorExpr->getType(), DSAStack->getOMPAllocatorHandleT()) || 22885 Context.typesAreCompatible(AllocatorExpr->getType(), 22886 DSAStack->getOMPAllocatorHandleT(), 22887 /*CompareUnqualified=*/true)) || 22888 (!IsPredefinedAllocator && 22889 (AllocatorExpr->getType().isConstant(Context) || 22890 !AllocatorExpr->isLValue()))) { 22891 Diag(D.Allocator->getExprLoc(), diag::err_omp_var_expected) 22892 << "omp_allocator_handle_t" << (DRE ? 1 : 0) 22893 << AllocatorExpr->getType() << D.Allocator->getSourceRange(); 22894 continue; 22895 } 22896 // OpenMP [2.12.5, target Construct] 22897 // Predefined allocators appearing in a uses_allocators clause cannot have 22898 // traits specified. 22899 if (IsPredefinedAllocator && D.AllocatorTraits) { 22900 Diag(D.AllocatorTraits->getExprLoc(), 22901 diag::err_omp_predefined_allocator_with_traits) 22902 << D.AllocatorTraits->getSourceRange(); 22903 Diag(D.Allocator->getExprLoc(), diag::note_omp_predefined_allocator) 22904 << cast<NamedDecl>(DRE->getDecl())->getName() 22905 << D.Allocator->getSourceRange(); 22906 continue; 22907 } 22908 // OpenMP [2.12.5, target Construct] 22909 // Non-predefined allocators appearing in a uses_allocators clause must 22910 // have traits specified. 22911 if (!IsPredefinedAllocator && !D.AllocatorTraits) { 22912 Diag(D.Allocator->getExprLoc(), 22913 diag::err_omp_nonpredefined_allocator_without_traits); 22914 continue; 22915 } 22916 // No allocator traits - just convert it to rvalue. 22917 if (!D.AllocatorTraits) 22918 AllocatorExpr = DefaultLvalueConversion(AllocatorExpr).get(); 22919 DSAStack->addUsesAllocatorsDecl( 22920 DRE->getDecl(), 22921 IsPredefinedAllocator 22922 ? DSAStackTy::UsesAllocatorsDeclKind::PredefinedAllocator 22923 : DSAStackTy::UsesAllocatorsDeclKind::UserDefinedAllocator); 22924 } 22925 Expr *AllocatorTraitsExpr = nullptr; 22926 if (D.AllocatorTraits) { 22927 if (D.AllocatorTraits->isTypeDependent()) { 22928 AllocatorTraitsExpr = D.AllocatorTraits; 22929 } else { 22930 // OpenMP [2.12.5, target Construct] 22931 // Arrays that contain allocator traits that appear in a uses_allocators 22932 // clause must be constant arrays, have constant values and be defined 22933 // in the same scope as the construct in which the clause appears. 22934 AllocatorTraitsExpr = D.AllocatorTraits->IgnoreParenImpCasts(); 22935 // Check that traits expr is a constant array. 22936 QualType TraitTy; 22937 if (const ArrayType *Ty = 22938 AllocatorTraitsExpr->getType()->getAsArrayTypeUnsafe()) 22939 if (const auto *ConstArrayTy = dyn_cast<ConstantArrayType>(Ty)) 22940 TraitTy = ConstArrayTy->getElementType(); 22941 if (TraitTy.isNull() || 22942 !(Context.hasSameUnqualifiedType(TraitTy, 22943 DSAStack->getOMPAlloctraitT()) || 22944 Context.typesAreCompatible(TraitTy, DSAStack->getOMPAlloctraitT(), 22945 /*CompareUnqualified=*/true))) { 22946 Diag(D.AllocatorTraits->getExprLoc(), 22947 diag::err_omp_expected_array_alloctraits) 22948 << AllocatorTraitsExpr->getType(); 22949 continue; 22950 } 22951 // Do not map by default allocator traits if it is a standalone 22952 // variable. 22953 if (auto *DRE = dyn_cast<DeclRefExpr>(AllocatorTraitsExpr)) 22954 DSAStack->addUsesAllocatorsDecl( 22955 DRE->getDecl(), 22956 DSAStackTy::UsesAllocatorsDeclKind::AllocatorTrait); 22957 } 22958 } 22959 OMPUsesAllocatorsClause::Data &NewD = NewData.emplace_back(); 22960 NewD.Allocator = AllocatorExpr; 22961 NewD.AllocatorTraits = AllocatorTraitsExpr; 22962 NewD.LParenLoc = D.LParenLoc; 22963 NewD.RParenLoc = D.RParenLoc; 22964 } 22965 return OMPUsesAllocatorsClause::Create(Context, StartLoc, LParenLoc, EndLoc, 22966 NewData); 22967 } 22968 22969 OMPClause *Sema::ActOnOpenMPAffinityClause( 22970 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation ColonLoc, 22971 SourceLocation EndLoc, Expr *Modifier, ArrayRef<Expr *> Locators) { 22972 SmallVector<Expr *, 8> Vars; 22973 for (Expr *RefExpr : Locators) { 22974 assert(RefExpr && "NULL expr in OpenMP shared clause."); 22975 if (isa<DependentScopeDeclRefExpr>(RefExpr) || RefExpr->isTypeDependent()) { 22976 // It will be analyzed later. 22977 Vars.push_back(RefExpr); 22978 continue; 22979 } 22980 22981 SourceLocation ELoc = RefExpr->getExprLoc(); 22982 Expr *SimpleExpr = RefExpr->IgnoreParenImpCasts(); 22983 22984 if (!SimpleExpr->isLValue()) { 22985 Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item) 22986 << 1 << 0 << RefExpr->getSourceRange(); 22987 continue; 22988 } 22989 22990 ExprResult Res; 22991 { 22992 Sema::TentativeAnalysisScope Trap(*this); 22993 Res = CreateBuiltinUnaryOp(ELoc, UO_AddrOf, SimpleExpr); 22994 } 22995 if (!Res.isUsable() && !isa<OMPArraySectionExpr>(SimpleExpr) && 22996 !isa<OMPArrayShapingExpr>(SimpleExpr)) { 22997 Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item) 22998 << 1 << 0 << RefExpr->getSourceRange(); 22999 continue; 23000 } 23001 Vars.push_back(SimpleExpr); 23002 } 23003 23004 return OMPAffinityClause::Create(Context, StartLoc, LParenLoc, ColonLoc, 23005 EndLoc, Modifier, Vars); 23006 } 23007 23008 OMPClause *Sema::ActOnOpenMPBindClause(OpenMPBindClauseKind Kind, 23009 SourceLocation KindLoc, 23010 SourceLocation StartLoc, 23011 SourceLocation LParenLoc, 23012 SourceLocation EndLoc) { 23013 if (Kind == OMPC_BIND_unknown) { 23014 Diag(KindLoc, diag::err_omp_unexpected_clause_value) 23015 << getListOfPossibleValues(OMPC_bind, /*First=*/0, 23016 /*Last=*/unsigned(OMPC_BIND_unknown)) 23017 << getOpenMPClauseName(OMPC_bind); 23018 return nullptr; 23019 } 23020 23021 return OMPBindClause::Create(Context, Kind, KindLoc, StartLoc, LParenLoc, 23022 EndLoc); 23023 } 23024