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/StmtCXX.h" 22 #include "clang/AST/StmtOpenMP.h" 23 #include "clang/AST/StmtVisitor.h" 24 #include "clang/AST/TypeOrdering.h" 25 #include "clang/Basic/DiagnosticSema.h" 26 #include "clang/Basic/OpenMPKinds.h" 27 #include "clang/Basic/PartialDiagnostic.h" 28 #include "clang/Basic/TargetInfo.h" 29 #include "clang/Sema/Initialization.h" 30 #include "clang/Sema/Lookup.h" 31 #include "clang/Sema/Scope.h" 32 #include "clang/Sema/ScopeInfo.h" 33 #include "clang/Sema/SemaInternal.h" 34 #include "llvm/ADT/IndexedMap.h" 35 #include "llvm/ADT/PointerEmbeddedInt.h" 36 #include "llvm/ADT/STLExtras.h" 37 #include "llvm/Frontend/OpenMP/OMPConstants.h" 38 #include <set> 39 40 using namespace clang; 41 using namespace llvm::omp; 42 43 //===----------------------------------------------------------------------===// 44 // Stack of data-sharing attributes for variables 45 //===----------------------------------------------------------------------===// 46 47 static const Expr *checkMapClauseExpressionBase( 48 Sema &SemaRef, Expr *E, 49 OMPClauseMappableExprCommon::MappableExprComponentList &CurComponents, 50 OpenMPClauseKind CKind, bool NoDiagnose); 51 52 namespace { 53 /// Default data sharing attributes, which can be applied to directive. 54 enum DefaultDataSharingAttributes { 55 DSA_unspecified = 0, /// Data sharing attribute not specified. 56 DSA_none = 1 << 0, /// Default data sharing attribute 'none'. 57 DSA_shared = 1 << 1, /// Default data sharing attribute 'shared'. 58 }; 59 60 /// Stack for tracking declarations used in OpenMP directives and 61 /// clauses and their data-sharing attributes. 62 class DSAStackTy { 63 public: 64 struct DSAVarData { 65 OpenMPDirectiveKind DKind = OMPD_unknown; 66 OpenMPClauseKind CKind = OMPC_unknown; 67 unsigned Modifier = 0; 68 const Expr *RefExpr = nullptr; 69 DeclRefExpr *PrivateCopy = nullptr; 70 SourceLocation ImplicitDSALoc; 71 DSAVarData() = default; 72 DSAVarData(OpenMPDirectiveKind DKind, OpenMPClauseKind CKind, 73 const Expr *RefExpr, DeclRefExpr *PrivateCopy, 74 SourceLocation ImplicitDSALoc, unsigned Modifier) 75 : DKind(DKind), CKind(CKind), Modifier(Modifier), RefExpr(RefExpr), 76 PrivateCopy(PrivateCopy), ImplicitDSALoc(ImplicitDSALoc) {} 77 }; 78 using OperatorOffsetTy = 79 llvm::SmallVector<std::pair<Expr *, OverloadedOperatorKind>, 4>; 80 using DoacrossDependMapTy = 81 llvm::DenseMap<OMPDependClause *, OperatorOffsetTy>; 82 83 private: 84 struct DSAInfo { 85 OpenMPClauseKind Attributes = OMPC_unknown; 86 unsigned Modifier = 0; 87 /// Pointer to a reference expression and a flag which shows that the 88 /// variable is marked as lastprivate(true) or not (false). 89 llvm::PointerIntPair<const Expr *, 1, bool> RefExpr; 90 DeclRefExpr *PrivateCopy = nullptr; 91 }; 92 using DeclSAMapTy = llvm::SmallDenseMap<const ValueDecl *, DSAInfo, 8>; 93 using UsedRefMapTy = llvm::SmallDenseMap<const ValueDecl *, const Expr *, 8>; 94 using LCDeclInfo = std::pair<unsigned, VarDecl *>; 95 using LoopControlVariablesMapTy = 96 llvm::SmallDenseMap<const ValueDecl *, LCDeclInfo, 8>; 97 /// Struct that associates a component with the clause kind where they are 98 /// found. 99 struct MappedExprComponentTy { 100 OMPClauseMappableExprCommon::MappableExprComponentLists Components; 101 OpenMPClauseKind Kind = OMPC_unknown; 102 }; 103 using MappedExprComponentsTy = 104 llvm::DenseMap<const ValueDecl *, MappedExprComponentTy>; 105 using CriticalsWithHintsTy = 106 llvm::StringMap<std::pair<const OMPCriticalDirective *, llvm::APSInt>>; 107 struct ReductionData { 108 using BOKPtrType = llvm::PointerEmbeddedInt<BinaryOperatorKind, 16>; 109 SourceRange ReductionRange; 110 llvm::PointerUnion<const Expr *, BOKPtrType> ReductionOp; 111 ReductionData() = default; 112 void set(BinaryOperatorKind BO, SourceRange RR) { 113 ReductionRange = RR; 114 ReductionOp = BO; 115 } 116 void set(const Expr *RefExpr, SourceRange RR) { 117 ReductionRange = RR; 118 ReductionOp = RefExpr; 119 } 120 }; 121 using DeclReductionMapTy = 122 llvm::SmallDenseMap<const ValueDecl *, ReductionData, 4>; 123 struct DefaultmapInfo { 124 OpenMPDefaultmapClauseModifier ImplicitBehavior = 125 OMPC_DEFAULTMAP_MODIFIER_unknown; 126 SourceLocation SLoc; 127 DefaultmapInfo() = default; 128 DefaultmapInfo(OpenMPDefaultmapClauseModifier M, SourceLocation Loc) 129 : ImplicitBehavior(M), SLoc(Loc) {} 130 }; 131 132 struct SharingMapTy { 133 DeclSAMapTy SharingMap; 134 DeclReductionMapTy ReductionMap; 135 UsedRefMapTy AlignedMap; 136 UsedRefMapTy NontemporalMap; 137 MappedExprComponentsTy MappedExprComponents; 138 LoopControlVariablesMapTy LCVMap; 139 DefaultDataSharingAttributes DefaultAttr = DSA_unspecified; 140 SourceLocation DefaultAttrLoc; 141 DefaultmapInfo DefaultmapMap[OMPC_DEFAULTMAP_unknown]; 142 OpenMPDirectiveKind Directive = OMPD_unknown; 143 DeclarationNameInfo DirectiveName; 144 Scope *CurScope = nullptr; 145 SourceLocation ConstructLoc; 146 /// Set of 'depend' clauses with 'sink|source' dependence kind. Required to 147 /// get the data (loop counters etc.) about enclosing loop-based construct. 148 /// This data is required during codegen. 149 DoacrossDependMapTy DoacrossDepends; 150 /// First argument (Expr *) contains optional argument of the 151 /// 'ordered' clause, the second one is true if the regions has 'ordered' 152 /// clause, false otherwise. 153 llvm::Optional<std::pair<const Expr *, OMPOrderedClause *>> OrderedRegion; 154 unsigned AssociatedLoops = 1; 155 bool HasMutipleLoops = false; 156 const Decl *PossiblyLoopCounter = nullptr; 157 bool NowaitRegion = false; 158 bool CancelRegion = false; 159 bool LoopStart = false; 160 bool BodyComplete = false; 161 SourceLocation PrevScanLocation; 162 SourceLocation InnerTeamsRegionLoc; 163 /// Reference to the taskgroup task_reduction reference expression. 164 Expr *TaskgroupReductionRef = nullptr; 165 llvm::DenseSet<QualType> MappedClassesQualTypes; 166 SmallVector<Expr *, 4> InnerUsedAllocators; 167 llvm::DenseSet<CanonicalDeclPtr<Decl>> ImplicitTaskFirstprivates; 168 /// List of globals marked as declare target link in this target region 169 /// (isOpenMPTargetExecutionDirective(Directive) == true). 170 llvm::SmallVector<DeclRefExpr *, 4> DeclareTargetLinkVarDecls; 171 /// List of decls used in inclusive/exclusive clauses of the scan directive. 172 llvm::DenseSet<CanonicalDeclPtr<Decl>> UsedInScanDirective; 173 SharingMapTy(OpenMPDirectiveKind DKind, DeclarationNameInfo Name, 174 Scope *CurScope, SourceLocation Loc) 175 : Directive(DKind), DirectiveName(Name), CurScope(CurScope), 176 ConstructLoc(Loc) {} 177 SharingMapTy() = default; 178 }; 179 180 using StackTy = SmallVector<SharingMapTy, 4>; 181 182 /// Stack of used declaration and their data-sharing attributes. 183 DeclSAMapTy Threadprivates; 184 const FunctionScopeInfo *CurrentNonCapturingFunctionScope = nullptr; 185 SmallVector<std::pair<StackTy, const FunctionScopeInfo *>, 4> Stack; 186 /// true, if check for DSA must be from parent directive, false, if 187 /// from current directive. 188 OpenMPClauseKind ClauseKindMode = OMPC_unknown; 189 Sema &SemaRef; 190 bool ForceCapturing = false; 191 /// true if all the variables in the target executable directives must be 192 /// captured by reference. 193 bool ForceCaptureByReferenceInTargetExecutable = false; 194 CriticalsWithHintsTy Criticals; 195 unsigned IgnoredStackElements = 0; 196 197 /// Iterators over the stack iterate in order from innermost to outermost 198 /// directive. 199 using const_iterator = StackTy::const_reverse_iterator; 200 const_iterator begin() const { 201 return Stack.empty() ? const_iterator() 202 : Stack.back().first.rbegin() + IgnoredStackElements; 203 } 204 const_iterator end() const { 205 return Stack.empty() ? const_iterator() : Stack.back().first.rend(); 206 } 207 using iterator = StackTy::reverse_iterator; 208 iterator begin() { 209 return Stack.empty() ? iterator() 210 : Stack.back().first.rbegin() + IgnoredStackElements; 211 } 212 iterator end() { 213 return Stack.empty() ? iterator() : Stack.back().first.rend(); 214 } 215 216 // Convenience operations to get at the elements of the stack. 217 218 bool isStackEmpty() const { 219 return Stack.empty() || 220 Stack.back().second != CurrentNonCapturingFunctionScope || 221 Stack.back().first.size() <= IgnoredStackElements; 222 } 223 size_t getStackSize() const { 224 return isStackEmpty() ? 0 225 : Stack.back().first.size() - IgnoredStackElements; 226 } 227 228 SharingMapTy *getTopOfStackOrNull() { 229 size_t Size = getStackSize(); 230 if (Size == 0) 231 return nullptr; 232 return &Stack.back().first[Size - 1]; 233 } 234 const SharingMapTy *getTopOfStackOrNull() const { 235 return const_cast<DSAStackTy&>(*this).getTopOfStackOrNull(); 236 } 237 SharingMapTy &getTopOfStack() { 238 assert(!isStackEmpty() && "no current directive"); 239 return *getTopOfStackOrNull(); 240 } 241 const SharingMapTy &getTopOfStack() const { 242 return const_cast<DSAStackTy&>(*this).getTopOfStack(); 243 } 244 245 SharingMapTy *getSecondOnStackOrNull() { 246 size_t Size = getStackSize(); 247 if (Size <= 1) 248 return nullptr; 249 return &Stack.back().first[Size - 2]; 250 } 251 const SharingMapTy *getSecondOnStackOrNull() const { 252 return const_cast<DSAStackTy&>(*this).getSecondOnStackOrNull(); 253 } 254 255 /// Get the stack element at a certain level (previously returned by 256 /// \c getNestingLevel). 257 /// 258 /// Note that nesting levels count from outermost to innermost, and this is 259 /// the reverse of our iteration order where new inner levels are pushed at 260 /// the front of the stack. 261 SharingMapTy &getStackElemAtLevel(unsigned Level) { 262 assert(Level < getStackSize() && "no such stack element"); 263 return Stack.back().first[Level]; 264 } 265 const SharingMapTy &getStackElemAtLevel(unsigned Level) const { 266 return const_cast<DSAStackTy&>(*this).getStackElemAtLevel(Level); 267 } 268 269 DSAVarData getDSA(const_iterator &Iter, ValueDecl *D) const; 270 271 /// Checks if the variable is a local for OpenMP region. 272 bool isOpenMPLocal(VarDecl *D, const_iterator Iter) const; 273 274 /// Vector of previously declared requires directives 275 SmallVector<const OMPRequiresDecl *, 2> RequiresDecls; 276 /// omp_allocator_handle_t type. 277 QualType OMPAllocatorHandleT; 278 /// omp_depend_t type. 279 QualType OMPDependT; 280 /// omp_event_handle_t type. 281 QualType OMPEventHandleT; 282 /// Expression for the predefined allocators. 283 Expr *OMPPredefinedAllocators[OMPAllocateDeclAttr::OMPUserDefinedMemAlloc] = { 284 nullptr}; 285 /// Vector of previously encountered target directives 286 SmallVector<SourceLocation, 2> TargetLocations; 287 SourceLocation AtomicLocation; 288 289 public: 290 explicit DSAStackTy(Sema &S) : SemaRef(S) {} 291 292 /// Sets omp_allocator_handle_t type. 293 void setOMPAllocatorHandleT(QualType Ty) { OMPAllocatorHandleT = Ty; } 294 /// Gets omp_allocator_handle_t type. 295 QualType getOMPAllocatorHandleT() const { return OMPAllocatorHandleT; } 296 /// Sets the given default allocator. 297 void setAllocator(OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind, 298 Expr *Allocator) { 299 OMPPredefinedAllocators[AllocatorKind] = Allocator; 300 } 301 /// Returns the specified default allocator. 302 Expr *getAllocator(OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind) const { 303 return OMPPredefinedAllocators[AllocatorKind]; 304 } 305 /// Sets omp_depend_t type. 306 void setOMPDependT(QualType Ty) { OMPDependT = Ty; } 307 /// Gets omp_depend_t type. 308 QualType getOMPDependT() const { return OMPDependT; } 309 310 /// Sets omp_event_handle_t type. 311 void setOMPEventHandleT(QualType Ty) { OMPEventHandleT = Ty; } 312 /// Gets omp_event_handle_t type. 313 QualType getOMPEventHandleT() const { return OMPEventHandleT; } 314 315 bool isClauseParsingMode() const { return ClauseKindMode != OMPC_unknown; } 316 OpenMPClauseKind getClauseParsingMode() const { 317 assert(isClauseParsingMode() && "Must be in clause parsing mode."); 318 return ClauseKindMode; 319 } 320 void setClauseParsingMode(OpenMPClauseKind K) { ClauseKindMode = K; } 321 322 bool isBodyComplete() const { 323 const SharingMapTy *Top = getTopOfStackOrNull(); 324 return Top && Top->BodyComplete; 325 } 326 void setBodyComplete() { 327 getTopOfStack().BodyComplete = true; 328 } 329 330 bool isForceVarCapturing() const { return ForceCapturing; } 331 void setForceVarCapturing(bool V) { ForceCapturing = V; } 332 333 void setForceCaptureByReferenceInTargetExecutable(bool V) { 334 ForceCaptureByReferenceInTargetExecutable = V; 335 } 336 bool isForceCaptureByReferenceInTargetExecutable() const { 337 return ForceCaptureByReferenceInTargetExecutable; 338 } 339 340 void push(OpenMPDirectiveKind DKind, const DeclarationNameInfo &DirName, 341 Scope *CurScope, SourceLocation Loc) { 342 assert(!IgnoredStackElements && 343 "cannot change stack while ignoring elements"); 344 if (Stack.empty() || 345 Stack.back().second != CurrentNonCapturingFunctionScope) 346 Stack.emplace_back(StackTy(), CurrentNonCapturingFunctionScope); 347 Stack.back().first.emplace_back(DKind, DirName, CurScope, Loc); 348 Stack.back().first.back().DefaultAttrLoc = Loc; 349 } 350 351 void pop() { 352 assert(!IgnoredStackElements && 353 "cannot change stack while ignoring elements"); 354 assert(!Stack.back().first.empty() && 355 "Data-sharing attributes stack is empty!"); 356 Stack.back().first.pop_back(); 357 } 358 359 /// RAII object to temporarily leave the scope of a directive when we want to 360 /// logically operate in its parent. 361 class ParentDirectiveScope { 362 DSAStackTy &Self; 363 bool Active; 364 public: 365 ParentDirectiveScope(DSAStackTy &Self, bool Activate) 366 : Self(Self), Active(false) { 367 if (Activate) 368 enable(); 369 } 370 ~ParentDirectiveScope() { disable(); } 371 void disable() { 372 if (Active) { 373 --Self.IgnoredStackElements; 374 Active = false; 375 } 376 } 377 void enable() { 378 if (!Active) { 379 ++Self.IgnoredStackElements; 380 Active = true; 381 } 382 } 383 }; 384 385 /// Marks that we're started loop parsing. 386 void loopInit() { 387 assert(isOpenMPLoopDirective(getCurrentDirective()) && 388 "Expected loop-based directive."); 389 getTopOfStack().LoopStart = true; 390 } 391 /// Start capturing of the variables in the loop context. 392 void loopStart() { 393 assert(isOpenMPLoopDirective(getCurrentDirective()) && 394 "Expected loop-based directive."); 395 getTopOfStack().LoopStart = false; 396 } 397 /// true, if variables are captured, false otherwise. 398 bool isLoopStarted() const { 399 assert(isOpenMPLoopDirective(getCurrentDirective()) && 400 "Expected loop-based directive."); 401 return !getTopOfStack().LoopStart; 402 } 403 /// Marks (or clears) declaration as possibly loop counter. 404 void resetPossibleLoopCounter(const Decl *D = nullptr) { 405 getTopOfStack().PossiblyLoopCounter = 406 D ? D->getCanonicalDecl() : D; 407 } 408 /// Gets the possible loop counter decl. 409 const Decl *getPossiblyLoopCunter() const { 410 return getTopOfStack().PossiblyLoopCounter; 411 } 412 /// Start new OpenMP region stack in new non-capturing function. 413 void pushFunction() { 414 assert(!IgnoredStackElements && 415 "cannot change stack while ignoring elements"); 416 const FunctionScopeInfo *CurFnScope = SemaRef.getCurFunction(); 417 assert(!isa<CapturingScopeInfo>(CurFnScope)); 418 CurrentNonCapturingFunctionScope = CurFnScope; 419 } 420 /// Pop region stack for non-capturing function. 421 void popFunction(const FunctionScopeInfo *OldFSI) { 422 assert(!IgnoredStackElements && 423 "cannot change stack while ignoring elements"); 424 if (!Stack.empty() && Stack.back().second == OldFSI) { 425 assert(Stack.back().first.empty()); 426 Stack.pop_back(); 427 } 428 CurrentNonCapturingFunctionScope = nullptr; 429 for (const FunctionScopeInfo *FSI : llvm::reverse(SemaRef.FunctionScopes)) { 430 if (!isa<CapturingScopeInfo>(FSI)) { 431 CurrentNonCapturingFunctionScope = FSI; 432 break; 433 } 434 } 435 } 436 437 void addCriticalWithHint(const OMPCriticalDirective *D, llvm::APSInt Hint) { 438 Criticals.try_emplace(D->getDirectiveName().getAsString(), D, Hint); 439 } 440 const std::pair<const OMPCriticalDirective *, llvm::APSInt> 441 getCriticalWithHint(const DeclarationNameInfo &Name) const { 442 auto I = Criticals.find(Name.getAsString()); 443 if (I != Criticals.end()) 444 return I->second; 445 return std::make_pair(nullptr, llvm::APSInt()); 446 } 447 /// If 'aligned' declaration for given variable \a D was not seen yet, 448 /// add it and return NULL; otherwise return previous occurrence's expression 449 /// for diagnostics. 450 const Expr *addUniqueAligned(const ValueDecl *D, const Expr *NewDE); 451 /// If 'nontemporal' declaration for given variable \a D was not seen yet, 452 /// add it and return NULL; otherwise return previous occurrence's expression 453 /// for diagnostics. 454 const Expr *addUniqueNontemporal(const ValueDecl *D, const Expr *NewDE); 455 456 /// Register specified variable as loop control variable. 457 void addLoopControlVariable(const ValueDecl *D, VarDecl *Capture); 458 /// Check if the specified variable is a loop control variable for 459 /// current region. 460 /// \return The index of the loop control variable in the list of associated 461 /// for-loops (from outer to inner). 462 const LCDeclInfo isLoopControlVariable(const ValueDecl *D) const; 463 /// Check if the specified variable is a loop control variable for 464 /// parent region. 465 /// \return The index of the loop control variable in the list of associated 466 /// for-loops (from outer to inner). 467 const LCDeclInfo isParentLoopControlVariable(const ValueDecl *D) const; 468 /// Check if the specified variable is a loop control variable for 469 /// current region. 470 /// \return The index of the loop control variable in the list of associated 471 /// for-loops (from outer to inner). 472 const LCDeclInfo isLoopControlVariable(const ValueDecl *D, 473 unsigned Level) const; 474 /// Get the loop control variable for the I-th loop (or nullptr) in 475 /// parent directive. 476 const ValueDecl *getParentLoopControlVariable(unsigned I) const; 477 478 /// Marks the specified decl \p D as used in scan directive. 479 void markDeclAsUsedInScanDirective(ValueDecl *D) { 480 if (SharingMapTy *Stack = getSecondOnStackOrNull()) 481 Stack->UsedInScanDirective.insert(D); 482 } 483 484 /// Checks if the specified declaration was used in the inner scan directive. 485 bool isUsedInScanDirective(ValueDecl *D) const { 486 if (const SharingMapTy *Stack = getTopOfStackOrNull()) 487 return Stack->UsedInScanDirective.count(D) > 0; 488 return false; 489 } 490 491 /// Adds explicit data sharing attribute to the specified declaration. 492 void addDSA(const ValueDecl *D, const Expr *E, OpenMPClauseKind A, 493 DeclRefExpr *PrivateCopy = nullptr, unsigned Modifier = 0); 494 495 /// Adds additional information for the reduction items with the reduction id 496 /// represented as an operator. 497 void addTaskgroupReductionData(const ValueDecl *D, SourceRange SR, 498 BinaryOperatorKind BOK); 499 /// Adds additional information for the reduction items with the reduction id 500 /// represented as reduction identifier. 501 void addTaskgroupReductionData(const ValueDecl *D, SourceRange SR, 502 const Expr *ReductionRef); 503 /// Returns the location and reduction operation from the innermost parent 504 /// region for the given \p D. 505 const DSAVarData 506 getTopMostTaskgroupReductionData(const ValueDecl *D, SourceRange &SR, 507 BinaryOperatorKind &BOK, 508 Expr *&TaskgroupDescriptor) const; 509 /// Returns the location and reduction operation from the innermost parent 510 /// region for the given \p D. 511 const DSAVarData 512 getTopMostTaskgroupReductionData(const ValueDecl *D, SourceRange &SR, 513 const Expr *&ReductionRef, 514 Expr *&TaskgroupDescriptor) const; 515 /// Return reduction reference expression for the current taskgroup. 516 Expr *getTaskgroupReductionRef() const { 517 assert(getTopOfStack().Directive == OMPD_taskgroup && 518 "taskgroup reference expression requested for non taskgroup " 519 "directive."); 520 return getTopOfStack().TaskgroupReductionRef; 521 } 522 /// Checks if the given \p VD declaration is actually a taskgroup reduction 523 /// descriptor variable at the \p Level of OpenMP regions. 524 bool isTaskgroupReductionRef(const ValueDecl *VD, unsigned Level) const { 525 return getStackElemAtLevel(Level).TaskgroupReductionRef && 526 cast<DeclRefExpr>(getStackElemAtLevel(Level).TaskgroupReductionRef) 527 ->getDecl() == VD; 528 } 529 530 /// Returns data sharing attributes from top of the stack for the 531 /// specified declaration. 532 const DSAVarData getTopDSA(ValueDecl *D, bool FromParent); 533 /// Returns data-sharing attributes for the specified declaration. 534 const DSAVarData getImplicitDSA(ValueDecl *D, bool FromParent) const; 535 /// Returns data-sharing attributes for the specified declaration. 536 const DSAVarData getImplicitDSA(ValueDecl *D, unsigned Level) const; 537 /// Checks if the specified variables has data-sharing attributes which 538 /// match specified \a CPred predicate in any directive which matches \a DPred 539 /// predicate. 540 const DSAVarData 541 hasDSA(ValueDecl *D, const llvm::function_ref<bool(OpenMPClauseKind)> CPred, 542 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred, 543 bool FromParent) const; 544 /// Checks if the specified variables has data-sharing attributes which 545 /// match specified \a CPred predicate in any innermost directive which 546 /// matches \a DPred predicate. 547 const DSAVarData 548 hasInnermostDSA(ValueDecl *D, 549 const llvm::function_ref<bool(OpenMPClauseKind)> CPred, 550 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred, 551 bool FromParent) const; 552 /// Checks if the specified variables has explicit data-sharing 553 /// attributes which match specified \a CPred predicate at the specified 554 /// OpenMP region. 555 bool hasExplicitDSA(const ValueDecl *D, 556 const llvm::function_ref<bool(OpenMPClauseKind)> CPred, 557 unsigned Level, bool NotLastprivate = false) const; 558 559 /// Returns true if the directive at level \Level matches in the 560 /// specified \a DPred predicate. 561 bool hasExplicitDirective( 562 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred, 563 unsigned Level) const; 564 565 /// Finds a directive which matches specified \a DPred predicate. 566 bool hasDirective( 567 const llvm::function_ref<bool( 568 OpenMPDirectiveKind, const DeclarationNameInfo &, SourceLocation)> 569 DPred, 570 bool FromParent) const; 571 572 /// Returns currently analyzed directive. 573 OpenMPDirectiveKind getCurrentDirective() const { 574 const SharingMapTy *Top = getTopOfStackOrNull(); 575 return Top ? Top->Directive : OMPD_unknown; 576 } 577 /// Returns directive kind at specified level. 578 OpenMPDirectiveKind getDirective(unsigned Level) const { 579 assert(!isStackEmpty() && "No directive at specified level."); 580 return getStackElemAtLevel(Level).Directive; 581 } 582 /// Returns the capture region at the specified level. 583 OpenMPDirectiveKind getCaptureRegion(unsigned Level, 584 unsigned OpenMPCaptureLevel) const { 585 SmallVector<OpenMPDirectiveKind, 4> CaptureRegions; 586 getOpenMPCaptureRegions(CaptureRegions, getDirective(Level)); 587 return CaptureRegions[OpenMPCaptureLevel]; 588 } 589 /// Returns parent directive. 590 OpenMPDirectiveKind getParentDirective() const { 591 const SharingMapTy *Parent = getSecondOnStackOrNull(); 592 return Parent ? Parent->Directive : OMPD_unknown; 593 } 594 595 /// Add requires decl to internal vector 596 void addRequiresDecl(OMPRequiresDecl *RD) { 597 RequiresDecls.push_back(RD); 598 } 599 600 /// Checks if the defined 'requires' directive has specified type of clause. 601 template <typename ClauseType> 602 bool hasRequiresDeclWithClause() const { 603 return llvm::any_of(RequiresDecls, [](const OMPRequiresDecl *D) { 604 return llvm::any_of(D->clauselists(), [](const OMPClause *C) { 605 return isa<ClauseType>(C); 606 }); 607 }); 608 } 609 610 /// Checks for a duplicate clause amongst previously declared requires 611 /// directives 612 bool hasDuplicateRequiresClause(ArrayRef<OMPClause *> ClauseList) const { 613 bool IsDuplicate = false; 614 for (OMPClause *CNew : ClauseList) { 615 for (const OMPRequiresDecl *D : RequiresDecls) { 616 for (const OMPClause *CPrev : D->clauselists()) { 617 if (CNew->getClauseKind() == CPrev->getClauseKind()) { 618 SemaRef.Diag(CNew->getBeginLoc(), 619 diag::err_omp_requires_clause_redeclaration) 620 << getOpenMPClauseName(CNew->getClauseKind()); 621 SemaRef.Diag(CPrev->getBeginLoc(), 622 diag::note_omp_requires_previous_clause) 623 << getOpenMPClauseName(CPrev->getClauseKind()); 624 IsDuplicate = true; 625 } 626 } 627 } 628 } 629 return IsDuplicate; 630 } 631 632 /// Add location of previously encountered target to internal vector 633 void addTargetDirLocation(SourceLocation LocStart) { 634 TargetLocations.push_back(LocStart); 635 } 636 637 /// Add location for the first encountered atomicc directive. 638 void addAtomicDirectiveLoc(SourceLocation Loc) { 639 if (AtomicLocation.isInvalid()) 640 AtomicLocation = Loc; 641 } 642 643 /// Returns the location of the first encountered atomic directive in the 644 /// module. 645 SourceLocation getAtomicDirectiveLoc() const { 646 return AtomicLocation; 647 } 648 649 // Return previously encountered target region locations. 650 ArrayRef<SourceLocation> getEncounteredTargetLocs() const { 651 return TargetLocations; 652 } 653 654 /// Set default data sharing attribute to none. 655 void setDefaultDSANone(SourceLocation Loc) { 656 getTopOfStack().DefaultAttr = DSA_none; 657 getTopOfStack().DefaultAttrLoc = Loc; 658 } 659 /// Set default data sharing attribute to shared. 660 void setDefaultDSAShared(SourceLocation Loc) { 661 getTopOfStack().DefaultAttr = DSA_shared; 662 getTopOfStack().DefaultAttrLoc = Loc; 663 } 664 /// Set default data mapping attribute to Modifier:Kind 665 void setDefaultDMAAttr(OpenMPDefaultmapClauseModifier M, 666 OpenMPDefaultmapClauseKind Kind, 667 SourceLocation Loc) { 668 DefaultmapInfo &DMI = getTopOfStack().DefaultmapMap[Kind]; 669 DMI.ImplicitBehavior = M; 670 DMI.SLoc = Loc; 671 } 672 /// Check whether the implicit-behavior has been set in defaultmap 673 bool checkDefaultmapCategory(OpenMPDefaultmapClauseKind VariableCategory) { 674 return getTopOfStack().DefaultmapMap[VariableCategory].ImplicitBehavior != 675 OMPC_DEFAULTMAP_MODIFIER_unknown; 676 } 677 678 DefaultDataSharingAttributes getDefaultDSA(unsigned Level) const { 679 return getStackSize() <= Level ? DSA_unspecified 680 : getStackElemAtLevel(Level).DefaultAttr; 681 } 682 DefaultDataSharingAttributes getDefaultDSA() const { 683 return isStackEmpty() ? DSA_unspecified 684 : getTopOfStack().DefaultAttr; 685 } 686 SourceLocation getDefaultDSALocation() const { 687 return isStackEmpty() ? SourceLocation() 688 : getTopOfStack().DefaultAttrLoc; 689 } 690 OpenMPDefaultmapClauseModifier 691 getDefaultmapModifier(OpenMPDefaultmapClauseKind Kind) const { 692 return isStackEmpty() 693 ? OMPC_DEFAULTMAP_MODIFIER_unknown 694 : getTopOfStack().DefaultmapMap[Kind].ImplicitBehavior; 695 } 696 OpenMPDefaultmapClauseModifier 697 getDefaultmapModifierAtLevel(unsigned Level, 698 OpenMPDefaultmapClauseKind Kind) const { 699 return getStackElemAtLevel(Level).DefaultmapMap[Kind].ImplicitBehavior; 700 } 701 bool isDefaultmapCapturedByRef(unsigned Level, 702 OpenMPDefaultmapClauseKind Kind) const { 703 OpenMPDefaultmapClauseModifier M = 704 getDefaultmapModifierAtLevel(Level, Kind); 705 if (Kind == OMPC_DEFAULTMAP_scalar || Kind == OMPC_DEFAULTMAP_pointer) { 706 return (M == OMPC_DEFAULTMAP_MODIFIER_alloc) || 707 (M == OMPC_DEFAULTMAP_MODIFIER_to) || 708 (M == OMPC_DEFAULTMAP_MODIFIER_from) || 709 (M == OMPC_DEFAULTMAP_MODIFIER_tofrom); 710 } 711 return true; 712 } 713 static bool mustBeFirstprivateBase(OpenMPDefaultmapClauseModifier M, 714 OpenMPDefaultmapClauseKind Kind) { 715 switch (Kind) { 716 case OMPC_DEFAULTMAP_scalar: 717 case OMPC_DEFAULTMAP_pointer: 718 return (M == OMPC_DEFAULTMAP_MODIFIER_unknown) || 719 (M == OMPC_DEFAULTMAP_MODIFIER_firstprivate) || 720 (M == OMPC_DEFAULTMAP_MODIFIER_default); 721 case OMPC_DEFAULTMAP_aggregate: 722 return M == OMPC_DEFAULTMAP_MODIFIER_firstprivate; 723 default: 724 break; 725 } 726 llvm_unreachable("Unexpected OpenMPDefaultmapClauseKind enum"); 727 } 728 bool mustBeFirstprivateAtLevel(unsigned Level, 729 OpenMPDefaultmapClauseKind Kind) const { 730 OpenMPDefaultmapClauseModifier M = 731 getDefaultmapModifierAtLevel(Level, Kind); 732 return mustBeFirstprivateBase(M, Kind); 733 } 734 bool mustBeFirstprivate(OpenMPDefaultmapClauseKind Kind) const { 735 OpenMPDefaultmapClauseModifier M = getDefaultmapModifier(Kind); 736 return mustBeFirstprivateBase(M, Kind); 737 } 738 739 /// Checks if the specified variable is a threadprivate. 740 bool isThreadPrivate(VarDecl *D) { 741 const DSAVarData DVar = getTopDSA(D, false); 742 return isOpenMPThreadPrivate(DVar.CKind); 743 } 744 745 /// Marks current region as ordered (it has an 'ordered' clause). 746 void setOrderedRegion(bool IsOrdered, const Expr *Param, 747 OMPOrderedClause *Clause) { 748 if (IsOrdered) 749 getTopOfStack().OrderedRegion.emplace(Param, Clause); 750 else 751 getTopOfStack().OrderedRegion.reset(); 752 } 753 /// Returns true, if region is ordered (has associated 'ordered' clause), 754 /// false - otherwise. 755 bool isOrderedRegion() const { 756 if (const SharingMapTy *Top = getTopOfStackOrNull()) 757 return Top->OrderedRegion.hasValue(); 758 return false; 759 } 760 /// Returns optional parameter for the ordered region. 761 std::pair<const Expr *, OMPOrderedClause *> getOrderedRegionParam() const { 762 if (const SharingMapTy *Top = getTopOfStackOrNull()) 763 if (Top->OrderedRegion.hasValue()) 764 return Top->OrderedRegion.getValue(); 765 return std::make_pair(nullptr, nullptr); 766 } 767 /// Returns true, if parent region is ordered (has associated 768 /// 'ordered' clause), false - otherwise. 769 bool isParentOrderedRegion() const { 770 if (const SharingMapTy *Parent = getSecondOnStackOrNull()) 771 return Parent->OrderedRegion.hasValue(); 772 return false; 773 } 774 /// Returns optional parameter for the ordered region. 775 std::pair<const Expr *, OMPOrderedClause *> 776 getParentOrderedRegionParam() const { 777 if (const SharingMapTy *Parent = getSecondOnStackOrNull()) 778 if (Parent->OrderedRegion.hasValue()) 779 return Parent->OrderedRegion.getValue(); 780 return std::make_pair(nullptr, nullptr); 781 } 782 /// Marks current region as nowait (it has a 'nowait' clause). 783 void setNowaitRegion(bool IsNowait = true) { 784 getTopOfStack().NowaitRegion = IsNowait; 785 } 786 /// Returns true, if parent region is nowait (has associated 787 /// 'nowait' clause), false - otherwise. 788 bool isParentNowaitRegion() const { 789 if (const SharingMapTy *Parent = getSecondOnStackOrNull()) 790 return Parent->NowaitRegion; 791 return false; 792 } 793 /// Marks parent region as cancel region. 794 void setParentCancelRegion(bool Cancel = true) { 795 if (SharingMapTy *Parent = getSecondOnStackOrNull()) 796 Parent->CancelRegion |= Cancel; 797 } 798 /// Return true if current region has inner cancel construct. 799 bool isCancelRegion() const { 800 const SharingMapTy *Top = getTopOfStackOrNull(); 801 return Top ? Top->CancelRegion : false; 802 } 803 804 /// Mark that parent region already has scan directive. 805 void setParentHasScanDirective(SourceLocation Loc) { 806 if (SharingMapTy *Parent = getSecondOnStackOrNull()) 807 Parent->PrevScanLocation = Loc; 808 } 809 /// Return true if current region has inner cancel construct. 810 bool doesParentHasScanDirective() const { 811 const SharingMapTy *Top = getSecondOnStackOrNull(); 812 return Top ? Top->PrevScanLocation.isValid() : false; 813 } 814 /// Return true if current region has inner cancel construct. 815 SourceLocation getParentScanDirectiveLoc() const { 816 const SharingMapTy *Top = getSecondOnStackOrNull(); 817 return Top ? Top->PrevScanLocation : SourceLocation(); 818 } 819 820 /// Set collapse value for the region. 821 void setAssociatedLoops(unsigned Val) { 822 getTopOfStack().AssociatedLoops = Val; 823 if (Val > 1) 824 getTopOfStack().HasMutipleLoops = true; 825 } 826 /// Return collapse value for region. 827 unsigned getAssociatedLoops() const { 828 const SharingMapTy *Top = getTopOfStackOrNull(); 829 return Top ? Top->AssociatedLoops : 0; 830 } 831 /// Returns true if the construct is associated with multiple loops. 832 bool hasMutipleLoops() const { 833 const SharingMapTy *Top = getTopOfStackOrNull(); 834 return Top ? Top->HasMutipleLoops : false; 835 } 836 837 /// Marks current target region as one with closely nested teams 838 /// region. 839 void setParentTeamsRegionLoc(SourceLocation TeamsRegionLoc) { 840 if (SharingMapTy *Parent = getSecondOnStackOrNull()) 841 Parent->InnerTeamsRegionLoc = TeamsRegionLoc; 842 } 843 /// Returns true, if current region has closely nested teams region. 844 bool hasInnerTeamsRegion() const { 845 return getInnerTeamsRegionLoc().isValid(); 846 } 847 /// Returns location of the nested teams region (if any). 848 SourceLocation getInnerTeamsRegionLoc() const { 849 const SharingMapTy *Top = getTopOfStackOrNull(); 850 return Top ? Top->InnerTeamsRegionLoc : SourceLocation(); 851 } 852 853 Scope *getCurScope() const { 854 const SharingMapTy *Top = getTopOfStackOrNull(); 855 return Top ? Top->CurScope : nullptr; 856 } 857 SourceLocation getConstructLoc() const { 858 const SharingMapTy *Top = getTopOfStackOrNull(); 859 return Top ? Top->ConstructLoc : SourceLocation(); 860 } 861 862 /// Do the check specified in \a Check to all component lists and return true 863 /// if any issue is found. 864 bool checkMappableExprComponentListsForDecl( 865 const ValueDecl *VD, bool CurrentRegionOnly, 866 const llvm::function_ref< 867 bool(OMPClauseMappableExprCommon::MappableExprComponentListRef, 868 OpenMPClauseKind)> 869 Check) const { 870 if (isStackEmpty()) 871 return false; 872 auto SI = begin(); 873 auto SE = end(); 874 875 if (SI == SE) 876 return false; 877 878 if (CurrentRegionOnly) 879 SE = std::next(SI); 880 else 881 std::advance(SI, 1); 882 883 for (; SI != SE; ++SI) { 884 auto MI = SI->MappedExprComponents.find(VD); 885 if (MI != SI->MappedExprComponents.end()) 886 for (OMPClauseMappableExprCommon::MappableExprComponentListRef L : 887 MI->second.Components) 888 if (Check(L, MI->second.Kind)) 889 return true; 890 } 891 return false; 892 } 893 894 /// Do the check specified in \a Check to all component lists at a given level 895 /// and return true if any issue is found. 896 bool checkMappableExprComponentListsForDeclAtLevel( 897 const ValueDecl *VD, unsigned Level, 898 const llvm::function_ref< 899 bool(OMPClauseMappableExprCommon::MappableExprComponentListRef, 900 OpenMPClauseKind)> 901 Check) const { 902 if (getStackSize() <= Level) 903 return false; 904 905 const SharingMapTy &StackElem = getStackElemAtLevel(Level); 906 auto MI = StackElem.MappedExprComponents.find(VD); 907 if (MI != StackElem.MappedExprComponents.end()) 908 for (OMPClauseMappableExprCommon::MappableExprComponentListRef L : 909 MI->second.Components) 910 if (Check(L, MI->second.Kind)) 911 return true; 912 return false; 913 } 914 915 /// Create a new mappable expression component list associated with a given 916 /// declaration and initialize it with the provided list of components. 917 void addMappableExpressionComponents( 918 const ValueDecl *VD, 919 OMPClauseMappableExprCommon::MappableExprComponentListRef Components, 920 OpenMPClauseKind WhereFoundClauseKind) { 921 MappedExprComponentTy &MEC = getTopOfStack().MappedExprComponents[VD]; 922 // Create new entry and append the new components there. 923 MEC.Components.resize(MEC.Components.size() + 1); 924 MEC.Components.back().append(Components.begin(), Components.end()); 925 MEC.Kind = WhereFoundClauseKind; 926 } 927 928 unsigned getNestingLevel() const { 929 assert(!isStackEmpty()); 930 return getStackSize() - 1; 931 } 932 void addDoacrossDependClause(OMPDependClause *C, 933 const OperatorOffsetTy &OpsOffs) { 934 SharingMapTy *Parent = getSecondOnStackOrNull(); 935 assert(Parent && isOpenMPWorksharingDirective(Parent->Directive)); 936 Parent->DoacrossDepends.try_emplace(C, OpsOffs); 937 } 938 llvm::iterator_range<DoacrossDependMapTy::const_iterator> 939 getDoacrossDependClauses() const { 940 const SharingMapTy &StackElem = getTopOfStack(); 941 if (isOpenMPWorksharingDirective(StackElem.Directive)) { 942 const DoacrossDependMapTy &Ref = StackElem.DoacrossDepends; 943 return llvm::make_range(Ref.begin(), Ref.end()); 944 } 945 return llvm::make_range(StackElem.DoacrossDepends.end(), 946 StackElem.DoacrossDepends.end()); 947 } 948 949 // Store types of classes which have been explicitly mapped 950 void addMappedClassesQualTypes(QualType QT) { 951 SharingMapTy &StackElem = getTopOfStack(); 952 StackElem.MappedClassesQualTypes.insert(QT); 953 } 954 955 // Return set of mapped classes types 956 bool isClassPreviouslyMapped(QualType QT) const { 957 const SharingMapTy &StackElem = getTopOfStack(); 958 return StackElem.MappedClassesQualTypes.count(QT) != 0; 959 } 960 961 /// Adds global declare target to the parent target region. 962 void addToParentTargetRegionLinkGlobals(DeclRefExpr *E) { 963 assert(*OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration( 964 E->getDecl()) == OMPDeclareTargetDeclAttr::MT_Link && 965 "Expected declare target link global."); 966 for (auto &Elem : *this) { 967 if (isOpenMPTargetExecutionDirective(Elem.Directive)) { 968 Elem.DeclareTargetLinkVarDecls.push_back(E); 969 return; 970 } 971 } 972 } 973 974 /// Returns the list of globals with declare target link if current directive 975 /// is target. 976 ArrayRef<DeclRefExpr *> getLinkGlobals() const { 977 assert(isOpenMPTargetExecutionDirective(getCurrentDirective()) && 978 "Expected target executable directive."); 979 return getTopOfStack().DeclareTargetLinkVarDecls; 980 } 981 982 /// Adds list of allocators expressions. 983 void addInnerAllocatorExpr(Expr *E) { 984 getTopOfStack().InnerUsedAllocators.push_back(E); 985 } 986 /// Return list of used allocators. 987 ArrayRef<Expr *> getInnerAllocators() const { 988 return getTopOfStack().InnerUsedAllocators; 989 } 990 /// Marks the declaration as implicitly firstprivate nin the task-based 991 /// regions. 992 void addImplicitTaskFirstprivate(unsigned Level, Decl *D) { 993 getStackElemAtLevel(Level).ImplicitTaskFirstprivates.insert(D); 994 } 995 /// Checks if the decl is implicitly firstprivate in the task-based region. 996 bool isImplicitTaskFirstprivate(Decl *D) const { 997 return getTopOfStack().ImplicitTaskFirstprivates.count(D) > 0; 998 } 999 }; 1000 1001 bool isImplicitTaskingRegion(OpenMPDirectiveKind DKind) { 1002 return isOpenMPParallelDirective(DKind) || isOpenMPTeamsDirective(DKind); 1003 } 1004 1005 bool isImplicitOrExplicitTaskingRegion(OpenMPDirectiveKind DKind) { 1006 return isImplicitTaskingRegion(DKind) || isOpenMPTaskingDirective(DKind) || 1007 DKind == OMPD_unknown; 1008 } 1009 1010 } // namespace 1011 1012 static const Expr *getExprAsWritten(const Expr *E) { 1013 if (const auto *FE = dyn_cast<FullExpr>(E)) 1014 E = FE->getSubExpr(); 1015 1016 if (const auto *MTE = dyn_cast<MaterializeTemporaryExpr>(E)) 1017 E = MTE->getSubExpr(); 1018 1019 while (const auto *Binder = dyn_cast<CXXBindTemporaryExpr>(E)) 1020 E = Binder->getSubExpr(); 1021 1022 if (const auto *ICE = dyn_cast<ImplicitCastExpr>(E)) 1023 E = ICE->getSubExprAsWritten(); 1024 return E->IgnoreParens(); 1025 } 1026 1027 static Expr *getExprAsWritten(Expr *E) { 1028 return const_cast<Expr *>(getExprAsWritten(const_cast<const Expr *>(E))); 1029 } 1030 1031 static const ValueDecl *getCanonicalDecl(const ValueDecl *D) { 1032 if (const auto *CED = dyn_cast<OMPCapturedExprDecl>(D)) 1033 if (const auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit()))) 1034 D = ME->getMemberDecl(); 1035 const auto *VD = dyn_cast<VarDecl>(D); 1036 const auto *FD = dyn_cast<FieldDecl>(D); 1037 if (VD != nullptr) { 1038 VD = VD->getCanonicalDecl(); 1039 D = VD; 1040 } else { 1041 assert(FD); 1042 FD = FD->getCanonicalDecl(); 1043 D = FD; 1044 } 1045 return D; 1046 } 1047 1048 static ValueDecl *getCanonicalDecl(ValueDecl *D) { 1049 return const_cast<ValueDecl *>( 1050 getCanonicalDecl(const_cast<const ValueDecl *>(D))); 1051 } 1052 1053 DSAStackTy::DSAVarData DSAStackTy::getDSA(const_iterator &Iter, 1054 ValueDecl *D) const { 1055 D = getCanonicalDecl(D); 1056 auto *VD = dyn_cast<VarDecl>(D); 1057 const auto *FD = dyn_cast<FieldDecl>(D); 1058 DSAVarData DVar; 1059 if (Iter == end()) { 1060 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 1061 // in a region but not in construct] 1062 // File-scope or namespace-scope variables referenced in called routines 1063 // in the region are shared unless they appear in a threadprivate 1064 // directive. 1065 if (VD && !VD->isFunctionOrMethodVarDecl() && !isa<ParmVarDecl>(VD)) 1066 DVar.CKind = OMPC_shared; 1067 1068 // OpenMP [2.9.1.2, Data-sharing Attribute Rules for Variables Referenced 1069 // in a region but not in construct] 1070 // Variables with static storage duration that are declared in called 1071 // routines in the region are shared. 1072 if (VD && VD->hasGlobalStorage()) 1073 DVar.CKind = OMPC_shared; 1074 1075 // Non-static data members are shared by default. 1076 if (FD) 1077 DVar.CKind = OMPC_shared; 1078 1079 return DVar; 1080 } 1081 1082 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 1083 // in a Construct, C/C++, predetermined, p.1] 1084 // Variables with automatic storage duration that are declared in a scope 1085 // inside the construct are private. 1086 if (VD && isOpenMPLocal(VD, Iter) && VD->isLocalVarDecl() && 1087 (VD->getStorageClass() == SC_Auto || VD->getStorageClass() == SC_None)) { 1088 DVar.CKind = OMPC_private; 1089 return DVar; 1090 } 1091 1092 DVar.DKind = Iter->Directive; 1093 // Explicitly specified attributes and local variables with predetermined 1094 // attributes. 1095 if (Iter->SharingMap.count(D)) { 1096 const DSAInfo &Data = Iter->SharingMap.lookup(D); 1097 DVar.RefExpr = Data.RefExpr.getPointer(); 1098 DVar.PrivateCopy = Data.PrivateCopy; 1099 DVar.CKind = Data.Attributes; 1100 DVar.ImplicitDSALoc = Iter->DefaultAttrLoc; 1101 DVar.Modifier = Data.Modifier; 1102 return DVar; 1103 } 1104 1105 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 1106 // in a Construct, C/C++, implicitly determined, p.1] 1107 // In a parallel or task construct, the data-sharing attributes of these 1108 // variables are determined by the default clause, if present. 1109 switch (Iter->DefaultAttr) { 1110 case DSA_shared: 1111 DVar.CKind = OMPC_shared; 1112 DVar.ImplicitDSALoc = Iter->DefaultAttrLoc; 1113 return DVar; 1114 case DSA_none: 1115 return DVar; 1116 case DSA_unspecified: 1117 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 1118 // in a Construct, implicitly determined, p.2] 1119 // In a parallel construct, if no default clause is present, these 1120 // variables are shared. 1121 DVar.ImplicitDSALoc = Iter->DefaultAttrLoc; 1122 if ((isOpenMPParallelDirective(DVar.DKind) && 1123 !isOpenMPTaskLoopDirective(DVar.DKind)) || 1124 isOpenMPTeamsDirective(DVar.DKind)) { 1125 DVar.CKind = OMPC_shared; 1126 return DVar; 1127 } 1128 1129 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 1130 // in a Construct, implicitly determined, p.4] 1131 // In a task construct, if no default clause is present, a variable that in 1132 // the enclosing context is determined to be shared by all implicit tasks 1133 // bound to the current team is shared. 1134 if (isOpenMPTaskingDirective(DVar.DKind)) { 1135 DSAVarData DVarTemp; 1136 const_iterator I = Iter, E = end(); 1137 do { 1138 ++I; 1139 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables 1140 // Referenced in a Construct, implicitly determined, p.6] 1141 // In a task construct, if no default clause is present, a variable 1142 // whose data-sharing attribute is not determined by the rules above is 1143 // firstprivate. 1144 DVarTemp = getDSA(I, D); 1145 if (DVarTemp.CKind != OMPC_shared) { 1146 DVar.RefExpr = nullptr; 1147 DVar.CKind = OMPC_firstprivate; 1148 return DVar; 1149 } 1150 } while (I != E && !isImplicitTaskingRegion(I->Directive)); 1151 DVar.CKind = 1152 (DVarTemp.CKind == OMPC_unknown) ? OMPC_firstprivate : OMPC_shared; 1153 return DVar; 1154 } 1155 } 1156 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 1157 // in a Construct, implicitly determined, p.3] 1158 // For constructs other than task, if no default clause is present, these 1159 // variables inherit their data-sharing attributes from the enclosing 1160 // context. 1161 return getDSA(++Iter, D); 1162 } 1163 1164 const Expr *DSAStackTy::addUniqueAligned(const ValueDecl *D, 1165 const Expr *NewDE) { 1166 assert(!isStackEmpty() && "Data sharing attributes stack is empty"); 1167 D = getCanonicalDecl(D); 1168 SharingMapTy &StackElem = getTopOfStack(); 1169 auto It = StackElem.AlignedMap.find(D); 1170 if (It == StackElem.AlignedMap.end()) { 1171 assert(NewDE && "Unexpected nullptr expr to be added into aligned map"); 1172 StackElem.AlignedMap[D] = NewDE; 1173 return nullptr; 1174 } 1175 assert(It->second && "Unexpected nullptr expr in the aligned map"); 1176 return It->second; 1177 } 1178 1179 const Expr *DSAStackTy::addUniqueNontemporal(const ValueDecl *D, 1180 const Expr *NewDE) { 1181 assert(!isStackEmpty() && "Data sharing attributes stack is empty"); 1182 D = getCanonicalDecl(D); 1183 SharingMapTy &StackElem = getTopOfStack(); 1184 auto It = StackElem.NontemporalMap.find(D); 1185 if (It == StackElem.NontemporalMap.end()) { 1186 assert(NewDE && "Unexpected nullptr expr to be added into aligned map"); 1187 StackElem.NontemporalMap[D] = NewDE; 1188 return nullptr; 1189 } 1190 assert(It->second && "Unexpected nullptr expr in the aligned map"); 1191 return It->second; 1192 } 1193 1194 void DSAStackTy::addLoopControlVariable(const ValueDecl *D, VarDecl *Capture) { 1195 assert(!isStackEmpty() && "Data-sharing attributes stack is empty"); 1196 D = getCanonicalDecl(D); 1197 SharingMapTy &StackElem = getTopOfStack(); 1198 StackElem.LCVMap.try_emplace( 1199 D, LCDeclInfo(StackElem.LCVMap.size() + 1, Capture)); 1200 } 1201 1202 const DSAStackTy::LCDeclInfo 1203 DSAStackTy::isLoopControlVariable(const ValueDecl *D) const { 1204 assert(!isStackEmpty() && "Data-sharing attributes stack is empty"); 1205 D = getCanonicalDecl(D); 1206 const SharingMapTy &StackElem = getTopOfStack(); 1207 auto It = StackElem.LCVMap.find(D); 1208 if (It != StackElem.LCVMap.end()) 1209 return It->second; 1210 return {0, nullptr}; 1211 } 1212 1213 const DSAStackTy::LCDeclInfo 1214 DSAStackTy::isLoopControlVariable(const ValueDecl *D, unsigned Level) const { 1215 assert(!isStackEmpty() && "Data-sharing attributes stack is empty"); 1216 D = getCanonicalDecl(D); 1217 for (unsigned I = Level + 1; I > 0; --I) { 1218 const SharingMapTy &StackElem = getStackElemAtLevel(I - 1); 1219 auto It = StackElem.LCVMap.find(D); 1220 if (It != StackElem.LCVMap.end()) 1221 return It->second; 1222 } 1223 return {0, nullptr}; 1224 } 1225 1226 const DSAStackTy::LCDeclInfo 1227 DSAStackTy::isParentLoopControlVariable(const ValueDecl *D) const { 1228 const SharingMapTy *Parent = getSecondOnStackOrNull(); 1229 assert(Parent && "Data-sharing attributes stack is empty"); 1230 D = getCanonicalDecl(D); 1231 auto It = Parent->LCVMap.find(D); 1232 if (It != Parent->LCVMap.end()) 1233 return It->second; 1234 return {0, nullptr}; 1235 } 1236 1237 const ValueDecl *DSAStackTy::getParentLoopControlVariable(unsigned I) const { 1238 const SharingMapTy *Parent = getSecondOnStackOrNull(); 1239 assert(Parent && "Data-sharing attributes stack is empty"); 1240 if (Parent->LCVMap.size() < I) 1241 return nullptr; 1242 for (const auto &Pair : Parent->LCVMap) 1243 if (Pair.second.first == I) 1244 return Pair.first; 1245 return nullptr; 1246 } 1247 1248 void DSAStackTy::addDSA(const ValueDecl *D, const Expr *E, OpenMPClauseKind A, 1249 DeclRefExpr *PrivateCopy, unsigned Modifier) { 1250 D = getCanonicalDecl(D); 1251 if (A == OMPC_threadprivate) { 1252 DSAInfo &Data = Threadprivates[D]; 1253 Data.Attributes = A; 1254 Data.RefExpr.setPointer(E); 1255 Data.PrivateCopy = nullptr; 1256 Data.Modifier = Modifier; 1257 } else { 1258 DSAInfo &Data = getTopOfStack().SharingMap[D]; 1259 assert(Data.Attributes == OMPC_unknown || (A == Data.Attributes) || 1260 (A == OMPC_firstprivate && Data.Attributes == OMPC_lastprivate) || 1261 (A == OMPC_lastprivate && Data.Attributes == OMPC_firstprivate) || 1262 (isLoopControlVariable(D).first && A == OMPC_private)); 1263 Data.Modifier = Modifier; 1264 if (A == OMPC_lastprivate && Data.Attributes == OMPC_firstprivate) { 1265 Data.RefExpr.setInt(/*IntVal=*/true); 1266 return; 1267 } 1268 const bool IsLastprivate = 1269 A == OMPC_lastprivate || Data.Attributes == OMPC_lastprivate; 1270 Data.Attributes = A; 1271 Data.RefExpr.setPointerAndInt(E, IsLastprivate); 1272 Data.PrivateCopy = PrivateCopy; 1273 if (PrivateCopy) { 1274 DSAInfo &Data = getTopOfStack().SharingMap[PrivateCopy->getDecl()]; 1275 Data.Modifier = Modifier; 1276 Data.Attributes = A; 1277 Data.RefExpr.setPointerAndInt(PrivateCopy, IsLastprivate); 1278 Data.PrivateCopy = nullptr; 1279 } 1280 } 1281 } 1282 1283 /// Build a variable declaration for OpenMP loop iteration variable. 1284 static VarDecl *buildVarDecl(Sema &SemaRef, SourceLocation Loc, QualType Type, 1285 StringRef Name, const AttrVec *Attrs = nullptr, 1286 DeclRefExpr *OrigRef = nullptr) { 1287 DeclContext *DC = SemaRef.CurContext; 1288 IdentifierInfo *II = &SemaRef.PP.getIdentifierTable().get(Name); 1289 TypeSourceInfo *TInfo = SemaRef.Context.getTrivialTypeSourceInfo(Type, Loc); 1290 auto *Decl = 1291 VarDecl::Create(SemaRef.Context, DC, Loc, Loc, II, Type, TInfo, SC_None); 1292 if (Attrs) { 1293 for (specific_attr_iterator<AlignedAttr> I(Attrs->begin()), E(Attrs->end()); 1294 I != E; ++I) 1295 Decl->addAttr(*I); 1296 } 1297 Decl->setImplicit(); 1298 if (OrigRef) { 1299 Decl->addAttr( 1300 OMPReferencedVarAttr::CreateImplicit(SemaRef.Context, OrigRef)); 1301 } 1302 return Decl; 1303 } 1304 1305 static DeclRefExpr *buildDeclRefExpr(Sema &S, VarDecl *D, QualType Ty, 1306 SourceLocation Loc, 1307 bool RefersToCapture = false) { 1308 D->setReferenced(); 1309 D->markUsed(S.Context); 1310 return DeclRefExpr::Create(S.getASTContext(), NestedNameSpecifierLoc(), 1311 SourceLocation(), D, RefersToCapture, Loc, Ty, 1312 VK_LValue); 1313 } 1314 1315 void DSAStackTy::addTaskgroupReductionData(const ValueDecl *D, SourceRange SR, 1316 BinaryOperatorKind BOK) { 1317 D = getCanonicalDecl(D); 1318 assert(!isStackEmpty() && "Data-sharing attributes stack is empty"); 1319 assert( 1320 getTopOfStack().SharingMap[D].Attributes == OMPC_reduction && 1321 "Additional reduction info may be specified only for reduction items."); 1322 ReductionData &ReductionData = getTopOfStack().ReductionMap[D]; 1323 assert(ReductionData.ReductionRange.isInvalid() && 1324 getTopOfStack().Directive == OMPD_taskgroup && 1325 "Additional reduction info may be specified only once for reduction " 1326 "items."); 1327 ReductionData.set(BOK, SR); 1328 Expr *&TaskgroupReductionRef = 1329 getTopOfStack().TaskgroupReductionRef; 1330 if (!TaskgroupReductionRef) { 1331 VarDecl *VD = buildVarDecl(SemaRef, SR.getBegin(), 1332 SemaRef.Context.VoidPtrTy, ".task_red."); 1333 TaskgroupReductionRef = 1334 buildDeclRefExpr(SemaRef, VD, SemaRef.Context.VoidPtrTy, SR.getBegin()); 1335 } 1336 } 1337 1338 void DSAStackTy::addTaskgroupReductionData(const ValueDecl *D, SourceRange SR, 1339 const Expr *ReductionRef) { 1340 D = getCanonicalDecl(D); 1341 assert(!isStackEmpty() && "Data-sharing attributes stack is empty"); 1342 assert( 1343 getTopOfStack().SharingMap[D].Attributes == OMPC_reduction && 1344 "Additional reduction info may be specified only for reduction items."); 1345 ReductionData &ReductionData = getTopOfStack().ReductionMap[D]; 1346 assert(ReductionData.ReductionRange.isInvalid() && 1347 getTopOfStack().Directive == OMPD_taskgroup && 1348 "Additional reduction info may be specified only once for reduction " 1349 "items."); 1350 ReductionData.set(ReductionRef, SR); 1351 Expr *&TaskgroupReductionRef = 1352 getTopOfStack().TaskgroupReductionRef; 1353 if (!TaskgroupReductionRef) { 1354 VarDecl *VD = buildVarDecl(SemaRef, SR.getBegin(), 1355 SemaRef.Context.VoidPtrTy, ".task_red."); 1356 TaskgroupReductionRef = 1357 buildDeclRefExpr(SemaRef, VD, SemaRef.Context.VoidPtrTy, SR.getBegin()); 1358 } 1359 } 1360 1361 const DSAStackTy::DSAVarData DSAStackTy::getTopMostTaskgroupReductionData( 1362 const ValueDecl *D, SourceRange &SR, BinaryOperatorKind &BOK, 1363 Expr *&TaskgroupDescriptor) const { 1364 D = getCanonicalDecl(D); 1365 assert(!isStackEmpty() && "Data-sharing attributes stack is empty."); 1366 for (const_iterator I = begin() + 1, E = end(); I != E; ++I) { 1367 const DSAInfo &Data = I->SharingMap.lookup(D); 1368 if (Data.Attributes != OMPC_reduction || I->Directive != OMPD_taskgroup) 1369 continue; 1370 const ReductionData &ReductionData = I->ReductionMap.lookup(D); 1371 if (!ReductionData.ReductionOp || 1372 ReductionData.ReductionOp.is<const Expr *>()) 1373 return DSAVarData(); 1374 SR = ReductionData.ReductionRange; 1375 BOK = ReductionData.ReductionOp.get<ReductionData::BOKPtrType>(); 1376 assert(I->TaskgroupReductionRef && "taskgroup reduction reference " 1377 "expression for the descriptor is not " 1378 "set."); 1379 TaskgroupDescriptor = I->TaskgroupReductionRef; 1380 return DSAVarData(OMPD_taskgroup, OMPC_reduction, Data.RefExpr.getPointer(), 1381 Data.PrivateCopy, I->DefaultAttrLoc, /*Modifier=*/0); 1382 } 1383 return DSAVarData(); 1384 } 1385 1386 const DSAStackTy::DSAVarData DSAStackTy::getTopMostTaskgroupReductionData( 1387 const ValueDecl *D, SourceRange &SR, const Expr *&ReductionRef, 1388 Expr *&TaskgroupDescriptor) const { 1389 D = getCanonicalDecl(D); 1390 assert(!isStackEmpty() && "Data-sharing attributes stack is empty."); 1391 for (const_iterator I = begin() + 1, E = end(); I != E; ++I) { 1392 const DSAInfo &Data = I->SharingMap.lookup(D); 1393 if (Data.Attributes != OMPC_reduction || I->Directive != OMPD_taskgroup) 1394 continue; 1395 const ReductionData &ReductionData = I->ReductionMap.lookup(D); 1396 if (!ReductionData.ReductionOp || 1397 !ReductionData.ReductionOp.is<const Expr *>()) 1398 return DSAVarData(); 1399 SR = ReductionData.ReductionRange; 1400 ReductionRef = ReductionData.ReductionOp.get<const Expr *>(); 1401 assert(I->TaskgroupReductionRef && "taskgroup reduction reference " 1402 "expression for the descriptor is not " 1403 "set."); 1404 TaskgroupDescriptor = I->TaskgroupReductionRef; 1405 return DSAVarData(OMPD_taskgroup, OMPC_reduction, Data.RefExpr.getPointer(), 1406 Data.PrivateCopy, I->DefaultAttrLoc, /*Modifier=*/0); 1407 } 1408 return DSAVarData(); 1409 } 1410 1411 bool DSAStackTy::isOpenMPLocal(VarDecl *D, const_iterator I) const { 1412 D = D->getCanonicalDecl(); 1413 for (const_iterator E = end(); I != E; ++I) { 1414 if (isImplicitOrExplicitTaskingRegion(I->Directive) || 1415 isOpenMPTargetExecutionDirective(I->Directive)) { 1416 Scope *TopScope = I->CurScope ? I->CurScope->getParent() : nullptr; 1417 Scope *CurScope = getCurScope(); 1418 while (CurScope && CurScope != TopScope && !CurScope->isDeclScope(D)) 1419 CurScope = CurScope->getParent(); 1420 return CurScope != TopScope; 1421 } 1422 } 1423 return false; 1424 } 1425 1426 static bool isConstNotMutableType(Sema &SemaRef, QualType Type, 1427 bool AcceptIfMutable = true, 1428 bool *IsClassType = nullptr) { 1429 ASTContext &Context = SemaRef.getASTContext(); 1430 Type = Type.getNonReferenceType().getCanonicalType(); 1431 bool IsConstant = Type.isConstant(Context); 1432 Type = Context.getBaseElementType(Type); 1433 const CXXRecordDecl *RD = AcceptIfMutable && SemaRef.getLangOpts().CPlusPlus 1434 ? Type->getAsCXXRecordDecl() 1435 : nullptr; 1436 if (const auto *CTSD = dyn_cast_or_null<ClassTemplateSpecializationDecl>(RD)) 1437 if (const ClassTemplateDecl *CTD = CTSD->getSpecializedTemplate()) 1438 RD = CTD->getTemplatedDecl(); 1439 if (IsClassType) 1440 *IsClassType = RD; 1441 return IsConstant && !(SemaRef.getLangOpts().CPlusPlus && RD && 1442 RD->hasDefinition() && RD->hasMutableFields()); 1443 } 1444 1445 static bool rejectConstNotMutableType(Sema &SemaRef, const ValueDecl *D, 1446 QualType Type, OpenMPClauseKind CKind, 1447 SourceLocation ELoc, 1448 bool AcceptIfMutable = true, 1449 bool ListItemNotVar = false) { 1450 ASTContext &Context = SemaRef.getASTContext(); 1451 bool IsClassType; 1452 if (isConstNotMutableType(SemaRef, Type, AcceptIfMutable, &IsClassType)) { 1453 unsigned Diag = ListItemNotVar 1454 ? diag::err_omp_const_list_item 1455 : IsClassType ? diag::err_omp_const_not_mutable_variable 1456 : diag::err_omp_const_variable; 1457 SemaRef.Diag(ELoc, Diag) << getOpenMPClauseName(CKind); 1458 if (!ListItemNotVar && D) { 1459 const VarDecl *VD = dyn_cast<VarDecl>(D); 1460 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) == 1461 VarDecl::DeclarationOnly; 1462 SemaRef.Diag(D->getLocation(), 1463 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 1464 << D; 1465 } 1466 return true; 1467 } 1468 return false; 1469 } 1470 1471 const DSAStackTy::DSAVarData DSAStackTy::getTopDSA(ValueDecl *D, 1472 bool FromParent) { 1473 D = getCanonicalDecl(D); 1474 DSAVarData DVar; 1475 1476 auto *VD = dyn_cast<VarDecl>(D); 1477 auto TI = Threadprivates.find(D); 1478 if (TI != Threadprivates.end()) { 1479 DVar.RefExpr = TI->getSecond().RefExpr.getPointer(); 1480 DVar.CKind = OMPC_threadprivate; 1481 DVar.Modifier = TI->getSecond().Modifier; 1482 return DVar; 1483 } 1484 if (VD && VD->hasAttr<OMPThreadPrivateDeclAttr>()) { 1485 DVar.RefExpr = buildDeclRefExpr( 1486 SemaRef, VD, D->getType().getNonReferenceType(), 1487 VD->getAttr<OMPThreadPrivateDeclAttr>()->getLocation()); 1488 DVar.CKind = OMPC_threadprivate; 1489 addDSA(D, DVar.RefExpr, OMPC_threadprivate); 1490 return DVar; 1491 } 1492 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 1493 // in a Construct, C/C++, predetermined, p.1] 1494 // Variables appearing in threadprivate directives are threadprivate. 1495 if ((VD && VD->getTLSKind() != VarDecl::TLS_None && 1496 !(VD->hasAttr<OMPThreadPrivateDeclAttr>() && 1497 SemaRef.getLangOpts().OpenMPUseTLS && 1498 SemaRef.getASTContext().getTargetInfo().isTLSSupported())) || 1499 (VD && VD->getStorageClass() == SC_Register && 1500 VD->hasAttr<AsmLabelAttr>() && !VD->isLocalVarDecl())) { 1501 DVar.RefExpr = buildDeclRefExpr( 1502 SemaRef, VD, D->getType().getNonReferenceType(), D->getLocation()); 1503 DVar.CKind = OMPC_threadprivate; 1504 addDSA(D, DVar.RefExpr, OMPC_threadprivate); 1505 return DVar; 1506 } 1507 if (SemaRef.getLangOpts().OpenMPCUDAMode && VD && 1508 VD->isLocalVarDeclOrParm() && !isStackEmpty() && 1509 !isLoopControlVariable(D).first) { 1510 const_iterator IterTarget = 1511 std::find_if(begin(), end(), [](const SharingMapTy &Data) { 1512 return isOpenMPTargetExecutionDirective(Data.Directive); 1513 }); 1514 if (IterTarget != end()) { 1515 const_iterator ParentIterTarget = IterTarget + 1; 1516 for (const_iterator Iter = begin(); 1517 Iter != ParentIterTarget; ++Iter) { 1518 if (isOpenMPLocal(VD, Iter)) { 1519 DVar.RefExpr = 1520 buildDeclRefExpr(SemaRef, VD, D->getType().getNonReferenceType(), 1521 D->getLocation()); 1522 DVar.CKind = OMPC_threadprivate; 1523 return DVar; 1524 } 1525 } 1526 if (!isClauseParsingMode() || IterTarget != begin()) { 1527 auto DSAIter = IterTarget->SharingMap.find(D); 1528 if (DSAIter != IterTarget->SharingMap.end() && 1529 isOpenMPPrivate(DSAIter->getSecond().Attributes)) { 1530 DVar.RefExpr = DSAIter->getSecond().RefExpr.getPointer(); 1531 DVar.CKind = OMPC_threadprivate; 1532 return DVar; 1533 } 1534 const_iterator End = end(); 1535 if (!SemaRef.isOpenMPCapturedByRef( 1536 D, std::distance(ParentIterTarget, End), 1537 /*OpenMPCaptureLevel=*/0)) { 1538 DVar.RefExpr = 1539 buildDeclRefExpr(SemaRef, VD, D->getType().getNonReferenceType(), 1540 IterTarget->ConstructLoc); 1541 DVar.CKind = OMPC_threadprivate; 1542 return DVar; 1543 } 1544 } 1545 } 1546 } 1547 1548 if (isStackEmpty()) 1549 // Not in OpenMP execution region and top scope was already checked. 1550 return DVar; 1551 1552 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 1553 // in a Construct, C/C++, predetermined, p.4] 1554 // Static data members are shared. 1555 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 1556 // in a Construct, C/C++, predetermined, p.7] 1557 // Variables with static storage duration that are declared in a scope 1558 // inside the construct are shared. 1559 if (VD && VD->isStaticDataMember()) { 1560 // Check for explicitly specified attributes. 1561 const_iterator I = begin(); 1562 const_iterator EndI = end(); 1563 if (FromParent && I != EndI) 1564 ++I; 1565 if (I != EndI) { 1566 auto It = I->SharingMap.find(D); 1567 if (It != I->SharingMap.end()) { 1568 const DSAInfo &Data = It->getSecond(); 1569 DVar.RefExpr = Data.RefExpr.getPointer(); 1570 DVar.PrivateCopy = Data.PrivateCopy; 1571 DVar.CKind = Data.Attributes; 1572 DVar.ImplicitDSALoc = I->DefaultAttrLoc; 1573 DVar.DKind = I->Directive; 1574 DVar.Modifier = Data.Modifier; 1575 return DVar; 1576 } 1577 } 1578 1579 DVar.CKind = OMPC_shared; 1580 return DVar; 1581 } 1582 1583 auto &&MatchesAlways = [](OpenMPDirectiveKind) { return true; }; 1584 // The predetermined shared attribute for const-qualified types having no 1585 // mutable members was removed after OpenMP 3.1. 1586 if (SemaRef.LangOpts.OpenMP <= 31) { 1587 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 1588 // in a Construct, C/C++, predetermined, p.6] 1589 // Variables with const qualified type having no mutable member are 1590 // shared. 1591 if (isConstNotMutableType(SemaRef, D->getType())) { 1592 // Variables with const-qualified type having no mutable member may be 1593 // listed in a firstprivate clause, even if they are static data members. 1594 DSAVarData DVarTemp = hasInnermostDSA( 1595 D, 1596 [](OpenMPClauseKind C) { 1597 return C == OMPC_firstprivate || C == OMPC_shared; 1598 }, 1599 MatchesAlways, FromParent); 1600 if (DVarTemp.CKind != OMPC_unknown && DVarTemp.RefExpr) 1601 return DVarTemp; 1602 1603 DVar.CKind = OMPC_shared; 1604 return DVar; 1605 } 1606 } 1607 1608 // Explicitly specified attributes and local variables with predetermined 1609 // attributes. 1610 const_iterator I = begin(); 1611 const_iterator EndI = end(); 1612 if (FromParent && I != EndI) 1613 ++I; 1614 if (I == EndI) 1615 return DVar; 1616 auto It = I->SharingMap.find(D); 1617 if (It != I->SharingMap.end()) { 1618 const DSAInfo &Data = It->getSecond(); 1619 DVar.RefExpr = Data.RefExpr.getPointer(); 1620 DVar.PrivateCopy = Data.PrivateCopy; 1621 DVar.CKind = Data.Attributes; 1622 DVar.ImplicitDSALoc = I->DefaultAttrLoc; 1623 DVar.DKind = I->Directive; 1624 DVar.Modifier = Data.Modifier; 1625 } 1626 1627 return DVar; 1628 } 1629 1630 const DSAStackTy::DSAVarData DSAStackTy::getImplicitDSA(ValueDecl *D, 1631 bool FromParent) const { 1632 if (isStackEmpty()) { 1633 const_iterator I; 1634 return getDSA(I, D); 1635 } 1636 D = getCanonicalDecl(D); 1637 const_iterator StartI = begin(); 1638 const_iterator EndI = end(); 1639 if (FromParent && StartI != EndI) 1640 ++StartI; 1641 return getDSA(StartI, D); 1642 } 1643 1644 const DSAStackTy::DSAVarData DSAStackTy::getImplicitDSA(ValueDecl *D, 1645 unsigned Level) const { 1646 if (getStackSize() <= Level) 1647 return DSAVarData(); 1648 D = getCanonicalDecl(D); 1649 const_iterator StartI = std::next(begin(), getStackSize() - 1 - Level); 1650 return getDSA(StartI, D); 1651 } 1652 1653 const DSAStackTy::DSAVarData 1654 DSAStackTy::hasDSA(ValueDecl *D, 1655 const llvm::function_ref<bool(OpenMPClauseKind)> CPred, 1656 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred, 1657 bool FromParent) const { 1658 if (isStackEmpty()) 1659 return {}; 1660 D = getCanonicalDecl(D); 1661 const_iterator I = begin(); 1662 const_iterator EndI = end(); 1663 if (FromParent && I != EndI) 1664 ++I; 1665 for (; I != EndI; ++I) { 1666 if (!DPred(I->Directive) && 1667 !isImplicitOrExplicitTaskingRegion(I->Directive)) 1668 continue; 1669 const_iterator NewI = I; 1670 DSAVarData DVar = getDSA(NewI, D); 1671 if (I == NewI && CPred(DVar.CKind)) 1672 return DVar; 1673 } 1674 return {}; 1675 } 1676 1677 const DSAStackTy::DSAVarData DSAStackTy::hasInnermostDSA( 1678 ValueDecl *D, const llvm::function_ref<bool(OpenMPClauseKind)> CPred, 1679 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred, 1680 bool FromParent) const { 1681 if (isStackEmpty()) 1682 return {}; 1683 D = getCanonicalDecl(D); 1684 const_iterator StartI = begin(); 1685 const_iterator EndI = end(); 1686 if (FromParent && StartI != EndI) 1687 ++StartI; 1688 if (StartI == EndI || !DPred(StartI->Directive)) 1689 return {}; 1690 const_iterator NewI = StartI; 1691 DSAVarData DVar = getDSA(NewI, D); 1692 return (NewI == StartI && CPred(DVar.CKind)) ? DVar : DSAVarData(); 1693 } 1694 1695 bool DSAStackTy::hasExplicitDSA( 1696 const ValueDecl *D, const llvm::function_ref<bool(OpenMPClauseKind)> CPred, 1697 unsigned Level, bool NotLastprivate) const { 1698 if (getStackSize() <= Level) 1699 return false; 1700 D = getCanonicalDecl(D); 1701 const SharingMapTy &StackElem = getStackElemAtLevel(Level); 1702 auto I = StackElem.SharingMap.find(D); 1703 if (I != StackElem.SharingMap.end() && 1704 I->getSecond().RefExpr.getPointer() && 1705 CPred(I->getSecond().Attributes) && 1706 (!NotLastprivate || !I->getSecond().RefExpr.getInt())) 1707 return true; 1708 // Check predetermined rules for the loop control variables. 1709 auto LI = StackElem.LCVMap.find(D); 1710 if (LI != StackElem.LCVMap.end()) 1711 return CPred(OMPC_private); 1712 return false; 1713 } 1714 1715 bool DSAStackTy::hasExplicitDirective( 1716 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred, 1717 unsigned Level) const { 1718 if (getStackSize() <= Level) 1719 return false; 1720 const SharingMapTy &StackElem = getStackElemAtLevel(Level); 1721 return DPred(StackElem.Directive); 1722 } 1723 1724 bool DSAStackTy::hasDirective( 1725 const llvm::function_ref<bool(OpenMPDirectiveKind, 1726 const DeclarationNameInfo &, SourceLocation)> 1727 DPred, 1728 bool FromParent) const { 1729 // We look only in the enclosing region. 1730 size_t Skip = FromParent ? 2 : 1; 1731 for (const_iterator I = begin() + std::min(Skip, getStackSize()), E = end(); 1732 I != E; ++I) { 1733 if (DPred(I->Directive, I->DirectiveName, I->ConstructLoc)) 1734 return true; 1735 } 1736 return false; 1737 } 1738 1739 void Sema::InitDataSharingAttributesStack() { 1740 VarDataSharingAttributesStack = new DSAStackTy(*this); 1741 } 1742 1743 #define DSAStack static_cast<DSAStackTy *>(VarDataSharingAttributesStack) 1744 1745 void Sema::pushOpenMPFunctionRegion() { 1746 DSAStack->pushFunction(); 1747 } 1748 1749 void Sema::popOpenMPFunctionRegion(const FunctionScopeInfo *OldFSI) { 1750 DSAStack->popFunction(OldFSI); 1751 } 1752 1753 static bool isOpenMPDeviceDelayedContext(Sema &S) { 1754 assert(S.LangOpts.OpenMP && S.LangOpts.OpenMPIsDevice && 1755 "Expected OpenMP device compilation."); 1756 return !S.isInOpenMPTargetExecutionDirective() && 1757 !S.isInOpenMPDeclareTargetContext(); 1758 } 1759 1760 namespace { 1761 /// Status of the function emission on the host/device. 1762 enum class FunctionEmissionStatus { 1763 Emitted, 1764 Discarded, 1765 Unknown, 1766 }; 1767 } // anonymous namespace 1768 1769 Sema::DeviceDiagBuilder Sema::diagIfOpenMPDeviceCode(SourceLocation Loc, 1770 unsigned DiagID) { 1771 assert(LangOpts.OpenMP && LangOpts.OpenMPIsDevice && 1772 "Expected OpenMP device compilation."); 1773 FunctionEmissionStatus FES = getEmissionStatus(getCurFunctionDecl()); 1774 DeviceDiagBuilder::Kind Kind = DeviceDiagBuilder::K_Nop; 1775 switch (FES) { 1776 case FunctionEmissionStatus::Emitted: 1777 Kind = DeviceDiagBuilder::K_Immediate; 1778 break; 1779 case FunctionEmissionStatus::Unknown: 1780 Kind = isOpenMPDeviceDelayedContext(*this) ? DeviceDiagBuilder::K_Deferred 1781 : DeviceDiagBuilder::K_Immediate; 1782 break; 1783 case FunctionEmissionStatus::TemplateDiscarded: 1784 case FunctionEmissionStatus::OMPDiscarded: 1785 Kind = DeviceDiagBuilder::K_Nop; 1786 break; 1787 case FunctionEmissionStatus::CUDADiscarded: 1788 llvm_unreachable("CUDADiscarded unexpected in OpenMP device compilation"); 1789 break; 1790 } 1791 1792 return DeviceDiagBuilder(Kind, Loc, DiagID, getCurFunctionDecl(), *this); 1793 } 1794 1795 Sema::DeviceDiagBuilder Sema::diagIfOpenMPHostCode(SourceLocation Loc, 1796 unsigned DiagID) { 1797 assert(LangOpts.OpenMP && !LangOpts.OpenMPIsDevice && 1798 "Expected OpenMP host compilation."); 1799 FunctionEmissionStatus FES = getEmissionStatus(getCurFunctionDecl()); 1800 DeviceDiagBuilder::Kind Kind = DeviceDiagBuilder::K_Nop; 1801 switch (FES) { 1802 case FunctionEmissionStatus::Emitted: 1803 Kind = DeviceDiagBuilder::K_Immediate; 1804 break; 1805 case FunctionEmissionStatus::Unknown: 1806 Kind = DeviceDiagBuilder::K_Deferred; 1807 break; 1808 case FunctionEmissionStatus::TemplateDiscarded: 1809 case FunctionEmissionStatus::OMPDiscarded: 1810 case FunctionEmissionStatus::CUDADiscarded: 1811 Kind = DeviceDiagBuilder::K_Nop; 1812 break; 1813 } 1814 1815 return DeviceDiagBuilder(Kind, Loc, DiagID, getCurFunctionDecl(), *this); 1816 } 1817 1818 void Sema::checkOpenMPDeviceExpr(const Expr *E) { 1819 assert(getLangOpts().OpenMP && getLangOpts().OpenMPIsDevice && 1820 "OpenMP device compilation mode is expected."); 1821 QualType Ty = E->getType(); 1822 if ((Ty->isFloat16Type() && !Context.getTargetInfo().hasFloat16Type()) || 1823 ((Ty->isFloat128Type() || 1824 (Ty->isRealFloatingType() && Context.getTypeSize(Ty) == 128)) && 1825 !Context.getTargetInfo().hasFloat128Type()) || 1826 (Ty->isIntegerType() && Context.getTypeSize(Ty) == 128 && 1827 !Context.getTargetInfo().hasInt128Type())) 1828 targetDiag(E->getExprLoc(), diag::err_omp_unsupported_type) 1829 << static_cast<unsigned>(Context.getTypeSize(Ty)) << Ty 1830 << Context.getTargetInfo().getTriple().str() << E->getSourceRange(); 1831 } 1832 1833 static OpenMPDefaultmapClauseKind 1834 getVariableCategoryFromDecl(const LangOptions &LO, const ValueDecl *VD) { 1835 if (LO.OpenMP <= 45) { 1836 if (VD->getType().getNonReferenceType()->isScalarType()) 1837 return OMPC_DEFAULTMAP_scalar; 1838 return OMPC_DEFAULTMAP_aggregate; 1839 } 1840 if (VD->getType().getNonReferenceType()->isAnyPointerType()) 1841 return OMPC_DEFAULTMAP_pointer; 1842 if (VD->getType().getNonReferenceType()->isScalarType()) 1843 return OMPC_DEFAULTMAP_scalar; 1844 return OMPC_DEFAULTMAP_aggregate; 1845 } 1846 1847 bool Sema::isOpenMPCapturedByRef(const ValueDecl *D, unsigned Level, 1848 unsigned OpenMPCaptureLevel) const { 1849 assert(LangOpts.OpenMP && "OpenMP is not allowed"); 1850 1851 ASTContext &Ctx = getASTContext(); 1852 bool IsByRef = true; 1853 1854 // Find the directive that is associated with the provided scope. 1855 D = cast<ValueDecl>(D->getCanonicalDecl()); 1856 QualType Ty = D->getType(); 1857 1858 bool IsVariableUsedInMapClause = false; 1859 if (DSAStack->hasExplicitDirective(isOpenMPTargetExecutionDirective, Level)) { 1860 // This table summarizes how a given variable should be passed to the device 1861 // given its type and the clauses where it appears. This table is based on 1862 // the description in OpenMP 4.5 [2.10.4, target Construct] and 1863 // OpenMP 4.5 [2.15.5, Data-mapping Attribute Rules and Clauses]. 1864 // 1865 // ========================================================================= 1866 // | type | defaultmap | pvt | first | is_device_ptr | map | res. | 1867 // | |(tofrom:scalar)| | pvt | | | | 1868 // ========================================================================= 1869 // | scl | | | | - | | bycopy| 1870 // | scl | | - | x | - | - | bycopy| 1871 // | scl | | x | - | - | - | null | 1872 // | scl | x | | | - | | byref | 1873 // | scl | x | - | x | - | - | bycopy| 1874 // | scl | x | x | - | - | - | null | 1875 // | scl | | - | - | - | x | byref | 1876 // | scl | x | - | - | - | x | byref | 1877 // 1878 // | agg | n.a. | | | - | | byref | 1879 // | agg | n.a. | - | x | - | - | byref | 1880 // | agg | n.a. | x | - | - | - | null | 1881 // | agg | n.a. | - | - | - | x | byref | 1882 // | agg | n.a. | - | - | - | x[] | byref | 1883 // 1884 // | ptr | n.a. | | | - | | bycopy| 1885 // | ptr | n.a. | - | x | - | - | bycopy| 1886 // | ptr | n.a. | x | - | - | - | null | 1887 // | ptr | n.a. | - | - | - | x | byref | 1888 // | ptr | n.a. | - | - | - | x[] | bycopy| 1889 // | ptr | n.a. | - | - | x | | bycopy| 1890 // | ptr | n.a. | - | - | x | x | bycopy| 1891 // | ptr | n.a. | - | - | x | x[] | bycopy| 1892 // ========================================================================= 1893 // Legend: 1894 // scl - scalar 1895 // ptr - pointer 1896 // agg - aggregate 1897 // x - applies 1898 // - - invalid in this combination 1899 // [] - mapped with an array section 1900 // byref - should be mapped by reference 1901 // byval - should be mapped by value 1902 // null - initialize a local variable to null on the device 1903 // 1904 // Observations: 1905 // - All scalar declarations that show up in a map clause have to be passed 1906 // by reference, because they may have been mapped in the enclosing data 1907 // environment. 1908 // - If the scalar value does not fit the size of uintptr, it has to be 1909 // passed by reference, regardless the result in the table above. 1910 // - For pointers mapped by value that have either an implicit map or an 1911 // array section, the runtime library may pass the NULL value to the 1912 // device instead of the value passed to it by the compiler. 1913 1914 if (Ty->isReferenceType()) 1915 Ty = Ty->castAs<ReferenceType>()->getPointeeType(); 1916 1917 // Locate map clauses and see if the variable being captured is referred to 1918 // in any of those clauses. Here we only care about variables, not fields, 1919 // because fields are part of aggregates. 1920 bool IsVariableAssociatedWithSection = false; 1921 1922 DSAStack->checkMappableExprComponentListsForDeclAtLevel( 1923 D, Level, 1924 [&IsVariableUsedInMapClause, &IsVariableAssociatedWithSection, D]( 1925 OMPClauseMappableExprCommon::MappableExprComponentListRef 1926 MapExprComponents, 1927 OpenMPClauseKind WhereFoundClauseKind) { 1928 // Only the map clause information influences how a variable is 1929 // captured. E.g. is_device_ptr does not require changing the default 1930 // behavior. 1931 if (WhereFoundClauseKind != OMPC_map) 1932 return false; 1933 1934 auto EI = MapExprComponents.rbegin(); 1935 auto EE = MapExprComponents.rend(); 1936 1937 assert(EI != EE && "Invalid map expression!"); 1938 1939 if (isa<DeclRefExpr>(EI->getAssociatedExpression())) 1940 IsVariableUsedInMapClause |= EI->getAssociatedDeclaration() == D; 1941 1942 ++EI; 1943 if (EI == EE) 1944 return false; 1945 1946 if (isa<ArraySubscriptExpr>(EI->getAssociatedExpression()) || 1947 isa<OMPArraySectionExpr>(EI->getAssociatedExpression()) || 1948 isa<MemberExpr>(EI->getAssociatedExpression()) || 1949 isa<OMPArrayShapingExpr>(EI->getAssociatedExpression())) { 1950 IsVariableAssociatedWithSection = true; 1951 // There is nothing more we need to know about this variable. 1952 return true; 1953 } 1954 1955 // Keep looking for more map info. 1956 return false; 1957 }); 1958 1959 if (IsVariableUsedInMapClause) { 1960 // If variable is identified in a map clause it is always captured by 1961 // reference except if it is a pointer that is dereferenced somehow. 1962 IsByRef = !(Ty->isPointerType() && IsVariableAssociatedWithSection); 1963 } else { 1964 // By default, all the data that has a scalar type is mapped by copy 1965 // (except for reduction variables). 1966 // Defaultmap scalar is mutual exclusive to defaultmap pointer 1967 IsByRef = 1968 (DSAStack->isForceCaptureByReferenceInTargetExecutable() && 1969 !Ty->isAnyPointerType()) || 1970 !Ty->isScalarType() || 1971 DSAStack->isDefaultmapCapturedByRef( 1972 Level, getVariableCategoryFromDecl(LangOpts, D)) || 1973 DSAStack->hasExplicitDSA( 1974 D, [](OpenMPClauseKind K) { return K == OMPC_reduction; }, Level); 1975 } 1976 } 1977 1978 if (IsByRef && Ty.getNonReferenceType()->isScalarType()) { 1979 IsByRef = 1980 ((IsVariableUsedInMapClause && 1981 DSAStack->getCaptureRegion(Level, OpenMPCaptureLevel) == 1982 OMPD_target) || 1983 !DSAStack->hasExplicitDSA( 1984 D, 1985 [](OpenMPClauseKind K) -> bool { return K == OMPC_firstprivate; }, 1986 Level, /*NotLastprivate=*/true)) && 1987 // If the variable is artificial and must be captured by value - try to 1988 // capture by value. 1989 !(isa<OMPCapturedExprDecl>(D) && !D->hasAttr<OMPCaptureNoInitAttr>() && 1990 !cast<OMPCapturedExprDecl>(D)->getInit()->isGLValue()); 1991 } 1992 1993 // When passing data by copy, we need to make sure it fits the uintptr size 1994 // and alignment, because the runtime library only deals with uintptr types. 1995 // If it does not fit the uintptr size, we need to pass the data by reference 1996 // instead. 1997 if (!IsByRef && 1998 (Ctx.getTypeSizeInChars(Ty) > 1999 Ctx.getTypeSizeInChars(Ctx.getUIntPtrType()) || 2000 Ctx.getDeclAlign(D) > Ctx.getTypeAlignInChars(Ctx.getUIntPtrType()))) { 2001 IsByRef = true; 2002 } 2003 2004 return IsByRef; 2005 } 2006 2007 unsigned Sema::getOpenMPNestingLevel() const { 2008 assert(getLangOpts().OpenMP); 2009 return DSAStack->getNestingLevel(); 2010 } 2011 2012 bool Sema::isInOpenMPTargetExecutionDirective() const { 2013 return (isOpenMPTargetExecutionDirective(DSAStack->getCurrentDirective()) && 2014 !DSAStack->isClauseParsingMode()) || 2015 DSAStack->hasDirective( 2016 [](OpenMPDirectiveKind K, const DeclarationNameInfo &, 2017 SourceLocation) -> bool { 2018 return isOpenMPTargetExecutionDirective(K); 2019 }, 2020 false); 2021 } 2022 2023 VarDecl *Sema::isOpenMPCapturedDecl(ValueDecl *D, bool CheckScopeInfo, 2024 unsigned StopAt) { 2025 assert(LangOpts.OpenMP && "OpenMP is not allowed"); 2026 D = getCanonicalDecl(D); 2027 2028 auto *VD = dyn_cast<VarDecl>(D); 2029 // Do not capture constexpr variables. 2030 if (VD && VD->isConstexpr()) 2031 return nullptr; 2032 2033 // If we want to determine whether the variable should be captured from the 2034 // perspective of the current capturing scope, and we've already left all the 2035 // capturing scopes of the top directive on the stack, check from the 2036 // perspective of its parent directive (if any) instead. 2037 DSAStackTy::ParentDirectiveScope InParentDirectiveRAII( 2038 *DSAStack, CheckScopeInfo && DSAStack->isBodyComplete()); 2039 2040 // If we are attempting to capture a global variable in a directive with 2041 // 'target' we return true so that this global is also mapped to the device. 2042 // 2043 if (VD && !VD->hasLocalStorage() && 2044 (getCurCapturedRegion() || getCurBlock() || getCurLambda())) { 2045 if (isInOpenMPDeclareTargetContext()) { 2046 // Try to mark variable as declare target if it is used in capturing 2047 // regions. 2048 if (LangOpts.OpenMP <= 45 && 2049 !OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD)) 2050 checkDeclIsAllowedInOpenMPTarget(nullptr, VD); 2051 return nullptr; 2052 } else if (isInOpenMPTargetExecutionDirective()) { 2053 // If the declaration is enclosed in a 'declare target' directive, 2054 // then it should not be captured. 2055 // 2056 if (OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD)) 2057 return nullptr; 2058 CapturedRegionScopeInfo *CSI = nullptr; 2059 for (FunctionScopeInfo *FSI : llvm::drop_begin( 2060 llvm::reverse(FunctionScopes), 2061 CheckScopeInfo ? (FunctionScopes.size() - (StopAt + 1)) : 0)) { 2062 if (!isa<CapturingScopeInfo>(FSI)) 2063 return nullptr; 2064 if (auto *RSI = dyn_cast<CapturedRegionScopeInfo>(FSI)) 2065 if (RSI->CapRegionKind == CR_OpenMP) { 2066 CSI = RSI; 2067 break; 2068 } 2069 } 2070 SmallVector<OpenMPDirectiveKind, 4> Regions; 2071 getOpenMPCaptureRegions(Regions, 2072 DSAStack->getDirective(CSI->OpenMPLevel)); 2073 if (Regions[CSI->OpenMPCaptureLevel] != OMPD_task) 2074 return VD; 2075 } 2076 } 2077 2078 if (CheckScopeInfo) { 2079 bool OpenMPFound = false; 2080 for (unsigned I = StopAt + 1; I > 0; --I) { 2081 FunctionScopeInfo *FSI = FunctionScopes[I - 1]; 2082 if(!isa<CapturingScopeInfo>(FSI)) 2083 return nullptr; 2084 if (auto *RSI = dyn_cast<CapturedRegionScopeInfo>(FSI)) 2085 if (RSI->CapRegionKind == CR_OpenMP) { 2086 OpenMPFound = true; 2087 break; 2088 } 2089 } 2090 if (!OpenMPFound) 2091 return nullptr; 2092 } 2093 2094 if (DSAStack->getCurrentDirective() != OMPD_unknown && 2095 (!DSAStack->isClauseParsingMode() || 2096 DSAStack->getParentDirective() != OMPD_unknown)) { 2097 auto &&Info = DSAStack->isLoopControlVariable(D); 2098 if (Info.first || 2099 (VD && VD->hasLocalStorage() && 2100 isImplicitOrExplicitTaskingRegion(DSAStack->getCurrentDirective())) || 2101 (VD && DSAStack->isForceVarCapturing())) 2102 return VD ? VD : Info.second; 2103 DSAStackTy::DSAVarData DVarPrivate = 2104 DSAStack->getTopDSA(D, DSAStack->isClauseParsingMode()); 2105 if (DVarPrivate.CKind != OMPC_unknown && isOpenMPPrivate(DVarPrivate.CKind)) 2106 return VD ? VD : cast<VarDecl>(DVarPrivate.PrivateCopy->getDecl()); 2107 // Threadprivate variables must not be captured. 2108 if (isOpenMPThreadPrivate(DVarPrivate.CKind)) 2109 return nullptr; 2110 // The variable is not private or it is the variable in the directive with 2111 // default(none) clause and not used in any clause. 2112 DVarPrivate = DSAStack->hasDSA(D, isOpenMPPrivate, 2113 [](OpenMPDirectiveKind) { return true; }, 2114 DSAStack->isClauseParsingMode()); 2115 if (DVarPrivate.CKind != OMPC_unknown || 2116 (VD && DSAStack->getDefaultDSA() == DSA_none)) 2117 return VD ? VD : cast<VarDecl>(DVarPrivate.PrivateCopy->getDecl()); 2118 } 2119 return nullptr; 2120 } 2121 2122 void Sema::adjustOpenMPTargetScopeIndex(unsigned &FunctionScopesIndex, 2123 unsigned Level) const { 2124 FunctionScopesIndex -= getOpenMPCaptureLevels(DSAStack->getDirective(Level)); 2125 } 2126 2127 void Sema::startOpenMPLoop() { 2128 assert(LangOpts.OpenMP && "OpenMP must be enabled."); 2129 if (isOpenMPLoopDirective(DSAStack->getCurrentDirective())) 2130 DSAStack->loopInit(); 2131 } 2132 2133 void Sema::startOpenMPCXXRangeFor() { 2134 assert(LangOpts.OpenMP && "OpenMP must be enabled."); 2135 if (isOpenMPLoopDirective(DSAStack->getCurrentDirective())) { 2136 DSAStack->resetPossibleLoopCounter(); 2137 DSAStack->loopStart(); 2138 } 2139 } 2140 2141 OpenMPClauseKind Sema::isOpenMPPrivateDecl(ValueDecl *D, unsigned Level, 2142 unsigned CapLevel) const { 2143 assert(LangOpts.OpenMP && "OpenMP is not allowed"); 2144 if (DSAStack->hasExplicitDirective( 2145 [](OpenMPDirectiveKind K) { return isOpenMPTaskingDirective(K); }, 2146 Level)) { 2147 bool IsTriviallyCopyable = 2148 D->getType().getNonReferenceType().isTriviallyCopyableType(Context); 2149 OpenMPDirectiveKind DKind = DSAStack->getDirective(Level); 2150 SmallVector<OpenMPDirectiveKind, 4> CaptureRegions; 2151 getOpenMPCaptureRegions(CaptureRegions, DKind); 2152 if (isOpenMPTaskingDirective(CaptureRegions[CapLevel]) && 2153 (IsTriviallyCopyable || 2154 !isOpenMPTaskLoopDirective(CaptureRegions[CapLevel]))) { 2155 if (DSAStack->hasExplicitDSA( 2156 D, [](OpenMPClauseKind K) { return K == OMPC_firstprivate; }, 2157 Level, /*NotLastprivate=*/true)) 2158 return OMPC_firstprivate; 2159 DSAStackTy::DSAVarData DVar = DSAStack->getImplicitDSA(D, Level); 2160 if (DVar.CKind != OMPC_shared && 2161 !DSAStack->isLoopControlVariable(D, Level).first && !DVar.RefExpr) { 2162 DSAStack->addImplicitTaskFirstprivate(Level, D); 2163 return OMPC_firstprivate; 2164 } 2165 } 2166 } 2167 if (isOpenMPLoopDirective(DSAStack->getCurrentDirective())) { 2168 if (DSAStack->getAssociatedLoops() > 0 && 2169 !DSAStack->isLoopStarted()) { 2170 DSAStack->resetPossibleLoopCounter(D); 2171 DSAStack->loopStart(); 2172 return OMPC_private; 2173 } 2174 if ((DSAStack->getPossiblyLoopCunter() == D->getCanonicalDecl() || 2175 DSAStack->isLoopControlVariable(D).first) && 2176 !DSAStack->hasExplicitDSA( 2177 D, [](OpenMPClauseKind K) { return K != OMPC_private; }, Level) && 2178 !isOpenMPSimdDirective(DSAStack->getCurrentDirective())) 2179 return OMPC_private; 2180 } 2181 if (const auto *VD = dyn_cast<VarDecl>(D)) { 2182 if (DSAStack->isThreadPrivate(const_cast<VarDecl *>(VD)) && 2183 DSAStack->isForceVarCapturing() && 2184 !DSAStack->hasExplicitDSA( 2185 D, [](OpenMPClauseKind K) { return K == OMPC_copyin; }, Level)) 2186 return OMPC_private; 2187 } 2188 return (DSAStack->hasExplicitDSA( 2189 D, [](OpenMPClauseKind K) { return K == OMPC_private; }, Level) || 2190 (DSAStack->isClauseParsingMode() && 2191 DSAStack->getClauseParsingMode() == OMPC_private) || 2192 // Consider taskgroup reduction descriptor variable a private 2193 // to avoid possible capture in the region. 2194 (DSAStack->hasExplicitDirective( 2195 [](OpenMPDirectiveKind K) { return K == OMPD_taskgroup; }, 2196 Level) && 2197 DSAStack->isTaskgroupReductionRef(D, Level))) 2198 ? OMPC_private 2199 : OMPC_unknown; 2200 } 2201 2202 void Sema::setOpenMPCaptureKind(FieldDecl *FD, const ValueDecl *D, 2203 unsigned Level) { 2204 assert(LangOpts.OpenMP && "OpenMP is not allowed"); 2205 D = getCanonicalDecl(D); 2206 OpenMPClauseKind OMPC = OMPC_unknown; 2207 for (unsigned I = DSAStack->getNestingLevel() + 1; I > Level; --I) { 2208 const unsigned NewLevel = I - 1; 2209 if (DSAStack->hasExplicitDSA(D, 2210 [&OMPC](const OpenMPClauseKind K) { 2211 if (isOpenMPPrivate(K)) { 2212 OMPC = K; 2213 return true; 2214 } 2215 return false; 2216 }, 2217 NewLevel)) 2218 break; 2219 if (DSAStack->checkMappableExprComponentListsForDeclAtLevel( 2220 D, NewLevel, 2221 [](OMPClauseMappableExprCommon::MappableExprComponentListRef, 2222 OpenMPClauseKind) { return true; })) { 2223 OMPC = OMPC_map; 2224 break; 2225 } 2226 if (DSAStack->hasExplicitDirective(isOpenMPTargetExecutionDirective, 2227 NewLevel)) { 2228 OMPC = OMPC_map; 2229 if (DSAStack->mustBeFirstprivateAtLevel( 2230 NewLevel, getVariableCategoryFromDecl(LangOpts, D))) 2231 OMPC = OMPC_firstprivate; 2232 break; 2233 } 2234 } 2235 if (OMPC != OMPC_unknown) 2236 FD->addAttr(OMPCaptureKindAttr::CreateImplicit(Context, unsigned(OMPC))); 2237 } 2238 2239 bool Sema::isOpenMPTargetCapturedDecl(const ValueDecl *D, unsigned Level, 2240 unsigned CaptureLevel) const { 2241 assert(LangOpts.OpenMP && "OpenMP is not allowed"); 2242 // Return true if the current level is no longer enclosed in a target region. 2243 2244 SmallVector<OpenMPDirectiveKind, 4> Regions; 2245 getOpenMPCaptureRegions(Regions, DSAStack->getDirective(Level)); 2246 const auto *VD = dyn_cast<VarDecl>(D); 2247 return VD && !VD->hasLocalStorage() && 2248 DSAStack->hasExplicitDirective(isOpenMPTargetExecutionDirective, 2249 Level) && 2250 Regions[CaptureLevel] != OMPD_task; 2251 } 2252 2253 bool Sema::isOpenMPGlobalCapturedDecl(ValueDecl *D, unsigned Level, 2254 unsigned CaptureLevel) const { 2255 assert(LangOpts.OpenMP && "OpenMP is not allowed"); 2256 // Return true if the current level is no longer enclosed in a target region. 2257 2258 if (const auto *VD = dyn_cast<VarDecl>(D)) { 2259 if (!VD->hasLocalStorage()) { 2260 DSAStackTy::DSAVarData TopDVar = 2261 DSAStack->getTopDSA(D, /*FromParent=*/false); 2262 unsigned NumLevels = 2263 getOpenMPCaptureLevels(DSAStack->getDirective(Level)); 2264 if (Level == 0) 2265 return (NumLevels == CaptureLevel + 1) && TopDVar.CKind != OMPC_shared; 2266 DSAStackTy::DSAVarData DVar = DSAStack->getImplicitDSA(D, Level - 1); 2267 return DVar.CKind != OMPC_shared || 2268 isOpenMPGlobalCapturedDecl( 2269 D, Level - 1, 2270 getOpenMPCaptureLevels(DSAStack->getDirective(Level - 1)) - 1); 2271 } 2272 } 2273 return true; 2274 } 2275 2276 void Sema::DestroyDataSharingAttributesStack() { delete DSAStack; } 2277 2278 void Sema::ActOnOpenMPBeginDeclareVariant(SourceLocation Loc, 2279 OMPTraitInfo &TI) { 2280 if (!OMPDeclareVariantScopes.empty()) { 2281 Diag(Loc, diag::warn_nested_declare_variant); 2282 return; 2283 } 2284 OMPDeclareVariantScopes.push_back(OMPDeclareVariantScope(TI)); 2285 } 2286 2287 void Sema::ActOnOpenMPEndDeclareVariant() { 2288 assert(isInOpenMPDeclareVariantScope() && 2289 "Not in OpenMP declare variant scope!"); 2290 2291 OMPDeclareVariantScopes.pop_back(); 2292 } 2293 2294 void Sema::finalizeOpenMPDelayedAnalysis(const FunctionDecl *Caller, 2295 const FunctionDecl *Callee, 2296 SourceLocation Loc) { 2297 assert(LangOpts.OpenMP && "Expected OpenMP compilation mode."); 2298 Optional<OMPDeclareTargetDeclAttr::DevTypeTy> DevTy = 2299 OMPDeclareTargetDeclAttr::getDeviceType(Caller->getMostRecentDecl()); 2300 // Ignore host functions during device analyzis. 2301 if (LangOpts.OpenMPIsDevice && DevTy && 2302 *DevTy == OMPDeclareTargetDeclAttr::DT_Host) 2303 return; 2304 // Ignore nohost functions during host analyzis. 2305 if (!LangOpts.OpenMPIsDevice && DevTy && 2306 *DevTy == OMPDeclareTargetDeclAttr::DT_NoHost) 2307 return; 2308 const FunctionDecl *FD = Callee->getMostRecentDecl(); 2309 DevTy = OMPDeclareTargetDeclAttr::getDeviceType(FD); 2310 if (LangOpts.OpenMPIsDevice && DevTy && 2311 *DevTy == OMPDeclareTargetDeclAttr::DT_Host) { 2312 // Diagnose host function called during device codegen. 2313 StringRef HostDevTy = 2314 getOpenMPSimpleClauseTypeName(OMPC_device_type, OMPC_DEVICE_TYPE_host); 2315 Diag(Loc, diag::err_omp_wrong_device_function_call) << HostDevTy << 0; 2316 Diag(FD->getAttr<OMPDeclareTargetDeclAttr>()->getLocation(), 2317 diag::note_omp_marked_device_type_here) 2318 << HostDevTy; 2319 return; 2320 } 2321 if (!LangOpts.OpenMPIsDevice && DevTy && 2322 *DevTy == OMPDeclareTargetDeclAttr::DT_NoHost) { 2323 // Diagnose nohost function called during host codegen. 2324 StringRef NoHostDevTy = getOpenMPSimpleClauseTypeName( 2325 OMPC_device_type, OMPC_DEVICE_TYPE_nohost); 2326 Diag(Loc, diag::err_omp_wrong_device_function_call) << NoHostDevTy << 1; 2327 Diag(FD->getAttr<OMPDeclareTargetDeclAttr>()->getLocation(), 2328 diag::note_omp_marked_device_type_here) 2329 << NoHostDevTy; 2330 } 2331 } 2332 2333 void Sema::StartOpenMPDSABlock(OpenMPDirectiveKind DKind, 2334 const DeclarationNameInfo &DirName, 2335 Scope *CurScope, SourceLocation Loc) { 2336 DSAStack->push(DKind, DirName, CurScope, Loc); 2337 PushExpressionEvaluationContext( 2338 ExpressionEvaluationContext::PotentiallyEvaluated); 2339 } 2340 2341 void Sema::StartOpenMPClause(OpenMPClauseKind K) { 2342 DSAStack->setClauseParsingMode(K); 2343 } 2344 2345 void Sema::EndOpenMPClause() { 2346 DSAStack->setClauseParsingMode(/*K=*/OMPC_unknown); 2347 } 2348 2349 static std::pair<ValueDecl *, bool> 2350 getPrivateItem(Sema &S, Expr *&RefExpr, SourceLocation &ELoc, 2351 SourceRange &ERange, bool AllowArraySection = false); 2352 2353 /// Check consistency of the reduction clauses. 2354 static void checkReductionClauses(Sema &S, DSAStackTy *Stack, 2355 ArrayRef<OMPClause *> Clauses) { 2356 bool InscanFound = false; 2357 SourceLocation InscanLoc; 2358 // OpenMP 5.0, 2.19.5.4 reduction Clause, Restrictions. 2359 // A reduction clause without the inscan reduction-modifier may not appear on 2360 // a construct on which a reduction clause with the inscan reduction-modifier 2361 // appears. 2362 for (OMPClause *C : Clauses) { 2363 if (C->getClauseKind() != OMPC_reduction) 2364 continue; 2365 auto *RC = cast<OMPReductionClause>(C); 2366 if (RC->getModifier() == OMPC_REDUCTION_inscan) { 2367 InscanFound = true; 2368 InscanLoc = RC->getModifierLoc(); 2369 break; 2370 } 2371 } 2372 if (InscanFound) { 2373 for (OMPClause *C : Clauses) { 2374 if (C->getClauseKind() != OMPC_reduction) 2375 continue; 2376 auto *RC = cast<OMPReductionClause>(C); 2377 if (RC->getModifier() != OMPC_REDUCTION_inscan) { 2378 S.Diag(RC->getModifier() == OMPC_REDUCTION_unknown 2379 ? RC->getBeginLoc() 2380 : RC->getModifierLoc(), 2381 diag::err_omp_inscan_reduction_expected); 2382 S.Diag(InscanLoc, diag::note_omp_previous_inscan_reduction); 2383 continue; 2384 } 2385 for (Expr *Ref : RC->varlists()) { 2386 assert(Ref && "NULL expr in OpenMP nontemporal clause."); 2387 SourceLocation ELoc; 2388 SourceRange ERange; 2389 Expr *SimpleRefExpr = Ref; 2390 auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange, 2391 /*AllowArraySection=*/true); 2392 ValueDecl *D = Res.first; 2393 if (!D) 2394 continue; 2395 if (!Stack->isUsedInScanDirective(getCanonicalDecl(D))) { 2396 S.Diag(Ref->getExprLoc(), 2397 diag::err_omp_reduction_not_inclusive_exclusive) 2398 << Ref->getSourceRange(); 2399 } 2400 } 2401 } 2402 } 2403 } 2404 2405 static void checkAllocateClauses(Sema &S, DSAStackTy *Stack, 2406 ArrayRef<OMPClause *> Clauses); 2407 static DeclRefExpr *buildCapture(Sema &S, ValueDecl *D, Expr *CaptureExpr, 2408 bool WithInit); 2409 2410 void Sema::EndOpenMPDSABlock(Stmt *CurDirective) { 2411 // OpenMP [2.14.3.5, Restrictions, C/C++, p.1] 2412 // A variable of class type (or array thereof) that appears in a lastprivate 2413 // clause requires an accessible, unambiguous default constructor for the 2414 // class type, unless the list item is also specified in a firstprivate 2415 // clause. 2416 if (const auto *D = dyn_cast_or_null<OMPExecutableDirective>(CurDirective)) { 2417 for (OMPClause *C : D->clauses()) { 2418 if (auto *Clause = dyn_cast<OMPLastprivateClause>(C)) { 2419 SmallVector<Expr *, 8> PrivateCopies; 2420 for (Expr *DE : Clause->varlists()) { 2421 if (DE->isValueDependent() || DE->isTypeDependent()) { 2422 PrivateCopies.push_back(nullptr); 2423 continue; 2424 } 2425 auto *DRE = cast<DeclRefExpr>(DE->IgnoreParens()); 2426 auto *VD = cast<VarDecl>(DRE->getDecl()); 2427 QualType Type = VD->getType().getNonReferenceType(); 2428 const DSAStackTy::DSAVarData DVar = 2429 DSAStack->getTopDSA(VD, /*FromParent=*/false); 2430 if (DVar.CKind == OMPC_lastprivate) { 2431 // Generate helper private variable and initialize it with the 2432 // default value. The address of the original variable is replaced 2433 // by the address of the new private variable in CodeGen. This new 2434 // variable is not added to IdResolver, so the code in the OpenMP 2435 // region uses original variable for proper diagnostics. 2436 VarDecl *VDPrivate = buildVarDecl( 2437 *this, DE->getExprLoc(), Type.getUnqualifiedType(), 2438 VD->getName(), VD->hasAttrs() ? &VD->getAttrs() : nullptr, DRE); 2439 ActOnUninitializedDecl(VDPrivate); 2440 if (VDPrivate->isInvalidDecl()) { 2441 PrivateCopies.push_back(nullptr); 2442 continue; 2443 } 2444 PrivateCopies.push_back(buildDeclRefExpr( 2445 *this, VDPrivate, DE->getType(), DE->getExprLoc())); 2446 } else { 2447 // The variable is also a firstprivate, so initialization sequence 2448 // for private copy is generated already. 2449 PrivateCopies.push_back(nullptr); 2450 } 2451 } 2452 Clause->setPrivateCopies(PrivateCopies); 2453 continue; 2454 } 2455 // Finalize nontemporal clause by handling private copies, if any. 2456 if (auto *Clause = dyn_cast<OMPNontemporalClause>(C)) { 2457 SmallVector<Expr *, 8> PrivateRefs; 2458 for (Expr *RefExpr : Clause->varlists()) { 2459 assert(RefExpr && "NULL expr in OpenMP nontemporal clause."); 2460 SourceLocation ELoc; 2461 SourceRange ERange; 2462 Expr *SimpleRefExpr = RefExpr; 2463 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 2464 if (Res.second) 2465 // It will be analyzed later. 2466 PrivateRefs.push_back(RefExpr); 2467 ValueDecl *D = Res.first; 2468 if (!D) 2469 continue; 2470 2471 const DSAStackTy::DSAVarData DVar = 2472 DSAStack->getTopDSA(D, /*FromParent=*/false); 2473 PrivateRefs.push_back(DVar.PrivateCopy ? DVar.PrivateCopy 2474 : SimpleRefExpr); 2475 } 2476 Clause->setPrivateRefs(PrivateRefs); 2477 continue; 2478 } 2479 } 2480 // Check allocate clauses. 2481 if (!CurContext->isDependentContext()) 2482 checkAllocateClauses(*this, DSAStack, D->clauses()); 2483 checkReductionClauses(*this, DSAStack, D->clauses()); 2484 } 2485 2486 DSAStack->pop(); 2487 DiscardCleanupsInEvaluationContext(); 2488 PopExpressionEvaluationContext(); 2489 } 2490 2491 static bool FinishOpenMPLinearClause(OMPLinearClause &Clause, DeclRefExpr *IV, 2492 Expr *NumIterations, Sema &SemaRef, 2493 Scope *S, DSAStackTy *Stack); 2494 2495 namespace { 2496 2497 class VarDeclFilterCCC final : public CorrectionCandidateCallback { 2498 private: 2499 Sema &SemaRef; 2500 2501 public: 2502 explicit VarDeclFilterCCC(Sema &S) : SemaRef(S) {} 2503 bool ValidateCandidate(const TypoCorrection &Candidate) override { 2504 NamedDecl *ND = Candidate.getCorrectionDecl(); 2505 if (const auto *VD = dyn_cast_or_null<VarDecl>(ND)) { 2506 return VD->hasGlobalStorage() && 2507 SemaRef.isDeclInScope(ND, SemaRef.getCurLexicalContext(), 2508 SemaRef.getCurScope()); 2509 } 2510 return false; 2511 } 2512 2513 std::unique_ptr<CorrectionCandidateCallback> clone() override { 2514 return std::make_unique<VarDeclFilterCCC>(*this); 2515 } 2516 2517 }; 2518 2519 class VarOrFuncDeclFilterCCC final : public CorrectionCandidateCallback { 2520 private: 2521 Sema &SemaRef; 2522 2523 public: 2524 explicit VarOrFuncDeclFilterCCC(Sema &S) : SemaRef(S) {} 2525 bool ValidateCandidate(const TypoCorrection &Candidate) override { 2526 NamedDecl *ND = Candidate.getCorrectionDecl(); 2527 if (ND && ((isa<VarDecl>(ND) && ND->getKind() == Decl::Var) || 2528 isa<FunctionDecl>(ND))) { 2529 return SemaRef.isDeclInScope(ND, SemaRef.getCurLexicalContext(), 2530 SemaRef.getCurScope()); 2531 } 2532 return false; 2533 } 2534 2535 std::unique_ptr<CorrectionCandidateCallback> clone() override { 2536 return std::make_unique<VarOrFuncDeclFilterCCC>(*this); 2537 } 2538 }; 2539 2540 } // namespace 2541 2542 ExprResult Sema::ActOnOpenMPIdExpression(Scope *CurScope, 2543 CXXScopeSpec &ScopeSpec, 2544 const DeclarationNameInfo &Id, 2545 OpenMPDirectiveKind Kind) { 2546 LookupResult Lookup(*this, Id, LookupOrdinaryName); 2547 LookupParsedName(Lookup, CurScope, &ScopeSpec, true); 2548 2549 if (Lookup.isAmbiguous()) 2550 return ExprError(); 2551 2552 VarDecl *VD; 2553 if (!Lookup.isSingleResult()) { 2554 VarDeclFilterCCC CCC(*this); 2555 if (TypoCorrection Corrected = 2556 CorrectTypo(Id, LookupOrdinaryName, CurScope, nullptr, CCC, 2557 CTK_ErrorRecovery)) { 2558 diagnoseTypo(Corrected, 2559 PDiag(Lookup.empty() 2560 ? diag::err_undeclared_var_use_suggest 2561 : diag::err_omp_expected_var_arg_suggest) 2562 << Id.getName()); 2563 VD = Corrected.getCorrectionDeclAs<VarDecl>(); 2564 } else { 2565 Diag(Id.getLoc(), Lookup.empty() ? diag::err_undeclared_var_use 2566 : diag::err_omp_expected_var_arg) 2567 << Id.getName(); 2568 return ExprError(); 2569 } 2570 } else if (!(VD = Lookup.getAsSingle<VarDecl>())) { 2571 Diag(Id.getLoc(), diag::err_omp_expected_var_arg) << Id.getName(); 2572 Diag(Lookup.getFoundDecl()->getLocation(), diag::note_declared_at); 2573 return ExprError(); 2574 } 2575 Lookup.suppressDiagnostics(); 2576 2577 // OpenMP [2.9.2, Syntax, C/C++] 2578 // Variables must be file-scope, namespace-scope, or static block-scope. 2579 if (Kind == OMPD_threadprivate && !VD->hasGlobalStorage()) { 2580 Diag(Id.getLoc(), diag::err_omp_global_var_arg) 2581 << getOpenMPDirectiveName(Kind) << !VD->isStaticLocal(); 2582 bool IsDecl = 2583 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 2584 Diag(VD->getLocation(), 2585 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 2586 << VD; 2587 return ExprError(); 2588 } 2589 2590 VarDecl *CanonicalVD = VD->getCanonicalDecl(); 2591 NamedDecl *ND = CanonicalVD; 2592 // OpenMP [2.9.2, Restrictions, C/C++, p.2] 2593 // A threadprivate directive for file-scope variables must appear outside 2594 // any definition or declaration. 2595 if (CanonicalVD->getDeclContext()->isTranslationUnit() && 2596 !getCurLexicalContext()->isTranslationUnit()) { 2597 Diag(Id.getLoc(), diag::err_omp_var_scope) 2598 << getOpenMPDirectiveName(Kind) << VD; 2599 bool IsDecl = 2600 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 2601 Diag(VD->getLocation(), 2602 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 2603 << VD; 2604 return ExprError(); 2605 } 2606 // OpenMP [2.9.2, Restrictions, C/C++, p.3] 2607 // A threadprivate directive for static class member variables must appear 2608 // in the class definition, in the same scope in which the member 2609 // variables are declared. 2610 if (CanonicalVD->isStaticDataMember() && 2611 !CanonicalVD->getDeclContext()->Equals(getCurLexicalContext())) { 2612 Diag(Id.getLoc(), diag::err_omp_var_scope) 2613 << getOpenMPDirectiveName(Kind) << VD; 2614 bool IsDecl = 2615 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 2616 Diag(VD->getLocation(), 2617 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 2618 << VD; 2619 return ExprError(); 2620 } 2621 // OpenMP [2.9.2, Restrictions, C/C++, p.4] 2622 // A threadprivate directive for namespace-scope variables must appear 2623 // outside any definition or declaration other than the namespace 2624 // definition itself. 2625 if (CanonicalVD->getDeclContext()->isNamespace() && 2626 (!getCurLexicalContext()->isFileContext() || 2627 !getCurLexicalContext()->Encloses(CanonicalVD->getDeclContext()))) { 2628 Diag(Id.getLoc(), diag::err_omp_var_scope) 2629 << getOpenMPDirectiveName(Kind) << VD; 2630 bool IsDecl = 2631 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 2632 Diag(VD->getLocation(), 2633 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 2634 << VD; 2635 return ExprError(); 2636 } 2637 // OpenMP [2.9.2, Restrictions, C/C++, p.6] 2638 // A threadprivate directive for static block-scope variables must appear 2639 // in the scope of the variable and not in a nested scope. 2640 if (CanonicalVD->isLocalVarDecl() && CurScope && 2641 !isDeclInScope(ND, getCurLexicalContext(), CurScope)) { 2642 Diag(Id.getLoc(), diag::err_omp_var_scope) 2643 << getOpenMPDirectiveName(Kind) << VD; 2644 bool IsDecl = 2645 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 2646 Diag(VD->getLocation(), 2647 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 2648 << VD; 2649 return ExprError(); 2650 } 2651 2652 // OpenMP [2.9.2, Restrictions, C/C++, p.2-6] 2653 // A threadprivate directive must lexically precede all references to any 2654 // of the variables in its list. 2655 if (Kind == OMPD_threadprivate && VD->isUsed() && 2656 !DSAStack->isThreadPrivate(VD)) { 2657 Diag(Id.getLoc(), diag::err_omp_var_used) 2658 << getOpenMPDirectiveName(Kind) << VD; 2659 return ExprError(); 2660 } 2661 2662 QualType ExprType = VD->getType().getNonReferenceType(); 2663 return DeclRefExpr::Create(Context, NestedNameSpecifierLoc(), 2664 SourceLocation(), VD, 2665 /*RefersToEnclosingVariableOrCapture=*/false, 2666 Id.getLoc(), ExprType, VK_LValue); 2667 } 2668 2669 Sema::DeclGroupPtrTy 2670 Sema::ActOnOpenMPThreadprivateDirective(SourceLocation Loc, 2671 ArrayRef<Expr *> VarList) { 2672 if (OMPThreadPrivateDecl *D = CheckOMPThreadPrivateDecl(Loc, VarList)) { 2673 CurContext->addDecl(D); 2674 return DeclGroupPtrTy::make(DeclGroupRef(D)); 2675 } 2676 return nullptr; 2677 } 2678 2679 namespace { 2680 class LocalVarRefChecker final 2681 : public ConstStmtVisitor<LocalVarRefChecker, bool> { 2682 Sema &SemaRef; 2683 2684 public: 2685 bool VisitDeclRefExpr(const DeclRefExpr *E) { 2686 if (const auto *VD = dyn_cast<VarDecl>(E->getDecl())) { 2687 if (VD->hasLocalStorage()) { 2688 SemaRef.Diag(E->getBeginLoc(), 2689 diag::err_omp_local_var_in_threadprivate_init) 2690 << E->getSourceRange(); 2691 SemaRef.Diag(VD->getLocation(), diag::note_defined_here) 2692 << VD << VD->getSourceRange(); 2693 return true; 2694 } 2695 } 2696 return false; 2697 } 2698 bool VisitStmt(const Stmt *S) { 2699 for (const Stmt *Child : S->children()) { 2700 if (Child && Visit(Child)) 2701 return true; 2702 } 2703 return false; 2704 } 2705 explicit LocalVarRefChecker(Sema &SemaRef) : SemaRef(SemaRef) {} 2706 }; 2707 } // namespace 2708 2709 OMPThreadPrivateDecl * 2710 Sema::CheckOMPThreadPrivateDecl(SourceLocation Loc, ArrayRef<Expr *> VarList) { 2711 SmallVector<Expr *, 8> Vars; 2712 for (Expr *RefExpr : VarList) { 2713 auto *DE = cast<DeclRefExpr>(RefExpr); 2714 auto *VD = cast<VarDecl>(DE->getDecl()); 2715 SourceLocation ILoc = DE->getExprLoc(); 2716 2717 // Mark variable as used. 2718 VD->setReferenced(); 2719 VD->markUsed(Context); 2720 2721 QualType QType = VD->getType(); 2722 if (QType->isDependentType() || QType->isInstantiationDependentType()) { 2723 // It will be analyzed later. 2724 Vars.push_back(DE); 2725 continue; 2726 } 2727 2728 // OpenMP [2.9.2, Restrictions, C/C++, p.10] 2729 // A threadprivate variable must not have an incomplete type. 2730 if (RequireCompleteType(ILoc, VD->getType(), 2731 diag::err_omp_threadprivate_incomplete_type)) { 2732 continue; 2733 } 2734 2735 // OpenMP [2.9.2, Restrictions, C/C++, p.10] 2736 // A threadprivate variable must not have a reference type. 2737 if (VD->getType()->isReferenceType()) { 2738 Diag(ILoc, diag::err_omp_ref_type_arg) 2739 << getOpenMPDirectiveName(OMPD_threadprivate) << VD->getType(); 2740 bool IsDecl = 2741 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 2742 Diag(VD->getLocation(), 2743 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 2744 << VD; 2745 continue; 2746 } 2747 2748 // Check if this is a TLS variable. If TLS is not being supported, produce 2749 // the corresponding diagnostic. 2750 if ((VD->getTLSKind() != VarDecl::TLS_None && 2751 !(VD->hasAttr<OMPThreadPrivateDeclAttr>() && 2752 getLangOpts().OpenMPUseTLS && 2753 getASTContext().getTargetInfo().isTLSSupported())) || 2754 (VD->getStorageClass() == SC_Register && VD->hasAttr<AsmLabelAttr>() && 2755 !VD->isLocalVarDecl())) { 2756 Diag(ILoc, diag::err_omp_var_thread_local) 2757 << VD << ((VD->getTLSKind() != VarDecl::TLS_None) ? 0 : 1); 2758 bool IsDecl = 2759 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 2760 Diag(VD->getLocation(), 2761 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 2762 << VD; 2763 continue; 2764 } 2765 2766 // Check if initial value of threadprivate variable reference variable with 2767 // local storage (it is not supported by runtime). 2768 if (const Expr *Init = VD->getAnyInitializer()) { 2769 LocalVarRefChecker Checker(*this); 2770 if (Checker.Visit(Init)) 2771 continue; 2772 } 2773 2774 Vars.push_back(RefExpr); 2775 DSAStack->addDSA(VD, DE, OMPC_threadprivate); 2776 VD->addAttr(OMPThreadPrivateDeclAttr::CreateImplicit( 2777 Context, SourceRange(Loc, Loc))); 2778 if (ASTMutationListener *ML = Context.getASTMutationListener()) 2779 ML->DeclarationMarkedOpenMPThreadPrivate(VD); 2780 } 2781 OMPThreadPrivateDecl *D = nullptr; 2782 if (!Vars.empty()) { 2783 D = OMPThreadPrivateDecl::Create(Context, getCurLexicalContext(), Loc, 2784 Vars); 2785 D->setAccess(AS_public); 2786 } 2787 return D; 2788 } 2789 2790 static OMPAllocateDeclAttr::AllocatorTypeTy 2791 getAllocatorKind(Sema &S, DSAStackTy *Stack, Expr *Allocator) { 2792 if (!Allocator) 2793 return OMPAllocateDeclAttr::OMPDefaultMemAlloc; 2794 if (Allocator->isTypeDependent() || Allocator->isValueDependent() || 2795 Allocator->isInstantiationDependent() || 2796 Allocator->containsUnexpandedParameterPack()) 2797 return OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; 2798 auto AllocatorKindRes = OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; 2799 const Expr *AE = Allocator->IgnoreParenImpCasts(); 2800 for (int I = OMPAllocateDeclAttr::OMPDefaultMemAlloc; 2801 I < OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; ++I) { 2802 auto AllocatorKind = static_cast<OMPAllocateDeclAttr::AllocatorTypeTy>(I); 2803 const Expr *DefAllocator = Stack->getAllocator(AllocatorKind); 2804 llvm::FoldingSetNodeID AEId, DAEId; 2805 AE->Profile(AEId, S.getASTContext(), /*Canonical=*/true); 2806 DefAllocator->Profile(DAEId, S.getASTContext(), /*Canonical=*/true); 2807 if (AEId == DAEId) { 2808 AllocatorKindRes = AllocatorKind; 2809 break; 2810 } 2811 } 2812 return AllocatorKindRes; 2813 } 2814 2815 static bool checkPreviousOMPAllocateAttribute( 2816 Sema &S, DSAStackTy *Stack, Expr *RefExpr, VarDecl *VD, 2817 OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind, Expr *Allocator) { 2818 if (!VD->hasAttr<OMPAllocateDeclAttr>()) 2819 return false; 2820 const auto *A = VD->getAttr<OMPAllocateDeclAttr>(); 2821 Expr *PrevAllocator = A->getAllocator(); 2822 OMPAllocateDeclAttr::AllocatorTypeTy PrevAllocatorKind = 2823 getAllocatorKind(S, Stack, PrevAllocator); 2824 bool AllocatorsMatch = AllocatorKind == PrevAllocatorKind; 2825 if (AllocatorsMatch && 2826 AllocatorKind == OMPAllocateDeclAttr::OMPUserDefinedMemAlloc && 2827 Allocator && PrevAllocator) { 2828 const Expr *AE = Allocator->IgnoreParenImpCasts(); 2829 const Expr *PAE = PrevAllocator->IgnoreParenImpCasts(); 2830 llvm::FoldingSetNodeID AEId, PAEId; 2831 AE->Profile(AEId, S.Context, /*Canonical=*/true); 2832 PAE->Profile(PAEId, S.Context, /*Canonical=*/true); 2833 AllocatorsMatch = AEId == PAEId; 2834 } 2835 if (!AllocatorsMatch) { 2836 SmallString<256> AllocatorBuffer; 2837 llvm::raw_svector_ostream AllocatorStream(AllocatorBuffer); 2838 if (Allocator) 2839 Allocator->printPretty(AllocatorStream, nullptr, S.getPrintingPolicy()); 2840 SmallString<256> PrevAllocatorBuffer; 2841 llvm::raw_svector_ostream PrevAllocatorStream(PrevAllocatorBuffer); 2842 if (PrevAllocator) 2843 PrevAllocator->printPretty(PrevAllocatorStream, nullptr, 2844 S.getPrintingPolicy()); 2845 2846 SourceLocation AllocatorLoc = 2847 Allocator ? Allocator->getExprLoc() : RefExpr->getExprLoc(); 2848 SourceRange AllocatorRange = 2849 Allocator ? Allocator->getSourceRange() : RefExpr->getSourceRange(); 2850 SourceLocation PrevAllocatorLoc = 2851 PrevAllocator ? PrevAllocator->getExprLoc() : A->getLocation(); 2852 SourceRange PrevAllocatorRange = 2853 PrevAllocator ? PrevAllocator->getSourceRange() : A->getRange(); 2854 S.Diag(AllocatorLoc, diag::warn_omp_used_different_allocator) 2855 << (Allocator ? 1 : 0) << AllocatorStream.str() 2856 << (PrevAllocator ? 1 : 0) << PrevAllocatorStream.str() 2857 << AllocatorRange; 2858 S.Diag(PrevAllocatorLoc, diag::note_omp_previous_allocator) 2859 << PrevAllocatorRange; 2860 return true; 2861 } 2862 return false; 2863 } 2864 2865 static void 2866 applyOMPAllocateAttribute(Sema &S, VarDecl *VD, 2867 OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind, 2868 Expr *Allocator, SourceRange SR) { 2869 if (VD->hasAttr<OMPAllocateDeclAttr>()) 2870 return; 2871 if (Allocator && 2872 (Allocator->isTypeDependent() || Allocator->isValueDependent() || 2873 Allocator->isInstantiationDependent() || 2874 Allocator->containsUnexpandedParameterPack())) 2875 return; 2876 auto *A = OMPAllocateDeclAttr::CreateImplicit(S.Context, AllocatorKind, 2877 Allocator, SR); 2878 VD->addAttr(A); 2879 if (ASTMutationListener *ML = S.Context.getASTMutationListener()) 2880 ML->DeclarationMarkedOpenMPAllocate(VD, A); 2881 } 2882 2883 Sema::DeclGroupPtrTy Sema::ActOnOpenMPAllocateDirective( 2884 SourceLocation Loc, ArrayRef<Expr *> VarList, 2885 ArrayRef<OMPClause *> Clauses, DeclContext *Owner) { 2886 assert(Clauses.size() <= 1 && "Expected at most one clause."); 2887 Expr *Allocator = nullptr; 2888 if (Clauses.empty()) { 2889 // OpenMP 5.0, 2.11.3 allocate Directive, Restrictions. 2890 // allocate directives that appear in a target region must specify an 2891 // allocator clause unless a requires directive with the dynamic_allocators 2892 // clause is present in the same compilation unit. 2893 if (LangOpts.OpenMPIsDevice && 2894 !DSAStack->hasRequiresDeclWithClause<OMPDynamicAllocatorsClause>()) 2895 targetDiag(Loc, diag::err_expected_allocator_clause); 2896 } else { 2897 Allocator = cast<OMPAllocatorClause>(Clauses.back())->getAllocator(); 2898 } 2899 OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind = 2900 getAllocatorKind(*this, DSAStack, Allocator); 2901 SmallVector<Expr *, 8> Vars; 2902 for (Expr *RefExpr : VarList) { 2903 auto *DE = cast<DeclRefExpr>(RefExpr); 2904 auto *VD = cast<VarDecl>(DE->getDecl()); 2905 2906 // Check if this is a TLS variable or global register. 2907 if (VD->getTLSKind() != VarDecl::TLS_None || 2908 VD->hasAttr<OMPThreadPrivateDeclAttr>() || 2909 (VD->getStorageClass() == SC_Register && VD->hasAttr<AsmLabelAttr>() && 2910 !VD->isLocalVarDecl())) 2911 continue; 2912 2913 // If the used several times in the allocate directive, the same allocator 2914 // must be used. 2915 if (checkPreviousOMPAllocateAttribute(*this, DSAStack, RefExpr, VD, 2916 AllocatorKind, Allocator)) 2917 continue; 2918 2919 // OpenMP, 2.11.3 allocate Directive, Restrictions, C / C++ 2920 // If a list item has a static storage type, the allocator expression in the 2921 // allocator clause must be a constant expression that evaluates to one of 2922 // the predefined memory allocator values. 2923 if (Allocator && VD->hasGlobalStorage()) { 2924 if (AllocatorKind == OMPAllocateDeclAttr::OMPUserDefinedMemAlloc) { 2925 Diag(Allocator->getExprLoc(), 2926 diag::err_omp_expected_predefined_allocator) 2927 << Allocator->getSourceRange(); 2928 bool IsDecl = VD->isThisDeclarationADefinition(Context) == 2929 VarDecl::DeclarationOnly; 2930 Diag(VD->getLocation(), 2931 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 2932 << VD; 2933 continue; 2934 } 2935 } 2936 2937 Vars.push_back(RefExpr); 2938 applyOMPAllocateAttribute(*this, VD, AllocatorKind, Allocator, 2939 DE->getSourceRange()); 2940 } 2941 if (Vars.empty()) 2942 return nullptr; 2943 if (!Owner) 2944 Owner = getCurLexicalContext(); 2945 auto *D = OMPAllocateDecl::Create(Context, Owner, Loc, Vars, Clauses); 2946 D->setAccess(AS_public); 2947 Owner->addDecl(D); 2948 return DeclGroupPtrTy::make(DeclGroupRef(D)); 2949 } 2950 2951 Sema::DeclGroupPtrTy 2952 Sema::ActOnOpenMPRequiresDirective(SourceLocation Loc, 2953 ArrayRef<OMPClause *> ClauseList) { 2954 OMPRequiresDecl *D = nullptr; 2955 if (!CurContext->isFileContext()) { 2956 Diag(Loc, diag::err_omp_invalid_scope) << "requires"; 2957 } else { 2958 D = CheckOMPRequiresDecl(Loc, ClauseList); 2959 if (D) { 2960 CurContext->addDecl(D); 2961 DSAStack->addRequiresDecl(D); 2962 } 2963 } 2964 return DeclGroupPtrTy::make(DeclGroupRef(D)); 2965 } 2966 2967 OMPRequiresDecl *Sema::CheckOMPRequiresDecl(SourceLocation Loc, 2968 ArrayRef<OMPClause *> ClauseList) { 2969 /// For target specific clauses, the requires directive cannot be 2970 /// specified after the handling of any of the target regions in the 2971 /// current compilation unit. 2972 ArrayRef<SourceLocation> TargetLocations = 2973 DSAStack->getEncounteredTargetLocs(); 2974 SourceLocation AtomicLoc = DSAStack->getAtomicDirectiveLoc(); 2975 if (!TargetLocations.empty() || !AtomicLoc.isInvalid()) { 2976 for (const OMPClause *CNew : ClauseList) { 2977 // Check if any of the requires clauses affect target regions. 2978 if (isa<OMPUnifiedSharedMemoryClause>(CNew) || 2979 isa<OMPUnifiedAddressClause>(CNew) || 2980 isa<OMPReverseOffloadClause>(CNew) || 2981 isa<OMPDynamicAllocatorsClause>(CNew)) { 2982 Diag(Loc, diag::err_omp_directive_before_requires) 2983 << "target" << getOpenMPClauseName(CNew->getClauseKind()); 2984 for (SourceLocation TargetLoc : TargetLocations) { 2985 Diag(TargetLoc, diag::note_omp_requires_encountered_directive) 2986 << "target"; 2987 } 2988 } else if (!AtomicLoc.isInvalid() && 2989 isa<OMPAtomicDefaultMemOrderClause>(CNew)) { 2990 Diag(Loc, diag::err_omp_directive_before_requires) 2991 << "atomic" << getOpenMPClauseName(CNew->getClauseKind()); 2992 Diag(AtomicLoc, diag::note_omp_requires_encountered_directive) 2993 << "atomic"; 2994 } 2995 } 2996 } 2997 2998 if (!DSAStack->hasDuplicateRequiresClause(ClauseList)) 2999 return OMPRequiresDecl::Create(Context, getCurLexicalContext(), Loc, 3000 ClauseList); 3001 return nullptr; 3002 } 3003 3004 static void reportOriginalDsa(Sema &SemaRef, const DSAStackTy *Stack, 3005 const ValueDecl *D, 3006 const DSAStackTy::DSAVarData &DVar, 3007 bool IsLoopIterVar = false) { 3008 if (DVar.RefExpr) { 3009 SemaRef.Diag(DVar.RefExpr->getExprLoc(), diag::note_omp_explicit_dsa) 3010 << getOpenMPClauseName(DVar.CKind); 3011 return; 3012 } 3013 enum { 3014 PDSA_StaticMemberShared, 3015 PDSA_StaticLocalVarShared, 3016 PDSA_LoopIterVarPrivate, 3017 PDSA_LoopIterVarLinear, 3018 PDSA_LoopIterVarLastprivate, 3019 PDSA_ConstVarShared, 3020 PDSA_GlobalVarShared, 3021 PDSA_TaskVarFirstprivate, 3022 PDSA_LocalVarPrivate, 3023 PDSA_Implicit 3024 } Reason = PDSA_Implicit; 3025 bool ReportHint = false; 3026 auto ReportLoc = D->getLocation(); 3027 auto *VD = dyn_cast<VarDecl>(D); 3028 if (IsLoopIterVar) { 3029 if (DVar.CKind == OMPC_private) 3030 Reason = PDSA_LoopIterVarPrivate; 3031 else if (DVar.CKind == OMPC_lastprivate) 3032 Reason = PDSA_LoopIterVarLastprivate; 3033 else 3034 Reason = PDSA_LoopIterVarLinear; 3035 } else if (isOpenMPTaskingDirective(DVar.DKind) && 3036 DVar.CKind == OMPC_firstprivate) { 3037 Reason = PDSA_TaskVarFirstprivate; 3038 ReportLoc = DVar.ImplicitDSALoc; 3039 } else if (VD && VD->isStaticLocal()) 3040 Reason = PDSA_StaticLocalVarShared; 3041 else if (VD && VD->isStaticDataMember()) 3042 Reason = PDSA_StaticMemberShared; 3043 else if (VD && VD->isFileVarDecl()) 3044 Reason = PDSA_GlobalVarShared; 3045 else if (D->getType().isConstant(SemaRef.getASTContext())) 3046 Reason = PDSA_ConstVarShared; 3047 else if (VD && VD->isLocalVarDecl() && DVar.CKind == OMPC_private) { 3048 ReportHint = true; 3049 Reason = PDSA_LocalVarPrivate; 3050 } 3051 if (Reason != PDSA_Implicit) { 3052 SemaRef.Diag(ReportLoc, diag::note_omp_predetermined_dsa) 3053 << Reason << ReportHint 3054 << getOpenMPDirectiveName(Stack->getCurrentDirective()); 3055 } else if (DVar.ImplicitDSALoc.isValid()) { 3056 SemaRef.Diag(DVar.ImplicitDSALoc, diag::note_omp_implicit_dsa) 3057 << getOpenMPClauseName(DVar.CKind); 3058 } 3059 } 3060 3061 static OpenMPMapClauseKind 3062 getMapClauseKindFromModifier(OpenMPDefaultmapClauseModifier M, 3063 bool IsAggregateOrDeclareTarget) { 3064 OpenMPMapClauseKind Kind = OMPC_MAP_unknown; 3065 switch (M) { 3066 case OMPC_DEFAULTMAP_MODIFIER_alloc: 3067 Kind = OMPC_MAP_alloc; 3068 break; 3069 case OMPC_DEFAULTMAP_MODIFIER_to: 3070 Kind = OMPC_MAP_to; 3071 break; 3072 case OMPC_DEFAULTMAP_MODIFIER_from: 3073 Kind = OMPC_MAP_from; 3074 break; 3075 case OMPC_DEFAULTMAP_MODIFIER_tofrom: 3076 Kind = OMPC_MAP_tofrom; 3077 break; 3078 case OMPC_DEFAULTMAP_MODIFIER_firstprivate: 3079 case OMPC_DEFAULTMAP_MODIFIER_last: 3080 llvm_unreachable("Unexpected defaultmap implicit behavior"); 3081 case OMPC_DEFAULTMAP_MODIFIER_none: 3082 case OMPC_DEFAULTMAP_MODIFIER_default: 3083 case OMPC_DEFAULTMAP_MODIFIER_unknown: 3084 // IsAggregateOrDeclareTarget could be true if: 3085 // 1. the implicit behavior for aggregate is tofrom 3086 // 2. it's a declare target link 3087 if (IsAggregateOrDeclareTarget) { 3088 Kind = OMPC_MAP_tofrom; 3089 break; 3090 } 3091 llvm_unreachable("Unexpected defaultmap implicit behavior"); 3092 } 3093 assert(Kind != OMPC_MAP_unknown && "Expect map kind to be known"); 3094 return Kind; 3095 } 3096 3097 namespace { 3098 class DSAAttrChecker final : public StmtVisitor<DSAAttrChecker, void> { 3099 DSAStackTy *Stack; 3100 Sema &SemaRef; 3101 bool ErrorFound = false; 3102 bool TryCaptureCXXThisMembers = false; 3103 CapturedStmt *CS = nullptr; 3104 llvm::SmallVector<Expr *, 4> ImplicitFirstprivate; 3105 llvm::SmallVector<Expr *, 4> ImplicitMap[OMPC_MAP_delete]; 3106 Sema::VarsWithInheritedDSAType VarsWithInheritedDSA; 3107 llvm::SmallDenseSet<const ValueDecl *, 4> ImplicitDeclarations; 3108 3109 void VisitSubCaptures(OMPExecutableDirective *S) { 3110 // Check implicitly captured variables. 3111 if (!S->hasAssociatedStmt() || !S->getAssociatedStmt()) 3112 return; 3113 visitSubCaptures(S->getInnermostCapturedStmt()); 3114 // Try to capture inner this->member references to generate correct mappings 3115 // and diagnostics. 3116 if (TryCaptureCXXThisMembers || 3117 (isOpenMPTargetExecutionDirective(Stack->getCurrentDirective()) && 3118 llvm::any_of(S->getInnermostCapturedStmt()->captures(), 3119 [](const CapturedStmt::Capture &C) { 3120 return C.capturesThis(); 3121 }))) { 3122 bool SavedTryCaptureCXXThisMembers = TryCaptureCXXThisMembers; 3123 TryCaptureCXXThisMembers = true; 3124 Visit(S->getInnermostCapturedStmt()->getCapturedStmt()); 3125 TryCaptureCXXThisMembers = SavedTryCaptureCXXThisMembers; 3126 } 3127 // In tasks firstprivates are not captured anymore, need to analyze them 3128 // explicitly. 3129 if (isOpenMPTaskingDirective(S->getDirectiveKind()) && 3130 !isOpenMPTaskLoopDirective(S->getDirectiveKind())) { 3131 for (OMPClause *C : S->clauses()) 3132 if (auto *FC = dyn_cast<OMPFirstprivateClause>(C)) { 3133 for (Expr *Ref : FC->varlists()) 3134 Visit(Ref); 3135 } 3136 } 3137 } 3138 3139 public: 3140 void VisitDeclRefExpr(DeclRefExpr *E) { 3141 if (TryCaptureCXXThisMembers || E->isTypeDependent() || 3142 E->isValueDependent() || E->containsUnexpandedParameterPack() || 3143 E->isInstantiationDependent()) 3144 return; 3145 if (auto *VD = dyn_cast<VarDecl>(E->getDecl())) { 3146 // Check the datasharing rules for the expressions in the clauses. 3147 if (!CS) { 3148 if (auto *CED = dyn_cast<OMPCapturedExprDecl>(VD)) 3149 if (!CED->hasAttr<OMPCaptureNoInitAttr>()) { 3150 Visit(CED->getInit()); 3151 return; 3152 } 3153 } else if (VD->isImplicit() || isa<OMPCapturedExprDecl>(VD)) 3154 // Do not analyze internal variables and do not enclose them into 3155 // implicit clauses. 3156 return; 3157 VD = VD->getCanonicalDecl(); 3158 // Skip internally declared variables. 3159 if (VD->hasLocalStorage() && CS && !CS->capturesVariable(VD) && 3160 !Stack->isImplicitTaskFirstprivate(VD)) 3161 return; 3162 3163 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(VD, /*FromParent=*/false); 3164 // Check if the variable has explicit DSA set and stop analysis if it so. 3165 if (DVar.RefExpr || !ImplicitDeclarations.insert(VD).second) 3166 return; 3167 3168 // Skip internally declared static variables. 3169 llvm::Optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res = 3170 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD); 3171 if (VD->hasGlobalStorage() && CS && !CS->capturesVariable(VD) && 3172 (Stack->hasRequiresDeclWithClause<OMPUnifiedSharedMemoryClause>() || 3173 !Res || *Res != OMPDeclareTargetDeclAttr::MT_Link) && 3174 !Stack->isImplicitTaskFirstprivate(VD)) 3175 return; 3176 3177 SourceLocation ELoc = E->getExprLoc(); 3178 OpenMPDirectiveKind DKind = Stack->getCurrentDirective(); 3179 // The default(none) clause requires that each variable that is referenced 3180 // in the construct, and does not have a predetermined data-sharing 3181 // attribute, must have its data-sharing attribute explicitly determined 3182 // by being listed in a data-sharing attribute clause. 3183 if (DVar.CKind == OMPC_unknown && Stack->getDefaultDSA() == DSA_none && 3184 isImplicitOrExplicitTaskingRegion(DKind) && 3185 VarsWithInheritedDSA.count(VD) == 0) { 3186 VarsWithInheritedDSA[VD] = E; 3187 return; 3188 } 3189 3190 // OpenMP 5.0 [2.19.7.2, defaultmap clause, Description] 3191 // If implicit-behavior is none, each variable referenced in the 3192 // construct that does not have a predetermined data-sharing attribute 3193 // and does not appear in a to or link clause on a declare target 3194 // directive must be listed in a data-mapping attribute clause, a 3195 // data-haring attribute clause (including a data-sharing attribute 3196 // clause on a combined construct where target. is one of the 3197 // constituent constructs), or an is_device_ptr clause. 3198 OpenMPDefaultmapClauseKind ClauseKind = 3199 getVariableCategoryFromDecl(SemaRef.getLangOpts(), VD); 3200 if (SemaRef.getLangOpts().OpenMP >= 50) { 3201 bool IsModifierNone = Stack->getDefaultmapModifier(ClauseKind) == 3202 OMPC_DEFAULTMAP_MODIFIER_none; 3203 if (DVar.CKind == OMPC_unknown && IsModifierNone && 3204 VarsWithInheritedDSA.count(VD) == 0 && !Res) { 3205 // Only check for data-mapping attribute and is_device_ptr here 3206 // since we have already make sure that the declaration does not 3207 // have a data-sharing attribute above 3208 if (!Stack->checkMappableExprComponentListsForDecl( 3209 VD, /*CurrentRegionOnly=*/true, 3210 [VD](OMPClauseMappableExprCommon::MappableExprComponentListRef 3211 MapExprComponents, 3212 OpenMPClauseKind) { 3213 auto MI = MapExprComponents.rbegin(); 3214 auto ME = MapExprComponents.rend(); 3215 return MI != ME && MI->getAssociatedDeclaration() == VD; 3216 })) { 3217 VarsWithInheritedDSA[VD] = E; 3218 return; 3219 } 3220 } 3221 } 3222 3223 if (isOpenMPTargetExecutionDirective(DKind) && 3224 !Stack->isLoopControlVariable(VD).first) { 3225 if (!Stack->checkMappableExprComponentListsForDecl( 3226 VD, /*CurrentRegionOnly=*/true, 3227 [](OMPClauseMappableExprCommon::MappableExprComponentListRef 3228 StackComponents, 3229 OpenMPClauseKind) { 3230 // Variable is used if it has been marked as an array, array 3231 // section, array shaping or the variable iself. 3232 return StackComponents.size() == 1 || 3233 std::all_of( 3234 std::next(StackComponents.rbegin()), 3235 StackComponents.rend(), 3236 [](const OMPClauseMappableExprCommon:: 3237 MappableComponent &MC) { 3238 return MC.getAssociatedDeclaration() == 3239 nullptr && 3240 (isa<OMPArraySectionExpr>( 3241 MC.getAssociatedExpression()) || 3242 isa<OMPArrayShapingExpr>( 3243 MC.getAssociatedExpression()) || 3244 isa<ArraySubscriptExpr>( 3245 MC.getAssociatedExpression())); 3246 }); 3247 })) { 3248 bool IsFirstprivate = false; 3249 // By default lambdas are captured as firstprivates. 3250 if (const auto *RD = 3251 VD->getType().getNonReferenceType()->getAsCXXRecordDecl()) 3252 IsFirstprivate = RD->isLambda(); 3253 IsFirstprivate = 3254 IsFirstprivate || (Stack->mustBeFirstprivate(ClauseKind) && !Res); 3255 if (IsFirstprivate) { 3256 ImplicitFirstprivate.emplace_back(E); 3257 } else { 3258 OpenMPDefaultmapClauseModifier M = 3259 Stack->getDefaultmapModifier(ClauseKind); 3260 OpenMPMapClauseKind Kind = getMapClauseKindFromModifier( 3261 M, ClauseKind == OMPC_DEFAULTMAP_aggregate || Res); 3262 ImplicitMap[Kind].emplace_back(E); 3263 } 3264 return; 3265 } 3266 } 3267 3268 // OpenMP [2.9.3.6, Restrictions, p.2] 3269 // A list item that appears in a reduction clause of the innermost 3270 // enclosing worksharing or parallel construct may not be accessed in an 3271 // explicit task. 3272 DVar = Stack->hasInnermostDSA( 3273 VD, [](OpenMPClauseKind C) { return C == OMPC_reduction; }, 3274 [](OpenMPDirectiveKind K) { 3275 return isOpenMPParallelDirective(K) || 3276 isOpenMPWorksharingDirective(K) || isOpenMPTeamsDirective(K); 3277 }, 3278 /*FromParent=*/true); 3279 if (isOpenMPTaskingDirective(DKind) && DVar.CKind == OMPC_reduction) { 3280 ErrorFound = true; 3281 SemaRef.Diag(ELoc, diag::err_omp_reduction_in_task); 3282 reportOriginalDsa(SemaRef, Stack, VD, DVar); 3283 return; 3284 } 3285 3286 // Define implicit data-sharing attributes for task. 3287 DVar = Stack->getImplicitDSA(VD, /*FromParent=*/false); 3288 if (isOpenMPTaskingDirective(DKind) && DVar.CKind != OMPC_shared && 3289 !Stack->isLoopControlVariable(VD).first) { 3290 ImplicitFirstprivate.push_back(E); 3291 return; 3292 } 3293 3294 // Store implicitly used globals with declare target link for parent 3295 // target. 3296 if (!isOpenMPTargetExecutionDirective(DKind) && Res && 3297 *Res == OMPDeclareTargetDeclAttr::MT_Link) { 3298 Stack->addToParentTargetRegionLinkGlobals(E); 3299 return; 3300 } 3301 } 3302 } 3303 void VisitMemberExpr(MemberExpr *E) { 3304 if (E->isTypeDependent() || E->isValueDependent() || 3305 E->containsUnexpandedParameterPack() || E->isInstantiationDependent()) 3306 return; 3307 auto *FD = dyn_cast<FieldDecl>(E->getMemberDecl()); 3308 OpenMPDirectiveKind DKind = Stack->getCurrentDirective(); 3309 if (auto *TE = dyn_cast<CXXThisExpr>(E->getBase()->IgnoreParenCasts())) { 3310 if (!FD) 3311 return; 3312 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(FD, /*FromParent=*/false); 3313 // Check if the variable has explicit DSA set and stop analysis if it 3314 // so. 3315 if (DVar.RefExpr || !ImplicitDeclarations.insert(FD).second) 3316 return; 3317 3318 if (isOpenMPTargetExecutionDirective(DKind) && 3319 !Stack->isLoopControlVariable(FD).first && 3320 !Stack->checkMappableExprComponentListsForDecl( 3321 FD, /*CurrentRegionOnly=*/true, 3322 [](OMPClauseMappableExprCommon::MappableExprComponentListRef 3323 StackComponents, 3324 OpenMPClauseKind) { 3325 return isa<CXXThisExpr>( 3326 cast<MemberExpr>( 3327 StackComponents.back().getAssociatedExpression()) 3328 ->getBase() 3329 ->IgnoreParens()); 3330 })) { 3331 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.3] 3332 // A bit-field cannot appear in a map clause. 3333 // 3334 if (FD->isBitField()) 3335 return; 3336 3337 // Check to see if the member expression is referencing a class that 3338 // has already been explicitly mapped 3339 if (Stack->isClassPreviouslyMapped(TE->getType())) 3340 return; 3341 3342 OpenMPDefaultmapClauseModifier Modifier = 3343 Stack->getDefaultmapModifier(OMPC_DEFAULTMAP_aggregate); 3344 OpenMPMapClauseKind Kind = getMapClauseKindFromModifier( 3345 Modifier, /*IsAggregateOrDeclareTarget*/ true); 3346 ImplicitMap[Kind].emplace_back(E); 3347 return; 3348 } 3349 3350 SourceLocation ELoc = E->getExprLoc(); 3351 // OpenMP [2.9.3.6, Restrictions, p.2] 3352 // A list item that appears in a reduction clause of the innermost 3353 // enclosing worksharing or parallel construct may not be accessed in 3354 // an explicit task. 3355 DVar = Stack->hasInnermostDSA( 3356 FD, [](OpenMPClauseKind C) { return C == OMPC_reduction; }, 3357 [](OpenMPDirectiveKind K) { 3358 return isOpenMPParallelDirective(K) || 3359 isOpenMPWorksharingDirective(K) || isOpenMPTeamsDirective(K); 3360 }, 3361 /*FromParent=*/true); 3362 if (isOpenMPTaskingDirective(DKind) && DVar.CKind == OMPC_reduction) { 3363 ErrorFound = true; 3364 SemaRef.Diag(ELoc, diag::err_omp_reduction_in_task); 3365 reportOriginalDsa(SemaRef, Stack, FD, DVar); 3366 return; 3367 } 3368 3369 // Define implicit data-sharing attributes for task. 3370 DVar = Stack->getImplicitDSA(FD, /*FromParent=*/false); 3371 if (isOpenMPTaskingDirective(DKind) && DVar.CKind != OMPC_shared && 3372 !Stack->isLoopControlVariable(FD).first) { 3373 // Check if there is a captured expression for the current field in the 3374 // region. Do not mark it as firstprivate unless there is no captured 3375 // expression. 3376 // TODO: try to make it firstprivate. 3377 if (DVar.CKind != OMPC_unknown) 3378 ImplicitFirstprivate.push_back(E); 3379 } 3380 return; 3381 } 3382 if (isOpenMPTargetExecutionDirective(DKind)) { 3383 OMPClauseMappableExprCommon::MappableExprComponentList CurComponents; 3384 if (!checkMapClauseExpressionBase(SemaRef, E, CurComponents, OMPC_map, 3385 /*NoDiagnose=*/true)) 3386 return; 3387 const auto *VD = cast<ValueDecl>( 3388 CurComponents.back().getAssociatedDeclaration()->getCanonicalDecl()); 3389 if (!Stack->checkMappableExprComponentListsForDecl( 3390 VD, /*CurrentRegionOnly=*/true, 3391 [&CurComponents]( 3392 OMPClauseMappableExprCommon::MappableExprComponentListRef 3393 StackComponents, 3394 OpenMPClauseKind) { 3395 auto CCI = CurComponents.rbegin(); 3396 auto CCE = CurComponents.rend(); 3397 for (const auto &SC : llvm::reverse(StackComponents)) { 3398 // Do both expressions have the same kind? 3399 if (CCI->getAssociatedExpression()->getStmtClass() != 3400 SC.getAssociatedExpression()->getStmtClass()) 3401 if (!((isa<OMPArraySectionExpr>( 3402 SC.getAssociatedExpression()) || 3403 isa<OMPArrayShapingExpr>( 3404 SC.getAssociatedExpression())) && 3405 isa<ArraySubscriptExpr>( 3406 CCI->getAssociatedExpression()))) 3407 return false; 3408 3409 const Decl *CCD = CCI->getAssociatedDeclaration(); 3410 const Decl *SCD = SC.getAssociatedDeclaration(); 3411 CCD = CCD ? CCD->getCanonicalDecl() : nullptr; 3412 SCD = SCD ? SCD->getCanonicalDecl() : nullptr; 3413 if (SCD != CCD) 3414 return false; 3415 std::advance(CCI, 1); 3416 if (CCI == CCE) 3417 break; 3418 } 3419 return true; 3420 })) { 3421 Visit(E->getBase()); 3422 } 3423 } else if (!TryCaptureCXXThisMembers) { 3424 Visit(E->getBase()); 3425 } 3426 } 3427 void VisitOMPExecutableDirective(OMPExecutableDirective *S) { 3428 for (OMPClause *C : S->clauses()) { 3429 // Skip analysis of arguments of implicitly defined firstprivate clause 3430 // for task|target directives. 3431 // Skip analysis of arguments of implicitly defined map clause for target 3432 // directives. 3433 if (C && !((isa<OMPFirstprivateClause>(C) || isa<OMPMapClause>(C)) && 3434 C->isImplicit())) { 3435 for (Stmt *CC : C->children()) { 3436 if (CC) 3437 Visit(CC); 3438 } 3439 } 3440 } 3441 // Check implicitly captured variables. 3442 VisitSubCaptures(S); 3443 } 3444 void VisitStmt(Stmt *S) { 3445 for (Stmt *C : S->children()) { 3446 if (C) { 3447 // Check implicitly captured variables in the task-based directives to 3448 // check if they must be firstprivatized. 3449 Visit(C); 3450 } 3451 } 3452 } 3453 3454 void visitSubCaptures(CapturedStmt *S) { 3455 for (const CapturedStmt::Capture &Cap : S->captures()) { 3456 if (!Cap.capturesVariable() && !Cap.capturesVariableByCopy()) 3457 continue; 3458 VarDecl *VD = Cap.getCapturedVar(); 3459 // Do not try to map the variable if it or its sub-component was mapped 3460 // already. 3461 if (isOpenMPTargetExecutionDirective(Stack->getCurrentDirective()) && 3462 Stack->checkMappableExprComponentListsForDecl( 3463 VD, /*CurrentRegionOnly=*/true, 3464 [](OMPClauseMappableExprCommon::MappableExprComponentListRef, 3465 OpenMPClauseKind) { return true; })) 3466 continue; 3467 DeclRefExpr *DRE = buildDeclRefExpr( 3468 SemaRef, VD, VD->getType().getNonLValueExprType(SemaRef.Context), 3469 Cap.getLocation(), /*RefersToCapture=*/true); 3470 Visit(DRE); 3471 } 3472 } 3473 bool isErrorFound() const { return ErrorFound; } 3474 ArrayRef<Expr *> getImplicitFirstprivate() const { 3475 return ImplicitFirstprivate; 3476 } 3477 ArrayRef<Expr *> getImplicitMap(OpenMPDefaultmapClauseKind Kind) const { 3478 return ImplicitMap[Kind]; 3479 } 3480 const Sema::VarsWithInheritedDSAType &getVarsWithInheritedDSA() const { 3481 return VarsWithInheritedDSA; 3482 } 3483 3484 DSAAttrChecker(DSAStackTy *S, Sema &SemaRef, CapturedStmt *CS) 3485 : Stack(S), SemaRef(SemaRef), ErrorFound(false), CS(CS) { 3486 // Process declare target link variables for the target directives. 3487 if (isOpenMPTargetExecutionDirective(S->getCurrentDirective())) { 3488 for (DeclRefExpr *E : Stack->getLinkGlobals()) 3489 Visit(E); 3490 } 3491 } 3492 }; 3493 } // namespace 3494 3495 void Sema::ActOnOpenMPRegionStart(OpenMPDirectiveKind DKind, Scope *CurScope) { 3496 switch (DKind) { 3497 case OMPD_parallel: 3498 case OMPD_parallel_for: 3499 case OMPD_parallel_for_simd: 3500 case OMPD_parallel_sections: 3501 case OMPD_parallel_master: 3502 case OMPD_teams: 3503 case OMPD_teams_distribute: 3504 case OMPD_teams_distribute_simd: { 3505 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 3506 QualType KmpInt32PtrTy = 3507 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3508 Sema::CapturedParamNameType Params[] = { 3509 std::make_pair(".global_tid.", KmpInt32PtrTy), 3510 std::make_pair(".bound_tid.", KmpInt32PtrTy), 3511 std::make_pair(StringRef(), QualType()) // __context with shared vars 3512 }; 3513 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3514 Params); 3515 break; 3516 } 3517 case OMPD_target_teams: 3518 case OMPD_target_parallel: 3519 case OMPD_target_parallel_for: 3520 case OMPD_target_parallel_for_simd: 3521 case OMPD_target_teams_distribute: 3522 case OMPD_target_teams_distribute_simd: { 3523 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 3524 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 3525 QualType KmpInt32PtrTy = 3526 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3527 QualType Args[] = {VoidPtrTy}; 3528 FunctionProtoType::ExtProtoInfo EPI; 3529 EPI.Variadic = true; 3530 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 3531 Sema::CapturedParamNameType Params[] = { 3532 std::make_pair(".global_tid.", KmpInt32Ty), 3533 std::make_pair(".part_id.", KmpInt32PtrTy), 3534 std::make_pair(".privates.", VoidPtrTy), 3535 std::make_pair( 3536 ".copy_fn.", 3537 Context.getPointerType(CopyFnType).withConst().withRestrict()), 3538 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 3539 std::make_pair(StringRef(), QualType()) // __context with shared vars 3540 }; 3541 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3542 Params, /*OpenMPCaptureLevel=*/0); 3543 // Mark this captured region as inlined, because we don't use outlined 3544 // function directly. 3545 getCurCapturedRegion()->TheCapturedDecl->addAttr( 3546 AlwaysInlineAttr::CreateImplicit( 3547 Context, {}, AttributeCommonInfo::AS_Keyword, 3548 AlwaysInlineAttr::Keyword_forceinline)); 3549 Sema::CapturedParamNameType ParamsTarget[] = { 3550 std::make_pair(StringRef(), QualType()) // __context with shared vars 3551 }; 3552 // Start a captured region for 'target' with no implicit parameters. 3553 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3554 ParamsTarget, /*OpenMPCaptureLevel=*/1); 3555 Sema::CapturedParamNameType ParamsTeamsOrParallel[] = { 3556 std::make_pair(".global_tid.", KmpInt32PtrTy), 3557 std::make_pair(".bound_tid.", KmpInt32PtrTy), 3558 std::make_pair(StringRef(), QualType()) // __context with shared vars 3559 }; 3560 // Start a captured region for 'teams' or 'parallel'. Both regions have 3561 // the same implicit parameters. 3562 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3563 ParamsTeamsOrParallel, /*OpenMPCaptureLevel=*/2); 3564 break; 3565 } 3566 case OMPD_target: 3567 case OMPD_target_simd: { 3568 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 3569 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 3570 QualType KmpInt32PtrTy = 3571 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3572 QualType Args[] = {VoidPtrTy}; 3573 FunctionProtoType::ExtProtoInfo EPI; 3574 EPI.Variadic = true; 3575 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 3576 Sema::CapturedParamNameType Params[] = { 3577 std::make_pair(".global_tid.", KmpInt32Ty), 3578 std::make_pair(".part_id.", KmpInt32PtrTy), 3579 std::make_pair(".privates.", VoidPtrTy), 3580 std::make_pair( 3581 ".copy_fn.", 3582 Context.getPointerType(CopyFnType).withConst().withRestrict()), 3583 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 3584 std::make_pair(StringRef(), QualType()) // __context with shared vars 3585 }; 3586 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3587 Params, /*OpenMPCaptureLevel=*/0); 3588 // Mark this captured region as inlined, because we don't use outlined 3589 // function directly. 3590 getCurCapturedRegion()->TheCapturedDecl->addAttr( 3591 AlwaysInlineAttr::CreateImplicit( 3592 Context, {}, AttributeCommonInfo::AS_Keyword, 3593 AlwaysInlineAttr::Keyword_forceinline)); 3594 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3595 std::make_pair(StringRef(), QualType()), 3596 /*OpenMPCaptureLevel=*/1); 3597 break; 3598 } 3599 case OMPD_simd: 3600 case OMPD_for: 3601 case OMPD_for_simd: 3602 case OMPD_sections: 3603 case OMPD_section: 3604 case OMPD_single: 3605 case OMPD_master: 3606 case OMPD_critical: 3607 case OMPD_taskgroup: 3608 case OMPD_distribute: 3609 case OMPD_distribute_simd: 3610 case OMPD_ordered: 3611 case OMPD_atomic: 3612 case OMPD_target_data: { 3613 Sema::CapturedParamNameType Params[] = { 3614 std::make_pair(StringRef(), QualType()) // __context with shared vars 3615 }; 3616 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3617 Params); 3618 break; 3619 } 3620 case OMPD_task: { 3621 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 3622 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 3623 QualType KmpInt32PtrTy = 3624 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3625 QualType Args[] = {VoidPtrTy}; 3626 FunctionProtoType::ExtProtoInfo EPI; 3627 EPI.Variadic = true; 3628 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 3629 Sema::CapturedParamNameType Params[] = { 3630 std::make_pair(".global_tid.", KmpInt32Ty), 3631 std::make_pair(".part_id.", KmpInt32PtrTy), 3632 std::make_pair(".privates.", VoidPtrTy), 3633 std::make_pair( 3634 ".copy_fn.", 3635 Context.getPointerType(CopyFnType).withConst().withRestrict()), 3636 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 3637 std::make_pair(StringRef(), QualType()) // __context with shared vars 3638 }; 3639 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3640 Params); 3641 // Mark this captured region as inlined, because we don't use outlined 3642 // function directly. 3643 getCurCapturedRegion()->TheCapturedDecl->addAttr( 3644 AlwaysInlineAttr::CreateImplicit( 3645 Context, {}, AttributeCommonInfo::AS_Keyword, 3646 AlwaysInlineAttr::Keyword_forceinline)); 3647 break; 3648 } 3649 case OMPD_taskloop: 3650 case OMPD_taskloop_simd: 3651 case OMPD_master_taskloop: 3652 case OMPD_master_taskloop_simd: { 3653 QualType KmpInt32Ty = 3654 Context.getIntTypeForBitwidth(/*DestWidth=*/32, /*Signed=*/1) 3655 .withConst(); 3656 QualType KmpUInt64Ty = 3657 Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/0) 3658 .withConst(); 3659 QualType KmpInt64Ty = 3660 Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/1) 3661 .withConst(); 3662 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 3663 QualType KmpInt32PtrTy = 3664 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3665 QualType Args[] = {VoidPtrTy}; 3666 FunctionProtoType::ExtProtoInfo EPI; 3667 EPI.Variadic = true; 3668 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 3669 Sema::CapturedParamNameType Params[] = { 3670 std::make_pair(".global_tid.", KmpInt32Ty), 3671 std::make_pair(".part_id.", KmpInt32PtrTy), 3672 std::make_pair(".privates.", VoidPtrTy), 3673 std::make_pair( 3674 ".copy_fn.", 3675 Context.getPointerType(CopyFnType).withConst().withRestrict()), 3676 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 3677 std::make_pair(".lb.", KmpUInt64Ty), 3678 std::make_pair(".ub.", KmpUInt64Ty), 3679 std::make_pair(".st.", KmpInt64Ty), 3680 std::make_pair(".liter.", KmpInt32Ty), 3681 std::make_pair(".reductions.", VoidPtrTy), 3682 std::make_pair(StringRef(), QualType()) // __context with shared vars 3683 }; 3684 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3685 Params); 3686 // Mark this captured region as inlined, because we don't use outlined 3687 // function directly. 3688 getCurCapturedRegion()->TheCapturedDecl->addAttr( 3689 AlwaysInlineAttr::CreateImplicit( 3690 Context, {}, AttributeCommonInfo::AS_Keyword, 3691 AlwaysInlineAttr::Keyword_forceinline)); 3692 break; 3693 } 3694 case OMPD_parallel_master_taskloop: 3695 case OMPD_parallel_master_taskloop_simd: { 3696 QualType KmpInt32Ty = 3697 Context.getIntTypeForBitwidth(/*DestWidth=*/32, /*Signed=*/1) 3698 .withConst(); 3699 QualType KmpUInt64Ty = 3700 Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/0) 3701 .withConst(); 3702 QualType KmpInt64Ty = 3703 Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/1) 3704 .withConst(); 3705 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 3706 QualType KmpInt32PtrTy = 3707 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3708 Sema::CapturedParamNameType ParamsParallel[] = { 3709 std::make_pair(".global_tid.", KmpInt32PtrTy), 3710 std::make_pair(".bound_tid.", KmpInt32PtrTy), 3711 std::make_pair(StringRef(), QualType()) // __context with shared vars 3712 }; 3713 // Start a captured region for 'parallel'. 3714 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3715 ParamsParallel, /*OpenMPCaptureLevel=*/0); 3716 QualType Args[] = {VoidPtrTy}; 3717 FunctionProtoType::ExtProtoInfo EPI; 3718 EPI.Variadic = true; 3719 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 3720 Sema::CapturedParamNameType Params[] = { 3721 std::make_pair(".global_tid.", KmpInt32Ty), 3722 std::make_pair(".part_id.", KmpInt32PtrTy), 3723 std::make_pair(".privates.", VoidPtrTy), 3724 std::make_pair( 3725 ".copy_fn.", 3726 Context.getPointerType(CopyFnType).withConst().withRestrict()), 3727 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 3728 std::make_pair(".lb.", KmpUInt64Ty), 3729 std::make_pair(".ub.", KmpUInt64Ty), 3730 std::make_pair(".st.", KmpInt64Ty), 3731 std::make_pair(".liter.", KmpInt32Ty), 3732 std::make_pair(".reductions.", VoidPtrTy), 3733 std::make_pair(StringRef(), QualType()) // __context with shared vars 3734 }; 3735 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3736 Params, /*OpenMPCaptureLevel=*/1); 3737 // Mark this captured region as inlined, because we don't use outlined 3738 // function directly. 3739 getCurCapturedRegion()->TheCapturedDecl->addAttr( 3740 AlwaysInlineAttr::CreateImplicit( 3741 Context, {}, AttributeCommonInfo::AS_Keyword, 3742 AlwaysInlineAttr::Keyword_forceinline)); 3743 break; 3744 } 3745 case OMPD_distribute_parallel_for_simd: 3746 case OMPD_distribute_parallel_for: { 3747 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 3748 QualType KmpInt32PtrTy = 3749 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3750 Sema::CapturedParamNameType Params[] = { 3751 std::make_pair(".global_tid.", KmpInt32PtrTy), 3752 std::make_pair(".bound_tid.", KmpInt32PtrTy), 3753 std::make_pair(".previous.lb.", Context.getSizeType().withConst()), 3754 std::make_pair(".previous.ub.", Context.getSizeType().withConst()), 3755 std::make_pair(StringRef(), QualType()) // __context with shared vars 3756 }; 3757 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3758 Params); 3759 break; 3760 } 3761 case OMPD_target_teams_distribute_parallel_for: 3762 case OMPD_target_teams_distribute_parallel_for_simd: { 3763 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 3764 QualType KmpInt32PtrTy = 3765 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3766 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 3767 3768 QualType Args[] = {VoidPtrTy}; 3769 FunctionProtoType::ExtProtoInfo EPI; 3770 EPI.Variadic = true; 3771 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 3772 Sema::CapturedParamNameType Params[] = { 3773 std::make_pair(".global_tid.", KmpInt32Ty), 3774 std::make_pair(".part_id.", KmpInt32PtrTy), 3775 std::make_pair(".privates.", VoidPtrTy), 3776 std::make_pair( 3777 ".copy_fn.", 3778 Context.getPointerType(CopyFnType).withConst().withRestrict()), 3779 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 3780 std::make_pair(StringRef(), QualType()) // __context with shared vars 3781 }; 3782 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3783 Params, /*OpenMPCaptureLevel=*/0); 3784 // Mark this captured region as inlined, because we don't use outlined 3785 // function directly. 3786 getCurCapturedRegion()->TheCapturedDecl->addAttr( 3787 AlwaysInlineAttr::CreateImplicit( 3788 Context, {}, AttributeCommonInfo::AS_Keyword, 3789 AlwaysInlineAttr::Keyword_forceinline)); 3790 Sema::CapturedParamNameType ParamsTarget[] = { 3791 std::make_pair(StringRef(), QualType()) // __context with shared vars 3792 }; 3793 // Start a captured region for 'target' with no implicit parameters. 3794 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3795 ParamsTarget, /*OpenMPCaptureLevel=*/1); 3796 3797 Sema::CapturedParamNameType ParamsTeams[] = { 3798 std::make_pair(".global_tid.", KmpInt32PtrTy), 3799 std::make_pair(".bound_tid.", KmpInt32PtrTy), 3800 std::make_pair(StringRef(), QualType()) // __context with shared vars 3801 }; 3802 // Start a captured region for 'target' with no implicit parameters. 3803 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3804 ParamsTeams, /*OpenMPCaptureLevel=*/2); 3805 3806 Sema::CapturedParamNameType ParamsParallel[] = { 3807 std::make_pair(".global_tid.", KmpInt32PtrTy), 3808 std::make_pair(".bound_tid.", KmpInt32PtrTy), 3809 std::make_pair(".previous.lb.", Context.getSizeType().withConst()), 3810 std::make_pair(".previous.ub.", Context.getSizeType().withConst()), 3811 std::make_pair(StringRef(), QualType()) // __context with shared vars 3812 }; 3813 // Start a captured region for 'teams' or 'parallel'. Both regions have 3814 // the same implicit parameters. 3815 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3816 ParamsParallel, /*OpenMPCaptureLevel=*/3); 3817 break; 3818 } 3819 3820 case OMPD_teams_distribute_parallel_for: 3821 case OMPD_teams_distribute_parallel_for_simd: { 3822 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 3823 QualType KmpInt32PtrTy = 3824 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3825 3826 Sema::CapturedParamNameType ParamsTeams[] = { 3827 std::make_pair(".global_tid.", KmpInt32PtrTy), 3828 std::make_pair(".bound_tid.", KmpInt32PtrTy), 3829 std::make_pair(StringRef(), QualType()) // __context with shared vars 3830 }; 3831 // Start a captured region for 'target' with no implicit parameters. 3832 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3833 ParamsTeams, /*OpenMPCaptureLevel=*/0); 3834 3835 Sema::CapturedParamNameType ParamsParallel[] = { 3836 std::make_pair(".global_tid.", KmpInt32PtrTy), 3837 std::make_pair(".bound_tid.", KmpInt32PtrTy), 3838 std::make_pair(".previous.lb.", Context.getSizeType().withConst()), 3839 std::make_pair(".previous.ub.", Context.getSizeType().withConst()), 3840 std::make_pair(StringRef(), QualType()) // __context with shared vars 3841 }; 3842 // Start a captured region for 'teams' or 'parallel'. Both regions have 3843 // the same implicit parameters. 3844 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3845 ParamsParallel, /*OpenMPCaptureLevel=*/1); 3846 break; 3847 } 3848 case OMPD_target_update: 3849 case OMPD_target_enter_data: 3850 case OMPD_target_exit_data: { 3851 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 3852 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 3853 QualType KmpInt32PtrTy = 3854 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3855 QualType Args[] = {VoidPtrTy}; 3856 FunctionProtoType::ExtProtoInfo EPI; 3857 EPI.Variadic = true; 3858 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 3859 Sema::CapturedParamNameType Params[] = { 3860 std::make_pair(".global_tid.", KmpInt32Ty), 3861 std::make_pair(".part_id.", KmpInt32PtrTy), 3862 std::make_pair(".privates.", VoidPtrTy), 3863 std::make_pair( 3864 ".copy_fn.", 3865 Context.getPointerType(CopyFnType).withConst().withRestrict()), 3866 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 3867 std::make_pair(StringRef(), QualType()) // __context with shared vars 3868 }; 3869 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3870 Params); 3871 // Mark this captured region as inlined, because we don't use outlined 3872 // function directly. 3873 getCurCapturedRegion()->TheCapturedDecl->addAttr( 3874 AlwaysInlineAttr::CreateImplicit( 3875 Context, {}, AttributeCommonInfo::AS_Keyword, 3876 AlwaysInlineAttr::Keyword_forceinline)); 3877 break; 3878 } 3879 case OMPD_threadprivate: 3880 case OMPD_allocate: 3881 case OMPD_taskyield: 3882 case OMPD_barrier: 3883 case OMPD_taskwait: 3884 case OMPD_cancellation_point: 3885 case OMPD_cancel: 3886 case OMPD_flush: 3887 case OMPD_depobj: 3888 case OMPD_scan: 3889 case OMPD_declare_reduction: 3890 case OMPD_declare_mapper: 3891 case OMPD_declare_simd: 3892 case OMPD_declare_target: 3893 case OMPD_end_declare_target: 3894 case OMPD_requires: 3895 case OMPD_declare_variant: 3896 case OMPD_begin_declare_variant: 3897 case OMPD_end_declare_variant: 3898 llvm_unreachable("OpenMP Directive is not allowed"); 3899 case OMPD_unknown: 3900 llvm_unreachable("Unknown OpenMP directive"); 3901 } 3902 } 3903 3904 int Sema::getNumberOfConstructScopes(unsigned Level) const { 3905 return getOpenMPCaptureLevels(DSAStack->getDirective(Level)); 3906 } 3907 3908 int Sema::getOpenMPCaptureLevels(OpenMPDirectiveKind DKind) { 3909 SmallVector<OpenMPDirectiveKind, 4> CaptureRegions; 3910 getOpenMPCaptureRegions(CaptureRegions, DKind); 3911 return CaptureRegions.size(); 3912 } 3913 3914 static OMPCapturedExprDecl *buildCaptureDecl(Sema &S, IdentifierInfo *Id, 3915 Expr *CaptureExpr, bool WithInit, 3916 bool AsExpression) { 3917 assert(CaptureExpr); 3918 ASTContext &C = S.getASTContext(); 3919 Expr *Init = AsExpression ? CaptureExpr : CaptureExpr->IgnoreImpCasts(); 3920 QualType Ty = Init->getType(); 3921 if (CaptureExpr->getObjectKind() == OK_Ordinary && CaptureExpr->isGLValue()) { 3922 if (S.getLangOpts().CPlusPlus) { 3923 Ty = C.getLValueReferenceType(Ty); 3924 } else { 3925 Ty = C.getPointerType(Ty); 3926 ExprResult Res = 3927 S.CreateBuiltinUnaryOp(CaptureExpr->getExprLoc(), UO_AddrOf, Init); 3928 if (!Res.isUsable()) 3929 return nullptr; 3930 Init = Res.get(); 3931 } 3932 WithInit = true; 3933 } 3934 auto *CED = OMPCapturedExprDecl::Create(C, S.CurContext, Id, Ty, 3935 CaptureExpr->getBeginLoc()); 3936 if (!WithInit) 3937 CED->addAttr(OMPCaptureNoInitAttr::CreateImplicit(C)); 3938 S.CurContext->addHiddenDecl(CED); 3939 S.AddInitializerToDecl(CED, Init, /*DirectInit=*/false); 3940 return CED; 3941 } 3942 3943 static DeclRefExpr *buildCapture(Sema &S, ValueDecl *D, Expr *CaptureExpr, 3944 bool WithInit) { 3945 OMPCapturedExprDecl *CD; 3946 if (VarDecl *VD = S.isOpenMPCapturedDecl(D)) 3947 CD = cast<OMPCapturedExprDecl>(VD); 3948 else 3949 CD = buildCaptureDecl(S, D->getIdentifier(), CaptureExpr, WithInit, 3950 /*AsExpression=*/false); 3951 return buildDeclRefExpr(S, CD, CD->getType().getNonReferenceType(), 3952 CaptureExpr->getExprLoc()); 3953 } 3954 3955 static ExprResult buildCapture(Sema &S, Expr *CaptureExpr, DeclRefExpr *&Ref) { 3956 CaptureExpr = S.DefaultLvalueConversion(CaptureExpr).get(); 3957 if (!Ref) { 3958 OMPCapturedExprDecl *CD = buildCaptureDecl( 3959 S, &S.getASTContext().Idents.get(".capture_expr."), CaptureExpr, 3960 /*WithInit=*/true, /*AsExpression=*/true); 3961 Ref = buildDeclRefExpr(S, CD, CD->getType().getNonReferenceType(), 3962 CaptureExpr->getExprLoc()); 3963 } 3964 ExprResult Res = Ref; 3965 if (!S.getLangOpts().CPlusPlus && 3966 CaptureExpr->getObjectKind() == OK_Ordinary && CaptureExpr->isGLValue() && 3967 Ref->getType()->isPointerType()) { 3968 Res = S.CreateBuiltinUnaryOp(CaptureExpr->getExprLoc(), UO_Deref, Ref); 3969 if (!Res.isUsable()) 3970 return ExprError(); 3971 } 3972 return S.DefaultLvalueConversion(Res.get()); 3973 } 3974 3975 namespace { 3976 // OpenMP directives parsed in this section are represented as a 3977 // CapturedStatement with an associated statement. If a syntax error 3978 // is detected during the parsing of the associated statement, the 3979 // compiler must abort processing and close the CapturedStatement. 3980 // 3981 // Combined directives such as 'target parallel' have more than one 3982 // nested CapturedStatements. This RAII ensures that we unwind out 3983 // of all the nested CapturedStatements when an error is found. 3984 class CaptureRegionUnwinderRAII { 3985 private: 3986 Sema &S; 3987 bool &ErrorFound; 3988 OpenMPDirectiveKind DKind = OMPD_unknown; 3989 3990 public: 3991 CaptureRegionUnwinderRAII(Sema &S, bool &ErrorFound, 3992 OpenMPDirectiveKind DKind) 3993 : S(S), ErrorFound(ErrorFound), DKind(DKind) {} 3994 ~CaptureRegionUnwinderRAII() { 3995 if (ErrorFound) { 3996 int ThisCaptureLevel = S.getOpenMPCaptureLevels(DKind); 3997 while (--ThisCaptureLevel >= 0) 3998 S.ActOnCapturedRegionError(); 3999 } 4000 } 4001 }; 4002 } // namespace 4003 4004 void Sema::tryCaptureOpenMPLambdas(ValueDecl *V) { 4005 // Capture variables captured by reference in lambdas for target-based 4006 // directives. 4007 if (!CurContext->isDependentContext() && 4008 (isOpenMPTargetExecutionDirective(DSAStack->getCurrentDirective()) || 4009 isOpenMPTargetDataManagementDirective( 4010 DSAStack->getCurrentDirective()))) { 4011 QualType Type = V->getType(); 4012 if (const auto *RD = Type.getCanonicalType() 4013 .getNonReferenceType() 4014 ->getAsCXXRecordDecl()) { 4015 bool SavedForceCaptureByReferenceInTargetExecutable = 4016 DSAStack->isForceCaptureByReferenceInTargetExecutable(); 4017 DSAStack->setForceCaptureByReferenceInTargetExecutable( 4018 /*V=*/true); 4019 if (RD->isLambda()) { 4020 llvm::DenseMap<const VarDecl *, FieldDecl *> Captures; 4021 FieldDecl *ThisCapture; 4022 RD->getCaptureFields(Captures, ThisCapture); 4023 for (const LambdaCapture &LC : RD->captures()) { 4024 if (LC.getCaptureKind() == LCK_ByRef) { 4025 VarDecl *VD = LC.getCapturedVar(); 4026 DeclContext *VDC = VD->getDeclContext(); 4027 if (!VDC->Encloses(CurContext)) 4028 continue; 4029 MarkVariableReferenced(LC.getLocation(), VD); 4030 } else if (LC.getCaptureKind() == LCK_This) { 4031 QualType ThisTy = getCurrentThisType(); 4032 if (!ThisTy.isNull() && 4033 Context.typesAreCompatible(ThisTy, ThisCapture->getType())) 4034 CheckCXXThisCapture(LC.getLocation()); 4035 } 4036 } 4037 } 4038 DSAStack->setForceCaptureByReferenceInTargetExecutable( 4039 SavedForceCaptureByReferenceInTargetExecutable); 4040 } 4041 } 4042 } 4043 4044 static bool checkOrderedOrderSpecified(Sema &S, 4045 const ArrayRef<OMPClause *> Clauses) { 4046 const OMPOrderedClause *Ordered = nullptr; 4047 const OMPOrderClause *Order = nullptr; 4048 4049 for (const OMPClause *Clause : Clauses) { 4050 if (Clause->getClauseKind() == OMPC_ordered) 4051 Ordered = cast<OMPOrderedClause>(Clause); 4052 else if (Clause->getClauseKind() == OMPC_order) { 4053 Order = cast<OMPOrderClause>(Clause); 4054 if (Order->getKind() != OMPC_ORDER_concurrent) 4055 Order = nullptr; 4056 } 4057 if (Ordered && Order) 4058 break; 4059 } 4060 4061 if (Ordered && Order) { 4062 S.Diag(Order->getKindKwLoc(), 4063 diag::err_omp_simple_clause_incompatible_with_ordered) 4064 << getOpenMPClauseName(OMPC_order) 4065 << getOpenMPSimpleClauseTypeName(OMPC_order, OMPC_ORDER_concurrent) 4066 << SourceRange(Order->getBeginLoc(), Order->getEndLoc()); 4067 S.Diag(Ordered->getBeginLoc(), diag::note_omp_ordered_param) 4068 << 0 << SourceRange(Ordered->getBeginLoc(), Ordered->getEndLoc()); 4069 return true; 4070 } 4071 return false; 4072 } 4073 4074 StmtResult Sema::ActOnOpenMPRegionEnd(StmtResult S, 4075 ArrayRef<OMPClause *> Clauses) { 4076 bool ErrorFound = false; 4077 CaptureRegionUnwinderRAII CaptureRegionUnwinder( 4078 *this, ErrorFound, DSAStack->getCurrentDirective()); 4079 if (!S.isUsable()) { 4080 ErrorFound = true; 4081 return StmtError(); 4082 } 4083 4084 SmallVector<OpenMPDirectiveKind, 4> CaptureRegions; 4085 getOpenMPCaptureRegions(CaptureRegions, DSAStack->getCurrentDirective()); 4086 OMPOrderedClause *OC = nullptr; 4087 OMPScheduleClause *SC = nullptr; 4088 SmallVector<const OMPLinearClause *, 4> LCs; 4089 SmallVector<const OMPClauseWithPreInit *, 4> PICs; 4090 // This is required for proper codegen. 4091 for (OMPClause *Clause : Clauses) { 4092 if (isOpenMPTaskingDirective(DSAStack->getCurrentDirective()) && 4093 Clause->getClauseKind() == OMPC_in_reduction) { 4094 // Capture taskgroup task_reduction descriptors inside the tasking regions 4095 // with the corresponding in_reduction items. 4096 auto *IRC = cast<OMPInReductionClause>(Clause); 4097 for (Expr *E : IRC->taskgroup_descriptors()) 4098 if (E) 4099 MarkDeclarationsReferencedInExpr(E); 4100 } 4101 if (isOpenMPPrivate(Clause->getClauseKind()) || 4102 Clause->getClauseKind() == OMPC_copyprivate || 4103 (getLangOpts().OpenMPUseTLS && 4104 getASTContext().getTargetInfo().isTLSSupported() && 4105 Clause->getClauseKind() == OMPC_copyin)) { 4106 DSAStack->setForceVarCapturing(Clause->getClauseKind() == OMPC_copyin); 4107 // Mark all variables in private list clauses as used in inner region. 4108 for (Stmt *VarRef : Clause->children()) { 4109 if (auto *E = cast_or_null<Expr>(VarRef)) { 4110 MarkDeclarationsReferencedInExpr(E); 4111 } 4112 } 4113 DSAStack->setForceVarCapturing(/*V=*/false); 4114 } else if (CaptureRegions.size() > 1 || 4115 CaptureRegions.back() != OMPD_unknown) { 4116 if (auto *C = OMPClauseWithPreInit::get(Clause)) 4117 PICs.push_back(C); 4118 if (auto *C = OMPClauseWithPostUpdate::get(Clause)) { 4119 if (Expr *E = C->getPostUpdateExpr()) 4120 MarkDeclarationsReferencedInExpr(E); 4121 } 4122 } 4123 if (Clause->getClauseKind() == OMPC_schedule) 4124 SC = cast<OMPScheduleClause>(Clause); 4125 else if (Clause->getClauseKind() == OMPC_ordered) 4126 OC = cast<OMPOrderedClause>(Clause); 4127 else if (Clause->getClauseKind() == OMPC_linear) 4128 LCs.push_back(cast<OMPLinearClause>(Clause)); 4129 } 4130 // Capture allocator expressions if used. 4131 for (Expr *E : DSAStack->getInnerAllocators()) 4132 MarkDeclarationsReferencedInExpr(E); 4133 // OpenMP, 2.7.1 Loop Construct, Restrictions 4134 // The nonmonotonic modifier cannot be specified if an ordered clause is 4135 // specified. 4136 if (SC && 4137 (SC->getFirstScheduleModifier() == OMPC_SCHEDULE_MODIFIER_nonmonotonic || 4138 SC->getSecondScheduleModifier() == 4139 OMPC_SCHEDULE_MODIFIER_nonmonotonic) && 4140 OC) { 4141 Diag(SC->getFirstScheduleModifier() == OMPC_SCHEDULE_MODIFIER_nonmonotonic 4142 ? SC->getFirstScheduleModifierLoc() 4143 : SC->getSecondScheduleModifierLoc(), 4144 diag::err_omp_simple_clause_incompatible_with_ordered) 4145 << getOpenMPClauseName(OMPC_schedule) 4146 << getOpenMPSimpleClauseTypeName(OMPC_schedule, 4147 OMPC_SCHEDULE_MODIFIER_nonmonotonic) 4148 << SourceRange(OC->getBeginLoc(), OC->getEndLoc()); 4149 ErrorFound = true; 4150 } 4151 // OpenMP 5.0, 2.9.2 Worksharing-Loop Construct, Restrictions. 4152 // If an order(concurrent) clause is present, an ordered clause may not appear 4153 // on the same directive. 4154 if (checkOrderedOrderSpecified(*this, Clauses)) 4155 ErrorFound = true; 4156 if (!LCs.empty() && OC && OC->getNumForLoops()) { 4157 for (const OMPLinearClause *C : LCs) { 4158 Diag(C->getBeginLoc(), diag::err_omp_linear_ordered) 4159 << SourceRange(OC->getBeginLoc(), OC->getEndLoc()); 4160 } 4161 ErrorFound = true; 4162 } 4163 if (isOpenMPWorksharingDirective(DSAStack->getCurrentDirective()) && 4164 isOpenMPSimdDirective(DSAStack->getCurrentDirective()) && OC && 4165 OC->getNumForLoops()) { 4166 Diag(OC->getBeginLoc(), diag::err_omp_ordered_simd) 4167 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 4168 ErrorFound = true; 4169 } 4170 if (ErrorFound) { 4171 return StmtError(); 4172 } 4173 StmtResult SR = S; 4174 unsigned CompletedRegions = 0; 4175 for (OpenMPDirectiveKind ThisCaptureRegion : llvm::reverse(CaptureRegions)) { 4176 // Mark all variables in private list clauses as used in inner region. 4177 // Required for proper codegen of combined directives. 4178 // TODO: add processing for other clauses. 4179 if (ThisCaptureRegion != OMPD_unknown) { 4180 for (const clang::OMPClauseWithPreInit *C : PICs) { 4181 OpenMPDirectiveKind CaptureRegion = C->getCaptureRegion(); 4182 // Find the particular capture region for the clause if the 4183 // directive is a combined one with multiple capture regions. 4184 // If the directive is not a combined one, the capture region 4185 // associated with the clause is OMPD_unknown and is generated 4186 // only once. 4187 if (CaptureRegion == ThisCaptureRegion || 4188 CaptureRegion == OMPD_unknown) { 4189 if (auto *DS = cast_or_null<DeclStmt>(C->getPreInitStmt())) { 4190 for (Decl *D : DS->decls()) 4191 MarkVariableReferenced(D->getLocation(), cast<VarDecl>(D)); 4192 } 4193 } 4194 } 4195 } 4196 if (++CompletedRegions == CaptureRegions.size()) 4197 DSAStack->setBodyComplete(); 4198 SR = ActOnCapturedRegionEnd(SR.get()); 4199 } 4200 return SR; 4201 } 4202 4203 static bool checkCancelRegion(Sema &SemaRef, OpenMPDirectiveKind CurrentRegion, 4204 OpenMPDirectiveKind CancelRegion, 4205 SourceLocation StartLoc) { 4206 // CancelRegion is only needed for cancel and cancellation_point. 4207 if (CurrentRegion != OMPD_cancel && CurrentRegion != OMPD_cancellation_point) 4208 return false; 4209 4210 if (CancelRegion == OMPD_parallel || CancelRegion == OMPD_for || 4211 CancelRegion == OMPD_sections || CancelRegion == OMPD_taskgroup) 4212 return false; 4213 4214 SemaRef.Diag(StartLoc, diag::err_omp_wrong_cancel_region) 4215 << getOpenMPDirectiveName(CancelRegion); 4216 return true; 4217 } 4218 4219 static bool checkNestingOfRegions(Sema &SemaRef, const DSAStackTy *Stack, 4220 OpenMPDirectiveKind CurrentRegion, 4221 const DeclarationNameInfo &CurrentName, 4222 OpenMPDirectiveKind CancelRegion, 4223 SourceLocation StartLoc) { 4224 if (Stack->getCurScope()) { 4225 OpenMPDirectiveKind ParentRegion = Stack->getParentDirective(); 4226 OpenMPDirectiveKind OffendingRegion = ParentRegion; 4227 bool NestingProhibited = false; 4228 bool CloseNesting = true; 4229 bool OrphanSeen = false; 4230 enum { 4231 NoRecommend, 4232 ShouldBeInParallelRegion, 4233 ShouldBeInOrderedRegion, 4234 ShouldBeInTargetRegion, 4235 ShouldBeInTeamsRegion, 4236 ShouldBeInLoopSimdRegion, 4237 } Recommend = NoRecommend; 4238 if (isOpenMPSimdDirective(ParentRegion) && 4239 ((SemaRef.LangOpts.OpenMP <= 45 && CurrentRegion != OMPD_ordered) || 4240 (SemaRef.LangOpts.OpenMP >= 50 && CurrentRegion != OMPD_ordered && 4241 CurrentRegion != OMPD_simd && CurrentRegion != OMPD_atomic && 4242 CurrentRegion != OMPD_scan))) { 4243 // OpenMP [2.16, Nesting of Regions] 4244 // OpenMP constructs may not be nested inside a simd region. 4245 // OpenMP [2.8.1,simd Construct, Restrictions] 4246 // An ordered construct with the simd clause is the only OpenMP 4247 // construct that can appear in the simd region. 4248 // Allowing a SIMD construct nested in another SIMD construct is an 4249 // extension. The OpenMP 4.5 spec does not allow it. Issue a warning 4250 // message. 4251 // OpenMP 5.0 [2.9.3.1, simd Construct, Restrictions] 4252 // The only OpenMP constructs that can be encountered during execution of 4253 // a simd region are the atomic construct, the loop construct, the simd 4254 // construct and the ordered construct with the simd clause. 4255 SemaRef.Diag(StartLoc, (CurrentRegion != OMPD_simd) 4256 ? diag::err_omp_prohibited_region_simd 4257 : diag::warn_omp_nesting_simd) 4258 << (SemaRef.LangOpts.OpenMP >= 50 ? 1 : 0); 4259 return CurrentRegion != OMPD_simd; 4260 } 4261 if (ParentRegion == OMPD_atomic) { 4262 // OpenMP [2.16, Nesting of Regions] 4263 // OpenMP constructs may not be nested inside an atomic region. 4264 SemaRef.Diag(StartLoc, diag::err_omp_prohibited_region_atomic); 4265 return true; 4266 } 4267 if (CurrentRegion == OMPD_section) { 4268 // OpenMP [2.7.2, sections Construct, Restrictions] 4269 // Orphaned section directives are prohibited. That is, the section 4270 // directives must appear within the sections construct and must not be 4271 // encountered elsewhere in the sections region. 4272 if (ParentRegion != OMPD_sections && 4273 ParentRegion != OMPD_parallel_sections) { 4274 SemaRef.Diag(StartLoc, diag::err_omp_orphaned_section_directive) 4275 << (ParentRegion != OMPD_unknown) 4276 << getOpenMPDirectiveName(ParentRegion); 4277 return true; 4278 } 4279 return false; 4280 } 4281 // Allow some constructs (except teams and cancellation constructs) to be 4282 // orphaned (they could be used in functions, called from OpenMP regions 4283 // with the required preconditions). 4284 if (ParentRegion == OMPD_unknown && 4285 !isOpenMPNestingTeamsDirective(CurrentRegion) && 4286 CurrentRegion != OMPD_cancellation_point && 4287 CurrentRegion != OMPD_cancel && CurrentRegion != OMPD_scan) 4288 return false; 4289 if (CurrentRegion == OMPD_cancellation_point || 4290 CurrentRegion == OMPD_cancel) { 4291 // OpenMP [2.16, Nesting of Regions] 4292 // A cancellation point construct for which construct-type-clause is 4293 // taskgroup must be nested inside a task construct. A cancellation 4294 // point construct for which construct-type-clause is not taskgroup must 4295 // be closely nested inside an OpenMP construct that matches the type 4296 // specified in construct-type-clause. 4297 // A cancel construct for which construct-type-clause is taskgroup must be 4298 // nested inside a task construct. A cancel construct for which 4299 // construct-type-clause is not taskgroup must be closely nested inside an 4300 // OpenMP construct that matches the type specified in 4301 // construct-type-clause. 4302 NestingProhibited = 4303 !((CancelRegion == OMPD_parallel && 4304 (ParentRegion == OMPD_parallel || 4305 ParentRegion == OMPD_target_parallel)) || 4306 (CancelRegion == OMPD_for && 4307 (ParentRegion == OMPD_for || ParentRegion == OMPD_parallel_for || 4308 ParentRegion == OMPD_target_parallel_for || 4309 ParentRegion == OMPD_distribute_parallel_for || 4310 ParentRegion == OMPD_teams_distribute_parallel_for || 4311 ParentRegion == OMPD_target_teams_distribute_parallel_for)) || 4312 (CancelRegion == OMPD_taskgroup && 4313 (ParentRegion == OMPD_task || 4314 (SemaRef.getLangOpts().OpenMP >= 50 && 4315 (ParentRegion == OMPD_taskloop || 4316 ParentRegion == OMPD_master_taskloop || 4317 ParentRegion == OMPD_parallel_master_taskloop)))) || 4318 (CancelRegion == OMPD_sections && 4319 (ParentRegion == OMPD_section || ParentRegion == OMPD_sections || 4320 ParentRegion == OMPD_parallel_sections))); 4321 OrphanSeen = ParentRegion == OMPD_unknown; 4322 } else if (CurrentRegion == OMPD_master) { 4323 // OpenMP [2.16, Nesting of Regions] 4324 // A master region may not be closely nested inside a worksharing, 4325 // atomic, or explicit task region. 4326 NestingProhibited = isOpenMPWorksharingDirective(ParentRegion) || 4327 isOpenMPTaskingDirective(ParentRegion); 4328 } else if (CurrentRegion == OMPD_critical && CurrentName.getName()) { 4329 // OpenMP [2.16, Nesting of Regions] 4330 // A critical region may not be nested (closely or otherwise) inside a 4331 // critical region with the same name. Note that this restriction is not 4332 // sufficient to prevent deadlock. 4333 SourceLocation PreviousCriticalLoc; 4334 bool DeadLock = Stack->hasDirective( 4335 [CurrentName, &PreviousCriticalLoc](OpenMPDirectiveKind K, 4336 const DeclarationNameInfo &DNI, 4337 SourceLocation Loc) { 4338 if (K == OMPD_critical && DNI.getName() == CurrentName.getName()) { 4339 PreviousCriticalLoc = Loc; 4340 return true; 4341 } 4342 return false; 4343 }, 4344 false /* skip top directive */); 4345 if (DeadLock) { 4346 SemaRef.Diag(StartLoc, 4347 diag::err_omp_prohibited_region_critical_same_name) 4348 << CurrentName.getName(); 4349 if (PreviousCriticalLoc.isValid()) 4350 SemaRef.Diag(PreviousCriticalLoc, 4351 diag::note_omp_previous_critical_region); 4352 return true; 4353 } 4354 } else if (CurrentRegion == OMPD_barrier) { 4355 // OpenMP [2.16, Nesting of Regions] 4356 // A barrier region may not be closely nested inside a worksharing, 4357 // explicit task, critical, ordered, atomic, or master region. 4358 NestingProhibited = isOpenMPWorksharingDirective(ParentRegion) || 4359 isOpenMPTaskingDirective(ParentRegion) || 4360 ParentRegion == OMPD_master || 4361 ParentRegion == OMPD_parallel_master || 4362 ParentRegion == OMPD_critical || 4363 ParentRegion == OMPD_ordered; 4364 } else if (isOpenMPWorksharingDirective(CurrentRegion) && 4365 !isOpenMPParallelDirective(CurrentRegion) && 4366 !isOpenMPTeamsDirective(CurrentRegion)) { 4367 // OpenMP [2.16, Nesting of Regions] 4368 // A worksharing region may not be closely nested inside a worksharing, 4369 // explicit task, critical, ordered, atomic, or master region. 4370 NestingProhibited = isOpenMPWorksharingDirective(ParentRegion) || 4371 isOpenMPTaskingDirective(ParentRegion) || 4372 ParentRegion == OMPD_master || 4373 ParentRegion == OMPD_parallel_master || 4374 ParentRegion == OMPD_critical || 4375 ParentRegion == OMPD_ordered; 4376 Recommend = ShouldBeInParallelRegion; 4377 } else if (CurrentRegion == OMPD_ordered) { 4378 // OpenMP [2.16, Nesting of Regions] 4379 // An ordered region may not be closely nested inside a critical, 4380 // atomic, or explicit task region. 4381 // An ordered region must be closely nested inside a loop region (or 4382 // parallel loop region) with an ordered clause. 4383 // OpenMP [2.8.1,simd Construct, Restrictions] 4384 // An ordered construct with the simd clause is the only OpenMP construct 4385 // that can appear in the simd region. 4386 NestingProhibited = ParentRegion == OMPD_critical || 4387 isOpenMPTaskingDirective(ParentRegion) || 4388 !(isOpenMPSimdDirective(ParentRegion) || 4389 Stack->isParentOrderedRegion()); 4390 Recommend = ShouldBeInOrderedRegion; 4391 } else if (isOpenMPNestingTeamsDirective(CurrentRegion)) { 4392 // OpenMP [2.16, Nesting of Regions] 4393 // If specified, a teams construct must be contained within a target 4394 // construct. 4395 NestingProhibited = 4396 (SemaRef.LangOpts.OpenMP <= 45 && ParentRegion != OMPD_target) || 4397 (SemaRef.LangOpts.OpenMP >= 50 && ParentRegion != OMPD_unknown && 4398 ParentRegion != OMPD_target); 4399 OrphanSeen = ParentRegion == OMPD_unknown; 4400 Recommend = ShouldBeInTargetRegion; 4401 } else if (CurrentRegion == OMPD_scan) { 4402 // OpenMP [2.16, Nesting of Regions] 4403 // If specified, a teams construct must be contained within a target 4404 // construct. 4405 NestingProhibited = 4406 SemaRef.LangOpts.OpenMP < 50 || 4407 (ParentRegion != OMPD_simd && ParentRegion != OMPD_for && 4408 ParentRegion != OMPD_for_simd && ParentRegion != OMPD_parallel_for && 4409 ParentRegion != OMPD_parallel_for_simd); 4410 OrphanSeen = ParentRegion == OMPD_unknown; 4411 Recommend = ShouldBeInLoopSimdRegion; 4412 } 4413 if (!NestingProhibited && 4414 !isOpenMPTargetExecutionDirective(CurrentRegion) && 4415 !isOpenMPTargetDataManagementDirective(CurrentRegion) && 4416 (ParentRegion == OMPD_teams || ParentRegion == OMPD_target_teams)) { 4417 // OpenMP [2.16, Nesting of Regions] 4418 // distribute, parallel, parallel sections, parallel workshare, and the 4419 // parallel loop and parallel loop SIMD constructs are the only OpenMP 4420 // constructs that can be closely nested in the teams region. 4421 NestingProhibited = !isOpenMPParallelDirective(CurrentRegion) && 4422 !isOpenMPDistributeDirective(CurrentRegion); 4423 Recommend = ShouldBeInParallelRegion; 4424 } 4425 if (!NestingProhibited && 4426 isOpenMPNestingDistributeDirective(CurrentRegion)) { 4427 // OpenMP 4.5 [2.17 Nesting of Regions] 4428 // The region associated with the distribute construct must be strictly 4429 // nested inside a teams region 4430 NestingProhibited = 4431 (ParentRegion != OMPD_teams && ParentRegion != OMPD_target_teams); 4432 Recommend = ShouldBeInTeamsRegion; 4433 } 4434 if (!NestingProhibited && 4435 (isOpenMPTargetExecutionDirective(CurrentRegion) || 4436 isOpenMPTargetDataManagementDirective(CurrentRegion))) { 4437 // OpenMP 4.5 [2.17 Nesting of Regions] 4438 // If a target, target update, target data, target enter data, or 4439 // target exit data construct is encountered during execution of a 4440 // target region, the behavior is unspecified. 4441 NestingProhibited = Stack->hasDirective( 4442 [&OffendingRegion](OpenMPDirectiveKind K, const DeclarationNameInfo &, 4443 SourceLocation) { 4444 if (isOpenMPTargetExecutionDirective(K)) { 4445 OffendingRegion = K; 4446 return true; 4447 } 4448 return false; 4449 }, 4450 false /* don't skip top directive */); 4451 CloseNesting = false; 4452 } 4453 if (NestingProhibited) { 4454 if (OrphanSeen) { 4455 SemaRef.Diag(StartLoc, diag::err_omp_orphaned_device_directive) 4456 << getOpenMPDirectiveName(CurrentRegion) << Recommend; 4457 } else { 4458 SemaRef.Diag(StartLoc, diag::err_omp_prohibited_region) 4459 << CloseNesting << getOpenMPDirectiveName(OffendingRegion) 4460 << Recommend << getOpenMPDirectiveName(CurrentRegion); 4461 } 4462 return true; 4463 } 4464 } 4465 return false; 4466 } 4467 4468 struct Kind2Unsigned { 4469 using argument_type = OpenMPDirectiveKind; 4470 unsigned operator()(argument_type DK) { return unsigned(DK); } 4471 }; 4472 static bool checkIfClauses(Sema &S, OpenMPDirectiveKind Kind, 4473 ArrayRef<OMPClause *> Clauses, 4474 ArrayRef<OpenMPDirectiveKind> AllowedNameModifiers) { 4475 bool ErrorFound = false; 4476 unsigned NamedModifiersNumber = 0; 4477 llvm::IndexedMap<const OMPIfClause *, Kind2Unsigned> FoundNameModifiers; 4478 FoundNameModifiers.resize(unsigned(OMPD_unknown) + 1); 4479 SmallVector<SourceLocation, 4> NameModifierLoc; 4480 for (const OMPClause *C : Clauses) { 4481 if (const auto *IC = dyn_cast_or_null<OMPIfClause>(C)) { 4482 // At most one if clause without a directive-name-modifier can appear on 4483 // the directive. 4484 OpenMPDirectiveKind CurNM = IC->getNameModifier(); 4485 if (FoundNameModifiers[CurNM]) { 4486 S.Diag(C->getBeginLoc(), diag::err_omp_more_one_clause) 4487 << getOpenMPDirectiveName(Kind) << getOpenMPClauseName(OMPC_if) 4488 << (CurNM != OMPD_unknown) << getOpenMPDirectiveName(CurNM); 4489 ErrorFound = true; 4490 } else if (CurNM != OMPD_unknown) { 4491 NameModifierLoc.push_back(IC->getNameModifierLoc()); 4492 ++NamedModifiersNumber; 4493 } 4494 FoundNameModifiers[CurNM] = IC; 4495 if (CurNM == OMPD_unknown) 4496 continue; 4497 // Check if the specified name modifier is allowed for the current 4498 // directive. 4499 // At most one if clause with the particular directive-name-modifier can 4500 // appear on the directive. 4501 bool MatchFound = false; 4502 for (auto NM : AllowedNameModifiers) { 4503 if (CurNM == NM) { 4504 MatchFound = true; 4505 break; 4506 } 4507 } 4508 if (!MatchFound) { 4509 S.Diag(IC->getNameModifierLoc(), 4510 diag::err_omp_wrong_if_directive_name_modifier) 4511 << getOpenMPDirectiveName(CurNM) << getOpenMPDirectiveName(Kind); 4512 ErrorFound = true; 4513 } 4514 } 4515 } 4516 // If any if clause on the directive includes a directive-name-modifier then 4517 // all if clauses on the directive must include a directive-name-modifier. 4518 if (FoundNameModifiers[OMPD_unknown] && NamedModifiersNumber > 0) { 4519 if (NamedModifiersNumber == AllowedNameModifiers.size()) { 4520 S.Diag(FoundNameModifiers[OMPD_unknown]->getBeginLoc(), 4521 diag::err_omp_no_more_if_clause); 4522 } else { 4523 std::string Values; 4524 std::string Sep(", "); 4525 unsigned AllowedCnt = 0; 4526 unsigned TotalAllowedNum = 4527 AllowedNameModifiers.size() - NamedModifiersNumber; 4528 for (unsigned Cnt = 0, End = AllowedNameModifiers.size(); Cnt < End; 4529 ++Cnt) { 4530 OpenMPDirectiveKind NM = AllowedNameModifiers[Cnt]; 4531 if (!FoundNameModifiers[NM]) { 4532 Values += "'"; 4533 Values += getOpenMPDirectiveName(NM); 4534 Values += "'"; 4535 if (AllowedCnt + 2 == TotalAllowedNum) 4536 Values += " or "; 4537 else if (AllowedCnt + 1 != TotalAllowedNum) 4538 Values += Sep; 4539 ++AllowedCnt; 4540 } 4541 } 4542 S.Diag(FoundNameModifiers[OMPD_unknown]->getCondition()->getBeginLoc(), 4543 diag::err_omp_unnamed_if_clause) 4544 << (TotalAllowedNum > 1) << Values; 4545 } 4546 for (SourceLocation Loc : NameModifierLoc) { 4547 S.Diag(Loc, diag::note_omp_previous_named_if_clause); 4548 } 4549 ErrorFound = true; 4550 } 4551 return ErrorFound; 4552 } 4553 4554 static std::pair<ValueDecl *, bool> getPrivateItem(Sema &S, Expr *&RefExpr, 4555 SourceLocation &ELoc, 4556 SourceRange &ERange, 4557 bool AllowArraySection) { 4558 if (RefExpr->isTypeDependent() || RefExpr->isValueDependent() || 4559 RefExpr->containsUnexpandedParameterPack()) 4560 return std::make_pair(nullptr, true); 4561 4562 // OpenMP [3.1, C/C++] 4563 // A list item is a variable name. 4564 // OpenMP [2.9.3.3, Restrictions, p.1] 4565 // A variable that is part of another variable (as an array or 4566 // structure element) cannot appear in a private clause. 4567 RefExpr = RefExpr->IgnoreParens(); 4568 enum { 4569 NoArrayExpr = -1, 4570 ArraySubscript = 0, 4571 OMPArraySection = 1 4572 } IsArrayExpr = NoArrayExpr; 4573 if (AllowArraySection) { 4574 if (auto *ASE = dyn_cast_or_null<ArraySubscriptExpr>(RefExpr)) { 4575 Expr *Base = ASE->getBase()->IgnoreParenImpCasts(); 4576 while (auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base)) 4577 Base = TempASE->getBase()->IgnoreParenImpCasts(); 4578 RefExpr = Base; 4579 IsArrayExpr = ArraySubscript; 4580 } else if (auto *OASE = dyn_cast_or_null<OMPArraySectionExpr>(RefExpr)) { 4581 Expr *Base = OASE->getBase()->IgnoreParenImpCasts(); 4582 while (auto *TempOASE = dyn_cast<OMPArraySectionExpr>(Base)) 4583 Base = TempOASE->getBase()->IgnoreParenImpCasts(); 4584 while (auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base)) 4585 Base = TempASE->getBase()->IgnoreParenImpCasts(); 4586 RefExpr = Base; 4587 IsArrayExpr = OMPArraySection; 4588 } 4589 } 4590 ELoc = RefExpr->getExprLoc(); 4591 ERange = RefExpr->getSourceRange(); 4592 RefExpr = RefExpr->IgnoreParenImpCasts(); 4593 auto *DE = dyn_cast_or_null<DeclRefExpr>(RefExpr); 4594 auto *ME = dyn_cast_or_null<MemberExpr>(RefExpr); 4595 if ((!DE || !isa<VarDecl>(DE->getDecl())) && 4596 (S.getCurrentThisType().isNull() || !ME || 4597 !isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts()) || 4598 !isa<FieldDecl>(ME->getMemberDecl()))) { 4599 if (IsArrayExpr != NoArrayExpr) { 4600 S.Diag(ELoc, diag::err_omp_expected_base_var_name) << IsArrayExpr 4601 << ERange; 4602 } else { 4603 S.Diag(ELoc, 4604 AllowArraySection 4605 ? diag::err_omp_expected_var_name_member_expr_or_array_item 4606 : diag::err_omp_expected_var_name_member_expr) 4607 << (S.getCurrentThisType().isNull() ? 0 : 1) << ERange; 4608 } 4609 return std::make_pair(nullptr, false); 4610 } 4611 return std::make_pair( 4612 getCanonicalDecl(DE ? DE->getDecl() : ME->getMemberDecl()), false); 4613 } 4614 4615 static void checkAllocateClauses(Sema &S, DSAStackTy *Stack, 4616 ArrayRef<OMPClause *> Clauses) { 4617 assert(!S.CurContext->isDependentContext() && 4618 "Expected non-dependent context."); 4619 auto AllocateRange = 4620 llvm::make_filter_range(Clauses, OMPAllocateClause::classof); 4621 llvm::DenseMap<CanonicalDeclPtr<Decl>, CanonicalDeclPtr<VarDecl>> 4622 DeclToCopy; 4623 auto PrivateRange = llvm::make_filter_range(Clauses, [](const OMPClause *C) { 4624 return isOpenMPPrivate(C->getClauseKind()); 4625 }); 4626 for (OMPClause *Cl : PrivateRange) { 4627 MutableArrayRef<Expr *>::iterator I, It, Et; 4628 if (Cl->getClauseKind() == OMPC_private) { 4629 auto *PC = cast<OMPPrivateClause>(Cl); 4630 I = PC->private_copies().begin(); 4631 It = PC->varlist_begin(); 4632 Et = PC->varlist_end(); 4633 } else if (Cl->getClauseKind() == OMPC_firstprivate) { 4634 auto *PC = cast<OMPFirstprivateClause>(Cl); 4635 I = PC->private_copies().begin(); 4636 It = PC->varlist_begin(); 4637 Et = PC->varlist_end(); 4638 } else if (Cl->getClauseKind() == OMPC_lastprivate) { 4639 auto *PC = cast<OMPLastprivateClause>(Cl); 4640 I = PC->private_copies().begin(); 4641 It = PC->varlist_begin(); 4642 Et = PC->varlist_end(); 4643 } else if (Cl->getClauseKind() == OMPC_linear) { 4644 auto *PC = cast<OMPLinearClause>(Cl); 4645 I = PC->privates().begin(); 4646 It = PC->varlist_begin(); 4647 Et = PC->varlist_end(); 4648 } else if (Cl->getClauseKind() == OMPC_reduction) { 4649 auto *PC = cast<OMPReductionClause>(Cl); 4650 I = PC->privates().begin(); 4651 It = PC->varlist_begin(); 4652 Et = PC->varlist_end(); 4653 } else if (Cl->getClauseKind() == OMPC_task_reduction) { 4654 auto *PC = cast<OMPTaskReductionClause>(Cl); 4655 I = PC->privates().begin(); 4656 It = PC->varlist_begin(); 4657 Et = PC->varlist_end(); 4658 } else if (Cl->getClauseKind() == OMPC_in_reduction) { 4659 auto *PC = cast<OMPInReductionClause>(Cl); 4660 I = PC->privates().begin(); 4661 It = PC->varlist_begin(); 4662 Et = PC->varlist_end(); 4663 } else { 4664 llvm_unreachable("Expected private clause."); 4665 } 4666 for (Expr *E : llvm::make_range(It, Et)) { 4667 if (!*I) { 4668 ++I; 4669 continue; 4670 } 4671 SourceLocation ELoc; 4672 SourceRange ERange; 4673 Expr *SimpleRefExpr = E; 4674 auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange, 4675 /*AllowArraySection=*/true); 4676 DeclToCopy.try_emplace(Res.first, 4677 cast<VarDecl>(cast<DeclRefExpr>(*I)->getDecl())); 4678 ++I; 4679 } 4680 } 4681 for (OMPClause *C : AllocateRange) { 4682 auto *AC = cast<OMPAllocateClause>(C); 4683 OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind = 4684 getAllocatorKind(S, Stack, AC->getAllocator()); 4685 // OpenMP, 2.11.4 allocate Clause, Restrictions. 4686 // For task, taskloop or target directives, allocation requests to memory 4687 // allocators with the trait access set to thread result in unspecified 4688 // behavior. 4689 if (AllocatorKind == OMPAllocateDeclAttr::OMPThreadMemAlloc && 4690 (isOpenMPTaskingDirective(Stack->getCurrentDirective()) || 4691 isOpenMPTargetExecutionDirective(Stack->getCurrentDirective()))) { 4692 S.Diag(AC->getAllocator()->getExprLoc(), 4693 diag::warn_omp_allocate_thread_on_task_target_directive) 4694 << getOpenMPDirectiveName(Stack->getCurrentDirective()); 4695 } 4696 for (Expr *E : AC->varlists()) { 4697 SourceLocation ELoc; 4698 SourceRange ERange; 4699 Expr *SimpleRefExpr = E; 4700 auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange); 4701 ValueDecl *VD = Res.first; 4702 DSAStackTy::DSAVarData Data = Stack->getTopDSA(VD, /*FromParent=*/false); 4703 if (!isOpenMPPrivate(Data.CKind)) { 4704 S.Diag(E->getExprLoc(), 4705 diag::err_omp_expected_private_copy_for_allocate); 4706 continue; 4707 } 4708 VarDecl *PrivateVD = DeclToCopy[VD]; 4709 if (checkPreviousOMPAllocateAttribute(S, Stack, E, PrivateVD, 4710 AllocatorKind, AC->getAllocator())) 4711 continue; 4712 applyOMPAllocateAttribute(S, PrivateVD, AllocatorKind, AC->getAllocator(), 4713 E->getSourceRange()); 4714 } 4715 } 4716 } 4717 4718 StmtResult Sema::ActOnOpenMPExecutableDirective( 4719 OpenMPDirectiveKind Kind, const DeclarationNameInfo &DirName, 4720 OpenMPDirectiveKind CancelRegion, ArrayRef<OMPClause *> Clauses, 4721 Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc) { 4722 StmtResult Res = StmtError(); 4723 // First check CancelRegion which is then used in checkNestingOfRegions. 4724 if (checkCancelRegion(*this, Kind, CancelRegion, StartLoc) || 4725 checkNestingOfRegions(*this, DSAStack, Kind, DirName, CancelRegion, 4726 StartLoc)) 4727 return StmtError(); 4728 4729 llvm::SmallVector<OMPClause *, 8> ClausesWithImplicit; 4730 VarsWithInheritedDSAType VarsWithInheritedDSA; 4731 bool ErrorFound = false; 4732 ClausesWithImplicit.append(Clauses.begin(), Clauses.end()); 4733 if (AStmt && !CurContext->isDependentContext()) { 4734 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 4735 4736 // Check default data sharing attributes for referenced variables. 4737 DSAAttrChecker DSAChecker(DSAStack, *this, cast<CapturedStmt>(AStmt)); 4738 int ThisCaptureLevel = getOpenMPCaptureLevels(Kind); 4739 Stmt *S = AStmt; 4740 while (--ThisCaptureLevel >= 0) 4741 S = cast<CapturedStmt>(S)->getCapturedStmt(); 4742 DSAChecker.Visit(S); 4743 if (!isOpenMPTargetDataManagementDirective(Kind) && 4744 !isOpenMPTaskingDirective(Kind)) { 4745 // Visit subcaptures to generate implicit clauses for captured vars. 4746 auto *CS = cast<CapturedStmt>(AStmt); 4747 SmallVector<OpenMPDirectiveKind, 4> CaptureRegions; 4748 getOpenMPCaptureRegions(CaptureRegions, Kind); 4749 // Ignore outer tasking regions for target directives. 4750 if (CaptureRegions.size() > 1 && CaptureRegions.front() == OMPD_task) 4751 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 4752 DSAChecker.visitSubCaptures(CS); 4753 } 4754 if (DSAChecker.isErrorFound()) 4755 return StmtError(); 4756 // Generate list of implicitly defined firstprivate variables. 4757 VarsWithInheritedDSA = DSAChecker.getVarsWithInheritedDSA(); 4758 4759 SmallVector<Expr *, 4> ImplicitFirstprivates( 4760 DSAChecker.getImplicitFirstprivate().begin(), 4761 DSAChecker.getImplicitFirstprivate().end()); 4762 SmallVector<Expr *, 4> ImplicitMaps[OMPC_MAP_delete]; 4763 for (unsigned I = 0; I < OMPC_MAP_delete; ++I) { 4764 ArrayRef<Expr *> ImplicitMap = 4765 DSAChecker.getImplicitMap(static_cast<OpenMPDefaultmapClauseKind>(I)); 4766 ImplicitMaps[I].append(ImplicitMap.begin(), ImplicitMap.end()); 4767 } 4768 // Mark taskgroup task_reduction descriptors as implicitly firstprivate. 4769 for (OMPClause *C : Clauses) { 4770 if (auto *IRC = dyn_cast<OMPInReductionClause>(C)) { 4771 for (Expr *E : IRC->taskgroup_descriptors()) 4772 if (E) 4773 ImplicitFirstprivates.emplace_back(E); 4774 } 4775 // OpenMP 5.0, 2.10.1 task Construct 4776 // [detach clause]... The event-handle will be considered as if it was 4777 // specified on a firstprivate clause. 4778 if (auto *DC = dyn_cast<OMPDetachClause>(C)) 4779 ImplicitFirstprivates.push_back(DC->getEventHandler()); 4780 } 4781 if (!ImplicitFirstprivates.empty()) { 4782 if (OMPClause *Implicit = ActOnOpenMPFirstprivateClause( 4783 ImplicitFirstprivates, SourceLocation(), SourceLocation(), 4784 SourceLocation())) { 4785 ClausesWithImplicit.push_back(Implicit); 4786 ErrorFound = cast<OMPFirstprivateClause>(Implicit)->varlist_size() != 4787 ImplicitFirstprivates.size(); 4788 } else { 4789 ErrorFound = true; 4790 } 4791 } 4792 int ClauseKindCnt = -1; 4793 for (ArrayRef<Expr *> ImplicitMap : ImplicitMaps) { 4794 ++ClauseKindCnt; 4795 if (ImplicitMap.empty()) 4796 continue; 4797 CXXScopeSpec MapperIdScopeSpec; 4798 DeclarationNameInfo MapperId; 4799 auto Kind = static_cast<OpenMPMapClauseKind>(ClauseKindCnt); 4800 if (OMPClause *Implicit = ActOnOpenMPMapClause( 4801 llvm::None, llvm::None, MapperIdScopeSpec, MapperId, Kind, 4802 /*IsMapTypeImplicit=*/true, SourceLocation(), SourceLocation(), 4803 ImplicitMap, OMPVarListLocTy())) { 4804 ClausesWithImplicit.emplace_back(Implicit); 4805 ErrorFound |= 4806 cast<OMPMapClause>(Implicit)->varlist_size() != ImplicitMap.size(); 4807 } else { 4808 ErrorFound = true; 4809 } 4810 } 4811 } 4812 4813 llvm::SmallVector<OpenMPDirectiveKind, 4> AllowedNameModifiers; 4814 switch (Kind) { 4815 case OMPD_parallel: 4816 Res = ActOnOpenMPParallelDirective(ClausesWithImplicit, AStmt, StartLoc, 4817 EndLoc); 4818 AllowedNameModifiers.push_back(OMPD_parallel); 4819 break; 4820 case OMPD_simd: 4821 Res = ActOnOpenMPSimdDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc, 4822 VarsWithInheritedDSA); 4823 if (LangOpts.OpenMP >= 50) 4824 AllowedNameModifiers.push_back(OMPD_simd); 4825 break; 4826 case OMPD_for: 4827 Res = ActOnOpenMPForDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc, 4828 VarsWithInheritedDSA); 4829 break; 4830 case OMPD_for_simd: 4831 Res = ActOnOpenMPForSimdDirective(ClausesWithImplicit, AStmt, StartLoc, 4832 EndLoc, VarsWithInheritedDSA); 4833 if (LangOpts.OpenMP >= 50) 4834 AllowedNameModifiers.push_back(OMPD_simd); 4835 break; 4836 case OMPD_sections: 4837 Res = ActOnOpenMPSectionsDirective(ClausesWithImplicit, AStmt, StartLoc, 4838 EndLoc); 4839 break; 4840 case OMPD_section: 4841 assert(ClausesWithImplicit.empty() && 4842 "No clauses are allowed for 'omp section' directive"); 4843 Res = ActOnOpenMPSectionDirective(AStmt, StartLoc, EndLoc); 4844 break; 4845 case OMPD_single: 4846 Res = ActOnOpenMPSingleDirective(ClausesWithImplicit, AStmt, StartLoc, 4847 EndLoc); 4848 break; 4849 case OMPD_master: 4850 assert(ClausesWithImplicit.empty() && 4851 "No clauses are allowed for 'omp master' directive"); 4852 Res = ActOnOpenMPMasterDirective(AStmt, StartLoc, EndLoc); 4853 break; 4854 case OMPD_critical: 4855 Res = ActOnOpenMPCriticalDirective(DirName, ClausesWithImplicit, AStmt, 4856 StartLoc, EndLoc); 4857 break; 4858 case OMPD_parallel_for: 4859 Res = ActOnOpenMPParallelForDirective(ClausesWithImplicit, AStmt, StartLoc, 4860 EndLoc, VarsWithInheritedDSA); 4861 AllowedNameModifiers.push_back(OMPD_parallel); 4862 break; 4863 case OMPD_parallel_for_simd: 4864 Res = ActOnOpenMPParallelForSimdDirective( 4865 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4866 AllowedNameModifiers.push_back(OMPD_parallel); 4867 if (LangOpts.OpenMP >= 50) 4868 AllowedNameModifiers.push_back(OMPD_simd); 4869 break; 4870 case OMPD_parallel_master: 4871 Res = ActOnOpenMPParallelMasterDirective(ClausesWithImplicit, AStmt, 4872 StartLoc, EndLoc); 4873 AllowedNameModifiers.push_back(OMPD_parallel); 4874 break; 4875 case OMPD_parallel_sections: 4876 Res = ActOnOpenMPParallelSectionsDirective(ClausesWithImplicit, AStmt, 4877 StartLoc, EndLoc); 4878 AllowedNameModifiers.push_back(OMPD_parallel); 4879 break; 4880 case OMPD_task: 4881 Res = 4882 ActOnOpenMPTaskDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc); 4883 AllowedNameModifiers.push_back(OMPD_task); 4884 break; 4885 case OMPD_taskyield: 4886 assert(ClausesWithImplicit.empty() && 4887 "No clauses are allowed for 'omp taskyield' directive"); 4888 assert(AStmt == nullptr && 4889 "No associated statement allowed for 'omp taskyield' directive"); 4890 Res = ActOnOpenMPTaskyieldDirective(StartLoc, EndLoc); 4891 break; 4892 case OMPD_barrier: 4893 assert(ClausesWithImplicit.empty() && 4894 "No clauses are allowed for 'omp barrier' directive"); 4895 assert(AStmt == nullptr && 4896 "No associated statement allowed for 'omp barrier' directive"); 4897 Res = ActOnOpenMPBarrierDirective(StartLoc, EndLoc); 4898 break; 4899 case OMPD_taskwait: 4900 assert(ClausesWithImplicit.empty() && 4901 "No clauses are allowed for 'omp taskwait' directive"); 4902 assert(AStmt == nullptr && 4903 "No associated statement allowed for 'omp taskwait' directive"); 4904 Res = ActOnOpenMPTaskwaitDirective(StartLoc, EndLoc); 4905 break; 4906 case OMPD_taskgroup: 4907 Res = ActOnOpenMPTaskgroupDirective(ClausesWithImplicit, AStmt, StartLoc, 4908 EndLoc); 4909 break; 4910 case OMPD_flush: 4911 assert(AStmt == nullptr && 4912 "No associated statement allowed for 'omp flush' directive"); 4913 Res = ActOnOpenMPFlushDirective(ClausesWithImplicit, StartLoc, EndLoc); 4914 break; 4915 case OMPD_depobj: 4916 assert(AStmt == nullptr && 4917 "No associated statement allowed for 'omp depobj' directive"); 4918 Res = ActOnOpenMPDepobjDirective(ClausesWithImplicit, StartLoc, EndLoc); 4919 break; 4920 case OMPD_scan: 4921 assert(AStmt == nullptr && 4922 "No associated statement allowed for 'omp scan' directive"); 4923 Res = ActOnOpenMPScanDirective(ClausesWithImplicit, StartLoc, EndLoc); 4924 break; 4925 case OMPD_ordered: 4926 Res = ActOnOpenMPOrderedDirective(ClausesWithImplicit, AStmt, StartLoc, 4927 EndLoc); 4928 break; 4929 case OMPD_atomic: 4930 Res = ActOnOpenMPAtomicDirective(ClausesWithImplicit, AStmt, StartLoc, 4931 EndLoc); 4932 break; 4933 case OMPD_teams: 4934 Res = 4935 ActOnOpenMPTeamsDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc); 4936 break; 4937 case OMPD_target: 4938 Res = ActOnOpenMPTargetDirective(ClausesWithImplicit, AStmt, StartLoc, 4939 EndLoc); 4940 AllowedNameModifiers.push_back(OMPD_target); 4941 break; 4942 case OMPD_target_parallel: 4943 Res = ActOnOpenMPTargetParallelDirective(ClausesWithImplicit, AStmt, 4944 StartLoc, EndLoc); 4945 AllowedNameModifiers.push_back(OMPD_target); 4946 AllowedNameModifiers.push_back(OMPD_parallel); 4947 break; 4948 case OMPD_target_parallel_for: 4949 Res = ActOnOpenMPTargetParallelForDirective( 4950 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4951 AllowedNameModifiers.push_back(OMPD_target); 4952 AllowedNameModifiers.push_back(OMPD_parallel); 4953 break; 4954 case OMPD_cancellation_point: 4955 assert(ClausesWithImplicit.empty() && 4956 "No clauses are allowed for 'omp cancellation point' directive"); 4957 assert(AStmt == nullptr && "No associated statement allowed for 'omp " 4958 "cancellation point' directive"); 4959 Res = ActOnOpenMPCancellationPointDirective(StartLoc, EndLoc, CancelRegion); 4960 break; 4961 case OMPD_cancel: 4962 assert(AStmt == nullptr && 4963 "No associated statement allowed for 'omp cancel' directive"); 4964 Res = ActOnOpenMPCancelDirective(ClausesWithImplicit, StartLoc, EndLoc, 4965 CancelRegion); 4966 AllowedNameModifiers.push_back(OMPD_cancel); 4967 break; 4968 case OMPD_target_data: 4969 Res = ActOnOpenMPTargetDataDirective(ClausesWithImplicit, AStmt, StartLoc, 4970 EndLoc); 4971 AllowedNameModifiers.push_back(OMPD_target_data); 4972 break; 4973 case OMPD_target_enter_data: 4974 Res = ActOnOpenMPTargetEnterDataDirective(ClausesWithImplicit, StartLoc, 4975 EndLoc, AStmt); 4976 AllowedNameModifiers.push_back(OMPD_target_enter_data); 4977 break; 4978 case OMPD_target_exit_data: 4979 Res = ActOnOpenMPTargetExitDataDirective(ClausesWithImplicit, StartLoc, 4980 EndLoc, AStmt); 4981 AllowedNameModifiers.push_back(OMPD_target_exit_data); 4982 break; 4983 case OMPD_taskloop: 4984 Res = ActOnOpenMPTaskLoopDirective(ClausesWithImplicit, AStmt, StartLoc, 4985 EndLoc, VarsWithInheritedDSA); 4986 AllowedNameModifiers.push_back(OMPD_taskloop); 4987 break; 4988 case OMPD_taskloop_simd: 4989 Res = ActOnOpenMPTaskLoopSimdDirective(ClausesWithImplicit, AStmt, StartLoc, 4990 EndLoc, VarsWithInheritedDSA); 4991 AllowedNameModifiers.push_back(OMPD_taskloop); 4992 if (LangOpts.OpenMP >= 50) 4993 AllowedNameModifiers.push_back(OMPD_simd); 4994 break; 4995 case OMPD_master_taskloop: 4996 Res = ActOnOpenMPMasterTaskLoopDirective( 4997 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4998 AllowedNameModifiers.push_back(OMPD_taskloop); 4999 break; 5000 case OMPD_master_taskloop_simd: 5001 Res = ActOnOpenMPMasterTaskLoopSimdDirective( 5002 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 5003 AllowedNameModifiers.push_back(OMPD_taskloop); 5004 if (LangOpts.OpenMP >= 50) 5005 AllowedNameModifiers.push_back(OMPD_simd); 5006 break; 5007 case OMPD_parallel_master_taskloop: 5008 Res = ActOnOpenMPParallelMasterTaskLoopDirective( 5009 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 5010 AllowedNameModifiers.push_back(OMPD_taskloop); 5011 AllowedNameModifiers.push_back(OMPD_parallel); 5012 break; 5013 case OMPD_parallel_master_taskloop_simd: 5014 Res = ActOnOpenMPParallelMasterTaskLoopSimdDirective( 5015 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 5016 AllowedNameModifiers.push_back(OMPD_taskloop); 5017 AllowedNameModifiers.push_back(OMPD_parallel); 5018 if (LangOpts.OpenMP >= 50) 5019 AllowedNameModifiers.push_back(OMPD_simd); 5020 break; 5021 case OMPD_distribute: 5022 Res = ActOnOpenMPDistributeDirective(ClausesWithImplicit, AStmt, StartLoc, 5023 EndLoc, VarsWithInheritedDSA); 5024 break; 5025 case OMPD_target_update: 5026 Res = ActOnOpenMPTargetUpdateDirective(ClausesWithImplicit, StartLoc, 5027 EndLoc, AStmt); 5028 AllowedNameModifiers.push_back(OMPD_target_update); 5029 break; 5030 case OMPD_distribute_parallel_for: 5031 Res = ActOnOpenMPDistributeParallelForDirective( 5032 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 5033 AllowedNameModifiers.push_back(OMPD_parallel); 5034 break; 5035 case OMPD_distribute_parallel_for_simd: 5036 Res = ActOnOpenMPDistributeParallelForSimdDirective( 5037 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 5038 AllowedNameModifiers.push_back(OMPD_parallel); 5039 if (LangOpts.OpenMP >= 50) 5040 AllowedNameModifiers.push_back(OMPD_simd); 5041 break; 5042 case OMPD_distribute_simd: 5043 Res = ActOnOpenMPDistributeSimdDirective( 5044 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 5045 if (LangOpts.OpenMP >= 50) 5046 AllowedNameModifiers.push_back(OMPD_simd); 5047 break; 5048 case OMPD_target_parallel_for_simd: 5049 Res = ActOnOpenMPTargetParallelForSimdDirective( 5050 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 5051 AllowedNameModifiers.push_back(OMPD_target); 5052 AllowedNameModifiers.push_back(OMPD_parallel); 5053 if (LangOpts.OpenMP >= 50) 5054 AllowedNameModifiers.push_back(OMPD_simd); 5055 break; 5056 case OMPD_target_simd: 5057 Res = ActOnOpenMPTargetSimdDirective(ClausesWithImplicit, AStmt, StartLoc, 5058 EndLoc, VarsWithInheritedDSA); 5059 AllowedNameModifiers.push_back(OMPD_target); 5060 if (LangOpts.OpenMP >= 50) 5061 AllowedNameModifiers.push_back(OMPD_simd); 5062 break; 5063 case OMPD_teams_distribute: 5064 Res = ActOnOpenMPTeamsDistributeDirective( 5065 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 5066 break; 5067 case OMPD_teams_distribute_simd: 5068 Res = ActOnOpenMPTeamsDistributeSimdDirective( 5069 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 5070 if (LangOpts.OpenMP >= 50) 5071 AllowedNameModifiers.push_back(OMPD_simd); 5072 break; 5073 case OMPD_teams_distribute_parallel_for_simd: 5074 Res = ActOnOpenMPTeamsDistributeParallelForSimdDirective( 5075 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 5076 AllowedNameModifiers.push_back(OMPD_parallel); 5077 if (LangOpts.OpenMP >= 50) 5078 AllowedNameModifiers.push_back(OMPD_simd); 5079 break; 5080 case OMPD_teams_distribute_parallel_for: 5081 Res = ActOnOpenMPTeamsDistributeParallelForDirective( 5082 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 5083 AllowedNameModifiers.push_back(OMPD_parallel); 5084 break; 5085 case OMPD_target_teams: 5086 Res = ActOnOpenMPTargetTeamsDirective(ClausesWithImplicit, AStmt, StartLoc, 5087 EndLoc); 5088 AllowedNameModifiers.push_back(OMPD_target); 5089 break; 5090 case OMPD_target_teams_distribute: 5091 Res = ActOnOpenMPTargetTeamsDistributeDirective( 5092 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 5093 AllowedNameModifiers.push_back(OMPD_target); 5094 break; 5095 case OMPD_target_teams_distribute_parallel_for: 5096 Res = ActOnOpenMPTargetTeamsDistributeParallelForDirective( 5097 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 5098 AllowedNameModifiers.push_back(OMPD_target); 5099 AllowedNameModifiers.push_back(OMPD_parallel); 5100 break; 5101 case OMPD_target_teams_distribute_parallel_for_simd: 5102 Res = ActOnOpenMPTargetTeamsDistributeParallelForSimdDirective( 5103 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 5104 AllowedNameModifiers.push_back(OMPD_target); 5105 AllowedNameModifiers.push_back(OMPD_parallel); 5106 if (LangOpts.OpenMP >= 50) 5107 AllowedNameModifiers.push_back(OMPD_simd); 5108 break; 5109 case OMPD_target_teams_distribute_simd: 5110 Res = ActOnOpenMPTargetTeamsDistributeSimdDirective( 5111 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 5112 AllowedNameModifiers.push_back(OMPD_target); 5113 if (LangOpts.OpenMP >= 50) 5114 AllowedNameModifiers.push_back(OMPD_simd); 5115 break; 5116 case OMPD_declare_target: 5117 case OMPD_end_declare_target: 5118 case OMPD_threadprivate: 5119 case OMPD_allocate: 5120 case OMPD_declare_reduction: 5121 case OMPD_declare_mapper: 5122 case OMPD_declare_simd: 5123 case OMPD_requires: 5124 case OMPD_declare_variant: 5125 case OMPD_begin_declare_variant: 5126 case OMPD_end_declare_variant: 5127 llvm_unreachable("OpenMP Directive is not allowed"); 5128 case OMPD_unknown: 5129 llvm_unreachable("Unknown OpenMP directive"); 5130 } 5131 5132 ErrorFound = Res.isInvalid() || ErrorFound; 5133 5134 // Check variables in the clauses if default(none) was specified. 5135 if (DSAStack->getDefaultDSA() == DSA_none) { 5136 DSAAttrChecker DSAChecker(DSAStack, *this, nullptr); 5137 for (OMPClause *C : Clauses) { 5138 switch (C->getClauseKind()) { 5139 case OMPC_num_threads: 5140 case OMPC_dist_schedule: 5141 // Do not analyse if no parent teams directive. 5142 if (isOpenMPTeamsDirective(Kind)) 5143 break; 5144 continue; 5145 case OMPC_if: 5146 if (isOpenMPTeamsDirective(Kind) && 5147 cast<OMPIfClause>(C)->getNameModifier() != OMPD_target) 5148 break; 5149 if (isOpenMPParallelDirective(Kind) && 5150 isOpenMPTaskLoopDirective(Kind) && 5151 cast<OMPIfClause>(C)->getNameModifier() != OMPD_parallel) 5152 break; 5153 continue; 5154 case OMPC_schedule: 5155 case OMPC_detach: 5156 break; 5157 case OMPC_grainsize: 5158 case OMPC_num_tasks: 5159 case OMPC_final: 5160 case OMPC_priority: 5161 // Do not analyze if no parent parallel directive. 5162 if (isOpenMPParallelDirective(Kind)) 5163 break; 5164 continue; 5165 case OMPC_ordered: 5166 case OMPC_device: 5167 case OMPC_num_teams: 5168 case OMPC_thread_limit: 5169 case OMPC_hint: 5170 case OMPC_collapse: 5171 case OMPC_safelen: 5172 case OMPC_simdlen: 5173 case OMPC_default: 5174 case OMPC_proc_bind: 5175 case OMPC_private: 5176 case OMPC_firstprivate: 5177 case OMPC_lastprivate: 5178 case OMPC_shared: 5179 case OMPC_reduction: 5180 case OMPC_task_reduction: 5181 case OMPC_in_reduction: 5182 case OMPC_linear: 5183 case OMPC_aligned: 5184 case OMPC_copyin: 5185 case OMPC_copyprivate: 5186 case OMPC_nowait: 5187 case OMPC_untied: 5188 case OMPC_mergeable: 5189 case OMPC_allocate: 5190 case OMPC_read: 5191 case OMPC_write: 5192 case OMPC_update: 5193 case OMPC_capture: 5194 case OMPC_seq_cst: 5195 case OMPC_acq_rel: 5196 case OMPC_acquire: 5197 case OMPC_release: 5198 case OMPC_relaxed: 5199 case OMPC_depend: 5200 case OMPC_threads: 5201 case OMPC_simd: 5202 case OMPC_map: 5203 case OMPC_nogroup: 5204 case OMPC_defaultmap: 5205 case OMPC_to: 5206 case OMPC_from: 5207 case OMPC_use_device_ptr: 5208 case OMPC_is_device_ptr: 5209 case OMPC_nontemporal: 5210 case OMPC_order: 5211 case OMPC_destroy: 5212 case OMPC_inclusive: 5213 case OMPC_exclusive: 5214 continue; 5215 case OMPC_allocator: 5216 case OMPC_flush: 5217 case OMPC_depobj: 5218 case OMPC_threadprivate: 5219 case OMPC_uniform: 5220 case OMPC_unknown: 5221 case OMPC_unified_address: 5222 case OMPC_unified_shared_memory: 5223 case OMPC_reverse_offload: 5224 case OMPC_dynamic_allocators: 5225 case OMPC_atomic_default_mem_order: 5226 case OMPC_device_type: 5227 case OMPC_match: 5228 llvm_unreachable("Unexpected clause"); 5229 } 5230 for (Stmt *CC : C->children()) { 5231 if (CC) 5232 DSAChecker.Visit(CC); 5233 } 5234 } 5235 for (const auto &P : DSAChecker.getVarsWithInheritedDSA()) 5236 VarsWithInheritedDSA[P.getFirst()] = P.getSecond(); 5237 } 5238 for (const auto &P : VarsWithInheritedDSA) { 5239 if (P.getFirst()->isImplicit() || isa<OMPCapturedExprDecl>(P.getFirst())) 5240 continue; 5241 ErrorFound = true; 5242 if (DSAStack->getDefaultDSA() == DSA_none) { 5243 Diag(P.second->getExprLoc(), diag::err_omp_no_dsa_for_variable) 5244 << P.first << P.second->getSourceRange(); 5245 Diag(DSAStack->getDefaultDSALocation(), diag::note_omp_default_dsa_none); 5246 } else if (getLangOpts().OpenMP >= 50) { 5247 Diag(P.second->getExprLoc(), 5248 diag::err_omp_defaultmap_no_attr_for_variable) 5249 << P.first << P.second->getSourceRange(); 5250 Diag(DSAStack->getDefaultDSALocation(), 5251 diag::note_omp_defaultmap_attr_none); 5252 } 5253 } 5254 5255 if (!AllowedNameModifiers.empty()) 5256 ErrorFound = checkIfClauses(*this, Kind, Clauses, AllowedNameModifiers) || 5257 ErrorFound; 5258 5259 if (ErrorFound) 5260 return StmtError(); 5261 5262 if (!CurContext->isDependentContext() && 5263 isOpenMPTargetExecutionDirective(Kind) && 5264 !(DSAStack->hasRequiresDeclWithClause<OMPUnifiedSharedMemoryClause>() || 5265 DSAStack->hasRequiresDeclWithClause<OMPUnifiedAddressClause>() || 5266 DSAStack->hasRequiresDeclWithClause<OMPReverseOffloadClause>() || 5267 DSAStack->hasRequiresDeclWithClause<OMPDynamicAllocatorsClause>())) { 5268 // Register target to DSA Stack. 5269 DSAStack->addTargetDirLocation(StartLoc); 5270 } 5271 5272 return Res; 5273 } 5274 5275 Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareSimdDirective( 5276 DeclGroupPtrTy DG, OMPDeclareSimdDeclAttr::BranchStateTy BS, Expr *Simdlen, 5277 ArrayRef<Expr *> Uniforms, ArrayRef<Expr *> Aligneds, 5278 ArrayRef<Expr *> Alignments, ArrayRef<Expr *> Linears, 5279 ArrayRef<unsigned> LinModifiers, ArrayRef<Expr *> Steps, SourceRange SR) { 5280 assert(Aligneds.size() == Alignments.size()); 5281 assert(Linears.size() == LinModifiers.size()); 5282 assert(Linears.size() == Steps.size()); 5283 if (!DG || DG.get().isNull()) 5284 return DeclGroupPtrTy(); 5285 5286 const int SimdId = 0; 5287 if (!DG.get().isSingleDecl()) { 5288 Diag(SR.getBegin(), diag::err_omp_single_decl_in_declare_simd_variant) 5289 << SimdId; 5290 return DG; 5291 } 5292 Decl *ADecl = DG.get().getSingleDecl(); 5293 if (auto *FTD = dyn_cast<FunctionTemplateDecl>(ADecl)) 5294 ADecl = FTD->getTemplatedDecl(); 5295 5296 auto *FD = dyn_cast<FunctionDecl>(ADecl); 5297 if (!FD) { 5298 Diag(ADecl->getLocation(), diag::err_omp_function_expected) << SimdId; 5299 return DeclGroupPtrTy(); 5300 } 5301 5302 // OpenMP [2.8.2, declare simd construct, Description] 5303 // The parameter of the simdlen clause must be a constant positive integer 5304 // expression. 5305 ExprResult SL; 5306 if (Simdlen) 5307 SL = VerifyPositiveIntegerConstantInClause(Simdlen, OMPC_simdlen); 5308 // OpenMP [2.8.2, declare simd construct, Description] 5309 // The special this pointer can be used as if was one of the arguments to the 5310 // function in any of the linear, aligned, or uniform clauses. 5311 // The uniform clause declares one or more arguments to have an invariant 5312 // value for all concurrent invocations of the function in the execution of a 5313 // single SIMD loop. 5314 llvm::DenseMap<const Decl *, const Expr *> UniformedArgs; 5315 const Expr *UniformedLinearThis = nullptr; 5316 for (const Expr *E : Uniforms) { 5317 E = E->IgnoreParenImpCasts(); 5318 if (const auto *DRE = dyn_cast<DeclRefExpr>(E)) 5319 if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) 5320 if (FD->getNumParams() > PVD->getFunctionScopeIndex() && 5321 FD->getParamDecl(PVD->getFunctionScopeIndex()) 5322 ->getCanonicalDecl() == PVD->getCanonicalDecl()) { 5323 UniformedArgs.try_emplace(PVD->getCanonicalDecl(), E); 5324 continue; 5325 } 5326 if (isa<CXXThisExpr>(E)) { 5327 UniformedLinearThis = E; 5328 continue; 5329 } 5330 Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause) 5331 << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0); 5332 } 5333 // OpenMP [2.8.2, declare simd construct, Description] 5334 // The aligned clause declares that the object to which each list item points 5335 // is aligned to the number of bytes expressed in the optional parameter of 5336 // the aligned clause. 5337 // The special this pointer can be used as if was one of the arguments to the 5338 // function in any of the linear, aligned, or uniform clauses. 5339 // The type of list items appearing in the aligned clause must be array, 5340 // pointer, reference to array, or reference to pointer. 5341 llvm::DenseMap<const Decl *, const Expr *> AlignedArgs; 5342 const Expr *AlignedThis = nullptr; 5343 for (const Expr *E : Aligneds) { 5344 E = E->IgnoreParenImpCasts(); 5345 if (const auto *DRE = dyn_cast<DeclRefExpr>(E)) 5346 if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) { 5347 const VarDecl *CanonPVD = PVD->getCanonicalDecl(); 5348 if (FD->getNumParams() > PVD->getFunctionScopeIndex() && 5349 FD->getParamDecl(PVD->getFunctionScopeIndex()) 5350 ->getCanonicalDecl() == CanonPVD) { 5351 // OpenMP [2.8.1, simd construct, Restrictions] 5352 // A list-item cannot appear in more than one aligned clause. 5353 if (AlignedArgs.count(CanonPVD) > 0) { 5354 Diag(E->getExprLoc(), diag::err_omp_used_in_clause_twice) 5355 << 1 << getOpenMPClauseName(OMPC_aligned) 5356 << E->getSourceRange(); 5357 Diag(AlignedArgs[CanonPVD]->getExprLoc(), 5358 diag::note_omp_explicit_dsa) 5359 << getOpenMPClauseName(OMPC_aligned); 5360 continue; 5361 } 5362 AlignedArgs[CanonPVD] = E; 5363 QualType QTy = PVD->getType() 5364 .getNonReferenceType() 5365 .getUnqualifiedType() 5366 .getCanonicalType(); 5367 const Type *Ty = QTy.getTypePtrOrNull(); 5368 if (!Ty || (!Ty->isArrayType() && !Ty->isPointerType())) { 5369 Diag(E->getExprLoc(), diag::err_omp_aligned_expected_array_or_ptr) 5370 << QTy << getLangOpts().CPlusPlus << E->getSourceRange(); 5371 Diag(PVD->getLocation(), diag::note_previous_decl) << PVD; 5372 } 5373 continue; 5374 } 5375 } 5376 if (isa<CXXThisExpr>(E)) { 5377 if (AlignedThis) { 5378 Diag(E->getExprLoc(), diag::err_omp_used_in_clause_twice) 5379 << 2 << getOpenMPClauseName(OMPC_aligned) << E->getSourceRange(); 5380 Diag(AlignedThis->getExprLoc(), diag::note_omp_explicit_dsa) 5381 << getOpenMPClauseName(OMPC_aligned); 5382 } 5383 AlignedThis = E; 5384 continue; 5385 } 5386 Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause) 5387 << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0); 5388 } 5389 // The optional parameter of the aligned clause, alignment, must be a constant 5390 // positive integer expression. If no optional parameter is specified, 5391 // implementation-defined default alignments for SIMD instructions on the 5392 // target platforms are assumed. 5393 SmallVector<const Expr *, 4> NewAligns; 5394 for (Expr *E : Alignments) { 5395 ExprResult Align; 5396 if (E) 5397 Align = VerifyPositiveIntegerConstantInClause(E, OMPC_aligned); 5398 NewAligns.push_back(Align.get()); 5399 } 5400 // OpenMP [2.8.2, declare simd construct, Description] 5401 // The linear clause declares one or more list items to be private to a SIMD 5402 // lane and to have a linear relationship with respect to the iteration space 5403 // of a loop. 5404 // The special this pointer can be used as if was one of the arguments to the 5405 // function in any of the linear, aligned, or uniform clauses. 5406 // When a linear-step expression is specified in a linear clause it must be 5407 // either a constant integer expression or an integer-typed parameter that is 5408 // specified in a uniform clause on the directive. 5409 llvm::DenseMap<const Decl *, const Expr *> LinearArgs; 5410 const bool IsUniformedThis = UniformedLinearThis != nullptr; 5411 auto MI = LinModifiers.begin(); 5412 for (const Expr *E : Linears) { 5413 auto LinKind = static_cast<OpenMPLinearClauseKind>(*MI); 5414 ++MI; 5415 E = E->IgnoreParenImpCasts(); 5416 if (const auto *DRE = dyn_cast<DeclRefExpr>(E)) 5417 if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) { 5418 const VarDecl *CanonPVD = PVD->getCanonicalDecl(); 5419 if (FD->getNumParams() > PVD->getFunctionScopeIndex() && 5420 FD->getParamDecl(PVD->getFunctionScopeIndex()) 5421 ->getCanonicalDecl() == CanonPVD) { 5422 // OpenMP [2.15.3.7, linear Clause, Restrictions] 5423 // A list-item cannot appear in more than one linear clause. 5424 if (LinearArgs.count(CanonPVD) > 0) { 5425 Diag(E->getExprLoc(), diag::err_omp_wrong_dsa) 5426 << getOpenMPClauseName(OMPC_linear) 5427 << getOpenMPClauseName(OMPC_linear) << E->getSourceRange(); 5428 Diag(LinearArgs[CanonPVD]->getExprLoc(), 5429 diag::note_omp_explicit_dsa) 5430 << getOpenMPClauseName(OMPC_linear); 5431 continue; 5432 } 5433 // Each argument can appear in at most one uniform or linear clause. 5434 if (UniformedArgs.count(CanonPVD) > 0) { 5435 Diag(E->getExprLoc(), diag::err_omp_wrong_dsa) 5436 << getOpenMPClauseName(OMPC_linear) 5437 << getOpenMPClauseName(OMPC_uniform) << E->getSourceRange(); 5438 Diag(UniformedArgs[CanonPVD]->getExprLoc(), 5439 diag::note_omp_explicit_dsa) 5440 << getOpenMPClauseName(OMPC_uniform); 5441 continue; 5442 } 5443 LinearArgs[CanonPVD] = E; 5444 if (E->isValueDependent() || E->isTypeDependent() || 5445 E->isInstantiationDependent() || 5446 E->containsUnexpandedParameterPack()) 5447 continue; 5448 (void)CheckOpenMPLinearDecl(CanonPVD, E->getExprLoc(), LinKind, 5449 PVD->getOriginalType(), 5450 /*IsDeclareSimd=*/true); 5451 continue; 5452 } 5453 } 5454 if (isa<CXXThisExpr>(E)) { 5455 if (UniformedLinearThis) { 5456 Diag(E->getExprLoc(), diag::err_omp_wrong_dsa) 5457 << getOpenMPClauseName(OMPC_linear) 5458 << getOpenMPClauseName(IsUniformedThis ? OMPC_uniform : OMPC_linear) 5459 << E->getSourceRange(); 5460 Diag(UniformedLinearThis->getExprLoc(), diag::note_omp_explicit_dsa) 5461 << getOpenMPClauseName(IsUniformedThis ? OMPC_uniform 5462 : OMPC_linear); 5463 continue; 5464 } 5465 UniformedLinearThis = E; 5466 if (E->isValueDependent() || E->isTypeDependent() || 5467 E->isInstantiationDependent() || E->containsUnexpandedParameterPack()) 5468 continue; 5469 (void)CheckOpenMPLinearDecl(/*D=*/nullptr, E->getExprLoc(), LinKind, 5470 E->getType(), /*IsDeclareSimd=*/true); 5471 continue; 5472 } 5473 Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause) 5474 << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0); 5475 } 5476 Expr *Step = nullptr; 5477 Expr *NewStep = nullptr; 5478 SmallVector<Expr *, 4> NewSteps; 5479 for (Expr *E : Steps) { 5480 // Skip the same step expression, it was checked already. 5481 if (Step == E || !E) { 5482 NewSteps.push_back(E ? NewStep : nullptr); 5483 continue; 5484 } 5485 Step = E; 5486 if (const auto *DRE = dyn_cast<DeclRefExpr>(Step)) 5487 if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) { 5488 const VarDecl *CanonPVD = PVD->getCanonicalDecl(); 5489 if (UniformedArgs.count(CanonPVD) == 0) { 5490 Diag(Step->getExprLoc(), diag::err_omp_expected_uniform_param) 5491 << Step->getSourceRange(); 5492 } else if (E->isValueDependent() || E->isTypeDependent() || 5493 E->isInstantiationDependent() || 5494 E->containsUnexpandedParameterPack() || 5495 CanonPVD->getType()->hasIntegerRepresentation()) { 5496 NewSteps.push_back(Step); 5497 } else { 5498 Diag(Step->getExprLoc(), diag::err_omp_expected_int_param) 5499 << Step->getSourceRange(); 5500 } 5501 continue; 5502 } 5503 NewStep = Step; 5504 if (Step && !Step->isValueDependent() && !Step->isTypeDependent() && 5505 !Step->isInstantiationDependent() && 5506 !Step->containsUnexpandedParameterPack()) { 5507 NewStep = PerformOpenMPImplicitIntegerConversion(Step->getExprLoc(), Step) 5508 .get(); 5509 if (NewStep) 5510 NewStep = VerifyIntegerConstantExpression(NewStep).get(); 5511 } 5512 NewSteps.push_back(NewStep); 5513 } 5514 auto *NewAttr = OMPDeclareSimdDeclAttr::CreateImplicit( 5515 Context, BS, SL.get(), const_cast<Expr **>(Uniforms.data()), 5516 Uniforms.size(), const_cast<Expr **>(Aligneds.data()), Aligneds.size(), 5517 const_cast<Expr **>(NewAligns.data()), NewAligns.size(), 5518 const_cast<Expr **>(Linears.data()), Linears.size(), 5519 const_cast<unsigned *>(LinModifiers.data()), LinModifiers.size(), 5520 NewSteps.data(), NewSteps.size(), SR); 5521 ADecl->addAttr(NewAttr); 5522 return DG; 5523 } 5524 5525 static void setPrototype(Sema &S, FunctionDecl *FD, FunctionDecl *FDWithProto, 5526 QualType NewType) { 5527 assert(NewType->isFunctionProtoType() && 5528 "Expected function type with prototype."); 5529 assert(FD->getType()->isFunctionNoProtoType() && 5530 "Expected function with type with no prototype."); 5531 assert(FDWithProto->getType()->isFunctionProtoType() && 5532 "Expected function with prototype."); 5533 // Synthesize parameters with the same types. 5534 FD->setType(NewType); 5535 SmallVector<ParmVarDecl *, 16> Params; 5536 for (const ParmVarDecl *P : FDWithProto->parameters()) { 5537 auto *Param = ParmVarDecl::Create(S.getASTContext(), FD, SourceLocation(), 5538 SourceLocation(), nullptr, P->getType(), 5539 /*TInfo=*/nullptr, SC_None, nullptr); 5540 Param->setScopeInfo(0, Params.size()); 5541 Param->setImplicit(); 5542 Params.push_back(Param); 5543 } 5544 5545 FD->setParams(Params); 5546 } 5547 5548 Sema::OMPDeclareVariantScope::OMPDeclareVariantScope(OMPTraitInfo &TI) 5549 : TI(&TI), NameSuffix(TI.getMangledName()) {} 5550 5551 FunctionDecl * 5552 Sema::ActOnStartOfFunctionDefinitionInOpenMPDeclareVariantScope(Scope *S, 5553 Declarator &D) { 5554 auto *BaseFD = cast<FunctionDecl>(ActOnDeclarator(S, D)); 5555 OMPDeclareVariantScope &DVScope = OMPDeclareVariantScopes.back(); 5556 std::string MangledName; 5557 MangledName += D.getIdentifier()->getName(); 5558 MangledName += getOpenMPVariantManglingSeparatorStr(); 5559 MangledName += DVScope.NameSuffix; 5560 IdentifierInfo &VariantII = Context.Idents.get(MangledName); 5561 5562 VariantII.setMangledOpenMPVariantName(true); 5563 D.SetIdentifier(&VariantII, D.getBeginLoc()); 5564 return BaseFD; 5565 } 5566 5567 void Sema::ActOnFinishedFunctionDefinitionInOpenMPDeclareVariantScope( 5568 FunctionDecl *FD, FunctionDecl *BaseFD) { 5569 // Do not mark function as is used to prevent its emission if this is the 5570 // only place where it is used. 5571 EnterExpressionEvaluationContext Unevaluated( 5572 *this, Sema::ExpressionEvaluationContext::Unevaluated); 5573 5574 Expr *VariantFuncRef = DeclRefExpr::Create( 5575 Context, NestedNameSpecifierLoc(), SourceLocation(), FD, 5576 /* RefersToEnclosingVariableOrCapture */ false, 5577 /* NameLoc */ FD->getLocation(), FD->getType(), ExprValueKind::VK_RValue); 5578 5579 OMPDeclareVariantScope &DVScope = OMPDeclareVariantScopes.back(); 5580 auto *OMPDeclareVariantA = OMPDeclareVariantAttr::CreateImplicit( 5581 Context, VariantFuncRef, DVScope.TI); 5582 BaseFD->addAttr(OMPDeclareVariantA); 5583 5584 BaseFD->setImplicit(true); 5585 } 5586 5587 ExprResult Sema::ActOnOpenMPCall(ExprResult Call, Scope *Scope, 5588 SourceLocation LParenLoc, 5589 MultiExprArg ArgExprs, 5590 SourceLocation RParenLoc, Expr *ExecConfig) { 5591 // The common case is a regular call we do not want to specialize at all. Try 5592 // to make that case fast by bailing early. 5593 CallExpr *CE = dyn_cast<CallExpr>(Call.get()); 5594 if (!CE) 5595 return Call; 5596 5597 FunctionDecl *CalleeFnDecl = CE->getDirectCallee(); 5598 if (!CalleeFnDecl) 5599 return Call; 5600 5601 if (!CalleeFnDecl->hasAttr<OMPDeclareVariantAttr>()) 5602 return Call; 5603 5604 ASTContext &Context = getASTContext(); 5605 OMPContext OMPCtx(getLangOpts().OpenMPIsDevice, 5606 Context.getTargetInfo().getTriple()); 5607 5608 SmallVector<Expr *, 4> Exprs; 5609 SmallVector<VariantMatchInfo, 4> VMIs; 5610 while (CalleeFnDecl) { 5611 for (OMPDeclareVariantAttr *A : 5612 CalleeFnDecl->specific_attrs<OMPDeclareVariantAttr>()) { 5613 Expr *VariantRef = A->getVariantFuncRef(); 5614 5615 VariantMatchInfo VMI; 5616 OMPTraitInfo &TI = A->getTraitInfo(); 5617 TI.getAsVariantMatchInfo(Context, VMI, /* DeviceSetOnly */ false); 5618 if (!isVariantApplicableInContext(VMI, OMPCtx)) 5619 continue; 5620 5621 VMIs.push_back(VMI); 5622 Exprs.push_back(VariantRef); 5623 } 5624 5625 CalleeFnDecl = CalleeFnDecl->getPreviousDecl(); 5626 } 5627 5628 ExprResult NewCall; 5629 do { 5630 int BestIdx = getBestVariantMatchForContext(VMIs, OMPCtx); 5631 if (BestIdx < 0) 5632 return Call; 5633 Expr *BestExpr = cast<DeclRefExpr>(Exprs[BestIdx]); 5634 Decl *BestDecl = cast<DeclRefExpr>(BestExpr)->getDecl(); 5635 5636 { 5637 // Try to build a (member) call expression for the current best applicable 5638 // variant expression. We allow this to fail in which case we continue 5639 // with the next best variant expression. The fail case is part of the 5640 // implementation defined behavior in the OpenMP standard when it talks 5641 // about what differences in the function prototypes: "Any differences 5642 // that the specific OpenMP context requires in the prototype of the 5643 // variant from the base function prototype are implementation defined." 5644 // This wording is there to allow the specialized variant to have a 5645 // different type than the base function. This is intended and OK but if 5646 // we cannot create a call the difference is not in the "implementation 5647 // defined range" we allow. 5648 Sema::TentativeAnalysisScope Trap(*this); 5649 5650 if (auto *SpecializedMethod = dyn_cast<CXXMethodDecl>(BestDecl)) { 5651 auto *MemberCall = dyn_cast<CXXMemberCallExpr>(CE); 5652 BestExpr = MemberExpr::CreateImplicit( 5653 Context, MemberCall->getImplicitObjectArgument(), 5654 /* IsArrow */ false, SpecializedMethod, Context.BoundMemberTy, 5655 MemberCall->getValueKind(), MemberCall->getObjectKind()); 5656 } 5657 NewCall = BuildCallExpr(Scope, BestExpr, LParenLoc, ArgExprs, RParenLoc, 5658 ExecConfig); 5659 if (NewCall.isUsable()) 5660 break; 5661 } 5662 5663 VMIs.erase(VMIs.begin() + BestIdx); 5664 Exprs.erase(Exprs.begin() + BestIdx); 5665 } while (!VMIs.empty()); 5666 5667 if (!NewCall.isUsable()) 5668 return Call; 5669 return PseudoObjectExpr::Create(Context, CE, {NewCall.get()}, 0); 5670 } 5671 5672 Optional<std::pair<FunctionDecl *, Expr *>> 5673 Sema::checkOpenMPDeclareVariantFunction(Sema::DeclGroupPtrTy DG, 5674 Expr *VariantRef, OMPTraitInfo &TI, 5675 SourceRange SR) { 5676 if (!DG || DG.get().isNull()) 5677 return None; 5678 5679 const int VariantId = 1; 5680 // Must be applied only to single decl. 5681 if (!DG.get().isSingleDecl()) { 5682 Diag(SR.getBegin(), diag::err_omp_single_decl_in_declare_simd_variant) 5683 << VariantId << SR; 5684 return None; 5685 } 5686 Decl *ADecl = DG.get().getSingleDecl(); 5687 if (auto *FTD = dyn_cast<FunctionTemplateDecl>(ADecl)) 5688 ADecl = FTD->getTemplatedDecl(); 5689 5690 // Decl must be a function. 5691 auto *FD = dyn_cast<FunctionDecl>(ADecl); 5692 if (!FD) { 5693 Diag(ADecl->getLocation(), diag::err_omp_function_expected) 5694 << VariantId << SR; 5695 return None; 5696 } 5697 5698 auto &&HasMultiVersionAttributes = [](const FunctionDecl *FD) { 5699 return FD->hasAttrs() && 5700 (FD->hasAttr<CPUDispatchAttr>() || FD->hasAttr<CPUSpecificAttr>() || 5701 FD->hasAttr<TargetAttr>()); 5702 }; 5703 // OpenMP is not compatible with CPU-specific attributes. 5704 if (HasMultiVersionAttributes(FD)) { 5705 Diag(FD->getLocation(), diag::err_omp_declare_variant_incompat_attributes) 5706 << SR; 5707 return None; 5708 } 5709 5710 // Allow #pragma omp declare variant only if the function is not used. 5711 if (FD->isUsed(false)) 5712 Diag(SR.getBegin(), diag::warn_omp_declare_variant_after_used) 5713 << FD->getLocation(); 5714 5715 // Check if the function was emitted already. 5716 const FunctionDecl *Definition; 5717 if (!FD->isThisDeclarationADefinition() && FD->isDefined(Definition) && 5718 (LangOpts.EmitAllDecls || Context.DeclMustBeEmitted(Definition))) 5719 Diag(SR.getBegin(), diag::warn_omp_declare_variant_after_emitted) 5720 << FD->getLocation(); 5721 5722 // The VariantRef must point to function. 5723 if (!VariantRef) { 5724 Diag(SR.getBegin(), diag::err_omp_function_expected) << VariantId; 5725 return None; 5726 } 5727 5728 auto ShouldDelayChecks = [](Expr *&E, bool) { 5729 return E && (E->isTypeDependent() || E->isValueDependent() || 5730 E->containsUnexpandedParameterPack() || 5731 E->isInstantiationDependent()); 5732 }; 5733 // Do not check templates, wait until instantiation. 5734 if (FD->isDependentContext() || ShouldDelayChecks(VariantRef, false) || 5735 TI.anyScoreOrCondition(ShouldDelayChecks)) 5736 return std::make_pair(FD, VariantRef); 5737 5738 // Deal with non-constant score and user condition expressions. 5739 auto HandleNonConstantScoresAndConditions = [this](Expr *&E, 5740 bool IsScore) -> bool { 5741 llvm::APSInt Result; 5742 if (!E || E->isIntegerConstantExpr(Result, Context)) 5743 return false; 5744 5745 if (IsScore) { 5746 // We warn on non-constant scores and pretend they were not present. 5747 Diag(E->getExprLoc(), diag::warn_omp_declare_variant_score_not_constant) 5748 << E; 5749 E = nullptr; 5750 } else { 5751 // We could replace a non-constant user condition with "false" but we 5752 // will soon need to handle these anyway for the dynamic version of 5753 // OpenMP context selectors. 5754 Diag(E->getExprLoc(), 5755 diag::err_omp_declare_variant_user_condition_not_constant) 5756 << E; 5757 } 5758 return true; 5759 }; 5760 if (TI.anyScoreOrCondition(HandleNonConstantScoresAndConditions)) 5761 return None; 5762 5763 // Convert VariantRef expression to the type of the original function to 5764 // resolve possible conflicts. 5765 ExprResult VariantRefCast; 5766 if (LangOpts.CPlusPlus) { 5767 QualType FnPtrType; 5768 auto *Method = dyn_cast<CXXMethodDecl>(FD); 5769 if (Method && !Method->isStatic()) { 5770 const Type *ClassType = 5771 Context.getTypeDeclType(Method->getParent()).getTypePtr(); 5772 FnPtrType = Context.getMemberPointerType(FD->getType(), ClassType); 5773 ExprResult ER; 5774 { 5775 // Build adrr_of unary op to correctly handle type checks for member 5776 // functions. 5777 Sema::TentativeAnalysisScope Trap(*this); 5778 ER = CreateBuiltinUnaryOp(VariantRef->getBeginLoc(), UO_AddrOf, 5779 VariantRef); 5780 } 5781 if (!ER.isUsable()) { 5782 Diag(VariantRef->getExprLoc(), diag::err_omp_function_expected) 5783 << VariantId << VariantRef->getSourceRange(); 5784 return None; 5785 } 5786 VariantRef = ER.get(); 5787 } else { 5788 FnPtrType = Context.getPointerType(FD->getType()); 5789 } 5790 ImplicitConversionSequence ICS = 5791 TryImplicitConversion(VariantRef, FnPtrType.getUnqualifiedType(), 5792 /*SuppressUserConversions=*/false, 5793 AllowedExplicit::None, 5794 /*InOverloadResolution=*/false, 5795 /*CStyle=*/false, 5796 /*AllowObjCWritebackConversion=*/false); 5797 if (ICS.isFailure()) { 5798 Diag(VariantRef->getExprLoc(), 5799 diag::err_omp_declare_variant_incompat_types) 5800 << VariantRef->getType() 5801 << ((Method && !Method->isStatic()) ? FnPtrType : FD->getType()) 5802 << VariantRef->getSourceRange(); 5803 return None; 5804 } 5805 VariantRefCast = PerformImplicitConversion( 5806 VariantRef, FnPtrType.getUnqualifiedType(), AA_Converting); 5807 if (!VariantRefCast.isUsable()) 5808 return None; 5809 // Drop previously built artificial addr_of unary op for member functions. 5810 if (Method && !Method->isStatic()) { 5811 Expr *PossibleAddrOfVariantRef = VariantRefCast.get(); 5812 if (auto *UO = dyn_cast<UnaryOperator>( 5813 PossibleAddrOfVariantRef->IgnoreImplicit())) 5814 VariantRefCast = UO->getSubExpr(); 5815 } 5816 } else { 5817 VariantRefCast = VariantRef; 5818 } 5819 5820 ExprResult ER = CheckPlaceholderExpr(VariantRefCast.get()); 5821 if (!ER.isUsable() || 5822 !ER.get()->IgnoreParenImpCasts()->getType()->isFunctionType()) { 5823 Diag(VariantRef->getExprLoc(), diag::err_omp_function_expected) 5824 << VariantId << VariantRef->getSourceRange(); 5825 return None; 5826 } 5827 5828 // The VariantRef must point to function. 5829 auto *DRE = dyn_cast<DeclRefExpr>(ER.get()->IgnoreParenImpCasts()); 5830 if (!DRE) { 5831 Diag(VariantRef->getExprLoc(), diag::err_omp_function_expected) 5832 << VariantId << VariantRef->getSourceRange(); 5833 return None; 5834 } 5835 auto *NewFD = dyn_cast_or_null<FunctionDecl>(DRE->getDecl()); 5836 if (!NewFD) { 5837 Diag(VariantRef->getExprLoc(), diag::err_omp_function_expected) 5838 << VariantId << VariantRef->getSourceRange(); 5839 return None; 5840 } 5841 5842 // Check if function types are compatible in C. 5843 if (!LangOpts.CPlusPlus) { 5844 QualType NewType = 5845 Context.mergeFunctionTypes(FD->getType(), NewFD->getType()); 5846 if (NewType.isNull()) { 5847 Diag(VariantRef->getExprLoc(), 5848 diag::err_omp_declare_variant_incompat_types) 5849 << NewFD->getType() << FD->getType() << VariantRef->getSourceRange(); 5850 return None; 5851 } 5852 if (NewType->isFunctionProtoType()) { 5853 if (FD->getType()->isFunctionNoProtoType()) 5854 setPrototype(*this, FD, NewFD, NewType); 5855 else if (NewFD->getType()->isFunctionNoProtoType()) 5856 setPrototype(*this, NewFD, FD, NewType); 5857 } 5858 } 5859 5860 // Check if variant function is not marked with declare variant directive. 5861 if (NewFD->hasAttrs() && NewFD->hasAttr<OMPDeclareVariantAttr>()) { 5862 Diag(VariantRef->getExprLoc(), 5863 diag::warn_omp_declare_variant_marked_as_declare_variant) 5864 << VariantRef->getSourceRange(); 5865 SourceRange SR = 5866 NewFD->specific_attr_begin<OMPDeclareVariantAttr>()->getRange(); 5867 Diag(SR.getBegin(), diag::note_omp_marked_declare_variant_here) << SR; 5868 return None; 5869 } 5870 5871 enum DoesntSupport { 5872 VirtFuncs = 1, 5873 Constructors = 3, 5874 Destructors = 4, 5875 DeletedFuncs = 5, 5876 DefaultedFuncs = 6, 5877 ConstexprFuncs = 7, 5878 ConstevalFuncs = 8, 5879 }; 5880 if (const auto *CXXFD = dyn_cast<CXXMethodDecl>(FD)) { 5881 if (CXXFD->isVirtual()) { 5882 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support) 5883 << VirtFuncs; 5884 return None; 5885 } 5886 5887 if (isa<CXXConstructorDecl>(FD)) { 5888 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support) 5889 << Constructors; 5890 return None; 5891 } 5892 5893 if (isa<CXXDestructorDecl>(FD)) { 5894 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support) 5895 << Destructors; 5896 return None; 5897 } 5898 } 5899 5900 if (FD->isDeleted()) { 5901 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support) 5902 << DeletedFuncs; 5903 return None; 5904 } 5905 5906 if (FD->isDefaulted()) { 5907 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support) 5908 << DefaultedFuncs; 5909 return None; 5910 } 5911 5912 if (FD->isConstexpr()) { 5913 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support) 5914 << (NewFD->isConsteval() ? ConstevalFuncs : ConstexprFuncs); 5915 return None; 5916 } 5917 5918 // Check general compatibility. 5919 if (areMultiversionVariantFunctionsCompatible( 5920 FD, NewFD, PartialDiagnostic::NullDiagnostic(), 5921 PartialDiagnosticAt(SourceLocation(), 5922 PartialDiagnostic::NullDiagnostic()), 5923 PartialDiagnosticAt( 5924 VariantRef->getExprLoc(), 5925 PDiag(diag::err_omp_declare_variant_doesnt_support)), 5926 PartialDiagnosticAt(VariantRef->getExprLoc(), 5927 PDiag(diag::err_omp_declare_variant_diff) 5928 << FD->getLocation()), 5929 /*TemplatesSupported=*/true, /*ConstexprSupported=*/false, 5930 /*CLinkageMayDiffer=*/true)) 5931 return None; 5932 return std::make_pair(FD, cast<Expr>(DRE)); 5933 } 5934 5935 void Sema::ActOnOpenMPDeclareVariantDirective(FunctionDecl *FD, 5936 Expr *VariantRef, 5937 OMPTraitInfo &TI, 5938 SourceRange SR) { 5939 auto *NewAttr = 5940 OMPDeclareVariantAttr::CreateImplicit(Context, VariantRef, &TI, SR); 5941 FD->addAttr(NewAttr); 5942 } 5943 5944 StmtResult Sema::ActOnOpenMPParallelDirective(ArrayRef<OMPClause *> Clauses, 5945 Stmt *AStmt, 5946 SourceLocation StartLoc, 5947 SourceLocation EndLoc) { 5948 if (!AStmt) 5949 return StmtError(); 5950 5951 auto *CS = cast<CapturedStmt>(AStmt); 5952 // 1.2.2 OpenMP Language Terminology 5953 // Structured block - An executable statement with a single entry at the 5954 // top and a single exit at the bottom. 5955 // The point of exit cannot be a branch out of the structured block. 5956 // longjmp() and throw() must not violate the entry/exit criteria. 5957 CS->getCapturedDecl()->setNothrow(); 5958 5959 setFunctionHasBranchProtectedScope(); 5960 5961 return OMPParallelDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt, 5962 DSAStack->isCancelRegion()); 5963 } 5964 5965 namespace { 5966 /// Iteration space of a single for loop. 5967 struct LoopIterationSpace final { 5968 /// True if the condition operator is the strict compare operator (<, > or 5969 /// !=). 5970 bool IsStrictCompare = false; 5971 /// Condition of the loop. 5972 Expr *PreCond = nullptr; 5973 /// This expression calculates the number of iterations in the loop. 5974 /// It is always possible to calculate it before starting the loop. 5975 Expr *NumIterations = nullptr; 5976 /// The loop counter variable. 5977 Expr *CounterVar = nullptr; 5978 /// Private loop counter variable. 5979 Expr *PrivateCounterVar = nullptr; 5980 /// This is initializer for the initial value of #CounterVar. 5981 Expr *CounterInit = nullptr; 5982 /// This is step for the #CounterVar used to generate its update: 5983 /// #CounterVar = #CounterInit + #CounterStep * CurrentIteration. 5984 Expr *CounterStep = nullptr; 5985 /// Should step be subtracted? 5986 bool Subtract = false; 5987 /// Source range of the loop init. 5988 SourceRange InitSrcRange; 5989 /// Source range of the loop condition. 5990 SourceRange CondSrcRange; 5991 /// Source range of the loop increment. 5992 SourceRange IncSrcRange; 5993 /// Minimum value that can have the loop control variable. Used to support 5994 /// non-rectangular loops. Applied only for LCV with the non-iterator types, 5995 /// since only such variables can be used in non-loop invariant expressions. 5996 Expr *MinValue = nullptr; 5997 /// Maximum value that can have the loop control variable. Used to support 5998 /// non-rectangular loops. Applied only for LCV with the non-iterator type, 5999 /// since only such variables can be used in non-loop invariant expressions. 6000 Expr *MaxValue = nullptr; 6001 /// true, if the lower bound depends on the outer loop control var. 6002 bool IsNonRectangularLB = false; 6003 /// true, if the upper bound depends on the outer loop control var. 6004 bool IsNonRectangularUB = false; 6005 /// Index of the loop this loop depends on and forms non-rectangular loop 6006 /// nest. 6007 unsigned LoopDependentIdx = 0; 6008 /// Final condition for the non-rectangular loop nest support. It is used to 6009 /// check that the number of iterations for this particular counter must be 6010 /// finished. 6011 Expr *FinalCondition = nullptr; 6012 }; 6013 6014 /// Helper class for checking canonical form of the OpenMP loops and 6015 /// extracting iteration space of each loop in the loop nest, that will be used 6016 /// for IR generation. 6017 class OpenMPIterationSpaceChecker { 6018 /// Reference to Sema. 6019 Sema &SemaRef; 6020 /// Data-sharing stack. 6021 DSAStackTy &Stack; 6022 /// A location for diagnostics (when there is no some better location). 6023 SourceLocation DefaultLoc; 6024 /// A location for diagnostics (when increment is not compatible). 6025 SourceLocation ConditionLoc; 6026 /// A source location for referring to loop init later. 6027 SourceRange InitSrcRange; 6028 /// A source location for referring to condition later. 6029 SourceRange ConditionSrcRange; 6030 /// A source location for referring to increment later. 6031 SourceRange IncrementSrcRange; 6032 /// Loop variable. 6033 ValueDecl *LCDecl = nullptr; 6034 /// Reference to loop variable. 6035 Expr *LCRef = nullptr; 6036 /// Lower bound (initializer for the var). 6037 Expr *LB = nullptr; 6038 /// Upper bound. 6039 Expr *UB = nullptr; 6040 /// Loop step (increment). 6041 Expr *Step = nullptr; 6042 /// This flag is true when condition is one of: 6043 /// Var < UB 6044 /// Var <= UB 6045 /// UB > Var 6046 /// UB >= Var 6047 /// This will have no value when the condition is != 6048 llvm::Optional<bool> TestIsLessOp; 6049 /// This flag is true when condition is strict ( < or > ). 6050 bool TestIsStrictOp = false; 6051 /// This flag is true when step is subtracted on each iteration. 6052 bool SubtractStep = false; 6053 /// The outer loop counter this loop depends on (if any). 6054 const ValueDecl *DepDecl = nullptr; 6055 /// Contains number of loop (starts from 1) on which loop counter init 6056 /// expression of this loop depends on. 6057 Optional<unsigned> InitDependOnLC; 6058 /// Contains number of loop (starts from 1) on which loop counter condition 6059 /// expression of this loop depends on. 6060 Optional<unsigned> CondDependOnLC; 6061 /// Checks if the provide statement depends on the loop counter. 6062 Optional<unsigned> doesDependOnLoopCounter(const Stmt *S, bool IsInitializer); 6063 /// Original condition required for checking of the exit condition for 6064 /// non-rectangular loop. 6065 Expr *Condition = nullptr; 6066 6067 public: 6068 OpenMPIterationSpaceChecker(Sema &SemaRef, DSAStackTy &Stack, 6069 SourceLocation DefaultLoc) 6070 : SemaRef(SemaRef), Stack(Stack), DefaultLoc(DefaultLoc), 6071 ConditionLoc(DefaultLoc) {} 6072 /// Check init-expr for canonical loop form and save loop counter 6073 /// variable - #Var and its initialization value - #LB. 6074 bool checkAndSetInit(Stmt *S, bool EmitDiags = true); 6075 /// Check test-expr for canonical form, save upper-bound (#UB), flags 6076 /// for less/greater and for strict/non-strict comparison. 6077 bool checkAndSetCond(Expr *S); 6078 /// Check incr-expr for canonical loop form and return true if it 6079 /// does not conform, otherwise save loop step (#Step). 6080 bool checkAndSetInc(Expr *S); 6081 /// Return the loop counter variable. 6082 ValueDecl *getLoopDecl() const { return LCDecl; } 6083 /// Return the reference expression to loop counter variable. 6084 Expr *getLoopDeclRefExpr() const { return LCRef; } 6085 /// Source range of the loop init. 6086 SourceRange getInitSrcRange() const { return InitSrcRange; } 6087 /// Source range of the loop condition. 6088 SourceRange getConditionSrcRange() const { return ConditionSrcRange; } 6089 /// Source range of the loop increment. 6090 SourceRange getIncrementSrcRange() const { return IncrementSrcRange; } 6091 /// True if the step should be subtracted. 6092 bool shouldSubtractStep() const { return SubtractStep; } 6093 /// True, if the compare operator is strict (<, > or !=). 6094 bool isStrictTestOp() const { return TestIsStrictOp; } 6095 /// Build the expression to calculate the number of iterations. 6096 Expr *buildNumIterations( 6097 Scope *S, ArrayRef<LoopIterationSpace> ResultIterSpaces, bool LimitedType, 6098 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const; 6099 /// Build the precondition expression for the loops. 6100 Expr * 6101 buildPreCond(Scope *S, Expr *Cond, 6102 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const; 6103 /// Build reference expression to the counter be used for codegen. 6104 DeclRefExpr * 6105 buildCounterVar(llvm::MapVector<const Expr *, DeclRefExpr *> &Captures, 6106 DSAStackTy &DSA) const; 6107 /// Build reference expression to the private counter be used for 6108 /// codegen. 6109 Expr *buildPrivateCounterVar() const; 6110 /// Build initialization of the counter be used for codegen. 6111 Expr *buildCounterInit() const; 6112 /// Build step of the counter be used for codegen. 6113 Expr *buildCounterStep() const; 6114 /// Build loop data with counter value for depend clauses in ordered 6115 /// directives. 6116 Expr * 6117 buildOrderedLoopData(Scope *S, Expr *Counter, 6118 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures, 6119 SourceLocation Loc, Expr *Inc = nullptr, 6120 OverloadedOperatorKind OOK = OO_Amp); 6121 /// Builds the minimum value for the loop counter. 6122 std::pair<Expr *, Expr *> buildMinMaxValues( 6123 Scope *S, llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const; 6124 /// Builds final condition for the non-rectangular loops. 6125 Expr *buildFinalCondition(Scope *S) const; 6126 /// Return true if any expression is dependent. 6127 bool dependent() const; 6128 /// Returns true if the initializer forms non-rectangular loop. 6129 bool doesInitDependOnLC() const { return InitDependOnLC.hasValue(); } 6130 /// Returns true if the condition forms non-rectangular loop. 6131 bool doesCondDependOnLC() const { return CondDependOnLC.hasValue(); } 6132 /// Returns index of the loop we depend on (starting from 1), or 0 otherwise. 6133 unsigned getLoopDependentIdx() const { 6134 return InitDependOnLC.getValueOr(CondDependOnLC.getValueOr(0)); 6135 } 6136 6137 private: 6138 /// Check the right-hand side of an assignment in the increment 6139 /// expression. 6140 bool checkAndSetIncRHS(Expr *RHS); 6141 /// Helper to set loop counter variable and its initializer. 6142 bool setLCDeclAndLB(ValueDecl *NewLCDecl, Expr *NewDeclRefExpr, Expr *NewLB, 6143 bool EmitDiags); 6144 /// Helper to set upper bound. 6145 bool setUB(Expr *NewUB, llvm::Optional<bool> LessOp, bool StrictOp, 6146 SourceRange SR, SourceLocation SL); 6147 /// Helper to set loop increment. 6148 bool setStep(Expr *NewStep, bool Subtract); 6149 }; 6150 6151 bool OpenMPIterationSpaceChecker::dependent() const { 6152 if (!LCDecl) { 6153 assert(!LB && !UB && !Step); 6154 return false; 6155 } 6156 return LCDecl->getType()->isDependentType() || 6157 (LB && LB->isValueDependent()) || (UB && UB->isValueDependent()) || 6158 (Step && Step->isValueDependent()); 6159 } 6160 6161 bool OpenMPIterationSpaceChecker::setLCDeclAndLB(ValueDecl *NewLCDecl, 6162 Expr *NewLCRefExpr, 6163 Expr *NewLB, bool EmitDiags) { 6164 // State consistency checking to ensure correct usage. 6165 assert(LCDecl == nullptr && LB == nullptr && LCRef == nullptr && 6166 UB == nullptr && Step == nullptr && !TestIsLessOp && !TestIsStrictOp); 6167 if (!NewLCDecl || !NewLB) 6168 return true; 6169 LCDecl = getCanonicalDecl(NewLCDecl); 6170 LCRef = NewLCRefExpr; 6171 if (auto *CE = dyn_cast_or_null<CXXConstructExpr>(NewLB)) 6172 if (const CXXConstructorDecl *Ctor = CE->getConstructor()) 6173 if ((Ctor->isCopyOrMoveConstructor() || 6174 Ctor->isConvertingConstructor(/*AllowExplicit=*/false)) && 6175 CE->getNumArgs() > 0 && CE->getArg(0) != nullptr) 6176 NewLB = CE->getArg(0)->IgnoreParenImpCasts(); 6177 LB = NewLB; 6178 if (EmitDiags) 6179 InitDependOnLC = doesDependOnLoopCounter(LB, /*IsInitializer=*/true); 6180 return false; 6181 } 6182 6183 bool OpenMPIterationSpaceChecker::setUB(Expr *NewUB, 6184 llvm::Optional<bool> LessOp, 6185 bool StrictOp, SourceRange SR, 6186 SourceLocation SL) { 6187 // State consistency checking to ensure correct usage. 6188 assert(LCDecl != nullptr && LB != nullptr && UB == nullptr && 6189 Step == nullptr && !TestIsLessOp && !TestIsStrictOp); 6190 if (!NewUB) 6191 return true; 6192 UB = NewUB; 6193 if (LessOp) 6194 TestIsLessOp = LessOp; 6195 TestIsStrictOp = StrictOp; 6196 ConditionSrcRange = SR; 6197 ConditionLoc = SL; 6198 CondDependOnLC = doesDependOnLoopCounter(UB, /*IsInitializer=*/false); 6199 return false; 6200 } 6201 6202 bool OpenMPIterationSpaceChecker::setStep(Expr *NewStep, bool Subtract) { 6203 // State consistency checking to ensure correct usage. 6204 assert(LCDecl != nullptr && LB != nullptr && Step == nullptr); 6205 if (!NewStep) 6206 return true; 6207 if (!NewStep->isValueDependent()) { 6208 // Check that the step is integer expression. 6209 SourceLocation StepLoc = NewStep->getBeginLoc(); 6210 ExprResult Val = SemaRef.PerformOpenMPImplicitIntegerConversion( 6211 StepLoc, getExprAsWritten(NewStep)); 6212 if (Val.isInvalid()) 6213 return true; 6214 NewStep = Val.get(); 6215 6216 // OpenMP [2.6, Canonical Loop Form, Restrictions] 6217 // If test-expr is of form var relational-op b and relational-op is < or 6218 // <= then incr-expr must cause var to increase on each iteration of the 6219 // loop. If test-expr is of form var relational-op b and relational-op is 6220 // > or >= then incr-expr must cause var to decrease on each iteration of 6221 // the loop. 6222 // If test-expr is of form b relational-op var and relational-op is < or 6223 // <= then incr-expr must cause var to decrease on each iteration of the 6224 // loop. If test-expr is of form b relational-op var and relational-op is 6225 // > or >= then incr-expr must cause var to increase on each iteration of 6226 // the loop. 6227 llvm::APSInt Result; 6228 bool IsConstant = NewStep->isIntegerConstantExpr(Result, SemaRef.Context); 6229 bool IsUnsigned = !NewStep->getType()->hasSignedIntegerRepresentation(); 6230 bool IsConstNeg = 6231 IsConstant && Result.isSigned() && (Subtract != Result.isNegative()); 6232 bool IsConstPos = 6233 IsConstant && Result.isSigned() && (Subtract == Result.isNegative()); 6234 bool IsConstZero = IsConstant && !Result.getBoolValue(); 6235 6236 // != with increment is treated as <; != with decrement is treated as > 6237 if (!TestIsLessOp.hasValue()) 6238 TestIsLessOp = IsConstPos || (IsUnsigned && !Subtract); 6239 if (UB && (IsConstZero || 6240 (TestIsLessOp.getValue() ? 6241 (IsConstNeg || (IsUnsigned && Subtract)) : 6242 (IsConstPos || (IsUnsigned && !Subtract))))) { 6243 SemaRef.Diag(NewStep->getExprLoc(), 6244 diag::err_omp_loop_incr_not_compatible) 6245 << LCDecl << TestIsLessOp.getValue() << NewStep->getSourceRange(); 6246 SemaRef.Diag(ConditionLoc, 6247 diag::note_omp_loop_cond_requres_compatible_incr) 6248 << TestIsLessOp.getValue() << ConditionSrcRange; 6249 return true; 6250 } 6251 if (TestIsLessOp.getValue() == Subtract) { 6252 NewStep = 6253 SemaRef.CreateBuiltinUnaryOp(NewStep->getExprLoc(), UO_Minus, NewStep) 6254 .get(); 6255 Subtract = !Subtract; 6256 } 6257 } 6258 6259 Step = NewStep; 6260 SubtractStep = Subtract; 6261 return false; 6262 } 6263 6264 namespace { 6265 /// Checker for the non-rectangular loops. Checks if the initializer or 6266 /// condition expression references loop counter variable. 6267 class LoopCounterRefChecker final 6268 : public ConstStmtVisitor<LoopCounterRefChecker, bool> { 6269 Sema &SemaRef; 6270 DSAStackTy &Stack; 6271 const ValueDecl *CurLCDecl = nullptr; 6272 const ValueDecl *DepDecl = nullptr; 6273 const ValueDecl *PrevDepDecl = nullptr; 6274 bool IsInitializer = true; 6275 unsigned BaseLoopId = 0; 6276 bool checkDecl(const Expr *E, const ValueDecl *VD) { 6277 if (getCanonicalDecl(VD) == getCanonicalDecl(CurLCDecl)) { 6278 SemaRef.Diag(E->getExprLoc(), diag::err_omp_stmt_depends_on_loop_counter) 6279 << (IsInitializer ? 0 : 1); 6280 return false; 6281 } 6282 const auto &&Data = Stack.isLoopControlVariable(VD); 6283 // OpenMP, 2.9.1 Canonical Loop Form, Restrictions. 6284 // The type of the loop iterator on which we depend may not have a random 6285 // access iterator type. 6286 if (Data.first && VD->getType()->isRecordType()) { 6287 SmallString<128> Name; 6288 llvm::raw_svector_ostream OS(Name); 6289 VD->getNameForDiagnostic(OS, SemaRef.getPrintingPolicy(), 6290 /*Qualified=*/true); 6291 SemaRef.Diag(E->getExprLoc(), 6292 diag::err_omp_wrong_dependency_iterator_type) 6293 << OS.str(); 6294 SemaRef.Diag(VD->getLocation(), diag::note_previous_decl) << VD; 6295 return false; 6296 } 6297 if (Data.first && 6298 (DepDecl || (PrevDepDecl && 6299 getCanonicalDecl(VD) != getCanonicalDecl(PrevDepDecl)))) { 6300 if (!DepDecl && PrevDepDecl) 6301 DepDecl = PrevDepDecl; 6302 SmallString<128> Name; 6303 llvm::raw_svector_ostream OS(Name); 6304 DepDecl->getNameForDiagnostic(OS, SemaRef.getPrintingPolicy(), 6305 /*Qualified=*/true); 6306 SemaRef.Diag(E->getExprLoc(), 6307 diag::err_omp_invariant_or_linear_dependency) 6308 << OS.str(); 6309 return false; 6310 } 6311 if (Data.first) { 6312 DepDecl = VD; 6313 BaseLoopId = Data.first; 6314 } 6315 return Data.first; 6316 } 6317 6318 public: 6319 bool VisitDeclRefExpr(const DeclRefExpr *E) { 6320 const ValueDecl *VD = E->getDecl(); 6321 if (isa<VarDecl>(VD)) 6322 return checkDecl(E, VD); 6323 return false; 6324 } 6325 bool VisitMemberExpr(const MemberExpr *E) { 6326 if (isa<CXXThisExpr>(E->getBase()->IgnoreParens())) { 6327 const ValueDecl *VD = E->getMemberDecl(); 6328 if (isa<VarDecl>(VD) || isa<FieldDecl>(VD)) 6329 return checkDecl(E, VD); 6330 } 6331 return false; 6332 } 6333 bool VisitStmt(const Stmt *S) { 6334 bool Res = false; 6335 for (const Stmt *Child : S->children()) 6336 Res = (Child && Visit(Child)) || Res; 6337 return Res; 6338 } 6339 explicit LoopCounterRefChecker(Sema &SemaRef, DSAStackTy &Stack, 6340 const ValueDecl *CurLCDecl, bool IsInitializer, 6341 const ValueDecl *PrevDepDecl = nullptr) 6342 : SemaRef(SemaRef), Stack(Stack), CurLCDecl(CurLCDecl), 6343 PrevDepDecl(PrevDepDecl), IsInitializer(IsInitializer) {} 6344 unsigned getBaseLoopId() const { 6345 assert(CurLCDecl && "Expected loop dependency."); 6346 return BaseLoopId; 6347 } 6348 const ValueDecl *getDepDecl() const { 6349 assert(CurLCDecl && "Expected loop dependency."); 6350 return DepDecl; 6351 } 6352 }; 6353 } // namespace 6354 6355 Optional<unsigned> 6356 OpenMPIterationSpaceChecker::doesDependOnLoopCounter(const Stmt *S, 6357 bool IsInitializer) { 6358 // Check for the non-rectangular loops. 6359 LoopCounterRefChecker LoopStmtChecker(SemaRef, Stack, LCDecl, IsInitializer, 6360 DepDecl); 6361 if (LoopStmtChecker.Visit(S)) { 6362 DepDecl = LoopStmtChecker.getDepDecl(); 6363 return LoopStmtChecker.getBaseLoopId(); 6364 } 6365 return llvm::None; 6366 } 6367 6368 bool OpenMPIterationSpaceChecker::checkAndSetInit(Stmt *S, bool EmitDiags) { 6369 // Check init-expr for canonical loop form and save loop counter 6370 // variable - #Var and its initialization value - #LB. 6371 // OpenMP [2.6] Canonical loop form. init-expr may be one of the following: 6372 // var = lb 6373 // integer-type var = lb 6374 // random-access-iterator-type var = lb 6375 // pointer-type var = lb 6376 // 6377 if (!S) { 6378 if (EmitDiags) { 6379 SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_init); 6380 } 6381 return true; 6382 } 6383 if (auto *ExprTemp = dyn_cast<ExprWithCleanups>(S)) 6384 if (!ExprTemp->cleanupsHaveSideEffects()) 6385 S = ExprTemp->getSubExpr(); 6386 6387 InitSrcRange = S->getSourceRange(); 6388 if (Expr *E = dyn_cast<Expr>(S)) 6389 S = E->IgnoreParens(); 6390 if (auto *BO = dyn_cast<BinaryOperator>(S)) { 6391 if (BO->getOpcode() == BO_Assign) { 6392 Expr *LHS = BO->getLHS()->IgnoreParens(); 6393 if (auto *DRE = dyn_cast<DeclRefExpr>(LHS)) { 6394 if (auto *CED = dyn_cast<OMPCapturedExprDecl>(DRE->getDecl())) 6395 if (auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit()))) 6396 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(), 6397 EmitDiags); 6398 return setLCDeclAndLB(DRE->getDecl(), DRE, BO->getRHS(), EmitDiags); 6399 } 6400 if (auto *ME = dyn_cast<MemberExpr>(LHS)) { 6401 if (ME->isArrow() && 6402 isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts())) 6403 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(), 6404 EmitDiags); 6405 } 6406 } 6407 } else if (auto *DS = dyn_cast<DeclStmt>(S)) { 6408 if (DS->isSingleDecl()) { 6409 if (auto *Var = dyn_cast_or_null<VarDecl>(DS->getSingleDecl())) { 6410 if (Var->hasInit() && !Var->getType()->isReferenceType()) { 6411 // Accept non-canonical init form here but emit ext. warning. 6412 if (Var->getInitStyle() != VarDecl::CInit && EmitDiags) 6413 SemaRef.Diag(S->getBeginLoc(), 6414 diag::ext_omp_loop_not_canonical_init) 6415 << S->getSourceRange(); 6416 return setLCDeclAndLB( 6417 Var, 6418 buildDeclRefExpr(SemaRef, Var, 6419 Var->getType().getNonReferenceType(), 6420 DS->getBeginLoc()), 6421 Var->getInit(), EmitDiags); 6422 } 6423 } 6424 } 6425 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) { 6426 if (CE->getOperator() == OO_Equal) { 6427 Expr *LHS = CE->getArg(0); 6428 if (auto *DRE = dyn_cast<DeclRefExpr>(LHS)) { 6429 if (auto *CED = dyn_cast<OMPCapturedExprDecl>(DRE->getDecl())) 6430 if (auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit()))) 6431 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(), 6432 EmitDiags); 6433 return setLCDeclAndLB(DRE->getDecl(), DRE, CE->getArg(1), EmitDiags); 6434 } 6435 if (auto *ME = dyn_cast<MemberExpr>(LHS)) { 6436 if (ME->isArrow() && 6437 isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts())) 6438 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(), 6439 EmitDiags); 6440 } 6441 } 6442 } 6443 6444 if (dependent() || SemaRef.CurContext->isDependentContext()) 6445 return false; 6446 if (EmitDiags) { 6447 SemaRef.Diag(S->getBeginLoc(), diag::err_omp_loop_not_canonical_init) 6448 << S->getSourceRange(); 6449 } 6450 return true; 6451 } 6452 6453 /// Ignore parenthesizes, implicit casts, copy constructor and return the 6454 /// variable (which may be the loop variable) if possible. 6455 static const ValueDecl *getInitLCDecl(const Expr *E) { 6456 if (!E) 6457 return nullptr; 6458 E = getExprAsWritten(E); 6459 if (const auto *CE = dyn_cast_or_null<CXXConstructExpr>(E)) 6460 if (const CXXConstructorDecl *Ctor = CE->getConstructor()) 6461 if ((Ctor->isCopyOrMoveConstructor() || 6462 Ctor->isConvertingConstructor(/*AllowExplicit=*/false)) && 6463 CE->getNumArgs() > 0 && CE->getArg(0) != nullptr) 6464 E = CE->getArg(0)->IgnoreParenImpCasts(); 6465 if (const auto *DRE = dyn_cast_or_null<DeclRefExpr>(E)) { 6466 if (const auto *VD = dyn_cast<VarDecl>(DRE->getDecl())) 6467 return getCanonicalDecl(VD); 6468 } 6469 if (const auto *ME = dyn_cast_or_null<MemberExpr>(E)) 6470 if (ME->isArrow() && isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts())) 6471 return getCanonicalDecl(ME->getMemberDecl()); 6472 return nullptr; 6473 } 6474 6475 bool OpenMPIterationSpaceChecker::checkAndSetCond(Expr *S) { 6476 // Check test-expr for canonical form, save upper-bound UB, flags for 6477 // less/greater and for strict/non-strict comparison. 6478 // OpenMP [2.9] Canonical loop form. Test-expr may be one of the following: 6479 // var relational-op b 6480 // b relational-op var 6481 // 6482 bool IneqCondIsCanonical = SemaRef.getLangOpts().OpenMP >= 50; 6483 if (!S) { 6484 SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_cond) 6485 << (IneqCondIsCanonical ? 1 : 0) << LCDecl; 6486 return true; 6487 } 6488 Condition = S; 6489 S = getExprAsWritten(S); 6490 SourceLocation CondLoc = S->getBeginLoc(); 6491 if (auto *BO = dyn_cast<BinaryOperator>(S)) { 6492 if (BO->isRelationalOp()) { 6493 if (getInitLCDecl(BO->getLHS()) == LCDecl) 6494 return setUB(BO->getRHS(), 6495 (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_LE), 6496 (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_GT), 6497 BO->getSourceRange(), BO->getOperatorLoc()); 6498 if (getInitLCDecl(BO->getRHS()) == LCDecl) 6499 return setUB(BO->getLHS(), 6500 (BO->getOpcode() == BO_GT || BO->getOpcode() == BO_GE), 6501 (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_GT), 6502 BO->getSourceRange(), BO->getOperatorLoc()); 6503 } else if (IneqCondIsCanonical && BO->getOpcode() == BO_NE) 6504 return setUB( 6505 getInitLCDecl(BO->getLHS()) == LCDecl ? BO->getRHS() : BO->getLHS(), 6506 /*LessOp=*/llvm::None, 6507 /*StrictOp=*/true, BO->getSourceRange(), BO->getOperatorLoc()); 6508 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) { 6509 if (CE->getNumArgs() == 2) { 6510 auto Op = CE->getOperator(); 6511 switch (Op) { 6512 case OO_Greater: 6513 case OO_GreaterEqual: 6514 case OO_Less: 6515 case OO_LessEqual: 6516 if (getInitLCDecl(CE->getArg(0)) == LCDecl) 6517 return setUB(CE->getArg(1), Op == OO_Less || Op == OO_LessEqual, 6518 Op == OO_Less || Op == OO_Greater, CE->getSourceRange(), 6519 CE->getOperatorLoc()); 6520 if (getInitLCDecl(CE->getArg(1)) == LCDecl) 6521 return setUB(CE->getArg(0), Op == OO_Greater || Op == OO_GreaterEqual, 6522 Op == OO_Less || Op == OO_Greater, CE->getSourceRange(), 6523 CE->getOperatorLoc()); 6524 break; 6525 case OO_ExclaimEqual: 6526 if (IneqCondIsCanonical) 6527 return setUB(getInitLCDecl(CE->getArg(0)) == LCDecl ? CE->getArg(1) 6528 : CE->getArg(0), 6529 /*LessOp=*/llvm::None, 6530 /*StrictOp=*/true, CE->getSourceRange(), 6531 CE->getOperatorLoc()); 6532 break; 6533 default: 6534 break; 6535 } 6536 } 6537 } 6538 if (dependent() || SemaRef.CurContext->isDependentContext()) 6539 return false; 6540 SemaRef.Diag(CondLoc, diag::err_omp_loop_not_canonical_cond) 6541 << (IneqCondIsCanonical ? 1 : 0) << S->getSourceRange() << LCDecl; 6542 return true; 6543 } 6544 6545 bool OpenMPIterationSpaceChecker::checkAndSetIncRHS(Expr *RHS) { 6546 // RHS of canonical loop form increment can be: 6547 // var + incr 6548 // incr + var 6549 // var - incr 6550 // 6551 RHS = RHS->IgnoreParenImpCasts(); 6552 if (auto *BO = dyn_cast<BinaryOperator>(RHS)) { 6553 if (BO->isAdditiveOp()) { 6554 bool IsAdd = BO->getOpcode() == BO_Add; 6555 if (getInitLCDecl(BO->getLHS()) == LCDecl) 6556 return setStep(BO->getRHS(), !IsAdd); 6557 if (IsAdd && getInitLCDecl(BO->getRHS()) == LCDecl) 6558 return setStep(BO->getLHS(), /*Subtract=*/false); 6559 } 6560 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(RHS)) { 6561 bool IsAdd = CE->getOperator() == OO_Plus; 6562 if ((IsAdd || CE->getOperator() == OO_Minus) && CE->getNumArgs() == 2) { 6563 if (getInitLCDecl(CE->getArg(0)) == LCDecl) 6564 return setStep(CE->getArg(1), !IsAdd); 6565 if (IsAdd && getInitLCDecl(CE->getArg(1)) == LCDecl) 6566 return setStep(CE->getArg(0), /*Subtract=*/false); 6567 } 6568 } 6569 if (dependent() || SemaRef.CurContext->isDependentContext()) 6570 return false; 6571 SemaRef.Diag(RHS->getBeginLoc(), diag::err_omp_loop_not_canonical_incr) 6572 << RHS->getSourceRange() << LCDecl; 6573 return true; 6574 } 6575 6576 bool OpenMPIterationSpaceChecker::checkAndSetInc(Expr *S) { 6577 // Check incr-expr for canonical loop form and return true if it 6578 // does not conform. 6579 // OpenMP [2.6] Canonical loop form. Test-expr may be one of the following: 6580 // ++var 6581 // var++ 6582 // --var 6583 // var-- 6584 // var += incr 6585 // var -= incr 6586 // var = var + incr 6587 // var = incr + var 6588 // var = var - incr 6589 // 6590 if (!S) { 6591 SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_incr) << LCDecl; 6592 return true; 6593 } 6594 if (auto *ExprTemp = dyn_cast<ExprWithCleanups>(S)) 6595 if (!ExprTemp->cleanupsHaveSideEffects()) 6596 S = ExprTemp->getSubExpr(); 6597 6598 IncrementSrcRange = S->getSourceRange(); 6599 S = S->IgnoreParens(); 6600 if (auto *UO = dyn_cast<UnaryOperator>(S)) { 6601 if (UO->isIncrementDecrementOp() && 6602 getInitLCDecl(UO->getSubExpr()) == LCDecl) 6603 return setStep(SemaRef 6604 .ActOnIntegerConstant(UO->getBeginLoc(), 6605 (UO->isDecrementOp() ? -1 : 1)) 6606 .get(), 6607 /*Subtract=*/false); 6608 } else if (auto *BO = dyn_cast<BinaryOperator>(S)) { 6609 switch (BO->getOpcode()) { 6610 case BO_AddAssign: 6611 case BO_SubAssign: 6612 if (getInitLCDecl(BO->getLHS()) == LCDecl) 6613 return setStep(BO->getRHS(), BO->getOpcode() == BO_SubAssign); 6614 break; 6615 case BO_Assign: 6616 if (getInitLCDecl(BO->getLHS()) == LCDecl) 6617 return checkAndSetIncRHS(BO->getRHS()); 6618 break; 6619 default: 6620 break; 6621 } 6622 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) { 6623 switch (CE->getOperator()) { 6624 case OO_PlusPlus: 6625 case OO_MinusMinus: 6626 if (getInitLCDecl(CE->getArg(0)) == LCDecl) 6627 return setStep(SemaRef 6628 .ActOnIntegerConstant( 6629 CE->getBeginLoc(), 6630 ((CE->getOperator() == OO_MinusMinus) ? -1 : 1)) 6631 .get(), 6632 /*Subtract=*/false); 6633 break; 6634 case OO_PlusEqual: 6635 case OO_MinusEqual: 6636 if (getInitLCDecl(CE->getArg(0)) == LCDecl) 6637 return setStep(CE->getArg(1), CE->getOperator() == OO_MinusEqual); 6638 break; 6639 case OO_Equal: 6640 if (getInitLCDecl(CE->getArg(0)) == LCDecl) 6641 return checkAndSetIncRHS(CE->getArg(1)); 6642 break; 6643 default: 6644 break; 6645 } 6646 } 6647 if (dependent() || SemaRef.CurContext->isDependentContext()) 6648 return false; 6649 SemaRef.Diag(S->getBeginLoc(), diag::err_omp_loop_not_canonical_incr) 6650 << S->getSourceRange() << LCDecl; 6651 return true; 6652 } 6653 6654 static ExprResult 6655 tryBuildCapture(Sema &SemaRef, Expr *Capture, 6656 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) { 6657 if (SemaRef.CurContext->isDependentContext()) 6658 return ExprResult(Capture); 6659 if (Capture->isEvaluatable(SemaRef.Context, Expr::SE_AllowSideEffects)) 6660 return SemaRef.PerformImplicitConversion( 6661 Capture->IgnoreImpCasts(), Capture->getType(), Sema::AA_Converting, 6662 /*AllowExplicit=*/true); 6663 auto I = Captures.find(Capture); 6664 if (I != Captures.end()) 6665 return buildCapture(SemaRef, Capture, I->second); 6666 DeclRefExpr *Ref = nullptr; 6667 ExprResult Res = buildCapture(SemaRef, Capture, Ref); 6668 Captures[Capture] = Ref; 6669 return Res; 6670 } 6671 6672 /// Build the expression to calculate the number of iterations. 6673 Expr *OpenMPIterationSpaceChecker::buildNumIterations( 6674 Scope *S, ArrayRef<LoopIterationSpace> ResultIterSpaces, bool LimitedType, 6675 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const { 6676 ExprResult Diff; 6677 QualType VarType = LCDecl->getType().getNonReferenceType(); 6678 if (VarType->isIntegerType() || VarType->isPointerType() || 6679 SemaRef.getLangOpts().CPlusPlus) { 6680 Expr *LBVal = LB; 6681 Expr *UBVal = UB; 6682 // LB = TestIsLessOp.getValue() ? min(LB(MinVal), LB(MaxVal)) : 6683 // max(LB(MinVal), LB(MaxVal)) 6684 if (InitDependOnLC) { 6685 const LoopIterationSpace &IS = 6686 ResultIterSpaces[ResultIterSpaces.size() - 1 - 6687 InitDependOnLC.getValueOr( 6688 CondDependOnLC.getValueOr(0))]; 6689 if (!IS.MinValue || !IS.MaxValue) 6690 return nullptr; 6691 // OuterVar = Min 6692 ExprResult MinValue = 6693 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MinValue); 6694 if (!MinValue.isUsable()) 6695 return nullptr; 6696 6697 ExprResult LBMinVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign, 6698 IS.CounterVar, MinValue.get()); 6699 if (!LBMinVal.isUsable()) 6700 return nullptr; 6701 // OuterVar = Min, LBVal 6702 LBMinVal = 6703 SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, LBMinVal.get(), LBVal); 6704 if (!LBMinVal.isUsable()) 6705 return nullptr; 6706 // (OuterVar = Min, LBVal) 6707 LBMinVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, LBMinVal.get()); 6708 if (!LBMinVal.isUsable()) 6709 return nullptr; 6710 6711 // OuterVar = Max 6712 ExprResult MaxValue = 6713 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MaxValue); 6714 if (!MaxValue.isUsable()) 6715 return nullptr; 6716 6717 ExprResult LBMaxVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign, 6718 IS.CounterVar, MaxValue.get()); 6719 if (!LBMaxVal.isUsable()) 6720 return nullptr; 6721 // OuterVar = Max, LBVal 6722 LBMaxVal = 6723 SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, LBMaxVal.get(), LBVal); 6724 if (!LBMaxVal.isUsable()) 6725 return nullptr; 6726 // (OuterVar = Max, LBVal) 6727 LBMaxVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, LBMaxVal.get()); 6728 if (!LBMaxVal.isUsable()) 6729 return nullptr; 6730 6731 Expr *LBMin = tryBuildCapture(SemaRef, LBMinVal.get(), Captures).get(); 6732 Expr *LBMax = tryBuildCapture(SemaRef, LBMaxVal.get(), Captures).get(); 6733 if (!LBMin || !LBMax) 6734 return nullptr; 6735 // LB(MinVal) < LB(MaxVal) 6736 ExprResult MinLessMaxRes = 6737 SemaRef.BuildBinOp(S, DefaultLoc, BO_LT, LBMin, LBMax); 6738 if (!MinLessMaxRes.isUsable()) 6739 return nullptr; 6740 Expr *MinLessMax = 6741 tryBuildCapture(SemaRef, MinLessMaxRes.get(), Captures).get(); 6742 if (!MinLessMax) 6743 return nullptr; 6744 if (TestIsLessOp.getValue()) { 6745 // LB(MinVal) < LB(MaxVal) ? LB(MinVal) : LB(MaxVal) - min(LB(MinVal), 6746 // LB(MaxVal)) 6747 ExprResult MinLB = SemaRef.ActOnConditionalOp(DefaultLoc, DefaultLoc, 6748 MinLessMax, LBMin, LBMax); 6749 if (!MinLB.isUsable()) 6750 return nullptr; 6751 LBVal = MinLB.get(); 6752 } else { 6753 // LB(MinVal) < LB(MaxVal) ? LB(MaxVal) : LB(MinVal) - max(LB(MinVal), 6754 // LB(MaxVal)) 6755 ExprResult MaxLB = SemaRef.ActOnConditionalOp(DefaultLoc, DefaultLoc, 6756 MinLessMax, LBMax, LBMin); 6757 if (!MaxLB.isUsable()) 6758 return nullptr; 6759 LBVal = MaxLB.get(); 6760 } 6761 } 6762 // UB = TestIsLessOp.getValue() ? max(UB(MinVal), UB(MaxVal)) : 6763 // min(UB(MinVal), UB(MaxVal)) 6764 if (CondDependOnLC) { 6765 const LoopIterationSpace &IS = 6766 ResultIterSpaces[ResultIterSpaces.size() - 1 - 6767 InitDependOnLC.getValueOr( 6768 CondDependOnLC.getValueOr(0))]; 6769 if (!IS.MinValue || !IS.MaxValue) 6770 return nullptr; 6771 // OuterVar = Min 6772 ExprResult MinValue = 6773 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MinValue); 6774 if (!MinValue.isUsable()) 6775 return nullptr; 6776 6777 ExprResult UBMinVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign, 6778 IS.CounterVar, MinValue.get()); 6779 if (!UBMinVal.isUsable()) 6780 return nullptr; 6781 // OuterVar = Min, UBVal 6782 UBMinVal = 6783 SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, UBMinVal.get(), UBVal); 6784 if (!UBMinVal.isUsable()) 6785 return nullptr; 6786 // (OuterVar = Min, UBVal) 6787 UBMinVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, UBMinVal.get()); 6788 if (!UBMinVal.isUsable()) 6789 return nullptr; 6790 6791 // OuterVar = Max 6792 ExprResult MaxValue = 6793 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MaxValue); 6794 if (!MaxValue.isUsable()) 6795 return nullptr; 6796 6797 ExprResult UBMaxVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign, 6798 IS.CounterVar, MaxValue.get()); 6799 if (!UBMaxVal.isUsable()) 6800 return nullptr; 6801 // OuterVar = Max, UBVal 6802 UBMaxVal = 6803 SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, UBMaxVal.get(), UBVal); 6804 if (!UBMaxVal.isUsable()) 6805 return nullptr; 6806 // (OuterVar = Max, UBVal) 6807 UBMaxVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, UBMaxVal.get()); 6808 if (!UBMaxVal.isUsable()) 6809 return nullptr; 6810 6811 Expr *UBMin = tryBuildCapture(SemaRef, UBMinVal.get(), Captures).get(); 6812 Expr *UBMax = tryBuildCapture(SemaRef, UBMaxVal.get(), Captures).get(); 6813 if (!UBMin || !UBMax) 6814 return nullptr; 6815 // UB(MinVal) > UB(MaxVal) 6816 ExprResult MinGreaterMaxRes = 6817 SemaRef.BuildBinOp(S, DefaultLoc, BO_GT, UBMin, UBMax); 6818 if (!MinGreaterMaxRes.isUsable()) 6819 return nullptr; 6820 Expr *MinGreaterMax = 6821 tryBuildCapture(SemaRef, MinGreaterMaxRes.get(), Captures).get(); 6822 if (!MinGreaterMax) 6823 return nullptr; 6824 if (TestIsLessOp.getValue()) { 6825 // UB(MinVal) > UB(MaxVal) ? UB(MinVal) : UB(MaxVal) - max(UB(MinVal), 6826 // UB(MaxVal)) 6827 ExprResult MaxUB = SemaRef.ActOnConditionalOp( 6828 DefaultLoc, DefaultLoc, MinGreaterMax, UBMin, UBMax); 6829 if (!MaxUB.isUsable()) 6830 return nullptr; 6831 UBVal = MaxUB.get(); 6832 } else { 6833 // UB(MinVal) > UB(MaxVal) ? UB(MaxVal) : UB(MinVal) - min(UB(MinVal), 6834 // UB(MaxVal)) 6835 ExprResult MinUB = SemaRef.ActOnConditionalOp( 6836 DefaultLoc, DefaultLoc, MinGreaterMax, UBMax, UBMin); 6837 if (!MinUB.isUsable()) 6838 return nullptr; 6839 UBVal = MinUB.get(); 6840 } 6841 } 6842 // Upper - Lower 6843 Expr *UBExpr = TestIsLessOp.getValue() ? UBVal : LBVal; 6844 Expr *LBExpr = TestIsLessOp.getValue() ? LBVal : UBVal; 6845 Expr *Upper = tryBuildCapture(SemaRef, UBExpr, Captures).get(); 6846 Expr *Lower = tryBuildCapture(SemaRef, LBExpr, Captures).get(); 6847 if (!Upper || !Lower) 6848 return nullptr; 6849 6850 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Lower); 6851 6852 if (!Diff.isUsable() && VarType->getAsCXXRecordDecl()) { 6853 // BuildBinOp already emitted error, this one is to point user to upper 6854 // and lower bound, and to tell what is passed to 'operator-'. 6855 SemaRef.Diag(Upper->getBeginLoc(), diag::err_omp_loop_diff_cxx) 6856 << Upper->getSourceRange() << Lower->getSourceRange(); 6857 return nullptr; 6858 } 6859 } 6860 6861 if (!Diff.isUsable()) 6862 return nullptr; 6863 6864 // Upper - Lower [- 1] 6865 if (TestIsStrictOp) 6866 Diff = SemaRef.BuildBinOp( 6867 S, DefaultLoc, BO_Sub, Diff.get(), 6868 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()); 6869 if (!Diff.isUsable()) 6870 return nullptr; 6871 6872 // Upper - Lower [- 1] + Step 6873 ExprResult NewStep = tryBuildCapture(SemaRef, Step, Captures); 6874 if (!NewStep.isUsable()) 6875 return nullptr; 6876 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Add, Diff.get(), NewStep.get()); 6877 if (!Diff.isUsable()) 6878 return nullptr; 6879 6880 // Parentheses (for dumping/debugging purposes only). 6881 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get()); 6882 if (!Diff.isUsable()) 6883 return nullptr; 6884 6885 // (Upper - Lower [- 1] + Step) / Step 6886 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Div, Diff.get(), NewStep.get()); 6887 if (!Diff.isUsable()) 6888 return nullptr; 6889 6890 // OpenMP runtime requires 32-bit or 64-bit loop variables. 6891 QualType Type = Diff.get()->getType(); 6892 ASTContext &C = SemaRef.Context; 6893 bool UseVarType = VarType->hasIntegerRepresentation() && 6894 C.getTypeSize(Type) > C.getTypeSize(VarType); 6895 if (!Type->isIntegerType() || UseVarType) { 6896 unsigned NewSize = 6897 UseVarType ? C.getTypeSize(VarType) : C.getTypeSize(Type); 6898 bool IsSigned = UseVarType ? VarType->hasSignedIntegerRepresentation() 6899 : Type->hasSignedIntegerRepresentation(); 6900 Type = C.getIntTypeForBitwidth(NewSize, IsSigned); 6901 if (!SemaRef.Context.hasSameType(Diff.get()->getType(), Type)) { 6902 Diff = SemaRef.PerformImplicitConversion( 6903 Diff.get(), Type, Sema::AA_Converting, /*AllowExplicit=*/true); 6904 if (!Diff.isUsable()) 6905 return nullptr; 6906 } 6907 } 6908 if (LimitedType) { 6909 unsigned NewSize = (C.getTypeSize(Type) > 32) ? 64 : 32; 6910 if (NewSize != C.getTypeSize(Type)) { 6911 if (NewSize < C.getTypeSize(Type)) { 6912 assert(NewSize == 64 && "incorrect loop var size"); 6913 SemaRef.Diag(DefaultLoc, diag::warn_omp_loop_64_bit_var) 6914 << InitSrcRange << ConditionSrcRange; 6915 } 6916 QualType NewType = C.getIntTypeForBitwidth( 6917 NewSize, Type->hasSignedIntegerRepresentation() || 6918 C.getTypeSize(Type) < NewSize); 6919 if (!SemaRef.Context.hasSameType(Diff.get()->getType(), NewType)) { 6920 Diff = SemaRef.PerformImplicitConversion(Diff.get(), NewType, 6921 Sema::AA_Converting, true); 6922 if (!Diff.isUsable()) 6923 return nullptr; 6924 } 6925 } 6926 } 6927 6928 return Diff.get(); 6929 } 6930 6931 std::pair<Expr *, Expr *> OpenMPIterationSpaceChecker::buildMinMaxValues( 6932 Scope *S, llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const { 6933 // Do not build for iterators, they cannot be used in non-rectangular loop 6934 // nests. 6935 if (LCDecl->getType()->isRecordType()) 6936 return std::make_pair(nullptr, nullptr); 6937 // If we subtract, the min is in the condition, otherwise the min is in the 6938 // init value. 6939 Expr *MinExpr = nullptr; 6940 Expr *MaxExpr = nullptr; 6941 Expr *LBExpr = TestIsLessOp.getValue() ? LB : UB; 6942 Expr *UBExpr = TestIsLessOp.getValue() ? UB : LB; 6943 bool LBNonRect = TestIsLessOp.getValue() ? InitDependOnLC.hasValue() 6944 : CondDependOnLC.hasValue(); 6945 bool UBNonRect = TestIsLessOp.getValue() ? CondDependOnLC.hasValue() 6946 : InitDependOnLC.hasValue(); 6947 Expr *Lower = 6948 LBNonRect ? LBExpr : tryBuildCapture(SemaRef, LBExpr, Captures).get(); 6949 Expr *Upper = 6950 UBNonRect ? UBExpr : tryBuildCapture(SemaRef, UBExpr, Captures).get(); 6951 if (!Upper || !Lower) 6952 return std::make_pair(nullptr, nullptr); 6953 6954 if (TestIsLessOp.getValue()) 6955 MinExpr = Lower; 6956 else 6957 MaxExpr = Upper; 6958 6959 // Build minimum/maximum value based on number of iterations. 6960 ExprResult Diff; 6961 QualType VarType = LCDecl->getType().getNonReferenceType(); 6962 6963 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Lower); 6964 if (!Diff.isUsable()) 6965 return std::make_pair(nullptr, nullptr); 6966 6967 // Upper - Lower [- 1] 6968 if (TestIsStrictOp) 6969 Diff = SemaRef.BuildBinOp( 6970 S, DefaultLoc, BO_Sub, Diff.get(), 6971 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()); 6972 if (!Diff.isUsable()) 6973 return std::make_pair(nullptr, nullptr); 6974 6975 // Upper - Lower [- 1] + Step 6976 ExprResult NewStep = tryBuildCapture(SemaRef, Step, Captures); 6977 if (!NewStep.isUsable()) 6978 return std::make_pair(nullptr, nullptr); 6979 6980 // Parentheses (for dumping/debugging purposes only). 6981 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get()); 6982 if (!Diff.isUsable()) 6983 return std::make_pair(nullptr, nullptr); 6984 6985 // (Upper - Lower [- 1]) / Step 6986 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Div, Diff.get(), NewStep.get()); 6987 if (!Diff.isUsable()) 6988 return std::make_pair(nullptr, nullptr); 6989 6990 // ((Upper - Lower [- 1]) / Step) * Step 6991 // Parentheses (for dumping/debugging purposes only). 6992 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get()); 6993 if (!Diff.isUsable()) 6994 return std::make_pair(nullptr, nullptr); 6995 6996 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Mul, Diff.get(), NewStep.get()); 6997 if (!Diff.isUsable()) 6998 return std::make_pair(nullptr, nullptr); 6999 7000 // Convert to the original type or ptrdiff_t, if original type is pointer. 7001 if (!VarType->isAnyPointerType() && 7002 !SemaRef.Context.hasSameType(Diff.get()->getType(), VarType)) { 7003 Diff = SemaRef.PerformImplicitConversion( 7004 Diff.get(), VarType, Sema::AA_Converting, /*AllowExplicit=*/true); 7005 } else if (VarType->isAnyPointerType() && 7006 !SemaRef.Context.hasSameType( 7007 Diff.get()->getType(), 7008 SemaRef.Context.getUnsignedPointerDiffType())) { 7009 Diff = SemaRef.PerformImplicitConversion( 7010 Diff.get(), SemaRef.Context.getUnsignedPointerDiffType(), 7011 Sema::AA_Converting, /*AllowExplicit=*/true); 7012 } 7013 if (!Diff.isUsable()) 7014 return std::make_pair(nullptr, nullptr); 7015 7016 // Parentheses (for dumping/debugging purposes only). 7017 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get()); 7018 if (!Diff.isUsable()) 7019 return std::make_pair(nullptr, nullptr); 7020 7021 if (TestIsLessOp.getValue()) { 7022 // MinExpr = Lower; 7023 // MaxExpr = Lower + (((Upper - Lower [- 1]) / Step) * Step) 7024 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Add, Lower, Diff.get()); 7025 if (!Diff.isUsable()) 7026 return std::make_pair(nullptr, nullptr); 7027 Diff = SemaRef.ActOnFinishFullExpr(Diff.get(), /*DiscardedValue*/ false); 7028 if (!Diff.isUsable()) 7029 return std::make_pair(nullptr, nullptr); 7030 MaxExpr = Diff.get(); 7031 } else { 7032 // MaxExpr = Upper; 7033 // MinExpr = Upper - (((Upper - Lower [- 1]) / Step) * Step) 7034 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Diff.get()); 7035 if (!Diff.isUsable()) 7036 return std::make_pair(nullptr, nullptr); 7037 Diff = SemaRef.ActOnFinishFullExpr(Diff.get(), /*DiscardedValue*/ false); 7038 if (!Diff.isUsable()) 7039 return std::make_pair(nullptr, nullptr); 7040 MinExpr = Diff.get(); 7041 } 7042 7043 return std::make_pair(MinExpr, MaxExpr); 7044 } 7045 7046 Expr *OpenMPIterationSpaceChecker::buildFinalCondition(Scope *S) const { 7047 if (InitDependOnLC || CondDependOnLC) 7048 return Condition; 7049 return nullptr; 7050 } 7051 7052 Expr *OpenMPIterationSpaceChecker::buildPreCond( 7053 Scope *S, Expr *Cond, 7054 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const { 7055 // Do not build a precondition when the condition/initialization is dependent 7056 // to prevent pessimistic early loop exit. 7057 // TODO: this can be improved by calculating min/max values but not sure that 7058 // it will be very effective. 7059 if (CondDependOnLC || InitDependOnLC) 7060 return SemaRef.PerformImplicitConversion( 7061 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get(), 7062 SemaRef.Context.BoolTy, /*Action=*/Sema::AA_Casting, 7063 /*AllowExplicit=*/true).get(); 7064 7065 // Try to build LB <op> UB, where <op> is <, >, <=, or >=. 7066 Sema::TentativeAnalysisScope Trap(SemaRef); 7067 7068 ExprResult NewLB = tryBuildCapture(SemaRef, LB, Captures); 7069 ExprResult NewUB = tryBuildCapture(SemaRef, UB, Captures); 7070 if (!NewLB.isUsable() || !NewUB.isUsable()) 7071 return nullptr; 7072 7073 ExprResult CondExpr = 7074 SemaRef.BuildBinOp(S, DefaultLoc, 7075 TestIsLessOp.getValue() ? 7076 (TestIsStrictOp ? BO_LT : BO_LE) : 7077 (TestIsStrictOp ? BO_GT : BO_GE), 7078 NewLB.get(), NewUB.get()); 7079 if (CondExpr.isUsable()) { 7080 if (!SemaRef.Context.hasSameUnqualifiedType(CondExpr.get()->getType(), 7081 SemaRef.Context.BoolTy)) 7082 CondExpr = SemaRef.PerformImplicitConversion( 7083 CondExpr.get(), SemaRef.Context.BoolTy, /*Action=*/Sema::AA_Casting, 7084 /*AllowExplicit=*/true); 7085 } 7086 7087 // Otherwise use original loop condition and evaluate it in runtime. 7088 return CondExpr.isUsable() ? CondExpr.get() : Cond; 7089 } 7090 7091 /// Build reference expression to the counter be used for codegen. 7092 DeclRefExpr *OpenMPIterationSpaceChecker::buildCounterVar( 7093 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures, 7094 DSAStackTy &DSA) const { 7095 auto *VD = dyn_cast<VarDecl>(LCDecl); 7096 if (!VD) { 7097 VD = SemaRef.isOpenMPCapturedDecl(LCDecl); 7098 DeclRefExpr *Ref = buildDeclRefExpr( 7099 SemaRef, VD, VD->getType().getNonReferenceType(), DefaultLoc); 7100 const DSAStackTy::DSAVarData Data = 7101 DSA.getTopDSA(LCDecl, /*FromParent=*/false); 7102 // If the loop control decl is explicitly marked as private, do not mark it 7103 // as captured again. 7104 if (!isOpenMPPrivate(Data.CKind) || !Data.RefExpr) 7105 Captures.insert(std::make_pair(LCRef, Ref)); 7106 return Ref; 7107 } 7108 return cast<DeclRefExpr>(LCRef); 7109 } 7110 7111 Expr *OpenMPIterationSpaceChecker::buildPrivateCounterVar() const { 7112 if (LCDecl && !LCDecl->isInvalidDecl()) { 7113 QualType Type = LCDecl->getType().getNonReferenceType(); 7114 VarDecl *PrivateVar = buildVarDecl( 7115 SemaRef, DefaultLoc, Type, LCDecl->getName(), 7116 LCDecl->hasAttrs() ? &LCDecl->getAttrs() : nullptr, 7117 isa<VarDecl>(LCDecl) 7118 ? buildDeclRefExpr(SemaRef, cast<VarDecl>(LCDecl), Type, DefaultLoc) 7119 : nullptr); 7120 if (PrivateVar->isInvalidDecl()) 7121 return nullptr; 7122 return buildDeclRefExpr(SemaRef, PrivateVar, Type, DefaultLoc); 7123 } 7124 return nullptr; 7125 } 7126 7127 /// Build initialization of the counter to be used for codegen. 7128 Expr *OpenMPIterationSpaceChecker::buildCounterInit() const { return LB; } 7129 7130 /// Build step of the counter be used for codegen. 7131 Expr *OpenMPIterationSpaceChecker::buildCounterStep() const { return Step; } 7132 7133 Expr *OpenMPIterationSpaceChecker::buildOrderedLoopData( 7134 Scope *S, Expr *Counter, 7135 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures, SourceLocation Loc, 7136 Expr *Inc, OverloadedOperatorKind OOK) { 7137 Expr *Cnt = SemaRef.DefaultLvalueConversion(Counter).get(); 7138 if (!Cnt) 7139 return nullptr; 7140 if (Inc) { 7141 assert((OOK == OO_Plus || OOK == OO_Minus) && 7142 "Expected only + or - operations for depend clauses."); 7143 BinaryOperatorKind BOK = (OOK == OO_Plus) ? BO_Add : BO_Sub; 7144 Cnt = SemaRef.BuildBinOp(S, Loc, BOK, Cnt, Inc).get(); 7145 if (!Cnt) 7146 return nullptr; 7147 } 7148 ExprResult Diff; 7149 QualType VarType = LCDecl->getType().getNonReferenceType(); 7150 if (VarType->isIntegerType() || VarType->isPointerType() || 7151 SemaRef.getLangOpts().CPlusPlus) { 7152 // Upper - Lower 7153 Expr *Upper = TestIsLessOp.getValue() 7154 ? Cnt 7155 : tryBuildCapture(SemaRef, LB, Captures).get(); 7156 Expr *Lower = TestIsLessOp.getValue() 7157 ? tryBuildCapture(SemaRef, LB, Captures).get() 7158 : Cnt; 7159 if (!Upper || !Lower) 7160 return nullptr; 7161 7162 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Lower); 7163 7164 if (!Diff.isUsable() && VarType->getAsCXXRecordDecl()) { 7165 // BuildBinOp already emitted error, this one is to point user to upper 7166 // and lower bound, and to tell what is passed to 'operator-'. 7167 SemaRef.Diag(Upper->getBeginLoc(), diag::err_omp_loop_diff_cxx) 7168 << Upper->getSourceRange() << Lower->getSourceRange(); 7169 return nullptr; 7170 } 7171 } 7172 7173 if (!Diff.isUsable()) 7174 return nullptr; 7175 7176 // Parentheses (for dumping/debugging purposes only). 7177 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get()); 7178 if (!Diff.isUsable()) 7179 return nullptr; 7180 7181 ExprResult NewStep = tryBuildCapture(SemaRef, Step, Captures); 7182 if (!NewStep.isUsable()) 7183 return nullptr; 7184 // (Upper - Lower) / Step 7185 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Div, Diff.get(), NewStep.get()); 7186 if (!Diff.isUsable()) 7187 return nullptr; 7188 7189 return Diff.get(); 7190 } 7191 } // namespace 7192 7193 void Sema::ActOnOpenMPLoopInitialization(SourceLocation ForLoc, Stmt *Init) { 7194 assert(getLangOpts().OpenMP && "OpenMP is not active."); 7195 assert(Init && "Expected loop in canonical form."); 7196 unsigned AssociatedLoops = DSAStack->getAssociatedLoops(); 7197 if (AssociatedLoops > 0 && 7198 isOpenMPLoopDirective(DSAStack->getCurrentDirective())) { 7199 DSAStack->loopStart(); 7200 OpenMPIterationSpaceChecker ISC(*this, *DSAStack, ForLoc); 7201 if (!ISC.checkAndSetInit(Init, /*EmitDiags=*/false)) { 7202 if (ValueDecl *D = ISC.getLoopDecl()) { 7203 auto *VD = dyn_cast<VarDecl>(D); 7204 DeclRefExpr *PrivateRef = nullptr; 7205 if (!VD) { 7206 if (VarDecl *Private = isOpenMPCapturedDecl(D)) { 7207 VD = Private; 7208 } else { 7209 PrivateRef = buildCapture(*this, D, ISC.getLoopDeclRefExpr(), 7210 /*WithInit=*/false); 7211 VD = cast<VarDecl>(PrivateRef->getDecl()); 7212 } 7213 } 7214 DSAStack->addLoopControlVariable(D, VD); 7215 const Decl *LD = DSAStack->getPossiblyLoopCunter(); 7216 if (LD != D->getCanonicalDecl()) { 7217 DSAStack->resetPossibleLoopCounter(); 7218 if (auto *Var = dyn_cast_or_null<VarDecl>(LD)) 7219 MarkDeclarationsReferencedInExpr( 7220 buildDeclRefExpr(*this, const_cast<VarDecl *>(Var), 7221 Var->getType().getNonLValueExprType(Context), 7222 ForLoc, /*RefersToCapture=*/true)); 7223 } 7224 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 7225 // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables 7226 // Referenced in a Construct, C/C++]. The loop iteration variable in the 7227 // associated for-loop of a simd construct with just one associated 7228 // for-loop may be listed in a linear clause with a constant-linear-step 7229 // that is the increment of the associated for-loop. The loop iteration 7230 // variable(s) in the associated for-loop(s) of a for or parallel for 7231 // construct may be listed in a private or lastprivate clause. 7232 DSAStackTy::DSAVarData DVar = 7233 DSAStack->getTopDSA(D, /*FromParent=*/false); 7234 // If LoopVarRefExpr is nullptr it means the corresponding loop variable 7235 // is declared in the loop and it is predetermined as a private. 7236 Expr *LoopDeclRefExpr = ISC.getLoopDeclRefExpr(); 7237 OpenMPClauseKind PredeterminedCKind = 7238 isOpenMPSimdDirective(DKind) 7239 ? (DSAStack->hasMutipleLoops() ? OMPC_lastprivate : OMPC_linear) 7240 : OMPC_private; 7241 if (((isOpenMPSimdDirective(DKind) && DVar.CKind != OMPC_unknown && 7242 DVar.CKind != PredeterminedCKind && DVar.RefExpr && 7243 (LangOpts.OpenMP <= 45 || (DVar.CKind != OMPC_lastprivate && 7244 DVar.CKind != OMPC_private))) || 7245 ((isOpenMPWorksharingDirective(DKind) || DKind == OMPD_taskloop || 7246 DKind == OMPD_master_taskloop || 7247 DKind == OMPD_parallel_master_taskloop || 7248 isOpenMPDistributeDirective(DKind)) && 7249 !isOpenMPSimdDirective(DKind) && DVar.CKind != OMPC_unknown && 7250 DVar.CKind != OMPC_private && DVar.CKind != OMPC_lastprivate)) && 7251 (DVar.CKind != OMPC_private || DVar.RefExpr)) { 7252 Diag(Init->getBeginLoc(), diag::err_omp_loop_var_dsa) 7253 << getOpenMPClauseName(DVar.CKind) 7254 << getOpenMPDirectiveName(DKind) 7255 << getOpenMPClauseName(PredeterminedCKind); 7256 if (DVar.RefExpr == nullptr) 7257 DVar.CKind = PredeterminedCKind; 7258 reportOriginalDsa(*this, DSAStack, D, DVar, 7259 /*IsLoopIterVar=*/true); 7260 } else if (LoopDeclRefExpr) { 7261 // Make the loop iteration variable private (for worksharing 7262 // constructs), linear (for simd directives with the only one 7263 // associated loop) or lastprivate (for simd directives with several 7264 // collapsed or ordered loops). 7265 if (DVar.CKind == OMPC_unknown) 7266 DSAStack->addDSA(D, LoopDeclRefExpr, PredeterminedCKind, 7267 PrivateRef); 7268 } 7269 } 7270 } 7271 DSAStack->setAssociatedLoops(AssociatedLoops - 1); 7272 } 7273 } 7274 7275 /// Called on a for stmt to check and extract its iteration space 7276 /// for further processing (such as collapsing). 7277 static bool checkOpenMPIterationSpace( 7278 OpenMPDirectiveKind DKind, Stmt *S, Sema &SemaRef, DSAStackTy &DSA, 7279 unsigned CurrentNestedLoopCount, unsigned NestedLoopCount, 7280 unsigned TotalNestedLoopCount, Expr *CollapseLoopCountExpr, 7281 Expr *OrderedLoopCountExpr, 7282 Sema::VarsWithInheritedDSAType &VarsWithImplicitDSA, 7283 llvm::MutableArrayRef<LoopIterationSpace> ResultIterSpaces, 7284 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) { 7285 // OpenMP [2.9.1, Canonical Loop Form] 7286 // for (init-expr; test-expr; incr-expr) structured-block 7287 // for (range-decl: range-expr) structured-block 7288 auto *For = dyn_cast_or_null<ForStmt>(S); 7289 auto *CXXFor = dyn_cast_or_null<CXXForRangeStmt>(S); 7290 // Ranged for is supported only in OpenMP 5.0. 7291 if (!For && (SemaRef.LangOpts.OpenMP <= 45 || !CXXFor)) { 7292 SemaRef.Diag(S->getBeginLoc(), diag::err_omp_not_for) 7293 << (CollapseLoopCountExpr != nullptr || OrderedLoopCountExpr != nullptr) 7294 << getOpenMPDirectiveName(DKind) << TotalNestedLoopCount 7295 << (CurrentNestedLoopCount > 0) << CurrentNestedLoopCount; 7296 if (TotalNestedLoopCount > 1) { 7297 if (CollapseLoopCountExpr && OrderedLoopCountExpr) 7298 SemaRef.Diag(DSA.getConstructLoc(), 7299 diag::note_omp_collapse_ordered_expr) 7300 << 2 << CollapseLoopCountExpr->getSourceRange() 7301 << OrderedLoopCountExpr->getSourceRange(); 7302 else if (CollapseLoopCountExpr) 7303 SemaRef.Diag(CollapseLoopCountExpr->getExprLoc(), 7304 diag::note_omp_collapse_ordered_expr) 7305 << 0 << CollapseLoopCountExpr->getSourceRange(); 7306 else 7307 SemaRef.Diag(OrderedLoopCountExpr->getExprLoc(), 7308 diag::note_omp_collapse_ordered_expr) 7309 << 1 << OrderedLoopCountExpr->getSourceRange(); 7310 } 7311 return true; 7312 } 7313 assert(((For && For->getBody()) || (CXXFor && CXXFor->getBody())) && 7314 "No loop body."); 7315 7316 OpenMPIterationSpaceChecker ISC(SemaRef, DSA, 7317 For ? For->getForLoc() : CXXFor->getForLoc()); 7318 7319 // Check init. 7320 Stmt *Init = For ? For->getInit() : CXXFor->getBeginStmt(); 7321 if (ISC.checkAndSetInit(Init)) 7322 return true; 7323 7324 bool HasErrors = false; 7325 7326 // Check loop variable's type. 7327 if (ValueDecl *LCDecl = ISC.getLoopDecl()) { 7328 // OpenMP [2.6, Canonical Loop Form] 7329 // Var is one of the following: 7330 // A variable of signed or unsigned integer type. 7331 // For C++, a variable of a random access iterator type. 7332 // For C, a variable of a pointer type. 7333 QualType VarType = LCDecl->getType().getNonReferenceType(); 7334 if (!VarType->isDependentType() && !VarType->isIntegerType() && 7335 !VarType->isPointerType() && 7336 !(SemaRef.getLangOpts().CPlusPlus && VarType->isOverloadableType())) { 7337 SemaRef.Diag(Init->getBeginLoc(), diag::err_omp_loop_variable_type) 7338 << SemaRef.getLangOpts().CPlusPlus; 7339 HasErrors = true; 7340 } 7341 7342 // OpenMP, 2.14.1.1 Data-sharing Attribute Rules for Variables Referenced in 7343 // a Construct 7344 // The loop iteration variable(s) in the associated for-loop(s) of a for or 7345 // parallel for construct is (are) private. 7346 // The loop iteration variable in the associated for-loop of a simd 7347 // construct with just one associated for-loop is linear with a 7348 // constant-linear-step that is the increment of the associated for-loop. 7349 // Exclude loop var from the list of variables with implicitly defined data 7350 // sharing attributes. 7351 VarsWithImplicitDSA.erase(LCDecl); 7352 7353 assert(isOpenMPLoopDirective(DKind) && "DSA for non-loop vars"); 7354 7355 // Check test-expr. 7356 HasErrors |= ISC.checkAndSetCond(For ? For->getCond() : CXXFor->getCond()); 7357 7358 // Check incr-expr. 7359 HasErrors |= ISC.checkAndSetInc(For ? For->getInc() : CXXFor->getInc()); 7360 } 7361 7362 if (ISC.dependent() || SemaRef.CurContext->isDependentContext() || HasErrors) 7363 return HasErrors; 7364 7365 // Build the loop's iteration space representation. 7366 ResultIterSpaces[CurrentNestedLoopCount].PreCond = ISC.buildPreCond( 7367 DSA.getCurScope(), For ? For->getCond() : CXXFor->getCond(), Captures); 7368 ResultIterSpaces[CurrentNestedLoopCount].NumIterations = 7369 ISC.buildNumIterations(DSA.getCurScope(), ResultIterSpaces, 7370 (isOpenMPWorksharingDirective(DKind) || 7371 isOpenMPTaskLoopDirective(DKind) || 7372 isOpenMPDistributeDirective(DKind)), 7373 Captures); 7374 ResultIterSpaces[CurrentNestedLoopCount].CounterVar = 7375 ISC.buildCounterVar(Captures, DSA); 7376 ResultIterSpaces[CurrentNestedLoopCount].PrivateCounterVar = 7377 ISC.buildPrivateCounterVar(); 7378 ResultIterSpaces[CurrentNestedLoopCount].CounterInit = ISC.buildCounterInit(); 7379 ResultIterSpaces[CurrentNestedLoopCount].CounterStep = ISC.buildCounterStep(); 7380 ResultIterSpaces[CurrentNestedLoopCount].InitSrcRange = ISC.getInitSrcRange(); 7381 ResultIterSpaces[CurrentNestedLoopCount].CondSrcRange = 7382 ISC.getConditionSrcRange(); 7383 ResultIterSpaces[CurrentNestedLoopCount].IncSrcRange = 7384 ISC.getIncrementSrcRange(); 7385 ResultIterSpaces[CurrentNestedLoopCount].Subtract = ISC.shouldSubtractStep(); 7386 ResultIterSpaces[CurrentNestedLoopCount].IsStrictCompare = 7387 ISC.isStrictTestOp(); 7388 std::tie(ResultIterSpaces[CurrentNestedLoopCount].MinValue, 7389 ResultIterSpaces[CurrentNestedLoopCount].MaxValue) = 7390 ISC.buildMinMaxValues(DSA.getCurScope(), Captures); 7391 ResultIterSpaces[CurrentNestedLoopCount].FinalCondition = 7392 ISC.buildFinalCondition(DSA.getCurScope()); 7393 ResultIterSpaces[CurrentNestedLoopCount].IsNonRectangularLB = 7394 ISC.doesInitDependOnLC(); 7395 ResultIterSpaces[CurrentNestedLoopCount].IsNonRectangularUB = 7396 ISC.doesCondDependOnLC(); 7397 ResultIterSpaces[CurrentNestedLoopCount].LoopDependentIdx = 7398 ISC.getLoopDependentIdx(); 7399 7400 HasErrors |= 7401 (ResultIterSpaces[CurrentNestedLoopCount].PreCond == nullptr || 7402 ResultIterSpaces[CurrentNestedLoopCount].NumIterations == nullptr || 7403 ResultIterSpaces[CurrentNestedLoopCount].CounterVar == nullptr || 7404 ResultIterSpaces[CurrentNestedLoopCount].PrivateCounterVar == nullptr || 7405 ResultIterSpaces[CurrentNestedLoopCount].CounterInit == nullptr || 7406 ResultIterSpaces[CurrentNestedLoopCount].CounterStep == nullptr); 7407 if (!HasErrors && DSA.isOrderedRegion()) { 7408 if (DSA.getOrderedRegionParam().second->getNumForLoops()) { 7409 if (CurrentNestedLoopCount < 7410 DSA.getOrderedRegionParam().second->getLoopNumIterations().size()) { 7411 DSA.getOrderedRegionParam().second->setLoopNumIterations( 7412 CurrentNestedLoopCount, 7413 ResultIterSpaces[CurrentNestedLoopCount].NumIterations); 7414 DSA.getOrderedRegionParam().second->setLoopCounter( 7415 CurrentNestedLoopCount, 7416 ResultIterSpaces[CurrentNestedLoopCount].CounterVar); 7417 } 7418 } 7419 for (auto &Pair : DSA.getDoacrossDependClauses()) { 7420 if (CurrentNestedLoopCount >= Pair.first->getNumLoops()) { 7421 // Erroneous case - clause has some problems. 7422 continue; 7423 } 7424 if (Pair.first->getDependencyKind() == OMPC_DEPEND_sink && 7425 Pair.second.size() <= CurrentNestedLoopCount) { 7426 // Erroneous case - clause has some problems. 7427 Pair.first->setLoopData(CurrentNestedLoopCount, nullptr); 7428 continue; 7429 } 7430 Expr *CntValue; 7431 if (Pair.first->getDependencyKind() == OMPC_DEPEND_source) 7432 CntValue = ISC.buildOrderedLoopData( 7433 DSA.getCurScope(), 7434 ResultIterSpaces[CurrentNestedLoopCount].CounterVar, Captures, 7435 Pair.first->getDependencyLoc()); 7436 else 7437 CntValue = ISC.buildOrderedLoopData( 7438 DSA.getCurScope(), 7439 ResultIterSpaces[CurrentNestedLoopCount].CounterVar, Captures, 7440 Pair.first->getDependencyLoc(), 7441 Pair.second[CurrentNestedLoopCount].first, 7442 Pair.second[CurrentNestedLoopCount].second); 7443 Pair.first->setLoopData(CurrentNestedLoopCount, CntValue); 7444 } 7445 } 7446 7447 return HasErrors; 7448 } 7449 7450 /// Build 'VarRef = Start. 7451 static ExprResult 7452 buildCounterInit(Sema &SemaRef, Scope *S, SourceLocation Loc, ExprResult VarRef, 7453 ExprResult Start, bool IsNonRectangularLB, 7454 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) { 7455 // Build 'VarRef = Start. 7456 ExprResult NewStart = IsNonRectangularLB 7457 ? Start.get() 7458 : tryBuildCapture(SemaRef, Start.get(), Captures); 7459 if (!NewStart.isUsable()) 7460 return ExprError(); 7461 if (!SemaRef.Context.hasSameType(NewStart.get()->getType(), 7462 VarRef.get()->getType())) { 7463 NewStart = SemaRef.PerformImplicitConversion( 7464 NewStart.get(), VarRef.get()->getType(), Sema::AA_Converting, 7465 /*AllowExplicit=*/true); 7466 if (!NewStart.isUsable()) 7467 return ExprError(); 7468 } 7469 7470 ExprResult Init = 7471 SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), NewStart.get()); 7472 return Init; 7473 } 7474 7475 /// Build 'VarRef = Start + Iter * Step'. 7476 static ExprResult buildCounterUpdate( 7477 Sema &SemaRef, Scope *S, SourceLocation Loc, ExprResult VarRef, 7478 ExprResult Start, ExprResult Iter, ExprResult Step, bool Subtract, 7479 bool IsNonRectangularLB, 7480 llvm::MapVector<const Expr *, DeclRefExpr *> *Captures = nullptr) { 7481 // Add parentheses (for debugging purposes only). 7482 Iter = SemaRef.ActOnParenExpr(Loc, Loc, Iter.get()); 7483 if (!VarRef.isUsable() || !Start.isUsable() || !Iter.isUsable() || 7484 !Step.isUsable()) 7485 return ExprError(); 7486 7487 ExprResult NewStep = Step; 7488 if (Captures) 7489 NewStep = tryBuildCapture(SemaRef, Step.get(), *Captures); 7490 if (NewStep.isInvalid()) 7491 return ExprError(); 7492 ExprResult Update = 7493 SemaRef.BuildBinOp(S, Loc, BO_Mul, Iter.get(), NewStep.get()); 7494 if (!Update.isUsable()) 7495 return ExprError(); 7496 7497 // Try to build 'VarRef = Start, VarRef (+|-)= Iter * Step' or 7498 // 'VarRef = Start (+|-) Iter * Step'. 7499 if (!Start.isUsable()) 7500 return ExprError(); 7501 ExprResult NewStart = SemaRef.ActOnParenExpr(Loc, Loc, Start.get()); 7502 if (!NewStart.isUsable()) 7503 return ExprError(); 7504 if (Captures && !IsNonRectangularLB) 7505 NewStart = tryBuildCapture(SemaRef, Start.get(), *Captures); 7506 if (NewStart.isInvalid()) 7507 return ExprError(); 7508 7509 // First attempt: try to build 'VarRef = Start, VarRef += Iter * Step'. 7510 ExprResult SavedUpdate = Update; 7511 ExprResult UpdateVal; 7512 if (VarRef.get()->getType()->isOverloadableType() || 7513 NewStart.get()->getType()->isOverloadableType() || 7514 Update.get()->getType()->isOverloadableType()) { 7515 Sema::TentativeAnalysisScope Trap(SemaRef); 7516 7517 Update = 7518 SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), NewStart.get()); 7519 if (Update.isUsable()) { 7520 UpdateVal = 7521 SemaRef.BuildBinOp(S, Loc, Subtract ? BO_SubAssign : BO_AddAssign, 7522 VarRef.get(), SavedUpdate.get()); 7523 if (UpdateVal.isUsable()) { 7524 Update = SemaRef.CreateBuiltinBinOp(Loc, BO_Comma, Update.get(), 7525 UpdateVal.get()); 7526 } 7527 } 7528 } 7529 7530 // Second attempt: try to build 'VarRef = Start (+|-) Iter * Step'. 7531 if (!Update.isUsable() || !UpdateVal.isUsable()) { 7532 Update = SemaRef.BuildBinOp(S, Loc, Subtract ? BO_Sub : BO_Add, 7533 NewStart.get(), SavedUpdate.get()); 7534 if (!Update.isUsable()) 7535 return ExprError(); 7536 7537 if (!SemaRef.Context.hasSameType(Update.get()->getType(), 7538 VarRef.get()->getType())) { 7539 Update = SemaRef.PerformImplicitConversion( 7540 Update.get(), VarRef.get()->getType(), Sema::AA_Converting, true); 7541 if (!Update.isUsable()) 7542 return ExprError(); 7543 } 7544 7545 Update = SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), Update.get()); 7546 } 7547 return Update; 7548 } 7549 7550 /// Convert integer expression \a E to make it have at least \a Bits 7551 /// bits. 7552 static ExprResult widenIterationCount(unsigned Bits, Expr *E, Sema &SemaRef) { 7553 if (E == nullptr) 7554 return ExprError(); 7555 ASTContext &C = SemaRef.Context; 7556 QualType OldType = E->getType(); 7557 unsigned HasBits = C.getTypeSize(OldType); 7558 if (HasBits >= Bits) 7559 return ExprResult(E); 7560 // OK to convert to signed, because new type has more bits than old. 7561 QualType NewType = C.getIntTypeForBitwidth(Bits, /* Signed */ true); 7562 return SemaRef.PerformImplicitConversion(E, NewType, Sema::AA_Converting, 7563 true); 7564 } 7565 7566 /// Check if the given expression \a E is a constant integer that fits 7567 /// into \a Bits bits. 7568 static bool fitsInto(unsigned Bits, bool Signed, const Expr *E, Sema &SemaRef) { 7569 if (E == nullptr) 7570 return false; 7571 llvm::APSInt Result; 7572 if (E->isIntegerConstantExpr(Result, SemaRef.Context)) 7573 return Signed ? Result.isSignedIntN(Bits) : Result.isIntN(Bits); 7574 return false; 7575 } 7576 7577 /// Build preinits statement for the given declarations. 7578 static Stmt *buildPreInits(ASTContext &Context, 7579 MutableArrayRef<Decl *> PreInits) { 7580 if (!PreInits.empty()) { 7581 return new (Context) DeclStmt( 7582 DeclGroupRef::Create(Context, PreInits.begin(), PreInits.size()), 7583 SourceLocation(), SourceLocation()); 7584 } 7585 return nullptr; 7586 } 7587 7588 /// Build preinits statement for the given declarations. 7589 static Stmt * 7590 buildPreInits(ASTContext &Context, 7591 const llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) { 7592 if (!Captures.empty()) { 7593 SmallVector<Decl *, 16> PreInits; 7594 for (const auto &Pair : Captures) 7595 PreInits.push_back(Pair.second->getDecl()); 7596 return buildPreInits(Context, PreInits); 7597 } 7598 return nullptr; 7599 } 7600 7601 /// Build postupdate expression for the given list of postupdates expressions. 7602 static Expr *buildPostUpdate(Sema &S, ArrayRef<Expr *> PostUpdates) { 7603 Expr *PostUpdate = nullptr; 7604 if (!PostUpdates.empty()) { 7605 for (Expr *E : PostUpdates) { 7606 Expr *ConvE = S.BuildCStyleCastExpr( 7607 E->getExprLoc(), 7608 S.Context.getTrivialTypeSourceInfo(S.Context.VoidTy), 7609 E->getExprLoc(), E) 7610 .get(); 7611 PostUpdate = PostUpdate 7612 ? S.CreateBuiltinBinOp(ConvE->getExprLoc(), BO_Comma, 7613 PostUpdate, ConvE) 7614 .get() 7615 : ConvE; 7616 } 7617 } 7618 return PostUpdate; 7619 } 7620 7621 /// Called on a for stmt to check itself and nested loops (if any). 7622 /// \return Returns 0 if one of the collapsed stmts is not canonical for loop, 7623 /// number of collapsed loops otherwise. 7624 static unsigned 7625 checkOpenMPLoop(OpenMPDirectiveKind DKind, Expr *CollapseLoopCountExpr, 7626 Expr *OrderedLoopCountExpr, Stmt *AStmt, Sema &SemaRef, 7627 DSAStackTy &DSA, 7628 Sema::VarsWithInheritedDSAType &VarsWithImplicitDSA, 7629 OMPLoopDirective::HelperExprs &Built) { 7630 unsigned NestedLoopCount = 1; 7631 if (CollapseLoopCountExpr) { 7632 // Found 'collapse' clause - calculate collapse number. 7633 Expr::EvalResult Result; 7634 if (!CollapseLoopCountExpr->isValueDependent() && 7635 CollapseLoopCountExpr->EvaluateAsInt(Result, SemaRef.getASTContext())) { 7636 NestedLoopCount = Result.Val.getInt().getLimitedValue(); 7637 } else { 7638 Built.clear(/*Size=*/1); 7639 return 1; 7640 } 7641 } 7642 unsigned OrderedLoopCount = 1; 7643 if (OrderedLoopCountExpr) { 7644 // Found 'ordered' clause - calculate collapse number. 7645 Expr::EvalResult EVResult; 7646 if (!OrderedLoopCountExpr->isValueDependent() && 7647 OrderedLoopCountExpr->EvaluateAsInt(EVResult, 7648 SemaRef.getASTContext())) { 7649 llvm::APSInt Result = EVResult.Val.getInt(); 7650 if (Result.getLimitedValue() < NestedLoopCount) { 7651 SemaRef.Diag(OrderedLoopCountExpr->getExprLoc(), 7652 diag::err_omp_wrong_ordered_loop_count) 7653 << OrderedLoopCountExpr->getSourceRange(); 7654 SemaRef.Diag(CollapseLoopCountExpr->getExprLoc(), 7655 diag::note_collapse_loop_count) 7656 << CollapseLoopCountExpr->getSourceRange(); 7657 } 7658 OrderedLoopCount = Result.getLimitedValue(); 7659 } else { 7660 Built.clear(/*Size=*/1); 7661 return 1; 7662 } 7663 } 7664 // This is helper routine for loop directives (e.g., 'for', 'simd', 7665 // 'for simd', etc.). 7666 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 7667 SmallVector<LoopIterationSpace, 4> IterSpaces( 7668 std::max(OrderedLoopCount, NestedLoopCount)); 7669 Stmt *CurStmt = AStmt->IgnoreContainers(/* IgnoreCaptured */ true); 7670 for (unsigned Cnt = 0; Cnt < NestedLoopCount; ++Cnt) { 7671 if (checkOpenMPIterationSpace( 7672 DKind, CurStmt, SemaRef, DSA, Cnt, NestedLoopCount, 7673 std::max(OrderedLoopCount, NestedLoopCount), CollapseLoopCountExpr, 7674 OrderedLoopCountExpr, VarsWithImplicitDSA, IterSpaces, Captures)) 7675 return 0; 7676 // Move on to the next nested for loop, or to the loop body. 7677 // OpenMP [2.8.1, simd construct, Restrictions] 7678 // All loops associated with the construct must be perfectly nested; that 7679 // is, there must be no intervening code nor any OpenMP directive between 7680 // any two loops. 7681 if (auto *For = dyn_cast<ForStmt>(CurStmt)) { 7682 CurStmt = For->getBody(); 7683 } else { 7684 assert(isa<CXXForRangeStmt>(CurStmt) && 7685 "Expected canonical for or range-based for loops."); 7686 CurStmt = cast<CXXForRangeStmt>(CurStmt)->getBody(); 7687 } 7688 CurStmt = OMPLoopDirective::tryToFindNextInnerLoop( 7689 CurStmt, SemaRef.LangOpts.OpenMP >= 50); 7690 } 7691 for (unsigned Cnt = NestedLoopCount; Cnt < OrderedLoopCount; ++Cnt) { 7692 if (checkOpenMPIterationSpace( 7693 DKind, CurStmt, SemaRef, DSA, Cnt, NestedLoopCount, 7694 std::max(OrderedLoopCount, NestedLoopCount), CollapseLoopCountExpr, 7695 OrderedLoopCountExpr, VarsWithImplicitDSA, IterSpaces, Captures)) 7696 return 0; 7697 if (Cnt > 0 && IterSpaces[Cnt].CounterVar) { 7698 // Handle initialization of captured loop iterator variables. 7699 auto *DRE = cast<DeclRefExpr>(IterSpaces[Cnt].CounterVar); 7700 if (isa<OMPCapturedExprDecl>(DRE->getDecl())) { 7701 Captures[DRE] = DRE; 7702 } 7703 } 7704 // Move on to the next nested for loop, or to the loop body. 7705 // OpenMP [2.8.1, simd construct, Restrictions] 7706 // All loops associated with the construct must be perfectly nested; that 7707 // is, there must be no intervening code nor any OpenMP directive between 7708 // any two loops. 7709 if (auto *For = dyn_cast<ForStmt>(CurStmt)) { 7710 CurStmt = For->getBody(); 7711 } else { 7712 assert(isa<CXXForRangeStmt>(CurStmt) && 7713 "Expected canonical for or range-based for loops."); 7714 CurStmt = cast<CXXForRangeStmt>(CurStmt)->getBody(); 7715 } 7716 CurStmt = OMPLoopDirective::tryToFindNextInnerLoop( 7717 CurStmt, SemaRef.LangOpts.OpenMP >= 50); 7718 } 7719 7720 Built.clear(/* size */ NestedLoopCount); 7721 7722 if (SemaRef.CurContext->isDependentContext()) 7723 return NestedLoopCount; 7724 7725 // An example of what is generated for the following code: 7726 // 7727 // #pragma omp simd collapse(2) ordered(2) 7728 // for (i = 0; i < NI; ++i) 7729 // for (k = 0; k < NK; ++k) 7730 // for (j = J0; j < NJ; j+=2) { 7731 // <loop body> 7732 // } 7733 // 7734 // We generate the code below. 7735 // Note: the loop body may be outlined in CodeGen. 7736 // Note: some counters may be C++ classes, operator- is used to find number of 7737 // iterations and operator+= to calculate counter value. 7738 // Note: decltype(NumIterations) must be integer type (in 'omp for', only i32 7739 // or i64 is currently supported). 7740 // 7741 // #define NumIterations (NI * ((NJ - J0 - 1 + 2) / 2)) 7742 // for (int[32|64]_t IV = 0; IV < NumIterations; ++IV ) { 7743 // .local.i = IV / ((NJ - J0 - 1 + 2) / 2); 7744 // .local.j = J0 + (IV % ((NJ - J0 - 1 + 2) / 2)) * 2; 7745 // // similar updates for vars in clauses (e.g. 'linear') 7746 // <loop body (using local i and j)> 7747 // } 7748 // i = NI; // assign final values of counters 7749 // j = NJ; 7750 // 7751 7752 // Last iteration number is (I1 * I2 * ... In) - 1, where I1, I2 ... In are 7753 // the iteration counts of the collapsed for loops. 7754 // Precondition tests if there is at least one iteration (all conditions are 7755 // true). 7756 auto PreCond = ExprResult(IterSpaces[0].PreCond); 7757 Expr *N0 = IterSpaces[0].NumIterations; 7758 ExprResult LastIteration32 = 7759 widenIterationCount(/*Bits=*/32, 7760 SemaRef 7761 .PerformImplicitConversion( 7762 N0->IgnoreImpCasts(), N0->getType(), 7763 Sema::AA_Converting, /*AllowExplicit=*/true) 7764 .get(), 7765 SemaRef); 7766 ExprResult LastIteration64 = widenIterationCount( 7767 /*Bits=*/64, 7768 SemaRef 7769 .PerformImplicitConversion(N0->IgnoreImpCasts(), N0->getType(), 7770 Sema::AA_Converting, 7771 /*AllowExplicit=*/true) 7772 .get(), 7773 SemaRef); 7774 7775 if (!LastIteration32.isUsable() || !LastIteration64.isUsable()) 7776 return NestedLoopCount; 7777 7778 ASTContext &C = SemaRef.Context; 7779 bool AllCountsNeedLessThan32Bits = C.getTypeSize(N0->getType()) < 32; 7780 7781 Scope *CurScope = DSA.getCurScope(); 7782 for (unsigned Cnt = 1; Cnt < NestedLoopCount; ++Cnt) { 7783 if (PreCond.isUsable()) { 7784 PreCond = 7785 SemaRef.BuildBinOp(CurScope, PreCond.get()->getExprLoc(), BO_LAnd, 7786 PreCond.get(), IterSpaces[Cnt].PreCond); 7787 } 7788 Expr *N = IterSpaces[Cnt].NumIterations; 7789 SourceLocation Loc = N->getExprLoc(); 7790 AllCountsNeedLessThan32Bits &= C.getTypeSize(N->getType()) < 32; 7791 if (LastIteration32.isUsable()) 7792 LastIteration32 = SemaRef.BuildBinOp( 7793 CurScope, Loc, BO_Mul, LastIteration32.get(), 7794 SemaRef 7795 .PerformImplicitConversion(N->IgnoreImpCasts(), N->getType(), 7796 Sema::AA_Converting, 7797 /*AllowExplicit=*/true) 7798 .get()); 7799 if (LastIteration64.isUsable()) 7800 LastIteration64 = SemaRef.BuildBinOp( 7801 CurScope, Loc, BO_Mul, LastIteration64.get(), 7802 SemaRef 7803 .PerformImplicitConversion(N->IgnoreImpCasts(), N->getType(), 7804 Sema::AA_Converting, 7805 /*AllowExplicit=*/true) 7806 .get()); 7807 } 7808 7809 // Choose either the 32-bit or 64-bit version. 7810 ExprResult LastIteration = LastIteration64; 7811 if (SemaRef.getLangOpts().OpenMPOptimisticCollapse || 7812 (LastIteration32.isUsable() && 7813 C.getTypeSize(LastIteration32.get()->getType()) == 32 && 7814 (AllCountsNeedLessThan32Bits || NestedLoopCount == 1 || 7815 fitsInto( 7816 /*Bits=*/32, 7817 LastIteration32.get()->getType()->hasSignedIntegerRepresentation(), 7818 LastIteration64.get(), SemaRef)))) 7819 LastIteration = LastIteration32; 7820 QualType VType = LastIteration.get()->getType(); 7821 QualType RealVType = VType; 7822 QualType StrideVType = VType; 7823 if (isOpenMPTaskLoopDirective(DKind)) { 7824 VType = 7825 SemaRef.Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/0); 7826 StrideVType = 7827 SemaRef.Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/1); 7828 } 7829 7830 if (!LastIteration.isUsable()) 7831 return 0; 7832 7833 // Save the number of iterations. 7834 ExprResult NumIterations = LastIteration; 7835 { 7836 LastIteration = SemaRef.BuildBinOp( 7837 CurScope, LastIteration.get()->getExprLoc(), BO_Sub, 7838 LastIteration.get(), 7839 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()); 7840 if (!LastIteration.isUsable()) 7841 return 0; 7842 } 7843 7844 // Calculate the last iteration number beforehand instead of doing this on 7845 // each iteration. Do not do this if the number of iterations may be kfold-ed. 7846 llvm::APSInt Result; 7847 bool IsConstant = 7848 LastIteration.get()->isIntegerConstantExpr(Result, SemaRef.Context); 7849 ExprResult CalcLastIteration; 7850 if (!IsConstant) { 7851 ExprResult SaveRef = 7852 tryBuildCapture(SemaRef, LastIteration.get(), Captures); 7853 LastIteration = SaveRef; 7854 7855 // Prepare SaveRef + 1. 7856 NumIterations = SemaRef.BuildBinOp( 7857 CurScope, SaveRef.get()->getExprLoc(), BO_Add, SaveRef.get(), 7858 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()); 7859 if (!NumIterations.isUsable()) 7860 return 0; 7861 } 7862 7863 SourceLocation InitLoc = IterSpaces[0].InitSrcRange.getBegin(); 7864 7865 // Build variables passed into runtime, necessary for worksharing directives. 7866 ExprResult LB, UB, IL, ST, EUB, CombLB, CombUB, PrevLB, PrevUB, CombEUB; 7867 if (isOpenMPWorksharingDirective(DKind) || isOpenMPTaskLoopDirective(DKind) || 7868 isOpenMPDistributeDirective(DKind)) { 7869 // Lower bound variable, initialized with zero. 7870 VarDecl *LBDecl = buildVarDecl(SemaRef, InitLoc, VType, ".omp.lb"); 7871 LB = buildDeclRefExpr(SemaRef, LBDecl, VType, InitLoc); 7872 SemaRef.AddInitializerToDecl(LBDecl, 7873 SemaRef.ActOnIntegerConstant(InitLoc, 0).get(), 7874 /*DirectInit*/ false); 7875 7876 // Upper bound variable, initialized with last iteration number. 7877 VarDecl *UBDecl = buildVarDecl(SemaRef, InitLoc, VType, ".omp.ub"); 7878 UB = buildDeclRefExpr(SemaRef, UBDecl, VType, InitLoc); 7879 SemaRef.AddInitializerToDecl(UBDecl, LastIteration.get(), 7880 /*DirectInit*/ false); 7881 7882 // A 32-bit variable-flag where runtime returns 1 for the last iteration. 7883 // This will be used to implement clause 'lastprivate'. 7884 QualType Int32Ty = SemaRef.Context.getIntTypeForBitwidth(32, true); 7885 VarDecl *ILDecl = buildVarDecl(SemaRef, InitLoc, Int32Ty, ".omp.is_last"); 7886 IL = buildDeclRefExpr(SemaRef, ILDecl, Int32Ty, InitLoc); 7887 SemaRef.AddInitializerToDecl(ILDecl, 7888 SemaRef.ActOnIntegerConstant(InitLoc, 0).get(), 7889 /*DirectInit*/ false); 7890 7891 // Stride variable returned by runtime (we initialize it to 1 by default). 7892 VarDecl *STDecl = 7893 buildVarDecl(SemaRef, InitLoc, StrideVType, ".omp.stride"); 7894 ST = buildDeclRefExpr(SemaRef, STDecl, StrideVType, InitLoc); 7895 SemaRef.AddInitializerToDecl(STDecl, 7896 SemaRef.ActOnIntegerConstant(InitLoc, 1).get(), 7897 /*DirectInit*/ false); 7898 7899 // Build expression: UB = min(UB, LastIteration) 7900 // It is necessary for CodeGen of directives with static scheduling. 7901 ExprResult IsUBGreater = SemaRef.BuildBinOp(CurScope, InitLoc, BO_GT, 7902 UB.get(), LastIteration.get()); 7903 ExprResult CondOp = SemaRef.ActOnConditionalOp( 7904 LastIteration.get()->getExprLoc(), InitLoc, IsUBGreater.get(), 7905 LastIteration.get(), UB.get()); 7906 EUB = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, UB.get(), 7907 CondOp.get()); 7908 EUB = SemaRef.ActOnFinishFullExpr(EUB.get(), /*DiscardedValue*/ false); 7909 7910 // If we have a combined directive that combines 'distribute', 'for' or 7911 // 'simd' we need to be able to access the bounds of the schedule of the 7912 // enclosing region. E.g. in 'distribute parallel for' the bounds obtained 7913 // by scheduling 'distribute' have to be passed to the schedule of 'for'. 7914 if (isOpenMPLoopBoundSharingDirective(DKind)) { 7915 // Lower bound variable, initialized with zero. 7916 VarDecl *CombLBDecl = 7917 buildVarDecl(SemaRef, InitLoc, VType, ".omp.comb.lb"); 7918 CombLB = buildDeclRefExpr(SemaRef, CombLBDecl, VType, InitLoc); 7919 SemaRef.AddInitializerToDecl( 7920 CombLBDecl, SemaRef.ActOnIntegerConstant(InitLoc, 0).get(), 7921 /*DirectInit*/ false); 7922 7923 // Upper bound variable, initialized with last iteration number. 7924 VarDecl *CombUBDecl = 7925 buildVarDecl(SemaRef, InitLoc, VType, ".omp.comb.ub"); 7926 CombUB = buildDeclRefExpr(SemaRef, CombUBDecl, VType, InitLoc); 7927 SemaRef.AddInitializerToDecl(CombUBDecl, LastIteration.get(), 7928 /*DirectInit*/ false); 7929 7930 ExprResult CombIsUBGreater = SemaRef.BuildBinOp( 7931 CurScope, InitLoc, BO_GT, CombUB.get(), LastIteration.get()); 7932 ExprResult CombCondOp = 7933 SemaRef.ActOnConditionalOp(InitLoc, InitLoc, CombIsUBGreater.get(), 7934 LastIteration.get(), CombUB.get()); 7935 CombEUB = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, CombUB.get(), 7936 CombCondOp.get()); 7937 CombEUB = 7938 SemaRef.ActOnFinishFullExpr(CombEUB.get(), /*DiscardedValue*/ false); 7939 7940 const CapturedDecl *CD = cast<CapturedStmt>(AStmt)->getCapturedDecl(); 7941 // We expect to have at least 2 more parameters than the 'parallel' 7942 // directive does - the lower and upper bounds of the previous schedule. 7943 assert(CD->getNumParams() >= 4 && 7944 "Unexpected number of parameters in loop combined directive"); 7945 7946 // Set the proper type for the bounds given what we learned from the 7947 // enclosed loops. 7948 ImplicitParamDecl *PrevLBDecl = CD->getParam(/*PrevLB=*/2); 7949 ImplicitParamDecl *PrevUBDecl = CD->getParam(/*PrevUB=*/3); 7950 7951 // Previous lower and upper bounds are obtained from the region 7952 // parameters. 7953 PrevLB = 7954 buildDeclRefExpr(SemaRef, PrevLBDecl, PrevLBDecl->getType(), InitLoc); 7955 PrevUB = 7956 buildDeclRefExpr(SemaRef, PrevUBDecl, PrevUBDecl->getType(), InitLoc); 7957 } 7958 } 7959 7960 // Build the iteration variable and its initialization before loop. 7961 ExprResult IV; 7962 ExprResult Init, CombInit; 7963 { 7964 VarDecl *IVDecl = buildVarDecl(SemaRef, InitLoc, RealVType, ".omp.iv"); 7965 IV = buildDeclRefExpr(SemaRef, IVDecl, RealVType, InitLoc); 7966 Expr *RHS = 7967 (isOpenMPWorksharingDirective(DKind) || 7968 isOpenMPTaskLoopDirective(DKind) || isOpenMPDistributeDirective(DKind)) 7969 ? LB.get() 7970 : SemaRef.ActOnIntegerConstant(SourceLocation(), 0).get(); 7971 Init = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, IV.get(), RHS); 7972 Init = SemaRef.ActOnFinishFullExpr(Init.get(), /*DiscardedValue*/ false); 7973 7974 if (isOpenMPLoopBoundSharingDirective(DKind)) { 7975 Expr *CombRHS = 7976 (isOpenMPWorksharingDirective(DKind) || 7977 isOpenMPTaskLoopDirective(DKind) || 7978 isOpenMPDistributeDirective(DKind)) 7979 ? CombLB.get() 7980 : SemaRef.ActOnIntegerConstant(SourceLocation(), 0).get(); 7981 CombInit = 7982 SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, IV.get(), CombRHS); 7983 CombInit = 7984 SemaRef.ActOnFinishFullExpr(CombInit.get(), /*DiscardedValue*/ false); 7985 } 7986 } 7987 7988 bool UseStrictCompare = 7989 RealVType->hasUnsignedIntegerRepresentation() && 7990 llvm::all_of(IterSpaces, [](const LoopIterationSpace &LIS) { 7991 return LIS.IsStrictCompare; 7992 }); 7993 // Loop condition (IV < NumIterations) or (IV <= UB or IV < UB + 1 (for 7994 // unsigned IV)) for worksharing loops. 7995 SourceLocation CondLoc = AStmt->getBeginLoc(); 7996 Expr *BoundUB = UB.get(); 7997 if (UseStrictCompare) { 7998 BoundUB = 7999 SemaRef 8000 .BuildBinOp(CurScope, CondLoc, BO_Add, BoundUB, 8001 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()) 8002 .get(); 8003 BoundUB = 8004 SemaRef.ActOnFinishFullExpr(BoundUB, /*DiscardedValue*/ false).get(); 8005 } 8006 ExprResult Cond = 8007 (isOpenMPWorksharingDirective(DKind) || 8008 isOpenMPTaskLoopDirective(DKind) || isOpenMPDistributeDirective(DKind)) 8009 ? SemaRef.BuildBinOp(CurScope, CondLoc, 8010 UseStrictCompare ? BO_LT : BO_LE, IV.get(), 8011 BoundUB) 8012 : SemaRef.BuildBinOp(CurScope, CondLoc, BO_LT, IV.get(), 8013 NumIterations.get()); 8014 ExprResult CombDistCond; 8015 if (isOpenMPLoopBoundSharingDirective(DKind)) { 8016 CombDistCond = SemaRef.BuildBinOp(CurScope, CondLoc, BO_LT, IV.get(), 8017 NumIterations.get()); 8018 } 8019 8020 ExprResult CombCond; 8021 if (isOpenMPLoopBoundSharingDirective(DKind)) { 8022 Expr *BoundCombUB = CombUB.get(); 8023 if (UseStrictCompare) { 8024 BoundCombUB = 8025 SemaRef 8026 .BuildBinOp( 8027 CurScope, CondLoc, BO_Add, BoundCombUB, 8028 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()) 8029 .get(); 8030 BoundCombUB = 8031 SemaRef.ActOnFinishFullExpr(BoundCombUB, /*DiscardedValue*/ false) 8032 .get(); 8033 } 8034 CombCond = 8035 SemaRef.BuildBinOp(CurScope, CondLoc, UseStrictCompare ? BO_LT : BO_LE, 8036 IV.get(), BoundCombUB); 8037 } 8038 // Loop increment (IV = IV + 1) 8039 SourceLocation IncLoc = AStmt->getBeginLoc(); 8040 ExprResult Inc = 8041 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, IV.get(), 8042 SemaRef.ActOnIntegerConstant(IncLoc, 1).get()); 8043 if (!Inc.isUsable()) 8044 return 0; 8045 Inc = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, IV.get(), Inc.get()); 8046 Inc = SemaRef.ActOnFinishFullExpr(Inc.get(), /*DiscardedValue*/ false); 8047 if (!Inc.isUsable()) 8048 return 0; 8049 8050 // Increments for worksharing loops (LB = LB + ST; UB = UB + ST). 8051 // Used for directives with static scheduling. 8052 // In combined construct, add combined version that use CombLB and CombUB 8053 // base variables for the update 8054 ExprResult NextLB, NextUB, CombNextLB, CombNextUB; 8055 if (isOpenMPWorksharingDirective(DKind) || isOpenMPTaskLoopDirective(DKind) || 8056 isOpenMPDistributeDirective(DKind)) { 8057 // LB + ST 8058 NextLB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, LB.get(), ST.get()); 8059 if (!NextLB.isUsable()) 8060 return 0; 8061 // LB = LB + ST 8062 NextLB = 8063 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, LB.get(), NextLB.get()); 8064 NextLB = 8065 SemaRef.ActOnFinishFullExpr(NextLB.get(), /*DiscardedValue*/ false); 8066 if (!NextLB.isUsable()) 8067 return 0; 8068 // UB + ST 8069 NextUB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, UB.get(), ST.get()); 8070 if (!NextUB.isUsable()) 8071 return 0; 8072 // UB = UB + ST 8073 NextUB = 8074 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, UB.get(), NextUB.get()); 8075 NextUB = 8076 SemaRef.ActOnFinishFullExpr(NextUB.get(), /*DiscardedValue*/ false); 8077 if (!NextUB.isUsable()) 8078 return 0; 8079 if (isOpenMPLoopBoundSharingDirective(DKind)) { 8080 CombNextLB = 8081 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, CombLB.get(), ST.get()); 8082 if (!NextLB.isUsable()) 8083 return 0; 8084 // LB = LB + ST 8085 CombNextLB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, CombLB.get(), 8086 CombNextLB.get()); 8087 CombNextLB = SemaRef.ActOnFinishFullExpr(CombNextLB.get(), 8088 /*DiscardedValue*/ false); 8089 if (!CombNextLB.isUsable()) 8090 return 0; 8091 // UB + ST 8092 CombNextUB = 8093 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, CombUB.get(), ST.get()); 8094 if (!CombNextUB.isUsable()) 8095 return 0; 8096 // UB = UB + ST 8097 CombNextUB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, CombUB.get(), 8098 CombNextUB.get()); 8099 CombNextUB = SemaRef.ActOnFinishFullExpr(CombNextUB.get(), 8100 /*DiscardedValue*/ false); 8101 if (!CombNextUB.isUsable()) 8102 return 0; 8103 } 8104 } 8105 8106 // Create increment expression for distribute loop when combined in a same 8107 // directive with for as IV = IV + ST; ensure upper bound expression based 8108 // on PrevUB instead of NumIterations - used to implement 'for' when found 8109 // in combination with 'distribute', like in 'distribute parallel for' 8110 SourceLocation DistIncLoc = AStmt->getBeginLoc(); 8111 ExprResult DistCond, DistInc, PrevEUB, ParForInDistCond; 8112 if (isOpenMPLoopBoundSharingDirective(DKind)) { 8113 DistCond = SemaRef.BuildBinOp( 8114 CurScope, CondLoc, UseStrictCompare ? BO_LT : BO_LE, IV.get(), BoundUB); 8115 assert(DistCond.isUsable() && "distribute cond expr was not built"); 8116 8117 DistInc = 8118 SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Add, IV.get(), ST.get()); 8119 assert(DistInc.isUsable() && "distribute inc expr was not built"); 8120 DistInc = SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Assign, IV.get(), 8121 DistInc.get()); 8122 DistInc = 8123 SemaRef.ActOnFinishFullExpr(DistInc.get(), /*DiscardedValue*/ false); 8124 assert(DistInc.isUsable() && "distribute inc expr was not built"); 8125 8126 // Build expression: UB = min(UB, prevUB) for #for in composite or combined 8127 // construct 8128 SourceLocation DistEUBLoc = AStmt->getBeginLoc(); 8129 ExprResult IsUBGreater = 8130 SemaRef.BuildBinOp(CurScope, DistEUBLoc, BO_GT, UB.get(), PrevUB.get()); 8131 ExprResult CondOp = SemaRef.ActOnConditionalOp( 8132 DistEUBLoc, DistEUBLoc, IsUBGreater.get(), PrevUB.get(), UB.get()); 8133 PrevEUB = SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Assign, UB.get(), 8134 CondOp.get()); 8135 PrevEUB = 8136 SemaRef.ActOnFinishFullExpr(PrevEUB.get(), /*DiscardedValue*/ false); 8137 8138 // Build IV <= PrevUB or IV < PrevUB + 1 for unsigned IV to be used in 8139 // parallel for is in combination with a distribute directive with 8140 // schedule(static, 1) 8141 Expr *BoundPrevUB = PrevUB.get(); 8142 if (UseStrictCompare) { 8143 BoundPrevUB = 8144 SemaRef 8145 .BuildBinOp( 8146 CurScope, CondLoc, BO_Add, BoundPrevUB, 8147 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()) 8148 .get(); 8149 BoundPrevUB = 8150 SemaRef.ActOnFinishFullExpr(BoundPrevUB, /*DiscardedValue*/ false) 8151 .get(); 8152 } 8153 ParForInDistCond = 8154 SemaRef.BuildBinOp(CurScope, CondLoc, UseStrictCompare ? BO_LT : BO_LE, 8155 IV.get(), BoundPrevUB); 8156 } 8157 8158 // Build updates and final values of the loop counters. 8159 bool HasErrors = false; 8160 Built.Counters.resize(NestedLoopCount); 8161 Built.Inits.resize(NestedLoopCount); 8162 Built.Updates.resize(NestedLoopCount); 8163 Built.Finals.resize(NestedLoopCount); 8164 Built.DependentCounters.resize(NestedLoopCount); 8165 Built.DependentInits.resize(NestedLoopCount); 8166 Built.FinalsConditions.resize(NestedLoopCount); 8167 { 8168 // We implement the following algorithm for obtaining the 8169 // original loop iteration variable values based on the 8170 // value of the collapsed loop iteration variable IV. 8171 // 8172 // Let n+1 be the number of collapsed loops in the nest. 8173 // Iteration variables (I0, I1, .... In) 8174 // Iteration counts (N0, N1, ... Nn) 8175 // 8176 // Acc = IV; 8177 // 8178 // To compute Ik for loop k, 0 <= k <= n, generate: 8179 // Prod = N(k+1) * N(k+2) * ... * Nn; 8180 // Ik = Acc / Prod; 8181 // Acc -= Ik * Prod; 8182 // 8183 ExprResult Acc = IV; 8184 for (unsigned int Cnt = 0; Cnt < NestedLoopCount; ++Cnt) { 8185 LoopIterationSpace &IS = IterSpaces[Cnt]; 8186 SourceLocation UpdLoc = IS.IncSrcRange.getBegin(); 8187 ExprResult Iter; 8188 8189 // Compute prod 8190 ExprResult Prod = 8191 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get(); 8192 for (unsigned int K = Cnt+1; K < NestedLoopCount; ++K) 8193 Prod = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Mul, Prod.get(), 8194 IterSpaces[K].NumIterations); 8195 8196 // Iter = Acc / Prod 8197 // If there is at least one more inner loop to avoid 8198 // multiplication by 1. 8199 if (Cnt + 1 < NestedLoopCount) 8200 Iter = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Div, 8201 Acc.get(), Prod.get()); 8202 else 8203 Iter = Acc; 8204 if (!Iter.isUsable()) { 8205 HasErrors = true; 8206 break; 8207 } 8208 8209 // Update Acc: 8210 // Acc -= Iter * Prod 8211 // Check if there is at least one more inner loop to avoid 8212 // multiplication by 1. 8213 if (Cnt + 1 < NestedLoopCount) 8214 Prod = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Mul, 8215 Iter.get(), Prod.get()); 8216 else 8217 Prod = Iter; 8218 Acc = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Sub, 8219 Acc.get(), Prod.get()); 8220 8221 // Build update: IS.CounterVar(Private) = IS.Start + Iter * IS.Step 8222 auto *VD = cast<VarDecl>(cast<DeclRefExpr>(IS.CounterVar)->getDecl()); 8223 DeclRefExpr *CounterVar = buildDeclRefExpr( 8224 SemaRef, VD, IS.CounterVar->getType(), IS.CounterVar->getExprLoc(), 8225 /*RefersToCapture=*/true); 8226 ExprResult Init = 8227 buildCounterInit(SemaRef, CurScope, UpdLoc, CounterVar, 8228 IS.CounterInit, IS.IsNonRectangularLB, Captures); 8229 if (!Init.isUsable()) { 8230 HasErrors = true; 8231 break; 8232 } 8233 ExprResult Update = buildCounterUpdate( 8234 SemaRef, CurScope, UpdLoc, CounterVar, IS.CounterInit, Iter, 8235 IS.CounterStep, IS.Subtract, IS.IsNonRectangularLB, &Captures); 8236 if (!Update.isUsable()) { 8237 HasErrors = true; 8238 break; 8239 } 8240 8241 // Build final: IS.CounterVar = IS.Start + IS.NumIters * IS.Step 8242 ExprResult Final = 8243 buildCounterUpdate(SemaRef, CurScope, UpdLoc, CounterVar, 8244 IS.CounterInit, IS.NumIterations, IS.CounterStep, 8245 IS.Subtract, IS.IsNonRectangularLB, &Captures); 8246 if (!Final.isUsable()) { 8247 HasErrors = true; 8248 break; 8249 } 8250 8251 if (!Update.isUsable() || !Final.isUsable()) { 8252 HasErrors = true; 8253 break; 8254 } 8255 // Save results 8256 Built.Counters[Cnt] = IS.CounterVar; 8257 Built.PrivateCounters[Cnt] = IS.PrivateCounterVar; 8258 Built.Inits[Cnt] = Init.get(); 8259 Built.Updates[Cnt] = Update.get(); 8260 Built.Finals[Cnt] = Final.get(); 8261 Built.DependentCounters[Cnt] = nullptr; 8262 Built.DependentInits[Cnt] = nullptr; 8263 Built.FinalsConditions[Cnt] = nullptr; 8264 if (IS.IsNonRectangularLB || IS.IsNonRectangularUB) { 8265 Built.DependentCounters[Cnt] = 8266 Built.Counters[NestedLoopCount - 1 - IS.LoopDependentIdx]; 8267 Built.DependentInits[Cnt] = 8268 Built.Inits[NestedLoopCount - 1 - IS.LoopDependentIdx]; 8269 Built.FinalsConditions[Cnt] = IS.FinalCondition; 8270 } 8271 } 8272 } 8273 8274 if (HasErrors) 8275 return 0; 8276 8277 // Save results 8278 Built.IterationVarRef = IV.get(); 8279 Built.LastIteration = LastIteration.get(); 8280 Built.NumIterations = NumIterations.get(); 8281 Built.CalcLastIteration = SemaRef 8282 .ActOnFinishFullExpr(CalcLastIteration.get(), 8283 /*DiscardedValue=*/false) 8284 .get(); 8285 Built.PreCond = PreCond.get(); 8286 Built.PreInits = buildPreInits(C, Captures); 8287 Built.Cond = Cond.get(); 8288 Built.Init = Init.get(); 8289 Built.Inc = Inc.get(); 8290 Built.LB = LB.get(); 8291 Built.UB = UB.get(); 8292 Built.IL = IL.get(); 8293 Built.ST = ST.get(); 8294 Built.EUB = EUB.get(); 8295 Built.NLB = NextLB.get(); 8296 Built.NUB = NextUB.get(); 8297 Built.PrevLB = PrevLB.get(); 8298 Built.PrevUB = PrevUB.get(); 8299 Built.DistInc = DistInc.get(); 8300 Built.PrevEUB = PrevEUB.get(); 8301 Built.DistCombinedFields.LB = CombLB.get(); 8302 Built.DistCombinedFields.UB = CombUB.get(); 8303 Built.DistCombinedFields.EUB = CombEUB.get(); 8304 Built.DistCombinedFields.Init = CombInit.get(); 8305 Built.DistCombinedFields.Cond = CombCond.get(); 8306 Built.DistCombinedFields.NLB = CombNextLB.get(); 8307 Built.DistCombinedFields.NUB = CombNextUB.get(); 8308 Built.DistCombinedFields.DistCond = CombDistCond.get(); 8309 Built.DistCombinedFields.ParForInDistCond = ParForInDistCond.get(); 8310 8311 return NestedLoopCount; 8312 } 8313 8314 static Expr *getCollapseNumberExpr(ArrayRef<OMPClause *> Clauses) { 8315 auto CollapseClauses = 8316 OMPExecutableDirective::getClausesOfKind<OMPCollapseClause>(Clauses); 8317 if (CollapseClauses.begin() != CollapseClauses.end()) 8318 return (*CollapseClauses.begin())->getNumForLoops(); 8319 return nullptr; 8320 } 8321 8322 static Expr *getOrderedNumberExpr(ArrayRef<OMPClause *> Clauses) { 8323 auto OrderedClauses = 8324 OMPExecutableDirective::getClausesOfKind<OMPOrderedClause>(Clauses); 8325 if (OrderedClauses.begin() != OrderedClauses.end()) 8326 return (*OrderedClauses.begin())->getNumForLoops(); 8327 return nullptr; 8328 } 8329 8330 static bool checkSimdlenSafelenSpecified(Sema &S, 8331 const ArrayRef<OMPClause *> Clauses) { 8332 const OMPSafelenClause *Safelen = nullptr; 8333 const OMPSimdlenClause *Simdlen = nullptr; 8334 8335 for (const OMPClause *Clause : Clauses) { 8336 if (Clause->getClauseKind() == OMPC_safelen) 8337 Safelen = cast<OMPSafelenClause>(Clause); 8338 else if (Clause->getClauseKind() == OMPC_simdlen) 8339 Simdlen = cast<OMPSimdlenClause>(Clause); 8340 if (Safelen && Simdlen) 8341 break; 8342 } 8343 8344 if (Simdlen && Safelen) { 8345 const Expr *SimdlenLength = Simdlen->getSimdlen(); 8346 const Expr *SafelenLength = Safelen->getSafelen(); 8347 if (SimdlenLength->isValueDependent() || SimdlenLength->isTypeDependent() || 8348 SimdlenLength->isInstantiationDependent() || 8349 SimdlenLength->containsUnexpandedParameterPack()) 8350 return false; 8351 if (SafelenLength->isValueDependent() || SafelenLength->isTypeDependent() || 8352 SafelenLength->isInstantiationDependent() || 8353 SafelenLength->containsUnexpandedParameterPack()) 8354 return false; 8355 Expr::EvalResult SimdlenResult, SafelenResult; 8356 SimdlenLength->EvaluateAsInt(SimdlenResult, S.Context); 8357 SafelenLength->EvaluateAsInt(SafelenResult, S.Context); 8358 llvm::APSInt SimdlenRes = SimdlenResult.Val.getInt(); 8359 llvm::APSInt SafelenRes = SafelenResult.Val.getInt(); 8360 // OpenMP 4.5 [2.8.1, simd Construct, Restrictions] 8361 // If both simdlen and safelen clauses are specified, the value of the 8362 // simdlen parameter must be less than or equal to the value of the safelen 8363 // parameter. 8364 if (SimdlenRes > SafelenRes) { 8365 S.Diag(SimdlenLength->getExprLoc(), 8366 diag::err_omp_wrong_simdlen_safelen_values) 8367 << SimdlenLength->getSourceRange() << SafelenLength->getSourceRange(); 8368 return true; 8369 } 8370 } 8371 return false; 8372 } 8373 8374 StmtResult 8375 Sema::ActOnOpenMPSimdDirective(ArrayRef<OMPClause *> Clauses, Stmt *AStmt, 8376 SourceLocation StartLoc, SourceLocation EndLoc, 8377 VarsWithInheritedDSAType &VarsWithImplicitDSA) { 8378 if (!AStmt) 8379 return StmtError(); 8380 8381 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 8382 OMPLoopDirective::HelperExprs B; 8383 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 8384 // define the nested loops number. 8385 unsigned NestedLoopCount = checkOpenMPLoop( 8386 OMPD_simd, getCollapseNumberExpr(Clauses), getOrderedNumberExpr(Clauses), 8387 AStmt, *this, *DSAStack, VarsWithImplicitDSA, B); 8388 if (NestedLoopCount == 0) 8389 return StmtError(); 8390 8391 assert((CurContext->isDependentContext() || B.builtAll()) && 8392 "omp simd loop exprs were not built"); 8393 8394 if (!CurContext->isDependentContext()) { 8395 // Finalize the clauses that need pre-built expressions for CodeGen. 8396 for (OMPClause *C : Clauses) { 8397 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 8398 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 8399 B.NumIterations, *this, CurScope, 8400 DSAStack)) 8401 return StmtError(); 8402 } 8403 } 8404 8405 if (checkSimdlenSafelenSpecified(*this, Clauses)) 8406 return StmtError(); 8407 8408 setFunctionHasBranchProtectedScope(); 8409 return OMPSimdDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount, 8410 Clauses, AStmt, B); 8411 } 8412 8413 StmtResult 8414 Sema::ActOnOpenMPForDirective(ArrayRef<OMPClause *> Clauses, Stmt *AStmt, 8415 SourceLocation StartLoc, SourceLocation EndLoc, 8416 VarsWithInheritedDSAType &VarsWithImplicitDSA) { 8417 if (!AStmt) 8418 return StmtError(); 8419 8420 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 8421 OMPLoopDirective::HelperExprs B; 8422 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 8423 // define the nested loops number. 8424 unsigned NestedLoopCount = checkOpenMPLoop( 8425 OMPD_for, getCollapseNumberExpr(Clauses), getOrderedNumberExpr(Clauses), 8426 AStmt, *this, *DSAStack, VarsWithImplicitDSA, B); 8427 if (NestedLoopCount == 0) 8428 return StmtError(); 8429 8430 assert((CurContext->isDependentContext() || B.builtAll()) && 8431 "omp for loop exprs were not built"); 8432 8433 if (!CurContext->isDependentContext()) { 8434 // Finalize the clauses that need pre-built expressions for CodeGen. 8435 for (OMPClause *C : Clauses) { 8436 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 8437 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 8438 B.NumIterations, *this, CurScope, 8439 DSAStack)) 8440 return StmtError(); 8441 } 8442 } 8443 8444 setFunctionHasBranchProtectedScope(); 8445 return OMPForDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount, 8446 Clauses, AStmt, B, DSAStack->isCancelRegion()); 8447 } 8448 8449 StmtResult Sema::ActOnOpenMPForSimdDirective( 8450 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 8451 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 8452 if (!AStmt) 8453 return StmtError(); 8454 8455 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 8456 OMPLoopDirective::HelperExprs B; 8457 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 8458 // define the nested loops number. 8459 unsigned NestedLoopCount = 8460 checkOpenMPLoop(OMPD_for_simd, getCollapseNumberExpr(Clauses), 8461 getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack, 8462 VarsWithImplicitDSA, B); 8463 if (NestedLoopCount == 0) 8464 return StmtError(); 8465 8466 assert((CurContext->isDependentContext() || B.builtAll()) && 8467 "omp for simd loop exprs were not built"); 8468 8469 if (!CurContext->isDependentContext()) { 8470 // Finalize the clauses that need pre-built expressions for CodeGen. 8471 for (OMPClause *C : Clauses) { 8472 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 8473 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 8474 B.NumIterations, *this, CurScope, 8475 DSAStack)) 8476 return StmtError(); 8477 } 8478 } 8479 8480 if (checkSimdlenSafelenSpecified(*this, Clauses)) 8481 return StmtError(); 8482 8483 setFunctionHasBranchProtectedScope(); 8484 return OMPForSimdDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount, 8485 Clauses, AStmt, B); 8486 } 8487 8488 StmtResult Sema::ActOnOpenMPSectionsDirective(ArrayRef<OMPClause *> Clauses, 8489 Stmt *AStmt, 8490 SourceLocation StartLoc, 8491 SourceLocation EndLoc) { 8492 if (!AStmt) 8493 return StmtError(); 8494 8495 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 8496 auto BaseStmt = AStmt; 8497 while (auto *CS = dyn_cast_or_null<CapturedStmt>(BaseStmt)) 8498 BaseStmt = CS->getCapturedStmt(); 8499 if (auto *C = dyn_cast_or_null<CompoundStmt>(BaseStmt)) { 8500 auto S = C->children(); 8501 if (S.begin() == S.end()) 8502 return StmtError(); 8503 // All associated statements must be '#pragma omp section' except for 8504 // the first one. 8505 for (Stmt *SectionStmt : llvm::make_range(std::next(S.begin()), S.end())) { 8506 if (!SectionStmt || !isa<OMPSectionDirective>(SectionStmt)) { 8507 if (SectionStmt) 8508 Diag(SectionStmt->getBeginLoc(), 8509 diag::err_omp_sections_substmt_not_section); 8510 return StmtError(); 8511 } 8512 cast<OMPSectionDirective>(SectionStmt) 8513 ->setHasCancel(DSAStack->isCancelRegion()); 8514 } 8515 } else { 8516 Diag(AStmt->getBeginLoc(), diag::err_omp_sections_not_compound_stmt); 8517 return StmtError(); 8518 } 8519 8520 setFunctionHasBranchProtectedScope(); 8521 8522 return OMPSectionsDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt, 8523 DSAStack->isCancelRegion()); 8524 } 8525 8526 StmtResult Sema::ActOnOpenMPSectionDirective(Stmt *AStmt, 8527 SourceLocation StartLoc, 8528 SourceLocation EndLoc) { 8529 if (!AStmt) 8530 return StmtError(); 8531 8532 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 8533 8534 setFunctionHasBranchProtectedScope(); 8535 DSAStack->setParentCancelRegion(DSAStack->isCancelRegion()); 8536 8537 return OMPSectionDirective::Create(Context, StartLoc, EndLoc, AStmt, 8538 DSAStack->isCancelRegion()); 8539 } 8540 8541 StmtResult Sema::ActOnOpenMPSingleDirective(ArrayRef<OMPClause *> Clauses, 8542 Stmt *AStmt, 8543 SourceLocation StartLoc, 8544 SourceLocation EndLoc) { 8545 if (!AStmt) 8546 return StmtError(); 8547 8548 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 8549 8550 setFunctionHasBranchProtectedScope(); 8551 8552 // OpenMP [2.7.3, single Construct, Restrictions] 8553 // The copyprivate clause must not be used with the nowait clause. 8554 const OMPClause *Nowait = nullptr; 8555 const OMPClause *Copyprivate = nullptr; 8556 for (const OMPClause *Clause : Clauses) { 8557 if (Clause->getClauseKind() == OMPC_nowait) 8558 Nowait = Clause; 8559 else if (Clause->getClauseKind() == OMPC_copyprivate) 8560 Copyprivate = Clause; 8561 if (Copyprivate && Nowait) { 8562 Diag(Copyprivate->getBeginLoc(), 8563 diag::err_omp_single_copyprivate_with_nowait); 8564 Diag(Nowait->getBeginLoc(), diag::note_omp_nowait_clause_here); 8565 return StmtError(); 8566 } 8567 } 8568 8569 return OMPSingleDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt); 8570 } 8571 8572 StmtResult Sema::ActOnOpenMPMasterDirective(Stmt *AStmt, 8573 SourceLocation StartLoc, 8574 SourceLocation EndLoc) { 8575 if (!AStmt) 8576 return StmtError(); 8577 8578 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 8579 8580 setFunctionHasBranchProtectedScope(); 8581 8582 return OMPMasterDirective::Create(Context, StartLoc, EndLoc, AStmt); 8583 } 8584 8585 StmtResult Sema::ActOnOpenMPCriticalDirective( 8586 const DeclarationNameInfo &DirName, ArrayRef<OMPClause *> Clauses, 8587 Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc) { 8588 if (!AStmt) 8589 return StmtError(); 8590 8591 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 8592 8593 bool ErrorFound = false; 8594 llvm::APSInt Hint; 8595 SourceLocation HintLoc; 8596 bool DependentHint = false; 8597 for (const OMPClause *C : Clauses) { 8598 if (C->getClauseKind() == OMPC_hint) { 8599 if (!DirName.getName()) { 8600 Diag(C->getBeginLoc(), diag::err_omp_hint_clause_no_name); 8601 ErrorFound = true; 8602 } 8603 Expr *E = cast<OMPHintClause>(C)->getHint(); 8604 if (E->isTypeDependent() || E->isValueDependent() || 8605 E->isInstantiationDependent()) { 8606 DependentHint = true; 8607 } else { 8608 Hint = E->EvaluateKnownConstInt(Context); 8609 HintLoc = C->getBeginLoc(); 8610 } 8611 } 8612 } 8613 if (ErrorFound) 8614 return StmtError(); 8615 const auto Pair = DSAStack->getCriticalWithHint(DirName); 8616 if (Pair.first && DirName.getName() && !DependentHint) { 8617 if (llvm::APSInt::compareValues(Hint, Pair.second) != 0) { 8618 Diag(StartLoc, diag::err_omp_critical_with_hint); 8619 if (HintLoc.isValid()) 8620 Diag(HintLoc, diag::note_omp_critical_hint_here) 8621 << 0 << Hint.toString(/*Radix=*/10, /*Signed=*/false); 8622 else 8623 Diag(StartLoc, diag::note_omp_critical_no_hint) << 0; 8624 if (const auto *C = Pair.first->getSingleClause<OMPHintClause>()) { 8625 Diag(C->getBeginLoc(), diag::note_omp_critical_hint_here) 8626 << 1 8627 << C->getHint()->EvaluateKnownConstInt(Context).toString( 8628 /*Radix=*/10, /*Signed=*/false); 8629 } else { 8630 Diag(Pair.first->getBeginLoc(), diag::note_omp_critical_no_hint) << 1; 8631 } 8632 } 8633 } 8634 8635 setFunctionHasBranchProtectedScope(); 8636 8637 auto *Dir = OMPCriticalDirective::Create(Context, DirName, StartLoc, EndLoc, 8638 Clauses, AStmt); 8639 if (!Pair.first && DirName.getName() && !DependentHint) 8640 DSAStack->addCriticalWithHint(Dir, Hint); 8641 return Dir; 8642 } 8643 8644 StmtResult Sema::ActOnOpenMPParallelForDirective( 8645 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 8646 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 8647 if (!AStmt) 8648 return StmtError(); 8649 8650 auto *CS = cast<CapturedStmt>(AStmt); 8651 // 1.2.2 OpenMP Language Terminology 8652 // Structured block - An executable statement with a single entry at the 8653 // top and a single exit at the bottom. 8654 // The point of exit cannot be a branch out of the structured block. 8655 // longjmp() and throw() must not violate the entry/exit criteria. 8656 CS->getCapturedDecl()->setNothrow(); 8657 8658 OMPLoopDirective::HelperExprs B; 8659 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 8660 // define the nested loops number. 8661 unsigned NestedLoopCount = 8662 checkOpenMPLoop(OMPD_parallel_for, getCollapseNumberExpr(Clauses), 8663 getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack, 8664 VarsWithImplicitDSA, B); 8665 if (NestedLoopCount == 0) 8666 return StmtError(); 8667 8668 assert((CurContext->isDependentContext() || B.builtAll()) && 8669 "omp parallel for loop exprs were not built"); 8670 8671 if (!CurContext->isDependentContext()) { 8672 // Finalize the clauses that need pre-built expressions for CodeGen. 8673 for (OMPClause *C : Clauses) { 8674 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 8675 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 8676 B.NumIterations, *this, CurScope, 8677 DSAStack)) 8678 return StmtError(); 8679 } 8680 } 8681 8682 setFunctionHasBranchProtectedScope(); 8683 return OMPParallelForDirective::Create(Context, StartLoc, EndLoc, 8684 NestedLoopCount, Clauses, AStmt, B, 8685 DSAStack->isCancelRegion()); 8686 } 8687 8688 StmtResult Sema::ActOnOpenMPParallelForSimdDirective( 8689 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 8690 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 8691 if (!AStmt) 8692 return StmtError(); 8693 8694 auto *CS = cast<CapturedStmt>(AStmt); 8695 // 1.2.2 OpenMP Language Terminology 8696 // Structured block - An executable statement with a single entry at the 8697 // top and a single exit at the bottom. 8698 // The point of exit cannot be a branch out of the structured block. 8699 // longjmp() and throw() must not violate the entry/exit criteria. 8700 CS->getCapturedDecl()->setNothrow(); 8701 8702 OMPLoopDirective::HelperExprs B; 8703 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 8704 // define the nested loops number. 8705 unsigned NestedLoopCount = 8706 checkOpenMPLoop(OMPD_parallel_for_simd, getCollapseNumberExpr(Clauses), 8707 getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack, 8708 VarsWithImplicitDSA, B); 8709 if (NestedLoopCount == 0) 8710 return StmtError(); 8711 8712 if (!CurContext->isDependentContext()) { 8713 // Finalize the clauses that need pre-built expressions for CodeGen. 8714 for (OMPClause *C : Clauses) { 8715 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 8716 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 8717 B.NumIterations, *this, CurScope, 8718 DSAStack)) 8719 return StmtError(); 8720 } 8721 } 8722 8723 if (checkSimdlenSafelenSpecified(*this, Clauses)) 8724 return StmtError(); 8725 8726 setFunctionHasBranchProtectedScope(); 8727 return OMPParallelForSimdDirective::Create( 8728 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 8729 } 8730 8731 StmtResult 8732 Sema::ActOnOpenMPParallelMasterDirective(ArrayRef<OMPClause *> Clauses, 8733 Stmt *AStmt, SourceLocation StartLoc, 8734 SourceLocation EndLoc) { 8735 if (!AStmt) 8736 return StmtError(); 8737 8738 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 8739 auto *CS = cast<CapturedStmt>(AStmt); 8740 // 1.2.2 OpenMP Language Terminology 8741 // Structured block - An executable statement with a single entry at the 8742 // top and a single exit at the bottom. 8743 // The point of exit cannot be a branch out of the structured block. 8744 // longjmp() and throw() must not violate the entry/exit criteria. 8745 CS->getCapturedDecl()->setNothrow(); 8746 8747 setFunctionHasBranchProtectedScope(); 8748 8749 return OMPParallelMasterDirective::Create(Context, StartLoc, EndLoc, Clauses, 8750 AStmt); 8751 } 8752 8753 StmtResult 8754 Sema::ActOnOpenMPParallelSectionsDirective(ArrayRef<OMPClause *> Clauses, 8755 Stmt *AStmt, SourceLocation StartLoc, 8756 SourceLocation EndLoc) { 8757 if (!AStmt) 8758 return StmtError(); 8759 8760 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 8761 auto BaseStmt = AStmt; 8762 while (auto *CS = dyn_cast_or_null<CapturedStmt>(BaseStmt)) 8763 BaseStmt = CS->getCapturedStmt(); 8764 if (auto *C = dyn_cast_or_null<CompoundStmt>(BaseStmt)) { 8765 auto S = C->children(); 8766 if (S.begin() == S.end()) 8767 return StmtError(); 8768 // All associated statements must be '#pragma omp section' except for 8769 // the first one. 8770 for (Stmt *SectionStmt : llvm::make_range(std::next(S.begin()), S.end())) { 8771 if (!SectionStmt || !isa<OMPSectionDirective>(SectionStmt)) { 8772 if (SectionStmt) 8773 Diag(SectionStmt->getBeginLoc(), 8774 diag::err_omp_parallel_sections_substmt_not_section); 8775 return StmtError(); 8776 } 8777 cast<OMPSectionDirective>(SectionStmt) 8778 ->setHasCancel(DSAStack->isCancelRegion()); 8779 } 8780 } else { 8781 Diag(AStmt->getBeginLoc(), 8782 diag::err_omp_parallel_sections_not_compound_stmt); 8783 return StmtError(); 8784 } 8785 8786 setFunctionHasBranchProtectedScope(); 8787 8788 return OMPParallelSectionsDirective::Create( 8789 Context, StartLoc, EndLoc, Clauses, AStmt, DSAStack->isCancelRegion()); 8790 } 8791 8792 /// detach and mergeable clauses are mutially exclusive, check for it. 8793 static bool checkDetachMergeableClauses(Sema &S, 8794 ArrayRef<OMPClause *> Clauses) { 8795 const OMPClause *PrevClause = nullptr; 8796 bool ErrorFound = false; 8797 for (const OMPClause *C : Clauses) { 8798 if (C->getClauseKind() == OMPC_detach || 8799 C->getClauseKind() == OMPC_mergeable) { 8800 if (!PrevClause) { 8801 PrevClause = C; 8802 } else if (PrevClause->getClauseKind() != C->getClauseKind()) { 8803 S.Diag(C->getBeginLoc(), diag::err_omp_clauses_mutually_exclusive) 8804 << getOpenMPClauseName(C->getClauseKind()) 8805 << getOpenMPClauseName(PrevClause->getClauseKind()); 8806 S.Diag(PrevClause->getBeginLoc(), diag::note_omp_previous_clause) 8807 << getOpenMPClauseName(PrevClause->getClauseKind()); 8808 ErrorFound = true; 8809 } 8810 } 8811 } 8812 return ErrorFound; 8813 } 8814 8815 StmtResult Sema::ActOnOpenMPTaskDirective(ArrayRef<OMPClause *> Clauses, 8816 Stmt *AStmt, SourceLocation StartLoc, 8817 SourceLocation EndLoc) { 8818 if (!AStmt) 8819 return StmtError(); 8820 8821 // OpenMP 5.0, 2.10.1 task Construct 8822 // If a detach clause appears on the directive, then a mergeable clause cannot 8823 // appear on the same directive. 8824 if (checkDetachMergeableClauses(*this, Clauses)) 8825 return StmtError(); 8826 8827 auto *CS = cast<CapturedStmt>(AStmt); 8828 // 1.2.2 OpenMP Language Terminology 8829 // Structured block - An executable statement with a single entry at the 8830 // top and a single exit at the bottom. 8831 // The point of exit cannot be a branch out of the structured block. 8832 // longjmp() and throw() must not violate the entry/exit criteria. 8833 CS->getCapturedDecl()->setNothrow(); 8834 8835 setFunctionHasBranchProtectedScope(); 8836 8837 return OMPTaskDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt, 8838 DSAStack->isCancelRegion()); 8839 } 8840 8841 StmtResult Sema::ActOnOpenMPTaskyieldDirective(SourceLocation StartLoc, 8842 SourceLocation EndLoc) { 8843 return OMPTaskyieldDirective::Create(Context, StartLoc, EndLoc); 8844 } 8845 8846 StmtResult Sema::ActOnOpenMPBarrierDirective(SourceLocation StartLoc, 8847 SourceLocation EndLoc) { 8848 return OMPBarrierDirective::Create(Context, StartLoc, EndLoc); 8849 } 8850 8851 StmtResult Sema::ActOnOpenMPTaskwaitDirective(SourceLocation StartLoc, 8852 SourceLocation EndLoc) { 8853 return OMPTaskwaitDirective::Create(Context, StartLoc, EndLoc); 8854 } 8855 8856 StmtResult Sema::ActOnOpenMPTaskgroupDirective(ArrayRef<OMPClause *> Clauses, 8857 Stmt *AStmt, 8858 SourceLocation StartLoc, 8859 SourceLocation EndLoc) { 8860 if (!AStmt) 8861 return StmtError(); 8862 8863 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 8864 8865 setFunctionHasBranchProtectedScope(); 8866 8867 return OMPTaskgroupDirective::Create(Context, StartLoc, EndLoc, Clauses, 8868 AStmt, 8869 DSAStack->getTaskgroupReductionRef()); 8870 } 8871 8872 StmtResult Sema::ActOnOpenMPFlushDirective(ArrayRef<OMPClause *> Clauses, 8873 SourceLocation StartLoc, 8874 SourceLocation EndLoc) { 8875 OMPFlushClause *FC = nullptr; 8876 OMPClause *OrderClause = nullptr; 8877 for (OMPClause *C : Clauses) { 8878 if (C->getClauseKind() == OMPC_flush) 8879 FC = cast<OMPFlushClause>(C); 8880 else 8881 OrderClause = C; 8882 } 8883 OpenMPClauseKind MemOrderKind = OMPC_unknown; 8884 SourceLocation MemOrderLoc; 8885 for (const OMPClause *C : Clauses) { 8886 if (C->getClauseKind() == OMPC_acq_rel || 8887 C->getClauseKind() == OMPC_acquire || 8888 C->getClauseKind() == OMPC_release) { 8889 if (MemOrderKind != OMPC_unknown) { 8890 Diag(C->getBeginLoc(), diag::err_omp_several_mem_order_clauses) 8891 << getOpenMPDirectiveName(OMPD_flush) << 1 8892 << SourceRange(C->getBeginLoc(), C->getEndLoc()); 8893 Diag(MemOrderLoc, diag::note_omp_previous_mem_order_clause) 8894 << getOpenMPClauseName(MemOrderKind); 8895 } else { 8896 MemOrderKind = C->getClauseKind(); 8897 MemOrderLoc = C->getBeginLoc(); 8898 } 8899 } 8900 } 8901 if (FC && OrderClause) { 8902 Diag(FC->getLParenLoc(), diag::err_omp_flush_order_clause_and_list) 8903 << getOpenMPClauseName(OrderClause->getClauseKind()); 8904 Diag(OrderClause->getBeginLoc(), diag::note_omp_flush_order_clause_here) 8905 << getOpenMPClauseName(OrderClause->getClauseKind()); 8906 return StmtError(); 8907 } 8908 return OMPFlushDirective::Create(Context, StartLoc, EndLoc, Clauses); 8909 } 8910 8911 StmtResult Sema::ActOnOpenMPDepobjDirective(ArrayRef<OMPClause *> Clauses, 8912 SourceLocation StartLoc, 8913 SourceLocation EndLoc) { 8914 if (Clauses.empty()) { 8915 Diag(StartLoc, diag::err_omp_depobj_expected); 8916 return StmtError(); 8917 } else if (Clauses[0]->getClauseKind() != OMPC_depobj) { 8918 Diag(Clauses[0]->getBeginLoc(), diag::err_omp_depobj_expected); 8919 return StmtError(); 8920 } 8921 // Only depobj expression and another single clause is allowed. 8922 if (Clauses.size() > 2) { 8923 Diag(Clauses[2]->getBeginLoc(), 8924 diag::err_omp_depobj_single_clause_expected); 8925 return StmtError(); 8926 } else if (Clauses.size() < 1) { 8927 Diag(Clauses[0]->getEndLoc(), diag::err_omp_depobj_single_clause_expected); 8928 return StmtError(); 8929 } 8930 return OMPDepobjDirective::Create(Context, StartLoc, EndLoc, Clauses); 8931 } 8932 8933 StmtResult Sema::ActOnOpenMPScanDirective(ArrayRef<OMPClause *> Clauses, 8934 SourceLocation StartLoc, 8935 SourceLocation EndLoc) { 8936 // Check that exactly one clause is specified. 8937 if (Clauses.size() != 1) { 8938 Diag(Clauses.empty() ? EndLoc : Clauses[1]->getBeginLoc(), 8939 diag::err_omp_scan_single_clause_expected); 8940 return StmtError(); 8941 } 8942 // Check that only one instance of scan directives is used in the same outer 8943 // region. 8944 if (DSAStack->doesParentHasScanDirective()) { 8945 Diag(StartLoc, diag::err_omp_several_scan_directives_in_region); 8946 Diag(DSAStack->getParentScanDirectiveLoc(), 8947 diag::note_omp_previous_scan_directive); 8948 return StmtError(); 8949 } 8950 DSAStack->setParentHasScanDirective(StartLoc); 8951 return OMPScanDirective::Create(Context, StartLoc, EndLoc, Clauses); 8952 } 8953 8954 StmtResult Sema::ActOnOpenMPOrderedDirective(ArrayRef<OMPClause *> Clauses, 8955 Stmt *AStmt, 8956 SourceLocation StartLoc, 8957 SourceLocation EndLoc) { 8958 const OMPClause *DependFound = nullptr; 8959 const OMPClause *DependSourceClause = nullptr; 8960 const OMPClause *DependSinkClause = nullptr; 8961 bool ErrorFound = false; 8962 const OMPThreadsClause *TC = nullptr; 8963 const OMPSIMDClause *SC = nullptr; 8964 for (const OMPClause *C : Clauses) { 8965 if (auto *DC = dyn_cast<OMPDependClause>(C)) { 8966 DependFound = C; 8967 if (DC->getDependencyKind() == OMPC_DEPEND_source) { 8968 if (DependSourceClause) { 8969 Diag(C->getBeginLoc(), diag::err_omp_more_one_clause) 8970 << getOpenMPDirectiveName(OMPD_ordered) 8971 << getOpenMPClauseName(OMPC_depend) << 2; 8972 ErrorFound = true; 8973 } else { 8974 DependSourceClause = C; 8975 } 8976 if (DependSinkClause) { 8977 Diag(C->getBeginLoc(), diag::err_omp_depend_sink_source_not_allowed) 8978 << 0; 8979 ErrorFound = true; 8980 } 8981 } else if (DC->getDependencyKind() == OMPC_DEPEND_sink) { 8982 if (DependSourceClause) { 8983 Diag(C->getBeginLoc(), diag::err_omp_depend_sink_source_not_allowed) 8984 << 1; 8985 ErrorFound = true; 8986 } 8987 DependSinkClause = C; 8988 } 8989 } else if (C->getClauseKind() == OMPC_threads) { 8990 TC = cast<OMPThreadsClause>(C); 8991 } else if (C->getClauseKind() == OMPC_simd) { 8992 SC = cast<OMPSIMDClause>(C); 8993 } 8994 } 8995 if (!ErrorFound && !SC && 8996 isOpenMPSimdDirective(DSAStack->getParentDirective())) { 8997 // OpenMP [2.8.1,simd Construct, Restrictions] 8998 // An ordered construct with the simd clause is the only OpenMP construct 8999 // that can appear in the simd region. 9000 Diag(StartLoc, diag::err_omp_prohibited_region_simd) 9001 << (LangOpts.OpenMP >= 50 ? 1 : 0); 9002 ErrorFound = true; 9003 } else if (DependFound && (TC || SC)) { 9004 Diag(DependFound->getBeginLoc(), diag::err_omp_depend_clause_thread_simd) 9005 << getOpenMPClauseName(TC ? TC->getClauseKind() : SC->getClauseKind()); 9006 ErrorFound = true; 9007 } else if (DependFound && !DSAStack->getParentOrderedRegionParam().first) { 9008 Diag(DependFound->getBeginLoc(), 9009 diag::err_omp_ordered_directive_without_param); 9010 ErrorFound = true; 9011 } else if (TC || Clauses.empty()) { 9012 if (const Expr *Param = DSAStack->getParentOrderedRegionParam().first) { 9013 SourceLocation ErrLoc = TC ? TC->getBeginLoc() : StartLoc; 9014 Diag(ErrLoc, diag::err_omp_ordered_directive_with_param) 9015 << (TC != nullptr); 9016 Diag(Param->getBeginLoc(), diag::note_omp_ordered_param) << 1; 9017 ErrorFound = true; 9018 } 9019 } 9020 if ((!AStmt && !DependFound) || ErrorFound) 9021 return StmtError(); 9022 9023 if (AStmt) { 9024 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 9025 9026 setFunctionHasBranchProtectedScope(); 9027 } 9028 9029 return OMPOrderedDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt); 9030 } 9031 9032 namespace { 9033 /// Helper class for checking expression in 'omp atomic [update]' 9034 /// construct. 9035 class OpenMPAtomicUpdateChecker { 9036 /// Error results for atomic update expressions. 9037 enum ExprAnalysisErrorCode { 9038 /// A statement is not an expression statement. 9039 NotAnExpression, 9040 /// Expression is not builtin binary or unary operation. 9041 NotABinaryOrUnaryExpression, 9042 /// Unary operation is not post-/pre- increment/decrement operation. 9043 NotAnUnaryIncDecExpression, 9044 /// An expression is not of scalar type. 9045 NotAScalarType, 9046 /// A binary operation is not an assignment operation. 9047 NotAnAssignmentOp, 9048 /// RHS part of the binary operation is not a binary expression. 9049 NotABinaryExpression, 9050 /// RHS part is not additive/multiplicative/shift/biwise binary 9051 /// expression. 9052 NotABinaryOperator, 9053 /// RHS binary operation does not have reference to the updated LHS 9054 /// part. 9055 NotAnUpdateExpression, 9056 /// No errors is found. 9057 NoError 9058 }; 9059 /// Reference to Sema. 9060 Sema &SemaRef; 9061 /// A location for note diagnostics (when error is found). 9062 SourceLocation NoteLoc; 9063 /// 'x' lvalue part of the source atomic expression. 9064 Expr *X; 9065 /// 'expr' rvalue part of the source atomic expression. 9066 Expr *E; 9067 /// Helper expression of the form 9068 /// 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or 9069 /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'. 9070 Expr *UpdateExpr; 9071 /// Is 'x' a LHS in a RHS part of full update expression. It is 9072 /// important for non-associative operations. 9073 bool IsXLHSInRHSPart; 9074 BinaryOperatorKind Op; 9075 SourceLocation OpLoc; 9076 /// true if the source expression is a postfix unary operation, false 9077 /// if it is a prefix unary operation. 9078 bool IsPostfixUpdate; 9079 9080 public: 9081 OpenMPAtomicUpdateChecker(Sema &SemaRef) 9082 : SemaRef(SemaRef), X(nullptr), E(nullptr), UpdateExpr(nullptr), 9083 IsXLHSInRHSPart(false), Op(BO_PtrMemD), IsPostfixUpdate(false) {} 9084 /// Check specified statement that it is suitable for 'atomic update' 9085 /// constructs and extract 'x', 'expr' and Operation from the original 9086 /// expression. If DiagId and NoteId == 0, then only check is performed 9087 /// without error notification. 9088 /// \param DiagId Diagnostic which should be emitted if error is found. 9089 /// \param NoteId Diagnostic note for the main error message. 9090 /// \return true if statement is not an update expression, false otherwise. 9091 bool checkStatement(Stmt *S, unsigned DiagId = 0, unsigned NoteId = 0); 9092 /// Return the 'x' lvalue part of the source atomic expression. 9093 Expr *getX() const { return X; } 9094 /// Return the 'expr' rvalue part of the source atomic expression. 9095 Expr *getExpr() const { return E; } 9096 /// Return the update expression used in calculation of the updated 9097 /// value. Always has form 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or 9098 /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'. 9099 Expr *getUpdateExpr() const { return UpdateExpr; } 9100 /// Return true if 'x' is LHS in RHS part of full update expression, 9101 /// false otherwise. 9102 bool isXLHSInRHSPart() const { return IsXLHSInRHSPart; } 9103 9104 /// true if the source expression is a postfix unary operation, false 9105 /// if it is a prefix unary operation. 9106 bool isPostfixUpdate() const { return IsPostfixUpdate; } 9107 9108 private: 9109 bool checkBinaryOperation(BinaryOperator *AtomicBinOp, unsigned DiagId = 0, 9110 unsigned NoteId = 0); 9111 }; 9112 } // namespace 9113 9114 bool OpenMPAtomicUpdateChecker::checkBinaryOperation( 9115 BinaryOperator *AtomicBinOp, unsigned DiagId, unsigned NoteId) { 9116 ExprAnalysisErrorCode ErrorFound = NoError; 9117 SourceLocation ErrorLoc, NoteLoc; 9118 SourceRange ErrorRange, NoteRange; 9119 // Allowed constructs are: 9120 // x = x binop expr; 9121 // x = expr binop x; 9122 if (AtomicBinOp->getOpcode() == BO_Assign) { 9123 X = AtomicBinOp->getLHS(); 9124 if (const auto *AtomicInnerBinOp = dyn_cast<BinaryOperator>( 9125 AtomicBinOp->getRHS()->IgnoreParenImpCasts())) { 9126 if (AtomicInnerBinOp->isMultiplicativeOp() || 9127 AtomicInnerBinOp->isAdditiveOp() || AtomicInnerBinOp->isShiftOp() || 9128 AtomicInnerBinOp->isBitwiseOp()) { 9129 Op = AtomicInnerBinOp->getOpcode(); 9130 OpLoc = AtomicInnerBinOp->getOperatorLoc(); 9131 Expr *LHS = AtomicInnerBinOp->getLHS(); 9132 Expr *RHS = AtomicInnerBinOp->getRHS(); 9133 llvm::FoldingSetNodeID XId, LHSId, RHSId; 9134 X->IgnoreParenImpCasts()->Profile(XId, SemaRef.getASTContext(), 9135 /*Canonical=*/true); 9136 LHS->IgnoreParenImpCasts()->Profile(LHSId, SemaRef.getASTContext(), 9137 /*Canonical=*/true); 9138 RHS->IgnoreParenImpCasts()->Profile(RHSId, SemaRef.getASTContext(), 9139 /*Canonical=*/true); 9140 if (XId == LHSId) { 9141 E = RHS; 9142 IsXLHSInRHSPart = true; 9143 } else if (XId == RHSId) { 9144 E = LHS; 9145 IsXLHSInRHSPart = false; 9146 } else { 9147 ErrorLoc = AtomicInnerBinOp->getExprLoc(); 9148 ErrorRange = AtomicInnerBinOp->getSourceRange(); 9149 NoteLoc = X->getExprLoc(); 9150 NoteRange = X->getSourceRange(); 9151 ErrorFound = NotAnUpdateExpression; 9152 } 9153 } else { 9154 ErrorLoc = AtomicInnerBinOp->getExprLoc(); 9155 ErrorRange = AtomicInnerBinOp->getSourceRange(); 9156 NoteLoc = AtomicInnerBinOp->getOperatorLoc(); 9157 NoteRange = SourceRange(NoteLoc, NoteLoc); 9158 ErrorFound = NotABinaryOperator; 9159 } 9160 } else { 9161 NoteLoc = ErrorLoc = AtomicBinOp->getRHS()->getExprLoc(); 9162 NoteRange = ErrorRange = AtomicBinOp->getRHS()->getSourceRange(); 9163 ErrorFound = NotABinaryExpression; 9164 } 9165 } else { 9166 ErrorLoc = AtomicBinOp->getExprLoc(); 9167 ErrorRange = AtomicBinOp->getSourceRange(); 9168 NoteLoc = AtomicBinOp->getOperatorLoc(); 9169 NoteRange = SourceRange(NoteLoc, NoteLoc); 9170 ErrorFound = NotAnAssignmentOp; 9171 } 9172 if (ErrorFound != NoError && DiagId != 0 && NoteId != 0) { 9173 SemaRef.Diag(ErrorLoc, DiagId) << ErrorRange; 9174 SemaRef.Diag(NoteLoc, NoteId) << ErrorFound << NoteRange; 9175 return true; 9176 } 9177 if (SemaRef.CurContext->isDependentContext()) 9178 E = X = UpdateExpr = nullptr; 9179 return ErrorFound != NoError; 9180 } 9181 9182 bool OpenMPAtomicUpdateChecker::checkStatement(Stmt *S, unsigned DiagId, 9183 unsigned NoteId) { 9184 ExprAnalysisErrorCode ErrorFound = NoError; 9185 SourceLocation ErrorLoc, NoteLoc; 9186 SourceRange ErrorRange, NoteRange; 9187 // Allowed constructs are: 9188 // x++; 9189 // x--; 9190 // ++x; 9191 // --x; 9192 // x binop= expr; 9193 // x = x binop expr; 9194 // x = expr binop x; 9195 if (auto *AtomicBody = dyn_cast<Expr>(S)) { 9196 AtomicBody = AtomicBody->IgnoreParenImpCasts(); 9197 if (AtomicBody->getType()->isScalarType() || 9198 AtomicBody->isInstantiationDependent()) { 9199 if (const auto *AtomicCompAssignOp = dyn_cast<CompoundAssignOperator>( 9200 AtomicBody->IgnoreParenImpCasts())) { 9201 // Check for Compound Assignment Operation 9202 Op = BinaryOperator::getOpForCompoundAssignment( 9203 AtomicCompAssignOp->getOpcode()); 9204 OpLoc = AtomicCompAssignOp->getOperatorLoc(); 9205 E = AtomicCompAssignOp->getRHS(); 9206 X = AtomicCompAssignOp->getLHS()->IgnoreParens(); 9207 IsXLHSInRHSPart = true; 9208 } else if (auto *AtomicBinOp = dyn_cast<BinaryOperator>( 9209 AtomicBody->IgnoreParenImpCasts())) { 9210 // Check for Binary Operation 9211 if (checkBinaryOperation(AtomicBinOp, DiagId, NoteId)) 9212 return true; 9213 } else if (const auto *AtomicUnaryOp = dyn_cast<UnaryOperator>( 9214 AtomicBody->IgnoreParenImpCasts())) { 9215 // Check for Unary Operation 9216 if (AtomicUnaryOp->isIncrementDecrementOp()) { 9217 IsPostfixUpdate = AtomicUnaryOp->isPostfix(); 9218 Op = AtomicUnaryOp->isIncrementOp() ? BO_Add : BO_Sub; 9219 OpLoc = AtomicUnaryOp->getOperatorLoc(); 9220 X = AtomicUnaryOp->getSubExpr()->IgnoreParens(); 9221 E = SemaRef.ActOnIntegerConstant(OpLoc, /*uint64_t Val=*/1).get(); 9222 IsXLHSInRHSPart = true; 9223 } else { 9224 ErrorFound = NotAnUnaryIncDecExpression; 9225 ErrorLoc = AtomicUnaryOp->getExprLoc(); 9226 ErrorRange = AtomicUnaryOp->getSourceRange(); 9227 NoteLoc = AtomicUnaryOp->getOperatorLoc(); 9228 NoteRange = SourceRange(NoteLoc, NoteLoc); 9229 } 9230 } else if (!AtomicBody->isInstantiationDependent()) { 9231 ErrorFound = NotABinaryOrUnaryExpression; 9232 NoteLoc = ErrorLoc = AtomicBody->getExprLoc(); 9233 NoteRange = ErrorRange = AtomicBody->getSourceRange(); 9234 } 9235 } else { 9236 ErrorFound = NotAScalarType; 9237 NoteLoc = ErrorLoc = AtomicBody->getBeginLoc(); 9238 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc); 9239 } 9240 } else { 9241 ErrorFound = NotAnExpression; 9242 NoteLoc = ErrorLoc = S->getBeginLoc(); 9243 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc); 9244 } 9245 if (ErrorFound != NoError && DiagId != 0 && NoteId != 0) { 9246 SemaRef.Diag(ErrorLoc, DiagId) << ErrorRange; 9247 SemaRef.Diag(NoteLoc, NoteId) << ErrorFound << NoteRange; 9248 return true; 9249 } 9250 if (SemaRef.CurContext->isDependentContext()) 9251 E = X = UpdateExpr = nullptr; 9252 if (ErrorFound == NoError && E && X) { 9253 // Build an update expression of form 'OpaqueValueExpr(x) binop 9254 // OpaqueValueExpr(expr)' or 'OpaqueValueExpr(expr) binop 9255 // OpaqueValueExpr(x)' and then cast it to the type of the 'x' expression. 9256 auto *OVEX = new (SemaRef.getASTContext()) 9257 OpaqueValueExpr(X->getExprLoc(), X->getType(), VK_RValue); 9258 auto *OVEExpr = new (SemaRef.getASTContext()) 9259 OpaqueValueExpr(E->getExprLoc(), E->getType(), VK_RValue); 9260 ExprResult Update = 9261 SemaRef.CreateBuiltinBinOp(OpLoc, Op, IsXLHSInRHSPart ? OVEX : OVEExpr, 9262 IsXLHSInRHSPart ? OVEExpr : OVEX); 9263 if (Update.isInvalid()) 9264 return true; 9265 Update = SemaRef.PerformImplicitConversion(Update.get(), X->getType(), 9266 Sema::AA_Casting); 9267 if (Update.isInvalid()) 9268 return true; 9269 UpdateExpr = Update.get(); 9270 } 9271 return ErrorFound != NoError; 9272 } 9273 9274 StmtResult Sema::ActOnOpenMPAtomicDirective(ArrayRef<OMPClause *> Clauses, 9275 Stmt *AStmt, 9276 SourceLocation StartLoc, 9277 SourceLocation EndLoc) { 9278 // Register location of the first atomic directive. 9279 DSAStack->addAtomicDirectiveLoc(StartLoc); 9280 if (!AStmt) 9281 return StmtError(); 9282 9283 auto *CS = cast<CapturedStmt>(AStmt); 9284 // 1.2.2 OpenMP Language Terminology 9285 // Structured block - An executable statement with a single entry at the 9286 // top and a single exit at the bottom. 9287 // The point of exit cannot be a branch out of the structured block. 9288 // longjmp() and throw() must not violate the entry/exit criteria. 9289 OpenMPClauseKind AtomicKind = OMPC_unknown; 9290 SourceLocation AtomicKindLoc; 9291 OpenMPClauseKind MemOrderKind = OMPC_unknown; 9292 SourceLocation MemOrderLoc; 9293 for (const OMPClause *C : Clauses) { 9294 if (C->getClauseKind() == OMPC_read || C->getClauseKind() == OMPC_write || 9295 C->getClauseKind() == OMPC_update || 9296 C->getClauseKind() == OMPC_capture) { 9297 if (AtomicKind != OMPC_unknown) { 9298 Diag(C->getBeginLoc(), diag::err_omp_atomic_several_clauses) 9299 << SourceRange(C->getBeginLoc(), C->getEndLoc()); 9300 Diag(AtomicKindLoc, diag::note_omp_previous_mem_order_clause) 9301 << getOpenMPClauseName(AtomicKind); 9302 } else { 9303 AtomicKind = C->getClauseKind(); 9304 AtomicKindLoc = C->getBeginLoc(); 9305 } 9306 } 9307 if (C->getClauseKind() == OMPC_seq_cst || 9308 C->getClauseKind() == OMPC_acq_rel || 9309 C->getClauseKind() == OMPC_acquire || 9310 C->getClauseKind() == OMPC_release || 9311 C->getClauseKind() == OMPC_relaxed) { 9312 if (MemOrderKind != OMPC_unknown) { 9313 Diag(C->getBeginLoc(), diag::err_omp_several_mem_order_clauses) 9314 << getOpenMPDirectiveName(OMPD_atomic) << 0 9315 << SourceRange(C->getBeginLoc(), C->getEndLoc()); 9316 Diag(MemOrderLoc, diag::note_omp_previous_mem_order_clause) 9317 << getOpenMPClauseName(MemOrderKind); 9318 } else { 9319 MemOrderKind = C->getClauseKind(); 9320 MemOrderLoc = C->getBeginLoc(); 9321 } 9322 } 9323 } 9324 // OpenMP 5.0, 2.17.7 atomic Construct, Restrictions 9325 // If atomic-clause is read then memory-order-clause must not be acq_rel or 9326 // release. 9327 // If atomic-clause is write then memory-order-clause must not be acq_rel or 9328 // acquire. 9329 // If atomic-clause is update or not present then memory-order-clause must not 9330 // be acq_rel or acquire. 9331 if ((AtomicKind == OMPC_read && 9332 (MemOrderKind == OMPC_acq_rel || MemOrderKind == OMPC_release)) || 9333 ((AtomicKind == OMPC_write || AtomicKind == OMPC_update || 9334 AtomicKind == OMPC_unknown) && 9335 (MemOrderKind == OMPC_acq_rel || MemOrderKind == OMPC_acquire))) { 9336 SourceLocation Loc = AtomicKindLoc; 9337 if (AtomicKind == OMPC_unknown) 9338 Loc = StartLoc; 9339 Diag(Loc, diag::err_omp_atomic_incompatible_mem_order_clause) 9340 << getOpenMPClauseName(AtomicKind) 9341 << (AtomicKind == OMPC_unknown ? 1 : 0) 9342 << getOpenMPClauseName(MemOrderKind); 9343 Diag(MemOrderLoc, diag::note_omp_previous_mem_order_clause) 9344 << getOpenMPClauseName(MemOrderKind); 9345 } 9346 9347 Stmt *Body = CS->getCapturedStmt(); 9348 if (auto *EWC = dyn_cast<ExprWithCleanups>(Body)) 9349 Body = EWC->getSubExpr(); 9350 9351 Expr *X = nullptr; 9352 Expr *V = nullptr; 9353 Expr *E = nullptr; 9354 Expr *UE = nullptr; 9355 bool IsXLHSInRHSPart = false; 9356 bool IsPostfixUpdate = false; 9357 // OpenMP [2.12.6, atomic Construct] 9358 // In the next expressions: 9359 // * x and v (as applicable) are both l-value expressions with scalar type. 9360 // * During the execution of an atomic region, multiple syntactic 9361 // occurrences of x must designate the same storage location. 9362 // * Neither of v and expr (as applicable) may access the storage location 9363 // designated by x. 9364 // * Neither of x and expr (as applicable) may access the storage location 9365 // designated by v. 9366 // * expr is an expression with scalar type. 9367 // * binop is one of +, *, -, /, &, ^, |, <<, or >>. 9368 // * binop, binop=, ++, and -- are not overloaded operators. 9369 // * The expression x binop expr must be numerically equivalent to x binop 9370 // (expr). This requirement is satisfied if the operators in expr have 9371 // precedence greater than binop, or by using parentheses around expr or 9372 // subexpressions of expr. 9373 // * The expression expr binop x must be numerically equivalent to (expr) 9374 // binop x. This requirement is satisfied if the operators in expr have 9375 // precedence equal to or greater than binop, or by using parentheses around 9376 // expr or subexpressions of expr. 9377 // * For forms that allow multiple occurrences of x, the number of times 9378 // that x is evaluated is unspecified. 9379 if (AtomicKind == OMPC_read) { 9380 enum { 9381 NotAnExpression, 9382 NotAnAssignmentOp, 9383 NotAScalarType, 9384 NotAnLValue, 9385 NoError 9386 } ErrorFound = NoError; 9387 SourceLocation ErrorLoc, NoteLoc; 9388 SourceRange ErrorRange, NoteRange; 9389 // If clause is read: 9390 // v = x; 9391 if (const auto *AtomicBody = dyn_cast<Expr>(Body)) { 9392 const auto *AtomicBinOp = 9393 dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts()); 9394 if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) { 9395 X = AtomicBinOp->getRHS()->IgnoreParenImpCasts(); 9396 V = AtomicBinOp->getLHS()->IgnoreParenImpCasts(); 9397 if ((X->isInstantiationDependent() || X->getType()->isScalarType()) && 9398 (V->isInstantiationDependent() || V->getType()->isScalarType())) { 9399 if (!X->isLValue() || !V->isLValue()) { 9400 const Expr *NotLValueExpr = X->isLValue() ? V : X; 9401 ErrorFound = NotAnLValue; 9402 ErrorLoc = AtomicBinOp->getExprLoc(); 9403 ErrorRange = AtomicBinOp->getSourceRange(); 9404 NoteLoc = NotLValueExpr->getExprLoc(); 9405 NoteRange = NotLValueExpr->getSourceRange(); 9406 } 9407 } else if (!X->isInstantiationDependent() || 9408 !V->isInstantiationDependent()) { 9409 const Expr *NotScalarExpr = 9410 (X->isInstantiationDependent() || X->getType()->isScalarType()) 9411 ? V 9412 : X; 9413 ErrorFound = NotAScalarType; 9414 ErrorLoc = AtomicBinOp->getExprLoc(); 9415 ErrorRange = AtomicBinOp->getSourceRange(); 9416 NoteLoc = NotScalarExpr->getExprLoc(); 9417 NoteRange = NotScalarExpr->getSourceRange(); 9418 } 9419 } else if (!AtomicBody->isInstantiationDependent()) { 9420 ErrorFound = NotAnAssignmentOp; 9421 ErrorLoc = AtomicBody->getExprLoc(); 9422 ErrorRange = AtomicBody->getSourceRange(); 9423 NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc() 9424 : AtomicBody->getExprLoc(); 9425 NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange() 9426 : AtomicBody->getSourceRange(); 9427 } 9428 } else { 9429 ErrorFound = NotAnExpression; 9430 NoteLoc = ErrorLoc = Body->getBeginLoc(); 9431 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc); 9432 } 9433 if (ErrorFound != NoError) { 9434 Diag(ErrorLoc, diag::err_omp_atomic_read_not_expression_statement) 9435 << ErrorRange; 9436 Diag(NoteLoc, diag::note_omp_atomic_read_write) << ErrorFound 9437 << NoteRange; 9438 return StmtError(); 9439 } 9440 if (CurContext->isDependentContext()) 9441 V = X = nullptr; 9442 } else if (AtomicKind == OMPC_write) { 9443 enum { 9444 NotAnExpression, 9445 NotAnAssignmentOp, 9446 NotAScalarType, 9447 NotAnLValue, 9448 NoError 9449 } ErrorFound = NoError; 9450 SourceLocation ErrorLoc, NoteLoc; 9451 SourceRange ErrorRange, NoteRange; 9452 // If clause is write: 9453 // x = expr; 9454 if (const auto *AtomicBody = dyn_cast<Expr>(Body)) { 9455 const auto *AtomicBinOp = 9456 dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts()); 9457 if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) { 9458 X = AtomicBinOp->getLHS(); 9459 E = AtomicBinOp->getRHS(); 9460 if ((X->isInstantiationDependent() || X->getType()->isScalarType()) && 9461 (E->isInstantiationDependent() || E->getType()->isScalarType())) { 9462 if (!X->isLValue()) { 9463 ErrorFound = NotAnLValue; 9464 ErrorLoc = AtomicBinOp->getExprLoc(); 9465 ErrorRange = AtomicBinOp->getSourceRange(); 9466 NoteLoc = X->getExprLoc(); 9467 NoteRange = X->getSourceRange(); 9468 } 9469 } else if (!X->isInstantiationDependent() || 9470 !E->isInstantiationDependent()) { 9471 const Expr *NotScalarExpr = 9472 (X->isInstantiationDependent() || X->getType()->isScalarType()) 9473 ? E 9474 : X; 9475 ErrorFound = NotAScalarType; 9476 ErrorLoc = AtomicBinOp->getExprLoc(); 9477 ErrorRange = AtomicBinOp->getSourceRange(); 9478 NoteLoc = NotScalarExpr->getExprLoc(); 9479 NoteRange = NotScalarExpr->getSourceRange(); 9480 } 9481 } else if (!AtomicBody->isInstantiationDependent()) { 9482 ErrorFound = NotAnAssignmentOp; 9483 ErrorLoc = AtomicBody->getExprLoc(); 9484 ErrorRange = AtomicBody->getSourceRange(); 9485 NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc() 9486 : AtomicBody->getExprLoc(); 9487 NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange() 9488 : AtomicBody->getSourceRange(); 9489 } 9490 } else { 9491 ErrorFound = NotAnExpression; 9492 NoteLoc = ErrorLoc = Body->getBeginLoc(); 9493 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc); 9494 } 9495 if (ErrorFound != NoError) { 9496 Diag(ErrorLoc, diag::err_omp_atomic_write_not_expression_statement) 9497 << ErrorRange; 9498 Diag(NoteLoc, diag::note_omp_atomic_read_write) << ErrorFound 9499 << NoteRange; 9500 return StmtError(); 9501 } 9502 if (CurContext->isDependentContext()) 9503 E = X = nullptr; 9504 } else if (AtomicKind == OMPC_update || AtomicKind == OMPC_unknown) { 9505 // If clause is update: 9506 // x++; 9507 // x--; 9508 // ++x; 9509 // --x; 9510 // x binop= expr; 9511 // x = x binop expr; 9512 // x = expr binop x; 9513 OpenMPAtomicUpdateChecker Checker(*this); 9514 if (Checker.checkStatement( 9515 Body, (AtomicKind == OMPC_update) 9516 ? diag::err_omp_atomic_update_not_expression_statement 9517 : diag::err_omp_atomic_not_expression_statement, 9518 diag::note_omp_atomic_update)) 9519 return StmtError(); 9520 if (!CurContext->isDependentContext()) { 9521 E = Checker.getExpr(); 9522 X = Checker.getX(); 9523 UE = Checker.getUpdateExpr(); 9524 IsXLHSInRHSPart = Checker.isXLHSInRHSPart(); 9525 } 9526 } else if (AtomicKind == OMPC_capture) { 9527 enum { 9528 NotAnAssignmentOp, 9529 NotACompoundStatement, 9530 NotTwoSubstatements, 9531 NotASpecificExpression, 9532 NoError 9533 } ErrorFound = NoError; 9534 SourceLocation ErrorLoc, NoteLoc; 9535 SourceRange ErrorRange, NoteRange; 9536 if (const auto *AtomicBody = dyn_cast<Expr>(Body)) { 9537 // If clause is a capture: 9538 // v = x++; 9539 // v = x--; 9540 // v = ++x; 9541 // v = --x; 9542 // v = x binop= expr; 9543 // v = x = x binop expr; 9544 // v = x = expr binop x; 9545 const auto *AtomicBinOp = 9546 dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts()); 9547 if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) { 9548 V = AtomicBinOp->getLHS(); 9549 Body = AtomicBinOp->getRHS()->IgnoreParenImpCasts(); 9550 OpenMPAtomicUpdateChecker Checker(*this); 9551 if (Checker.checkStatement( 9552 Body, diag::err_omp_atomic_capture_not_expression_statement, 9553 diag::note_omp_atomic_update)) 9554 return StmtError(); 9555 E = Checker.getExpr(); 9556 X = Checker.getX(); 9557 UE = Checker.getUpdateExpr(); 9558 IsXLHSInRHSPart = Checker.isXLHSInRHSPart(); 9559 IsPostfixUpdate = Checker.isPostfixUpdate(); 9560 } else if (!AtomicBody->isInstantiationDependent()) { 9561 ErrorLoc = AtomicBody->getExprLoc(); 9562 ErrorRange = AtomicBody->getSourceRange(); 9563 NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc() 9564 : AtomicBody->getExprLoc(); 9565 NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange() 9566 : AtomicBody->getSourceRange(); 9567 ErrorFound = NotAnAssignmentOp; 9568 } 9569 if (ErrorFound != NoError) { 9570 Diag(ErrorLoc, diag::err_omp_atomic_capture_not_expression_statement) 9571 << ErrorRange; 9572 Diag(NoteLoc, diag::note_omp_atomic_capture) << ErrorFound << NoteRange; 9573 return StmtError(); 9574 } 9575 if (CurContext->isDependentContext()) 9576 UE = V = E = X = nullptr; 9577 } else { 9578 // If clause is a capture: 9579 // { v = x; x = expr; } 9580 // { v = x; x++; } 9581 // { v = x; x--; } 9582 // { v = x; ++x; } 9583 // { v = x; --x; } 9584 // { v = x; x binop= expr; } 9585 // { v = x; x = x binop expr; } 9586 // { v = x; x = expr binop x; } 9587 // { x++; v = x; } 9588 // { x--; v = x; } 9589 // { ++x; v = x; } 9590 // { --x; v = x; } 9591 // { x binop= expr; v = x; } 9592 // { x = x binop expr; v = x; } 9593 // { x = expr binop x; v = x; } 9594 if (auto *CS = dyn_cast<CompoundStmt>(Body)) { 9595 // Check that this is { expr1; expr2; } 9596 if (CS->size() == 2) { 9597 Stmt *First = CS->body_front(); 9598 Stmt *Second = CS->body_back(); 9599 if (auto *EWC = dyn_cast<ExprWithCleanups>(First)) 9600 First = EWC->getSubExpr()->IgnoreParenImpCasts(); 9601 if (auto *EWC = dyn_cast<ExprWithCleanups>(Second)) 9602 Second = EWC->getSubExpr()->IgnoreParenImpCasts(); 9603 // Need to find what subexpression is 'v' and what is 'x'. 9604 OpenMPAtomicUpdateChecker Checker(*this); 9605 bool IsUpdateExprFound = !Checker.checkStatement(Second); 9606 BinaryOperator *BinOp = nullptr; 9607 if (IsUpdateExprFound) { 9608 BinOp = dyn_cast<BinaryOperator>(First); 9609 IsUpdateExprFound = BinOp && BinOp->getOpcode() == BO_Assign; 9610 } 9611 if (IsUpdateExprFound && !CurContext->isDependentContext()) { 9612 // { v = x; x++; } 9613 // { v = x; x--; } 9614 // { v = x; ++x; } 9615 // { v = x; --x; } 9616 // { v = x; x binop= expr; } 9617 // { v = x; x = x binop expr; } 9618 // { v = x; x = expr binop x; } 9619 // Check that the first expression has form v = x. 9620 Expr *PossibleX = BinOp->getRHS()->IgnoreParenImpCasts(); 9621 llvm::FoldingSetNodeID XId, PossibleXId; 9622 Checker.getX()->Profile(XId, Context, /*Canonical=*/true); 9623 PossibleX->Profile(PossibleXId, Context, /*Canonical=*/true); 9624 IsUpdateExprFound = XId == PossibleXId; 9625 if (IsUpdateExprFound) { 9626 V = BinOp->getLHS(); 9627 X = Checker.getX(); 9628 E = Checker.getExpr(); 9629 UE = Checker.getUpdateExpr(); 9630 IsXLHSInRHSPart = Checker.isXLHSInRHSPart(); 9631 IsPostfixUpdate = true; 9632 } 9633 } 9634 if (!IsUpdateExprFound) { 9635 IsUpdateExprFound = !Checker.checkStatement(First); 9636 BinOp = nullptr; 9637 if (IsUpdateExprFound) { 9638 BinOp = dyn_cast<BinaryOperator>(Second); 9639 IsUpdateExprFound = BinOp && BinOp->getOpcode() == BO_Assign; 9640 } 9641 if (IsUpdateExprFound && !CurContext->isDependentContext()) { 9642 // { x++; v = x; } 9643 // { x--; v = x; } 9644 // { ++x; v = x; } 9645 // { --x; v = x; } 9646 // { x binop= expr; v = x; } 9647 // { x = x binop expr; v = x; } 9648 // { x = expr binop x; v = x; } 9649 // Check that the second expression has form v = x. 9650 Expr *PossibleX = BinOp->getRHS()->IgnoreParenImpCasts(); 9651 llvm::FoldingSetNodeID XId, PossibleXId; 9652 Checker.getX()->Profile(XId, Context, /*Canonical=*/true); 9653 PossibleX->Profile(PossibleXId, Context, /*Canonical=*/true); 9654 IsUpdateExprFound = XId == PossibleXId; 9655 if (IsUpdateExprFound) { 9656 V = BinOp->getLHS(); 9657 X = Checker.getX(); 9658 E = Checker.getExpr(); 9659 UE = Checker.getUpdateExpr(); 9660 IsXLHSInRHSPart = Checker.isXLHSInRHSPart(); 9661 IsPostfixUpdate = false; 9662 } 9663 } 9664 } 9665 if (!IsUpdateExprFound) { 9666 // { v = x; x = expr; } 9667 auto *FirstExpr = dyn_cast<Expr>(First); 9668 auto *SecondExpr = dyn_cast<Expr>(Second); 9669 if (!FirstExpr || !SecondExpr || 9670 !(FirstExpr->isInstantiationDependent() || 9671 SecondExpr->isInstantiationDependent())) { 9672 auto *FirstBinOp = dyn_cast<BinaryOperator>(First); 9673 if (!FirstBinOp || FirstBinOp->getOpcode() != BO_Assign) { 9674 ErrorFound = NotAnAssignmentOp; 9675 NoteLoc = ErrorLoc = FirstBinOp ? FirstBinOp->getOperatorLoc() 9676 : First->getBeginLoc(); 9677 NoteRange = ErrorRange = FirstBinOp 9678 ? FirstBinOp->getSourceRange() 9679 : SourceRange(ErrorLoc, ErrorLoc); 9680 } else { 9681 auto *SecondBinOp = dyn_cast<BinaryOperator>(Second); 9682 if (!SecondBinOp || SecondBinOp->getOpcode() != BO_Assign) { 9683 ErrorFound = NotAnAssignmentOp; 9684 NoteLoc = ErrorLoc = SecondBinOp 9685 ? SecondBinOp->getOperatorLoc() 9686 : Second->getBeginLoc(); 9687 NoteRange = ErrorRange = 9688 SecondBinOp ? SecondBinOp->getSourceRange() 9689 : SourceRange(ErrorLoc, ErrorLoc); 9690 } else { 9691 Expr *PossibleXRHSInFirst = 9692 FirstBinOp->getRHS()->IgnoreParenImpCasts(); 9693 Expr *PossibleXLHSInSecond = 9694 SecondBinOp->getLHS()->IgnoreParenImpCasts(); 9695 llvm::FoldingSetNodeID X1Id, X2Id; 9696 PossibleXRHSInFirst->Profile(X1Id, Context, 9697 /*Canonical=*/true); 9698 PossibleXLHSInSecond->Profile(X2Id, Context, 9699 /*Canonical=*/true); 9700 IsUpdateExprFound = X1Id == X2Id; 9701 if (IsUpdateExprFound) { 9702 V = FirstBinOp->getLHS(); 9703 X = SecondBinOp->getLHS(); 9704 E = SecondBinOp->getRHS(); 9705 UE = nullptr; 9706 IsXLHSInRHSPart = false; 9707 IsPostfixUpdate = true; 9708 } else { 9709 ErrorFound = NotASpecificExpression; 9710 ErrorLoc = FirstBinOp->getExprLoc(); 9711 ErrorRange = FirstBinOp->getSourceRange(); 9712 NoteLoc = SecondBinOp->getLHS()->getExprLoc(); 9713 NoteRange = SecondBinOp->getRHS()->getSourceRange(); 9714 } 9715 } 9716 } 9717 } 9718 } 9719 } else { 9720 NoteLoc = ErrorLoc = Body->getBeginLoc(); 9721 NoteRange = ErrorRange = 9722 SourceRange(Body->getBeginLoc(), Body->getBeginLoc()); 9723 ErrorFound = NotTwoSubstatements; 9724 } 9725 } else { 9726 NoteLoc = ErrorLoc = Body->getBeginLoc(); 9727 NoteRange = ErrorRange = 9728 SourceRange(Body->getBeginLoc(), Body->getBeginLoc()); 9729 ErrorFound = NotACompoundStatement; 9730 } 9731 if (ErrorFound != NoError) { 9732 Diag(ErrorLoc, diag::err_omp_atomic_capture_not_compound_statement) 9733 << ErrorRange; 9734 Diag(NoteLoc, diag::note_omp_atomic_capture) << ErrorFound << NoteRange; 9735 return StmtError(); 9736 } 9737 if (CurContext->isDependentContext()) 9738 UE = V = E = X = nullptr; 9739 } 9740 } 9741 9742 setFunctionHasBranchProtectedScope(); 9743 9744 return OMPAtomicDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt, 9745 X, V, E, UE, IsXLHSInRHSPart, 9746 IsPostfixUpdate); 9747 } 9748 9749 StmtResult Sema::ActOnOpenMPTargetDirective(ArrayRef<OMPClause *> Clauses, 9750 Stmt *AStmt, 9751 SourceLocation StartLoc, 9752 SourceLocation EndLoc) { 9753 if (!AStmt) 9754 return StmtError(); 9755 9756 auto *CS = cast<CapturedStmt>(AStmt); 9757 // 1.2.2 OpenMP Language Terminology 9758 // Structured block - An executable statement with a single entry at the 9759 // top and a single exit at the bottom. 9760 // The point of exit cannot be a branch out of the structured block. 9761 // longjmp() and throw() must not violate the entry/exit criteria. 9762 CS->getCapturedDecl()->setNothrow(); 9763 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target); 9764 ThisCaptureLevel > 1; --ThisCaptureLevel) { 9765 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 9766 // 1.2.2 OpenMP Language Terminology 9767 // Structured block - An executable statement with a single entry at the 9768 // top and a single exit at the bottom. 9769 // The point of exit cannot be a branch out of the structured block. 9770 // longjmp() and throw() must not violate the entry/exit criteria. 9771 CS->getCapturedDecl()->setNothrow(); 9772 } 9773 9774 // OpenMP [2.16, Nesting of Regions] 9775 // If specified, a teams construct must be contained within a target 9776 // construct. That target construct must contain no statements or directives 9777 // outside of the teams construct. 9778 if (DSAStack->hasInnerTeamsRegion()) { 9779 const Stmt *S = CS->IgnoreContainers(/*IgnoreCaptured=*/true); 9780 bool OMPTeamsFound = true; 9781 if (const auto *CS = dyn_cast<CompoundStmt>(S)) { 9782 auto I = CS->body_begin(); 9783 while (I != CS->body_end()) { 9784 const auto *OED = dyn_cast<OMPExecutableDirective>(*I); 9785 if (!OED || !isOpenMPTeamsDirective(OED->getDirectiveKind()) || 9786 OMPTeamsFound) { 9787 9788 OMPTeamsFound = false; 9789 break; 9790 } 9791 ++I; 9792 } 9793 assert(I != CS->body_end() && "Not found statement"); 9794 S = *I; 9795 } else { 9796 const auto *OED = dyn_cast<OMPExecutableDirective>(S); 9797 OMPTeamsFound = OED && isOpenMPTeamsDirective(OED->getDirectiveKind()); 9798 } 9799 if (!OMPTeamsFound) { 9800 Diag(StartLoc, diag::err_omp_target_contains_not_only_teams); 9801 Diag(DSAStack->getInnerTeamsRegionLoc(), 9802 diag::note_omp_nested_teams_construct_here); 9803 Diag(S->getBeginLoc(), diag::note_omp_nested_statement_here) 9804 << isa<OMPExecutableDirective>(S); 9805 return StmtError(); 9806 } 9807 } 9808 9809 setFunctionHasBranchProtectedScope(); 9810 9811 return OMPTargetDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt); 9812 } 9813 9814 StmtResult 9815 Sema::ActOnOpenMPTargetParallelDirective(ArrayRef<OMPClause *> Clauses, 9816 Stmt *AStmt, SourceLocation StartLoc, 9817 SourceLocation EndLoc) { 9818 if (!AStmt) 9819 return StmtError(); 9820 9821 auto *CS = cast<CapturedStmt>(AStmt); 9822 // 1.2.2 OpenMP Language Terminology 9823 // Structured block - An executable statement with a single entry at the 9824 // top and a single exit at the bottom. 9825 // The point of exit cannot be a branch out of the structured block. 9826 // longjmp() and throw() must not violate the entry/exit criteria. 9827 CS->getCapturedDecl()->setNothrow(); 9828 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel); 9829 ThisCaptureLevel > 1; --ThisCaptureLevel) { 9830 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 9831 // 1.2.2 OpenMP Language Terminology 9832 // Structured block - An executable statement with a single entry at the 9833 // top and a single exit at the bottom. 9834 // The point of exit cannot be a branch out of the structured block. 9835 // longjmp() and throw() must not violate the entry/exit criteria. 9836 CS->getCapturedDecl()->setNothrow(); 9837 } 9838 9839 setFunctionHasBranchProtectedScope(); 9840 9841 return OMPTargetParallelDirective::Create(Context, StartLoc, EndLoc, Clauses, 9842 AStmt); 9843 } 9844 9845 StmtResult Sema::ActOnOpenMPTargetParallelForDirective( 9846 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 9847 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 9848 if (!AStmt) 9849 return StmtError(); 9850 9851 auto *CS = cast<CapturedStmt>(AStmt); 9852 // 1.2.2 OpenMP Language Terminology 9853 // Structured block - An executable statement with a single entry at the 9854 // top and a single exit at the bottom. 9855 // The point of exit cannot be a branch out of the structured block. 9856 // longjmp() and throw() must not violate the entry/exit criteria. 9857 CS->getCapturedDecl()->setNothrow(); 9858 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel_for); 9859 ThisCaptureLevel > 1; --ThisCaptureLevel) { 9860 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 9861 // 1.2.2 OpenMP Language Terminology 9862 // Structured block - An executable statement with a single entry at the 9863 // top and a single exit at the bottom. 9864 // The point of exit cannot be a branch out of the structured block. 9865 // longjmp() and throw() must not violate the entry/exit criteria. 9866 CS->getCapturedDecl()->setNothrow(); 9867 } 9868 9869 OMPLoopDirective::HelperExprs B; 9870 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 9871 // define the nested loops number. 9872 unsigned NestedLoopCount = 9873 checkOpenMPLoop(OMPD_target_parallel_for, getCollapseNumberExpr(Clauses), 9874 getOrderedNumberExpr(Clauses), CS, *this, *DSAStack, 9875 VarsWithImplicitDSA, B); 9876 if (NestedLoopCount == 0) 9877 return StmtError(); 9878 9879 assert((CurContext->isDependentContext() || B.builtAll()) && 9880 "omp target parallel for loop exprs were not built"); 9881 9882 if (!CurContext->isDependentContext()) { 9883 // Finalize the clauses that need pre-built expressions for CodeGen. 9884 for (OMPClause *C : Clauses) { 9885 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 9886 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 9887 B.NumIterations, *this, CurScope, 9888 DSAStack)) 9889 return StmtError(); 9890 } 9891 } 9892 9893 setFunctionHasBranchProtectedScope(); 9894 return OMPTargetParallelForDirective::Create(Context, StartLoc, EndLoc, 9895 NestedLoopCount, Clauses, AStmt, 9896 B, DSAStack->isCancelRegion()); 9897 } 9898 9899 /// Check for existence of a map clause in the list of clauses. 9900 static bool hasClauses(ArrayRef<OMPClause *> Clauses, 9901 const OpenMPClauseKind K) { 9902 return llvm::any_of( 9903 Clauses, [K](const OMPClause *C) { return C->getClauseKind() == K; }); 9904 } 9905 9906 template <typename... Params> 9907 static bool hasClauses(ArrayRef<OMPClause *> Clauses, const OpenMPClauseKind K, 9908 const Params... ClauseTypes) { 9909 return hasClauses(Clauses, K) || hasClauses(Clauses, ClauseTypes...); 9910 } 9911 9912 StmtResult Sema::ActOnOpenMPTargetDataDirective(ArrayRef<OMPClause *> Clauses, 9913 Stmt *AStmt, 9914 SourceLocation StartLoc, 9915 SourceLocation EndLoc) { 9916 if (!AStmt) 9917 return StmtError(); 9918 9919 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 9920 9921 // OpenMP [2.10.1, Restrictions, p. 97] 9922 // At least one map clause must appear on the directive. 9923 if (!hasClauses(Clauses, OMPC_map, OMPC_use_device_ptr)) { 9924 Diag(StartLoc, diag::err_omp_no_clause_for_directive) 9925 << "'map' or 'use_device_ptr'" 9926 << getOpenMPDirectiveName(OMPD_target_data); 9927 return StmtError(); 9928 } 9929 9930 setFunctionHasBranchProtectedScope(); 9931 9932 return OMPTargetDataDirective::Create(Context, StartLoc, EndLoc, Clauses, 9933 AStmt); 9934 } 9935 9936 StmtResult 9937 Sema::ActOnOpenMPTargetEnterDataDirective(ArrayRef<OMPClause *> Clauses, 9938 SourceLocation StartLoc, 9939 SourceLocation EndLoc, Stmt *AStmt) { 9940 if (!AStmt) 9941 return StmtError(); 9942 9943 auto *CS = cast<CapturedStmt>(AStmt); 9944 // 1.2.2 OpenMP Language Terminology 9945 // Structured block - An executable statement with a single entry at the 9946 // top and a single exit at the bottom. 9947 // The point of exit cannot be a branch out of the structured block. 9948 // longjmp() and throw() must not violate the entry/exit criteria. 9949 CS->getCapturedDecl()->setNothrow(); 9950 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_enter_data); 9951 ThisCaptureLevel > 1; --ThisCaptureLevel) { 9952 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 9953 // 1.2.2 OpenMP Language Terminology 9954 // Structured block - An executable statement with a single entry at the 9955 // top and a single exit at the bottom. 9956 // The point of exit cannot be a branch out of the structured block. 9957 // longjmp() and throw() must not violate the entry/exit criteria. 9958 CS->getCapturedDecl()->setNothrow(); 9959 } 9960 9961 // OpenMP [2.10.2, Restrictions, p. 99] 9962 // At least one map clause must appear on the directive. 9963 if (!hasClauses(Clauses, OMPC_map)) { 9964 Diag(StartLoc, diag::err_omp_no_clause_for_directive) 9965 << "'map'" << getOpenMPDirectiveName(OMPD_target_enter_data); 9966 return StmtError(); 9967 } 9968 9969 return OMPTargetEnterDataDirective::Create(Context, StartLoc, EndLoc, Clauses, 9970 AStmt); 9971 } 9972 9973 StmtResult 9974 Sema::ActOnOpenMPTargetExitDataDirective(ArrayRef<OMPClause *> Clauses, 9975 SourceLocation StartLoc, 9976 SourceLocation EndLoc, Stmt *AStmt) { 9977 if (!AStmt) 9978 return StmtError(); 9979 9980 auto *CS = cast<CapturedStmt>(AStmt); 9981 // 1.2.2 OpenMP Language Terminology 9982 // Structured block - An executable statement with a single entry at the 9983 // top and a single exit at the bottom. 9984 // The point of exit cannot be a branch out of the structured block. 9985 // longjmp() and throw() must not violate the entry/exit criteria. 9986 CS->getCapturedDecl()->setNothrow(); 9987 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_exit_data); 9988 ThisCaptureLevel > 1; --ThisCaptureLevel) { 9989 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 9990 // 1.2.2 OpenMP Language Terminology 9991 // Structured block - An executable statement with a single entry at the 9992 // top and a single exit at the bottom. 9993 // The point of exit cannot be a branch out of the structured block. 9994 // longjmp() and throw() must not violate the entry/exit criteria. 9995 CS->getCapturedDecl()->setNothrow(); 9996 } 9997 9998 // OpenMP [2.10.3, Restrictions, p. 102] 9999 // At least one map clause must appear on the directive. 10000 if (!hasClauses(Clauses, OMPC_map)) { 10001 Diag(StartLoc, diag::err_omp_no_clause_for_directive) 10002 << "'map'" << getOpenMPDirectiveName(OMPD_target_exit_data); 10003 return StmtError(); 10004 } 10005 10006 return OMPTargetExitDataDirective::Create(Context, StartLoc, EndLoc, Clauses, 10007 AStmt); 10008 } 10009 10010 StmtResult Sema::ActOnOpenMPTargetUpdateDirective(ArrayRef<OMPClause *> Clauses, 10011 SourceLocation StartLoc, 10012 SourceLocation EndLoc, 10013 Stmt *AStmt) { 10014 if (!AStmt) 10015 return StmtError(); 10016 10017 auto *CS = cast<CapturedStmt>(AStmt); 10018 // 1.2.2 OpenMP Language Terminology 10019 // Structured block - An executable statement with a single entry at the 10020 // top and a single exit at the bottom. 10021 // The point of exit cannot be a branch out of the structured block. 10022 // longjmp() and throw() must not violate the entry/exit criteria. 10023 CS->getCapturedDecl()->setNothrow(); 10024 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_update); 10025 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10026 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10027 // 1.2.2 OpenMP Language Terminology 10028 // Structured block - An executable statement with a single entry at the 10029 // top and a single exit at the bottom. 10030 // The point of exit cannot be a branch out of the structured block. 10031 // longjmp() and throw() must not violate the entry/exit criteria. 10032 CS->getCapturedDecl()->setNothrow(); 10033 } 10034 10035 if (!hasClauses(Clauses, OMPC_to, OMPC_from)) { 10036 Diag(StartLoc, diag::err_omp_at_least_one_motion_clause_required); 10037 return StmtError(); 10038 } 10039 return OMPTargetUpdateDirective::Create(Context, StartLoc, EndLoc, Clauses, 10040 AStmt); 10041 } 10042 10043 StmtResult Sema::ActOnOpenMPTeamsDirective(ArrayRef<OMPClause *> Clauses, 10044 Stmt *AStmt, SourceLocation StartLoc, 10045 SourceLocation EndLoc) { 10046 if (!AStmt) 10047 return StmtError(); 10048 10049 auto *CS = cast<CapturedStmt>(AStmt); 10050 // 1.2.2 OpenMP Language Terminology 10051 // Structured block - An executable statement with a single entry at the 10052 // top and a single exit at the bottom. 10053 // The point of exit cannot be a branch out of the structured block. 10054 // longjmp() and throw() must not violate the entry/exit criteria. 10055 CS->getCapturedDecl()->setNothrow(); 10056 10057 setFunctionHasBranchProtectedScope(); 10058 10059 DSAStack->setParentTeamsRegionLoc(StartLoc); 10060 10061 return OMPTeamsDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt); 10062 } 10063 10064 StmtResult 10065 Sema::ActOnOpenMPCancellationPointDirective(SourceLocation StartLoc, 10066 SourceLocation EndLoc, 10067 OpenMPDirectiveKind CancelRegion) { 10068 if (DSAStack->isParentNowaitRegion()) { 10069 Diag(StartLoc, diag::err_omp_parent_cancel_region_nowait) << 0; 10070 return StmtError(); 10071 } 10072 if (DSAStack->isParentOrderedRegion()) { 10073 Diag(StartLoc, diag::err_omp_parent_cancel_region_ordered) << 0; 10074 return StmtError(); 10075 } 10076 return OMPCancellationPointDirective::Create(Context, StartLoc, EndLoc, 10077 CancelRegion); 10078 } 10079 10080 StmtResult Sema::ActOnOpenMPCancelDirective(ArrayRef<OMPClause *> Clauses, 10081 SourceLocation StartLoc, 10082 SourceLocation EndLoc, 10083 OpenMPDirectiveKind CancelRegion) { 10084 if (DSAStack->isParentNowaitRegion()) { 10085 Diag(StartLoc, diag::err_omp_parent_cancel_region_nowait) << 1; 10086 return StmtError(); 10087 } 10088 if (DSAStack->isParentOrderedRegion()) { 10089 Diag(StartLoc, diag::err_omp_parent_cancel_region_ordered) << 1; 10090 return StmtError(); 10091 } 10092 DSAStack->setParentCancelRegion(/*Cancel=*/true); 10093 return OMPCancelDirective::Create(Context, StartLoc, EndLoc, Clauses, 10094 CancelRegion); 10095 } 10096 10097 static bool checkGrainsizeNumTasksClauses(Sema &S, 10098 ArrayRef<OMPClause *> Clauses) { 10099 const OMPClause *PrevClause = nullptr; 10100 bool ErrorFound = false; 10101 for (const OMPClause *C : Clauses) { 10102 if (C->getClauseKind() == OMPC_grainsize || 10103 C->getClauseKind() == OMPC_num_tasks) { 10104 if (!PrevClause) 10105 PrevClause = C; 10106 else if (PrevClause->getClauseKind() != C->getClauseKind()) { 10107 S.Diag(C->getBeginLoc(), diag::err_omp_clauses_mutually_exclusive) 10108 << getOpenMPClauseName(C->getClauseKind()) 10109 << getOpenMPClauseName(PrevClause->getClauseKind()); 10110 S.Diag(PrevClause->getBeginLoc(), diag::note_omp_previous_clause) 10111 << getOpenMPClauseName(PrevClause->getClauseKind()); 10112 ErrorFound = true; 10113 } 10114 } 10115 } 10116 return ErrorFound; 10117 } 10118 10119 static bool checkReductionClauseWithNogroup(Sema &S, 10120 ArrayRef<OMPClause *> Clauses) { 10121 const OMPClause *ReductionClause = nullptr; 10122 const OMPClause *NogroupClause = nullptr; 10123 for (const OMPClause *C : Clauses) { 10124 if (C->getClauseKind() == OMPC_reduction) { 10125 ReductionClause = C; 10126 if (NogroupClause) 10127 break; 10128 continue; 10129 } 10130 if (C->getClauseKind() == OMPC_nogroup) { 10131 NogroupClause = C; 10132 if (ReductionClause) 10133 break; 10134 continue; 10135 } 10136 } 10137 if (ReductionClause && NogroupClause) { 10138 S.Diag(ReductionClause->getBeginLoc(), diag::err_omp_reduction_with_nogroup) 10139 << SourceRange(NogroupClause->getBeginLoc(), 10140 NogroupClause->getEndLoc()); 10141 return true; 10142 } 10143 return false; 10144 } 10145 10146 StmtResult Sema::ActOnOpenMPTaskLoopDirective( 10147 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10148 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10149 if (!AStmt) 10150 return StmtError(); 10151 10152 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 10153 OMPLoopDirective::HelperExprs B; 10154 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 10155 // define the nested loops number. 10156 unsigned NestedLoopCount = 10157 checkOpenMPLoop(OMPD_taskloop, getCollapseNumberExpr(Clauses), 10158 /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack, 10159 VarsWithImplicitDSA, B); 10160 if (NestedLoopCount == 0) 10161 return StmtError(); 10162 10163 assert((CurContext->isDependentContext() || B.builtAll()) && 10164 "omp for loop exprs were not built"); 10165 10166 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 10167 // The grainsize clause and num_tasks clause are mutually exclusive and may 10168 // not appear on the same taskloop directive. 10169 if (checkGrainsizeNumTasksClauses(*this, Clauses)) 10170 return StmtError(); 10171 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 10172 // If a reduction clause is present on the taskloop directive, the nogroup 10173 // clause must not be specified. 10174 if (checkReductionClauseWithNogroup(*this, Clauses)) 10175 return StmtError(); 10176 10177 setFunctionHasBranchProtectedScope(); 10178 return OMPTaskLoopDirective::Create(Context, StartLoc, EndLoc, 10179 NestedLoopCount, Clauses, AStmt, B, 10180 DSAStack->isCancelRegion()); 10181 } 10182 10183 StmtResult Sema::ActOnOpenMPTaskLoopSimdDirective( 10184 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10185 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10186 if (!AStmt) 10187 return StmtError(); 10188 10189 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 10190 OMPLoopDirective::HelperExprs B; 10191 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 10192 // define the nested loops number. 10193 unsigned NestedLoopCount = 10194 checkOpenMPLoop(OMPD_taskloop_simd, getCollapseNumberExpr(Clauses), 10195 /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack, 10196 VarsWithImplicitDSA, B); 10197 if (NestedLoopCount == 0) 10198 return StmtError(); 10199 10200 assert((CurContext->isDependentContext() || B.builtAll()) && 10201 "omp for loop exprs were not built"); 10202 10203 if (!CurContext->isDependentContext()) { 10204 // Finalize the clauses that need pre-built expressions for CodeGen. 10205 for (OMPClause *C : Clauses) { 10206 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 10207 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 10208 B.NumIterations, *this, CurScope, 10209 DSAStack)) 10210 return StmtError(); 10211 } 10212 } 10213 10214 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 10215 // The grainsize clause and num_tasks clause are mutually exclusive and may 10216 // not appear on the same taskloop directive. 10217 if (checkGrainsizeNumTasksClauses(*this, Clauses)) 10218 return StmtError(); 10219 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 10220 // If a reduction clause is present on the taskloop directive, the nogroup 10221 // clause must not be specified. 10222 if (checkReductionClauseWithNogroup(*this, Clauses)) 10223 return StmtError(); 10224 if (checkSimdlenSafelenSpecified(*this, Clauses)) 10225 return StmtError(); 10226 10227 setFunctionHasBranchProtectedScope(); 10228 return OMPTaskLoopSimdDirective::Create(Context, StartLoc, EndLoc, 10229 NestedLoopCount, Clauses, AStmt, B); 10230 } 10231 10232 StmtResult Sema::ActOnOpenMPMasterTaskLoopDirective( 10233 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10234 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10235 if (!AStmt) 10236 return StmtError(); 10237 10238 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 10239 OMPLoopDirective::HelperExprs B; 10240 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 10241 // define the nested loops number. 10242 unsigned NestedLoopCount = 10243 checkOpenMPLoop(OMPD_master_taskloop, getCollapseNumberExpr(Clauses), 10244 /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack, 10245 VarsWithImplicitDSA, B); 10246 if (NestedLoopCount == 0) 10247 return StmtError(); 10248 10249 assert((CurContext->isDependentContext() || B.builtAll()) && 10250 "omp for loop exprs were not built"); 10251 10252 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 10253 // The grainsize clause and num_tasks clause are mutually exclusive and may 10254 // not appear on the same taskloop directive. 10255 if (checkGrainsizeNumTasksClauses(*this, Clauses)) 10256 return StmtError(); 10257 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 10258 // If a reduction clause is present on the taskloop directive, the nogroup 10259 // clause must not be specified. 10260 if (checkReductionClauseWithNogroup(*this, Clauses)) 10261 return StmtError(); 10262 10263 setFunctionHasBranchProtectedScope(); 10264 return OMPMasterTaskLoopDirective::Create(Context, StartLoc, EndLoc, 10265 NestedLoopCount, Clauses, AStmt, B, 10266 DSAStack->isCancelRegion()); 10267 } 10268 10269 StmtResult Sema::ActOnOpenMPMasterTaskLoopSimdDirective( 10270 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10271 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10272 if (!AStmt) 10273 return StmtError(); 10274 10275 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 10276 OMPLoopDirective::HelperExprs B; 10277 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 10278 // define the nested loops number. 10279 unsigned NestedLoopCount = 10280 checkOpenMPLoop(OMPD_master_taskloop_simd, getCollapseNumberExpr(Clauses), 10281 /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack, 10282 VarsWithImplicitDSA, B); 10283 if (NestedLoopCount == 0) 10284 return StmtError(); 10285 10286 assert((CurContext->isDependentContext() || B.builtAll()) && 10287 "omp for loop exprs were not built"); 10288 10289 if (!CurContext->isDependentContext()) { 10290 // Finalize the clauses that need pre-built expressions for CodeGen. 10291 for (OMPClause *C : Clauses) { 10292 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 10293 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 10294 B.NumIterations, *this, CurScope, 10295 DSAStack)) 10296 return StmtError(); 10297 } 10298 } 10299 10300 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 10301 // The grainsize clause and num_tasks clause are mutually exclusive and may 10302 // not appear on the same taskloop directive. 10303 if (checkGrainsizeNumTasksClauses(*this, Clauses)) 10304 return StmtError(); 10305 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 10306 // If a reduction clause is present on the taskloop directive, the nogroup 10307 // clause must not be specified. 10308 if (checkReductionClauseWithNogroup(*this, Clauses)) 10309 return StmtError(); 10310 if (checkSimdlenSafelenSpecified(*this, Clauses)) 10311 return StmtError(); 10312 10313 setFunctionHasBranchProtectedScope(); 10314 return OMPMasterTaskLoopSimdDirective::Create( 10315 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 10316 } 10317 10318 StmtResult Sema::ActOnOpenMPParallelMasterTaskLoopDirective( 10319 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10320 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10321 if (!AStmt) 10322 return StmtError(); 10323 10324 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 10325 auto *CS = cast<CapturedStmt>(AStmt); 10326 // 1.2.2 OpenMP Language Terminology 10327 // Structured block - An executable statement with a single entry at the 10328 // top and a single exit at the bottom. 10329 // The point of exit cannot be a branch out of the structured block. 10330 // longjmp() and throw() must not violate the entry/exit criteria. 10331 CS->getCapturedDecl()->setNothrow(); 10332 for (int ThisCaptureLevel = 10333 getOpenMPCaptureLevels(OMPD_parallel_master_taskloop); 10334 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10335 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10336 // 1.2.2 OpenMP Language Terminology 10337 // Structured block - An executable statement with a single entry at the 10338 // top and a single exit at the bottom. 10339 // The point of exit cannot be a branch out of the structured block. 10340 // longjmp() and throw() must not violate the entry/exit criteria. 10341 CS->getCapturedDecl()->setNothrow(); 10342 } 10343 10344 OMPLoopDirective::HelperExprs B; 10345 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 10346 // define the nested loops number. 10347 unsigned NestedLoopCount = checkOpenMPLoop( 10348 OMPD_parallel_master_taskloop, getCollapseNumberExpr(Clauses), 10349 /*OrderedLoopCountExpr=*/nullptr, CS, *this, *DSAStack, 10350 VarsWithImplicitDSA, B); 10351 if (NestedLoopCount == 0) 10352 return StmtError(); 10353 10354 assert((CurContext->isDependentContext() || B.builtAll()) && 10355 "omp for loop exprs were not built"); 10356 10357 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 10358 // The grainsize clause and num_tasks clause are mutually exclusive and may 10359 // not appear on the same taskloop directive. 10360 if (checkGrainsizeNumTasksClauses(*this, Clauses)) 10361 return StmtError(); 10362 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 10363 // If a reduction clause is present on the taskloop directive, the nogroup 10364 // clause must not be specified. 10365 if (checkReductionClauseWithNogroup(*this, Clauses)) 10366 return StmtError(); 10367 10368 setFunctionHasBranchProtectedScope(); 10369 return OMPParallelMasterTaskLoopDirective::Create( 10370 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B, 10371 DSAStack->isCancelRegion()); 10372 } 10373 10374 StmtResult Sema::ActOnOpenMPParallelMasterTaskLoopSimdDirective( 10375 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10376 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10377 if (!AStmt) 10378 return StmtError(); 10379 10380 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 10381 auto *CS = cast<CapturedStmt>(AStmt); 10382 // 1.2.2 OpenMP Language Terminology 10383 // Structured block - An executable statement with a single entry at the 10384 // top and a single exit at the bottom. 10385 // The point of exit cannot be a branch out of the structured block. 10386 // longjmp() and throw() must not violate the entry/exit criteria. 10387 CS->getCapturedDecl()->setNothrow(); 10388 for (int ThisCaptureLevel = 10389 getOpenMPCaptureLevels(OMPD_parallel_master_taskloop_simd); 10390 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10391 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10392 // 1.2.2 OpenMP Language Terminology 10393 // Structured block - An executable statement with a single entry at the 10394 // top and a single exit at the bottom. 10395 // The point of exit cannot be a branch out of the structured block. 10396 // longjmp() and throw() must not violate the entry/exit criteria. 10397 CS->getCapturedDecl()->setNothrow(); 10398 } 10399 10400 OMPLoopDirective::HelperExprs B; 10401 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 10402 // define the nested loops number. 10403 unsigned NestedLoopCount = checkOpenMPLoop( 10404 OMPD_parallel_master_taskloop_simd, getCollapseNumberExpr(Clauses), 10405 /*OrderedLoopCountExpr=*/nullptr, CS, *this, *DSAStack, 10406 VarsWithImplicitDSA, B); 10407 if (NestedLoopCount == 0) 10408 return StmtError(); 10409 10410 assert((CurContext->isDependentContext() || B.builtAll()) && 10411 "omp for loop exprs were not built"); 10412 10413 if (!CurContext->isDependentContext()) { 10414 // Finalize the clauses that need pre-built expressions for CodeGen. 10415 for (OMPClause *C : Clauses) { 10416 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 10417 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 10418 B.NumIterations, *this, CurScope, 10419 DSAStack)) 10420 return StmtError(); 10421 } 10422 } 10423 10424 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 10425 // The grainsize clause and num_tasks clause are mutually exclusive and may 10426 // not appear on the same taskloop directive. 10427 if (checkGrainsizeNumTasksClauses(*this, Clauses)) 10428 return StmtError(); 10429 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 10430 // If a reduction clause is present on the taskloop directive, the nogroup 10431 // clause must not be specified. 10432 if (checkReductionClauseWithNogroup(*this, Clauses)) 10433 return StmtError(); 10434 if (checkSimdlenSafelenSpecified(*this, Clauses)) 10435 return StmtError(); 10436 10437 setFunctionHasBranchProtectedScope(); 10438 return OMPParallelMasterTaskLoopSimdDirective::Create( 10439 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 10440 } 10441 10442 StmtResult Sema::ActOnOpenMPDistributeDirective( 10443 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10444 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10445 if (!AStmt) 10446 return StmtError(); 10447 10448 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 10449 OMPLoopDirective::HelperExprs B; 10450 // In presence of clause 'collapse' with number of loops, it will 10451 // define the nested loops number. 10452 unsigned NestedLoopCount = 10453 checkOpenMPLoop(OMPD_distribute, getCollapseNumberExpr(Clauses), 10454 nullptr /*ordered not a clause on distribute*/, AStmt, 10455 *this, *DSAStack, VarsWithImplicitDSA, B); 10456 if (NestedLoopCount == 0) 10457 return StmtError(); 10458 10459 assert((CurContext->isDependentContext() || B.builtAll()) && 10460 "omp for loop exprs were not built"); 10461 10462 setFunctionHasBranchProtectedScope(); 10463 return OMPDistributeDirective::Create(Context, StartLoc, EndLoc, 10464 NestedLoopCount, Clauses, AStmt, B); 10465 } 10466 10467 StmtResult Sema::ActOnOpenMPDistributeParallelForDirective( 10468 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10469 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10470 if (!AStmt) 10471 return StmtError(); 10472 10473 auto *CS = cast<CapturedStmt>(AStmt); 10474 // 1.2.2 OpenMP Language Terminology 10475 // Structured block - An executable statement with a single entry at the 10476 // top and a single exit at the bottom. 10477 // The point of exit cannot be a branch out of the structured block. 10478 // longjmp() and throw() must not violate the entry/exit criteria. 10479 CS->getCapturedDecl()->setNothrow(); 10480 for (int ThisCaptureLevel = 10481 getOpenMPCaptureLevels(OMPD_distribute_parallel_for); 10482 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10483 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10484 // 1.2.2 OpenMP Language Terminology 10485 // Structured block - An executable statement with a single entry at the 10486 // top and a single exit at the bottom. 10487 // The point of exit cannot be a branch out of the structured block. 10488 // longjmp() and throw() must not violate the entry/exit criteria. 10489 CS->getCapturedDecl()->setNothrow(); 10490 } 10491 10492 OMPLoopDirective::HelperExprs B; 10493 // In presence of clause 'collapse' with number of loops, it will 10494 // define the nested loops number. 10495 unsigned NestedLoopCount = checkOpenMPLoop( 10496 OMPD_distribute_parallel_for, getCollapseNumberExpr(Clauses), 10497 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 10498 VarsWithImplicitDSA, B); 10499 if (NestedLoopCount == 0) 10500 return StmtError(); 10501 10502 assert((CurContext->isDependentContext() || B.builtAll()) && 10503 "omp for loop exprs were not built"); 10504 10505 setFunctionHasBranchProtectedScope(); 10506 return OMPDistributeParallelForDirective::Create( 10507 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B, 10508 DSAStack->isCancelRegion()); 10509 } 10510 10511 StmtResult Sema::ActOnOpenMPDistributeParallelForSimdDirective( 10512 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10513 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10514 if (!AStmt) 10515 return StmtError(); 10516 10517 auto *CS = cast<CapturedStmt>(AStmt); 10518 // 1.2.2 OpenMP Language Terminology 10519 // Structured block - An executable statement with a single entry at the 10520 // top and a single exit at the bottom. 10521 // The point of exit cannot be a branch out of the structured block. 10522 // longjmp() and throw() must not violate the entry/exit criteria. 10523 CS->getCapturedDecl()->setNothrow(); 10524 for (int ThisCaptureLevel = 10525 getOpenMPCaptureLevels(OMPD_distribute_parallel_for_simd); 10526 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10527 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10528 // 1.2.2 OpenMP Language Terminology 10529 // Structured block - An executable statement with a single entry at the 10530 // top and a single exit at the bottom. 10531 // The point of exit cannot be a branch out of the structured block. 10532 // longjmp() and throw() must not violate the entry/exit criteria. 10533 CS->getCapturedDecl()->setNothrow(); 10534 } 10535 10536 OMPLoopDirective::HelperExprs B; 10537 // In presence of clause 'collapse' with number of loops, it will 10538 // define the nested loops number. 10539 unsigned NestedLoopCount = checkOpenMPLoop( 10540 OMPD_distribute_parallel_for_simd, getCollapseNumberExpr(Clauses), 10541 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 10542 VarsWithImplicitDSA, B); 10543 if (NestedLoopCount == 0) 10544 return StmtError(); 10545 10546 assert((CurContext->isDependentContext() || B.builtAll()) && 10547 "omp for loop exprs were not built"); 10548 10549 if (!CurContext->isDependentContext()) { 10550 // Finalize the clauses that need pre-built expressions for CodeGen. 10551 for (OMPClause *C : Clauses) { 10552 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 10553 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 10554 B.NumIterations, *this, CurScope, 10555 DSAStack)) 10556 return StmtError(); 10557 } 10558 } 10559 10560 if (checkSimdlenSafelenSpecified(*this, Clauses)) 10561 return StmtError(); 10562 10563 setFunctionHasBranchProtectedScope(); 10564 return OMPDistributeParallelForSimdDirective::Create( 10565 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 10566 } 10567 10568 StmtResult Sema::ActOnOpenMPDistributeSimdDirective( 10569 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10570 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10571 if (!AStmt) 10572 return StmtError(); 10573 10574 auto *CS = cast<CapturedStmt>(AStmt); 10575 // 1.2.2 OpenMP Language Terminology 10576 // Structured block - An executable statement with a single entry at the 10577 // top and a single exit at the bottom. 10578 // The point of exit cannot be a branch out of the structured block. 10579 // longjmp() and throw() must not violate the entry/exit criteria. 10580 CS->getCapturedDecl()->setNothrow(); 10581 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_distribute_simd); 10582 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10583 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10584 // 1.2.2 OpenMP Language Terminology 10585 // Structured block - An executable statement with a single entry at the 10586 // top and a single exit at the bottom. 10587 // The point of exit cannot be a branch out of the structured block. 10588 // longjmp() and throw() must not violate the entry/exit criteria. 10589 CS->getCapturedDecl()->setNothrow(); 10590 } 10591 10592 OMPLoopDirective::HelperExprs B; 10593 // In presence of clause 'collapse' with number of loops, it will 10594 // define the nested loops number. 10595 unsigned NestedLoopCount = 10596 checkOpenMPLoop(OMPD_distribute_simd, getCollapseNumberExpr(Clauses), 10597 nullptr /*ordered not a clause on distribute*/, CS, *this, 10598 *DSAStack, VarsWithImplicitDSA, B); 10599 if (NestedLoopCount == 0) 10600 return StmtError(); 10601 10602 assert((CurContext->isDependentContext() || B.builtAll()) && 10603 "omp for loop exprs were not built"); 10604 10605 if (!CurContext->isDependentContext()) { 10606 // Finalize the clauses that need pre-built expressions for CodeGen. 10607 for (OMPClause *C : Clauses) { 10608 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 10609 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 10610 B.NumIterations, *this, CurScope, 10611 DSAStack)) 10612 return StmtError(); 10613 } 10614 } 10615 10616 if (checkSimdlenSafelenSpecified(*this, Clauses)) 10617 return StmtError(); 10618 10619 setFunctionHasBranchProtectedScope(); 10620 return OMPDistributeSimdDirective::Create(Context, StartLoc, EndLoc, 10621 NestedLoopCount, Clauses, AStmt, B); 10622 } 10623 10624 StmtResult Sema::ActOnOpenMPTargetParallelForSimdDirective( 10625 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10626 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10627 if (!AStmt) 10628 return StmtError(); 10629 10630 auto *CS = cast<CapturedStmt>(AStmt); 10631 // 1.2.2 OpenMP Language Terminology 10632 // Structured block - An executable statement with a single entry at the 10633 // top and a single exit at the bottom. 10634 // The point of exit cannot be a branch out of the structured block. 10635 // longjmp() and throw() must not violate the entry/exit criteria. 10636 CS->getCapturedDecl()->setNothrow(); 10637 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel_for); 10638 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10639 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10640 // 1.2.2 OpenMP Language Terminology 10641 // Structured block - An executable statement with a single entry at the 10642 // top and a single exit at the bottom. 10643 // The point of exit cannot be a branch out of the structured block. 10644 // longjmp() and throw() must not violate the entry/exit criteria. 10645 CS->getCapturedDecl()->setNothrow(); 10646 } 10647 10648 OMPLoopDirective::HelperExprs B; 10649 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 10650 // define the nested loops number. 10651 unsigned NestedLoopCount = checkOpenMPLoop( 10652 OMPD_target_parallel_for_simd, getCollapseNumberExpr(Clauses), 10653 getOrderedNumberExpr(Clauses), CS, *this, *DSAStack, 10654 VarsWithImplicitDSA, B); 10655 if (NestedLoopCount == 0) 10656 return StmtError(); 10657 10658 assert((CurContext->isDependentContext() || B.builtAll()) && 10659 "omp target parallel for simd loop exprs were not built"); 10660 10661 if (!CurContext->isDependentContext()) { 10662 // Finalize the clauses that need pre-built expressions for CodeGen. 10663 for (OMPClause *C : Clauses) { 10664 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 10665 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 10666 B.NumIterations, *this, CurScope, 10667 DSAStack)) 10668 return StmtError(); 10669 } 10670 } 10671 if (checkSimdlenSafelenSpecified(*this, Clauses)) 10672 return StmtError(); 10673 10674 setFunctionHasBranchProtectedScope(); 10675 return OMPTargetParallelForSimdDirective::Create( 10676 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 10677 } 10678 10679 StmtResult Sema::ActOnOpenMPTargetSimdDirective( 10680 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10681 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10682 if (!AStmt) 10683 return StmtError(); 10684 10685 auto *CS = cast<CapturedStmt>(AStmt); 10686 // 1.2.2 OpenMP Language Terminology 10687 // Structured block - An executable statement with a single entry at the 10688 // top and a single exit at the bottom. 10689 // The point of exit cannot be a branch out of the structured block. 10690 // longjmp() and throw() must not violate the entry/exit criteria. 10691 CS->getCapturedDecl()->setNothrow(); 10692 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_simd); 10693 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10694 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10695 // 1.2.2 OpenMP Language Terminology 10696 // Structured block - An executable statement with a single entry at the 10697 // top and a single exit at the bottom. 10698 // The point of exit cannot be a branch out of the structured block. 10699 // longjmp() and throw() must not violate the entry/exit criteria. 10700 CS->getCapturedDecl()->setNothrow(); 10701 } 10702 10703 OMPLoopDirective::HelperExprs B; 10704 // In presence of clause 'collapse' with number of loops, it will define the 10705 // nested loops number. 10706 unsigned NestedLoopCount = 10707 checkOpenMPLoop(OMPD_target_simd, getCollapseNumberExpr(Clauses), 10708 getOrderedNumberExpr(Clauses), CS, *this, *DSAStack, 10709 VarsWithImplicitDSA, B); 10710 if (NestedLoopCount == 0) 10711 return StmtError(); 10712 10713 assert((CurContext->isDependentContext() || B.builtAll()) && 10714 "omp target simd loop exprs were not built"); 10715 10716 if (!CurContext->isDependentContext()) { 10717 // Finalize the clauses that need pre-built expressions for CodeGen. 10718 for (OMPClause *C : Clauses) { 10719 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 10720 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 10721 B.NumIterations, *this, CurScope, 10722 DSAStack)) 10723 return StmtError(); 10724 } 10725 } 10726 10727 if (checkSimdlenSafelenSpecified(*this, Clauses)) 10728 return StmtError(); 10729 10730 setFunctionHasBranchProtectedScope(); 10731 return OMPTargetSimdDirective::Create(Context, StartLoc, EndLoc, 10732 NestedLoopCount, Clauses, AStmt, B); 10733 } 10734 10735 StmtResult Sema::ActOnOpenMPTeamsDistributeDirective( 10736 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10737 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10738 if (!AStmt) 10739 return StmtError(); 10740 10741 auto *CS = cast<CapturedStmt>(AStmt); 10742 // 1.2.2 OpenMP Language Terminology 10743 // Structured block - An executable statement with a single entry at the 10744 // top and a single exit at the bottom. 10745 // The point of exit cannot be a branch out of the structured block. 10746 // longjmp() and throw() must not violate the entry/exit criteria. 10747 CS->getCapturedDecl()->setNothrow(); 10748 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_teams_distribute); 10749 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10750 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10751 // 1.2.2 OpenMP Language Terminology 10752 // Structured block - An executable statement with a single entry at the 10753 // top and a single exit at the bottom. 10754 // The point of exit cannot be a branch out of the structured block. 10755 // longjmp() and throw() must not violate the entry/exit criteria. 10756 CS->getCapturedDecl()->setNothrow(); 10757 } 10758 10759 OMPLoopDirective::HelperExprs B; 10760 // In presence of clause 'collapse' with number of loops, it will 10761 // define the nested loops number. 10762 unsigned NestedLoopCount = 10763 checkOpenMPLoop(OMPD_teams_distribute, getCollapseNumberExpr(Clauses), 10764 nullptr /*ordered not a clause on distribute*/, CS, *this, 10765 *DSAStack, VarsWithImplicitDSA, B); 10766 if (NestedLoopCount == 0) 10767 return StmtError(); 10768 10769 assert((CurContext->isDependentContext() || B.builtAll()) && 10770 "omp teams distribute loop exprs were not built"); 10771 10772 setFunctionHasBranchProtectedScope(); 10773 10774 DSAStack->setParentTeamsRegionLoc(StartLoc); 10775 10776 return OMPTeamsDistributeDirective::Create( 10777 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 10778 } 10779 10780 StmtResult Sema::ActOnOpenMPTeamsDistributeSimdDirective( 10781 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10782 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10783 if (!AStmt) 10784 return StmtError(); 10785 10786 auto *CS = cast<CapturedStmt>(AStmt); 10787 // 1.2.2 OpenMP Language Terminology 10788 // Structured block - An executable statement with a single entry at the 10789 // top and a single exit at the bottom. 10790 // The point of exit cannot be a branch out of the structured block. 10791 // longjmp() and throw() must not violate the entry/exit criteria. 10792 CS->getCapturedDecl()->setNothrow(); 10793 for (int ThisCaptureLevel = 10794 getOpenMPCaptureLevels(OMPD_teams_distribute_simd); 10795 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10796 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10797 // 1.2.2 OpenMP Language Terminology 10798 // Structured block - An executable statement with a single entry at the 10799 // top and a single exit at the bottom. 10800 // The point of exit cannot be a branch out of the structured block. 10801 // longjmp() and throw() must not violate the entry/exit criteria. 10802 CS->getCapturedDecl()->setNothrow(); 10803 } 10804 10805 OMPLoopDirective::HelperExprs B; 10806 // In presence of clause 'collapse' with number of loops, it will 10807 // define the nested loops number. 10808 unsigned NestedLoopCount = checkOpenMPLoop( 10809 OMPD_teams_distribute_simd, getCollapseNumberExpr(Clauses), 10810 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 10811 VarsWithImplicitDSA, B); 10812 10813 if (NestedLoopCount == 0) 10814 return StmtError(); 10815 10816 assert((CurContext->isDependentContext() || B.builtAll()) && 10817 "omp teams distribute simd loop exprs were not built"); 10818 10819 if (!CurContext->isDependentContext()) { 10820 // Finalize the clauses that need pre-built expressions for CodeGen. 10821 for (OMPClause *C : Clauses) { 10822 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 10823 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 10824 B.NumIterations, *this, CurScope, 10825 DSAStack)) 10826 return StmtError(); 10827 } 10828 } 10829 10830 if (checkSimdlenSafelenSpecified(*this, Clauses)) 10831 return StmtError(); 10832 10833 setFunctionHasBranchProtectedScope(); 10834 10835 DSAStack->setParentTeamsRegionLoc(StartLoc); 10836 10837 return OMPTeamsDistributeSimdDirective::Create( 10838 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 10839 } 10840 10841 StmtResult Sema::ActOnOpenMPTeamsDistributeParallelForSimdDirective( 10842 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10843 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10844 if (!AStmt) 10845 return StmtError(); 10846 10847 auto *CS = cast<CapturedStmt>(AStmt); 10848 // 1.2.2 OpenMP Language Terminology 10849 // Structured block - An executable statement with a single entry at the 10850 // top and a single exit at the bottom. 10851 // The point of exit cannot be a branch out of the structured block. 10852 // longjmp() and throw() must not violate the entry/exit criteria. 10853 CS->getCapturedDecl()->setNothrow(); 10854 10855 for (int ThisCaptureLevel = 10856 getOpenMPCaptureLevels(OMPD_teams_distribute_parallel_for_simd); 10857 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10858 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10859 // 1.2.2 OpenMP Language Terminology 10860 // Structured block - An executable statement with a single entry at the 10861 // top and a single exit at the bottom. 10862 // The point of exit cannot be a branch out of the structured block. 10863 // longjmp() and throw() must not violate the entry/exit criteria. 10864 CS->getCapturedDecl()->setNothrow(); 10865 } 10866 10867 OMPLoopDirective::HelperExprs B; 10868 // In presence of clause 'collapse' with number of loops, it will 10869 // define the nested loops number. 10870 unsigned NestedLoopCount = checkOpenMPLoop( 10871 OMPD_teams_distribute_parallel_for_simd, getCollapseNumberExpr(Clauses), 10872 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 10873 VarsWithImplicitDSA, B); 10874 10875 if (NestedLoopCount == 0) 10876 return StmtError(); 10877 10878 assert((CurContext->isDependentContext() || B.builtAll()) && 10879 "omp for loop exprs were not built"); 10880 10881 if (!CurContext->isDependentContext()) { 10882 // Finalize the clauses that need pre-built expressions for CodeGen. 10883 for (OMPClause *C : Clauses) { 10884 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 10885 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 10886 B.NumIterations, *this, CurScope, 10887 DSAStack)) 10888 return StmtError(); 10889 } 10890 } 10891 10892 if (checkSimdlenSafelenSpecified(*this, Clauses)) 10893 return StmtError(); 10894 10895 setFunctionHasBranchProtectedScope(); 10896 10897 DSAStack->setParentTeamsRegionLoc(StartLoc); 10898 10899 return OMPTeamsDistributeParallelForSimdDirective::Create( 10900 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 10901 } 10902 10903 StmtResult Sema::ActOnOpenMPTeamsDistributeParallelForDirective( 10904 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10905 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10906 if (!AStmt) 10907 return StmtError(); 10908 10909 auto *CS = cast<CapturedStmt>(AStmt); 10910 // 1.2.2 OpenMP Language Terminology 10911 // Structured block - An executable statement with a single entry at the 10912 // top and a single exit at the bottom. 10913 // The point of exit cannot be a branch out of the structured block. 10914 // longjmp() and throw() must not violate the entry/exit criteria. 10915 CS->getCapturedDecl()->setNothrow(); 10916 10917 for (int ThisCaptureLevel = 10918 getOpenMPCaptureLevels(OMPD_teams_distribute_parallel_for); 10919 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10920 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10921 // 1.2.2 OpenMP Language Terminology 10922 // Structured block - An executable statement with a single entry at the 10923 // top and a single exit at the bottom. 10924 // The point of exit cannot be a branch out of the structured block. 10925 // longjmp() and throw() must not violate the entry/exit criteria. 10926 CS->getCapturedDecl()->setNothrow(); 10927 } 10928 10929 OMPLoopDirective::HelperExprs B; 10930 // In presence of clause 'collapse' with number of loops, it will 10931 // define the nested loops number. 10932 unsigned NestedLoopCount = checkOpenMPLoop( 10933 OMPD_teams_distribute_parallel_for, getCollapseNumberExpr(Clauses), 10934 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 10935 VarsWithImplicitDSA, B); 10936 10937 if (NestedLoopCount == 0) 10938 return StmtError(); 10939 10940 assert((CurContext->isDependentContext() || B.builtAll()) && 10941 "omp for loop exprs were not built"); 10942 10943 setFunctionHasBranchProtectedScope(); 10944 10945 DSAStack->setParentTeamsRegionLoc(StartLoc); 10946 10947 return OMPTeamsDistributeParallelForDirective::Create( 10948 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B, 10949 DSAStack->isCancelRegion()); 10950 } 10951 10952 StmtResult Sema::ActOnOpenMPTargetTeamsDirective(ArrayRef<OMPClause *> Clauses, 10953 Stmt *AStmt, 10954 SourceLocation StartLoc, 10955 SourceLocation EndLoc) { 10956 if (!AStmt) 10957 return StmtError(); 10958 10959 auto *CS = cast<CapturedStmt>(AStmt); 10960 // 1.2.2 OpenMP Language Terminology 10961 // Structured block - An executable statement with a single entry at the 10962 // top and a single exit at the bottom. 10963 // The point of exit cannot be a branch out of the structured block. 10964 // longjmp() and throw() must not violate the entry/exit criteria. 10965 CS->getCapturedDecl()->setNothrow(); 10966 10967 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_teams); 10968 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10969 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10970 // 1.2.2 OpenMP Language Terminology 10971 // Structured block - An executable statement with a single entry at the 10972 // top and a single exit at the bottom. 10973 // The point of exit cannot be a branch out of the structured block. 10974 // longjmp() and throw() must not violate the entry/exit criteria. 10975 CS->getCapturedDecl()->setNothrow(); 10976 } 10977 setFunctionHasBranchProtectedScope(); 10978 10979 return OMPTargetTeamsDirective::Create(Context, StartLoc, EndLoc, Clauses, 10980 AStmt); 10981 } 10982 10983 StmtResult Sema::ActOnOpenMPTargetTeamsDistributeDirective( 10984 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10985 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10986 if (!AStmt) 10987 return StmtError(); 10988 10989 auto *CS = cast<CapturedStmt>(AStmt); 10990 // 1.2.2 OpenMP Language Terminology 10991 // Structured block - An executable statement with a single entry at the 10992 // top and a single exit at the bottom. 10993 // The point of exit cannot be a branch out of the structured block. 10994 // longjmp() and throw() must not violate the entry/exit criteria. 10995 CS->getCapturedDecl()->setNothrow(); 10996 for (int ThisCaptureLevel = 10997 getOpenMPCaptureLevels(OMPD_target_teams_distribute); 10998 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10999 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 11000 // 1.2.2 OpenMP Language Terminology 11001 // Structured block - An executable statement with a single entry at the 11002 // top and a single exit at the bottom. 11003 // The point of exit cannot be a branch out of the structured block. 11004 // longjmp() and throw() must not violate the entry/exit criteria. 11005 CS->getCapturedDecl()->setNothrow(); 11006 } 11007 11008 OMPLoopDirective::HelperExprs B; 11009 // In presence of clause 'collapse' with number of loops, it will 11010 // define the nested loops number. 11011 unsigned NestedLoopCount = checkOpenMPLoop( 11012 OMPD_target_teams_distribute, getCollapseNumberExpr(Clauses), 11013 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 11014 VarsWithImplicitDSA, B); 11015 if (NestedLoopCount == 0) 11016 return StmtError(); 11017 11018 assert((CurContext->isDependentContext() || B.builtAll()) && 11019 "omp target teams distribute loop exprs were not built"); 11020 11021 setFunctionHasBranchProtectedScope(); 11022 return OMPTargetTeamsDistributeDirective::Create( 11023 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 11024 } 11025 11026 StmtResult Sema::ActOnOpenMPTargetTeamsDistributeParallelForDirective( 11027 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 11028 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 11029 if (!AStmt) 11030 return StmtError(); 11031 11032 auto *CS = cast<CapturedStmt>(AStmt); 11033 // 1.2.2 OpenMP Language Terminology 11034 // Structured block - An executable statement with a single entry at the 11035 // top and a single exit at the bottom. 11036 // The point of exit cannot be a branch out of the structured block. 11037 // longjmp() and throw() must not violate the entry/exit criteria. 11038 CS->getCapturedDecl()->setNothrow(); 11039 for (int ThisCaptureLevel = 11040 getOpenMPCaptureLevels(OMPD_target_teams_distribute_parallel_for); 11041 ThisCaptureLevel > 1; --ThisCaptureLevel) { 11042 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 11043 // 1.2.2 OpenMP Language Terminology 11044 // Structured block - An executable statement with a single entry at the 11045 // top and a single exit at the bottom. 11046 // The point of exit cannot be a branch out of the structured block. 11047 // longjmp() and throw() must not violate the entry/exit criteria. 11048 CS->getCapturedDecl()->setNothrow(); 11049 } 11050 11051 OMPLoopDirective::HelperExprs B; 11052 // In presence of clause 'collapse' with number of loops, it will 11053 // define the nested loops number. 11054 unsigned NestedLoopCount = checkOpenMPLoop( 11055 OMPD_target_teams_distribute_parallel_for, getCollapseNumberExpr(Clauses), 11056 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 11057 VarsWithImplicitDSA, B); 11058 if (NestedLoopCount == 0) 11059 return StmtError(); 11060 11061 assert((CurContext->isDependentContext() || B.builtAll()) && 11062 "omp target teams distribute parallel for loop exprs were not built"); 11063 11064 if (!CurContext->isDependentContext()) { 11065 // Finalize the clauses that need pre-built expressions for CodeGen. 11066 for (OMPClause *C : Clauses) { 11067 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 11068 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 11069 B.NumIterations, *this, CurScope, 11070 DSAStack)) 11071 return StmtError(); 11072 } 11073 } 11074 11075 setFunctionHasBranchProtectedScope(); 11076 return OMPTargetTeamsDistributeParallelForDirective::Create( 11077 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B, 11078 DSAStack->isCancelRegion()); 11079 } 11080 11081 StmtResult Sema::ActOnOpenMPTargetTeamsDistributeParallelForSimdDirective( 11082 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 11083 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 11084 if (!AStmt) 11085 return StmtError(); 11086 11087 auto *CS = cast<CapturedStmt>(AStmt); 11088 // 1.2.2 OpenMP Language Terminology 11089 // Structured block - An executable statement with a single entry at the 11090 // top and a single exit at the bottom. 11091 // The point of exit cannot be a branch out of the structured block. 11092 // longjmp() and throw() must not violate the entry/exit criteria. 11093 CS->getCapturedDecl()->setNothrow(); 11094 for (int ThisCaptureLevel = getOpenMPCaptureLevels( 11095 OMPD_target_teams_distribute_parallel_for_simd); 11096 ThisCaptureLevel > 1; --ThisCaptureLevel) { 11097 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 11098 // 1.2.2 OpenMP Language Terminology 11099 // Structured block - An executable statement with a single entry at the 11100 // top and a single exit at the bottom. 11101 // The point of exit cannot be a branch out of the structured block. 11102 // longjmp() and throw() must not violate the entry/exit criteria. 11103 CS->getCapturedDecl()->setNothrow(); 11104 } 11105 11106 OMPLoopDirective::HelperExprs B; 11107 // In presence of clause 'collapse' with number of loops, it will 11108 // define the nested loops number. 11109 unsigned NestedLoopCount = 11110 checkOpenMPLoop(OMPD_target_teams_distribute_parallel_for_simd, 11111 getCollapseNumberExpr(Clauses), 11112 nullptr /*ordered not a clause on distribute*/, CS, *this, 11113 *DSAStack, VarsWithImplicitDSA, B); 11114 if (NestedLoopCount == 0) 11115 return StmtError(); 11116 11117 assert((CurContext->isDependentContext() || B.builtAll()) && 11118 "omp target teams distribute parallel for simd loop exprs were not " 11119 "built"); 11120 11121 if (!CurContext->isDependentContext()) { 11122 // Finalize the clauses that need pre-built expressions for CodeGen. 11123 for (OMPClause *C : Clauses) { 11124 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 11125 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 11126 B.NumIterations, *this, CurScope, 11127 DSAStack)) 11128 return StmtError(); 11129 } 11130 } 11131 11132 if (checkSimdlenSafelenSpecified(*this, Clauses)) 11133 return StmtError(); 11134 11135 setFunctionHasBranchProtectedScope(); 11136 return OMPTargetTeamsDistributeParallelForSimdDirective::Create( 11137 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 11138 } 11139 11140 StmtResult Sema::ActOnOpenMPTargetTeamsDistributeSimdDirective( 11141 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 11142 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 11143 if (!AStmt) 11144 return StmtError(); 11145 11146 auto *CS = cast<CapturedStmt>(AStmt); 11147 // 1.2.2 OpenMP Language Terminology 11148 // Structured block - An executable statement with a single entry at the 11149 // top and a single exit at the bottom. 11150 // The point of exit cannot be a branch out of the structured block. 11151 // longjmp() and throw() must not violate the entry/exit criteria. 11152 CS->getCapturedDecl()->setNothrow(); 11153 for (int ThisCaptureLevel = 11154 getOpenMPCaptureLevels(OMPD_target_teams_distribute_simd); 11155 ThisCaptureLevel > 1; --ThisCaptureLevel) { 11156 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 11157 // 1.2.2 OpenMP Language Terminology 11158 // Structured block - An executable statement with a single entry at the 11159 // top and a single exit at the bottom. 11160 // The point of exit cannot be a branch out of the structured block. 11161 // longjmp() and throw() must not violate the entry/exit criteria. 11162 CS->getCapturedDecl()->setNothrow(); 11163 } 11164 11165 OMPLoopDirective::HelperExprs B; 11166 // In presence of clause 'collapse' with number of loops, it will 11167 // define the nested loops number. 11168 unsigned NestedLoopCount = checkOpenMPLoop( 11169 OMPD_target_teams_distribute_simd, getCollapseNumberExpr(Clauses), 11170 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 11171 VarsWithImplicitDSA, B); 11172 if (NestedLoopCount == 0) 11173 return StmtError(); 11174 11175 assert((CurContext->isDependentContext() || B.builtAll()) && 11176 "omp target teams distribute simd loop exprs were not built"); 11177 11178 if (!CurContext->isDependentContext()) { 11179 // Finalize the clauses that need pre-built expressions for CodeGen. 11180 for (OMPClause *C : Clauses) { 11181 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 11182 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 11183 B.NumIterations, *this, CurScope, 11184 DSAStack)) 11185 return StmtError(); 11186 } 11187 } 11188 11189 if (checkSimdlenSafelenSpecified(*this, Clauses)) 11190 return StmtError(); 11191 11192 setFunctionHasBranchProtectedScope(); 11193 return OMPTargetTeamsDistributeSimdDirective::Create( 11194 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 11195 } 11196 11197 OMPClause *Sema::ActOnOpenMPSingleExprClause(OpenMPClauseKind Kind, Expr *Expr, 11198 SourceLocation StartLoc, 11199 SourceLocation LParenLoc, 11200 SourceLocation EndLoc) { 11201 OMPClause *Res = nullptr; 11202 switch (Kind) { 11203 case OMPC_final: 11204 Res = ActOnOpenMPFinalClause(Expr, StartLoc, LParenLoc, EndLoc); 11205 break; 11206 case OMPC_num_threads: 11207 Res = ActOnOpenMPNumThreadsClause(Expr, StartLoc, LParenLoc, EndLoc); 11208 break; 11209 case OMPC_safelen: 11210 Res = ActOnOpenMPSafelenClause(Expr, StartLoc, LParenLoc, EndLoc); 11211 break; 11212 case OMPC_simdlen: 11213 Res = ActOnOpenMPSimdlenClause(Expr, StartLoc, LParenLoc, EndLoc); 11214 break; 11215 case OMPC_allocator: 11216 Res = ActOnOpenMPAllocatorClause(Expr, StartLoc, LParenLoc, EndLoc); 11217 break; 11218 case OMPC_collapse: 11219 Res = ActOnOpenMPCollapseClause(Expr, StartLoc, LParenLoc, EndLoc); 11220 break; 11221 case OMPC_ordered: 11222 Res = ActOnOpenMPOrderedClause(StartLoc, EndLoc, LParenLoc, Expr); 11223 break; 11224 case OMPC_num_teams: 11225 Res = ActOnOpenMPNumTeamsClause(Expr, StartLoc, LParenLoc, EndLoc); 11226 break; 11227 case OMPC_thread_limit: 11228 Res = ActOnOpenMPThreadLimitClause(Expr, StartLoc, LParenLoc, EndLoc); 11229 break; 11230 case OMPC_priority: 11231 Res = ActOnOpenMPPriorityClause(Expr, StartLoc, LParenLoc, EndLoc); 11232 break; 11233 case OMPC_grainsize: 11234 Res = ActOnOpenMPGrainsizeClause(Expr, StartLoc, LParenLoc, EndLoc); 11235 break; 11236 case OMPC_num_tasks: 11237 Res = ActOnOpenMPNumTasksClause(Expr, StartLoc, LParenLoc, EndLoc); 11238 break; 11239 case OMPC_hint: 11240 Res = ActOnOpenMPHintClause(Expr, StartLoc, LParenLoc, EndLoc); 11241 break; 11242 case OMPC_depobj: 11243 Res = ActOnOpenMPDepobjClause(Expr, StartLoc, LParenLoc, EndLoc); 11244 break; 11245 case OMPC_detach: 11246 Res = ActOnOpenMPDetachClause(Expr, StartLoc, LParenLoc, EndLoc); 11247 break; 11248 case OMPC_device: 11249 case OMPC_if: 11250 case OMPC_default: 11251 case OMPC_proc_bind: 11252 case OMPC_schedule: 11253 case OMPC_private: 11254 case OMPC_firstprivate: 11255 case OMPC_lastprivate: 11256 case OMPC_shared: 11257 case OMPC_reduction: 11258 case OMPC_task_reduction: 11259 case OMPC_in_reduction: 11260 case OMPC_linear: 11261 case OMPC_aligned: 11262 case OMPC_copyin: 11263 case OMPC_copyprivate: 11264 case OMPC_nowait: 11265 case OMPC_untied: 11266 case OMPC_mergeable: 11267 case OMPC_threadprivate: 11268 case OMPC_allocate: 11269 case OMPC_flush: 11270 case OMPC_read: 11271 case OMPC_write: 11272 case OMPC_update: 11273 case OMPC_capture: 11274 case OMPC_seq_cst: 11275 case OMPC_acq_rel: 11276 case OMPC_acquire: 11277 case OMPC_release: 11278 case OMPC_relaxed: 11279 case OMPC_depend: 11280 case OMPC_threads: 11281 case OMPC_simd: 11282 case OMPC_map: 11283 case OMPC_nogroup: 11284 case OMPC_dist_schedule: 11285 case OMPC_defaultmap: 11286 case OMPC_unknown: 11287 case OMPC_uniform: 11288 case OMPC_to: 11289 case OMPC_from: 11290 case OMPC_use_device_ptr: 11291 case OMPC_is_device_ptr: 11292 case OMPC_unified_address: 11293 case OMPC_unified_shared_memory: 11294 case OMPC_reverse_offload: 11295 case OMPC_dynamic_allocators: 11296 case OMPC_atomic_default_mem_order: 11297 case OMPC_device_type: 11298 case OMPC_match: 11299 case OMPC_nontemporal: 11300 case OMPC_order: 11301 case OMPC_destroy: 11302 case OMPC_inclusive: 11303 case OMPC_exclusive: 11304 llvm_unreachable("Clause is not allowed."); 11305 } 11306 return Res; 11307 } 11308 11309 // An OpenMP directive such as 'target parallel' has two captured regions: 11310 // for the 'target' and 'parallel' respectively. This function returns 11311 // the region in which to capture expressions associated with a clause. 11312 // A return value of OMPD_unknown signifies that the expression should not 11313 // be captured. 11314 static OpenMPDirectiveKind getOpenMPCaptureRegionForClause( 11315 OpenMPDirectiveKind DKind, OpenMPClauseKind CKind, unsigned OpenMPVersion, 11316 OpenMPDirectiveKind NameModifier = OMPD_unknown) { 11317 OpenMPDirectiveKind CaptureRegion = OMPD_unknown; 11318 switch (CKind) { 11319 case OMPC_if: 11320 switch (DKind) { 11321 case OMPD_target_parallel_for_simd: 11322 if (OpenMPVersion >= 50 && 11323 (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)) { 11324 CaptureRegion = OMPD_parallel; 11325 break; 11326 } 11327 LLVM_FALLTHROUGH; 11328 case OMPD_target_parallel: 11329 case OMPD_target_parallel_for: 11330 // If this clause applies to the nested 'parallel' region, capture within 11331 // the 'target' region, otherwise do not capture. 11332 if (NameModifier == OMPD_unknown || NameModifier == OMPD_parallel) 11333 CaptureRegion = OMPD_target; 11334 break; 11335 case OMPD_target_teams_distribute_parallel_for_simd: 11336 if (OpenMPVersion >= 50 && 11337 (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)) { 11338 CaptureRegion = OMPD_parallel; 11339 break; 11340 } 11341 LLVM_FALLTHROUGH; 11342 case OMPD_target_teams_distribute_parallel_for: 11343 // If this clause applies to the nested 'parallel' region, capture within 11344 // the 'teams' region, otherwise do not capture. 11345 if (NameModifier == OMPD_unknown || NameModifier == OMPD_parallel) 11346 CaptureRegion = OMPD_teams; 11347 break; 11348 case OMPD_teams_distribute_parallel_for_simd: 11349 if (OpenMPVersion >= 50 && 11350 (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)) { 11351 CaptureRegion = OMPD_parallel; 11352 break; 11353 } 11354 LLVM_FALLTHROUGH; 11355 case OMPD_teams_distribute_parallel_for: 11356 CaptureRegion = OMPD_teams; 11357 break; 11358 case OMPD_target_update: 11359 case OMPD_target_enter_data: 11360 case OMPD_target_exit_data: 11361 CaptureRegion = OMPD_task; 11362 break; 11363 case OMPD_parallel_master_taskloop: 11364 if (NameModifier == OMPD_unknown || NameModifier == OMPD_taskloop) 11365 CaptureRegion = OMPD_parallel; 11366 break; 11367 case OMPD_parallel_master_taskloop_simd: 11368 if ((OpenMPVersion <= 45 && NameModifier == OMPD_unknown) || 11369 NameModifier == OMPD_taskloop) { 11370 CaptureRegion = OMPD_parallel; 11371 break; 11372 } 11373 if (OpenMPVersion <= 45) 11374 break; 11375 if (NameModifier == OMPD_unknown || NameModifier == OMPD_simd) 11376 CaptureRegion = OMPD_taskloop; 11377 break; 11378 case OMPD_parallel_for_simd: 11379 if (OpenMPVersion <= 45) 11380 break; 11381 if (NameModifier == OMPD_unknown || NameModifier == OMPD_simd) 11382 CaptureRegion = OMPD_parallel; 11383 break; 11384 case OMPD_taskloop_simd: 11385 case OMPD_master_taskloop_simd: 11386 if (OpenMPVersion <= 45) 11387 break; 11388 if (NameModifier == OMPD_unknown || NameModifier == OMPD_simd) 11389 CaptureRegion = OMPD_taskloop; 11390 break; 11391 case OMPD_distribute_parallel_for_simd: 11392 if (OpenMPVersion <= 45) 11393 break; 11394 if (NameModifier == OMPD_unknown || NameModifier == OMPD_simd) 11395 CaptureRegion = OMPD_parallel; 11396 break; 11397 case OMPD_target_simd: 11398 if (OpenMPVersion >= 50 && 11399 (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)) 11400 CaptureRegion = OMPD_target; 11401 break; 11402 case OMPD_teams_distribute_simd: 11403 case OMPD_target_teams_distribute_simd: 11404 if (OpenMPVersion >= 50 && 11405 (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)) 11406 CaptureRegion = OMPD_teams; 11407 break; 11408 case OMPD_cancel: 11409 case OMPD_parallel: 11410 case OMPD_parallel_master: 11411 case OMPD_parallel_sections: 11412 case OMPD_parallel_for: 11413 case OMPD_target: 11414 case OMPD_target_teams: 11415 case OMPD_target_teams_distribute: 11416 case OMPD_distribute_parallel_for: 11417 case OMPD_task: 11418 case OMPD_taskloop: 11419 case OMPD_master_taskloop: 11420 case OMPD_target_data: 11421 case OMPD_simd: 11422 case OMPD_for_simd: 11423 case OMPD_distribute_simd: 11424 // Do not capture if-clause expressions. 11425 break; 11426 case OMPD_threadprivate: 11427 case OMPD_allocate: 11428 case OMPD_taskyield: 11429 case OMPD_barrier: 11430 case OMPD_taskwait: 11431 case OMPD_cancellation_point: 11432 case OMPD_flush: 11433 case OMPD_depobj: 11434 case OMPD_scan: 11435 case OMPD_declare_reduction: 11436 case OMPD_declare_mapper: 11437 case OMPD_declare_simd: 11438 case OMPD_declare_variant: 11439 case OMPD_begin_declare_variant: 11440 case OMPD_end_declare_variant: 11441 case OMPD_declare_target: 11442 case OMPD_end_declare_target: 11443 case OMPD_teams: 11444 case OMPD_for: 11445 case OMPD_sections: 11446 case OMPD_section: 11447 case OMPD_single: 11448 case OMPD_master: 11449 case OMPD_critical: 11450 case OMPD_taskgroup: 11451 case OMPD_distribute: 11452 case OMPD_ordered: 11453 case OMPD_atomic: 11454 case OMPD_teams_distribute: 11455 case OMPD_requires: 11456 llvm_unreachable("Unexpected OpenMP directive with if-clause"); 11457 case OMPD_unknown: 11458 llvm_unreachable("Unknown OpenMP directive"); 11459 } 11460 break; 11461 case OMPC_num_threads: 11462 switch (DKind) { 11463 case OMPD_target_parallel: 11464 case OMPD_target_parallel_for: 11465 case OMPD_target_parallel_for_simd: 11466 CaptureRegion = OMPD_target; 11467 break; 11468 case OMPD_teams_distribute_parallel_for: 11469 case OMPD_teams_distribute_parallel_for_simd: 11470 case OMPD_target_teams_distribute_parallel_for: 11471 case OMPD_target_teams_distribute_parallel_for_simd: 11472 CaptureRegion = OMPD_teams; 11473 break; 11474 case OMPD_parallel: 11475 case OMPD_parallel_master: 11476 case OMPD_parallel_sections: 11477 case OMPD_parallel_for: 11478 case OMPD_parallel_for_simd: 11479 case OMPD_distribute_parallel_for: 11480 case OMPD_distribute_parallel_for_simd: 11481 case OMPD_parallel_master_taskloop: 11482 case OMPD_parallel_master_taskloop_simd: 11483 // Do not capture num_threads-clause expressions. 11484 break; 11485 case OMPD_target_data: 11486 case OMPD_target_enter_data: 11487 case OMPD_target_exit_data: 11488 case OMPD_target_update: 11489 case OMPD_target: 11490 case OMPD_target_simd: 11491 case OMPD_target_teams: 11492 case OMPD_target_teams_distribute: 11493 case OMPD_target_teams_distribute_simd: 11494 case OMPD_cancel: 11495 case OMPD_task: 11496 case OMPD_taskloop: 11497 case OMPD_taskloop_simd: 11498 case OMPD_master_taskloop: 11499 case OMPD_master_taskloop_simd: 11500 case OMPD_threadprivate: 11501 case OMPD_allocate: 11502 case OMPD_taskyield: 11503 case OMPD_barrier: 11504 case OMPD_taskwait: 11505 case OMPD_cancellation_point: 11506 case OMPD_flush: 11507 case OMPD_depobj: 11508 case OMPD_scan: 11509 case OMPD_declare_reduction: 11510 case OMPD_declare_mapper: 11511 case OMPD_declare_simd: 11512 case OMPD_declare_variant: 11513 case OMPD_begin_declare_variant: 11514 case OMPD_end_declare_variant: 11515 case OMPD_declare_target: 11516 case OMPD_end_declare_target: 11517 case OMPD_teams: 11518 case OMPD_simd: 11519 case OMPD_for: 11520 case OMPD_for_simd: 11521 case OMPD_sections: 11522 case OMPD_section: 11523 case OMPD_single: 11524 case OMPD_master: 11525 case OMPD_critical: 11526 case OMPD_taskgroup: 11527 case OMPD_distribute: 11528 case OMPD_ordered: 11529 case OMPD_atomic: 11530 case OMPD_distribute_simd: 11531 case OMPD_teams_distribute: 11532 case OMPD_teams_distribute_simd: 11533 case OMPD_requires: 11534 llvm_unreachable("Unexpected OpenMP directive with num_threads-clause"); 11535 case OMPD_unknown: 11536 llvm_unreachable("Unknown OpenMP directive"); 11537 } 11538 break; 11539 case OMPC_num_teams: 11540 switch (DKind) { 11541 case OMPD_target_teams: 11542 case OMPD_target_teams_distribute: 11543 case OMPD_target_teams_distribute_simd: 11544 case OMPD_target_teams_distribute_parallel_for: 11545 case OMPD_target_teams_distribute_parallel_for_simd: 11546 CaptureRegion = OMPD_target; 11547 break; 11548 case OMPD_teams_distribute_parallel_for: 11549 case OMPD_teams_distribute_parallel_for_simd: 11550 case OMPD_teams: 11551 case OMPD_teams_distribute: 11552 case OMPD_teams_distribute_simd: 11553 // Do not capture num_teams-clause expressions. 11554 break; 11555 case OMPD_distribute_parallel_for: 11556 case OMPD_distribute_parallel_for_simd: 11557 case OMPD_task: 11558 case OMPD_taskloop: 11559 case OMPD_taskloop_simd: 11560 case OMPD_master_taskloop: 11561 case OMPD_master_taskloop_simd: 11562 case OMPD_parallel_master_taskloop: 11563 case OMPD_parallel_master_taskloop_simd: 11564 case OMPD_target_data: 11565 case OMPD_target_enter_data: 11566 case OMPD_target_exit_data: 11567 case OMPD_target_update: 11568 case OMPD_cancel: 11569 case OMPD_parallel: 11570 case OMPD_parallel_master: 11571 case OMPD_parallel_sections: 11572 case OMPD_parallel_for: 11573 case OMPD_parallel_for_simd: 11574 case OMPD_target: 11575 case OMPD_target_simd: 11576 case OMPD_target_parallel: 11577 case OMPD_target_parallel_for: 11578 case OMPD_target_parallel_for_simd: 11579 case OMPD_threadprivate: 11580 case OMPD_allocate: 11581 case OMPD_taskyield: 11582 case OMPD_barrier: 11583 case OMPD_taskwait: 11584 case OMPD_cancellation_point: 11585 case OMPD_flush: 11586 case OMPD_depobj: 11587 case OMPD_scan: 11588 case OMPD_declare_reduction: 11589 case OMPD_declare_mapper: 11590 case OMPD_declare_simd: 11591 case OMPD_declare_variant: 11592 case OMPD_begin_declare_variant: 11593 case OMPD_end_declare_variant: 11594 case OMPD_declare_target: 11595 case OMPD_end_declare_target: 11596 case OMPD_simd: 11597 case OMPD_for: 11598 case OMPD_for_simd: 11599 case OMPD_sections: 11600 case OMPD_section: 11601 case OMPD_single: 11602 case OMPD_master: 11603 case OMPD_critical: 11604 case OMPD_taskgroup: 11605 case OMPD_distribute: 11606 case OMPD_ordered: 11607 case OMPD_atomic: 11608 case OMPD_distribute_simd: 11609 case OMPD_requires: 11610 llvm_unreachable("Unexpected OpenMP directive with num_teams-clause"); 11611 case OMPD_unknown: 11612 llvm_unreachable("Unknown OpenMP directive"); 11613 } 11614 break; 11615 case OMPC_thread_limit: 11616 switch (DKind) { 11617 case OMPD_target_teams: 11618 case OMPD_target_teams_distribute: 11619 case OMPD_target_teams_distribute_simd: 11620 case OMPD_target_teams_distribute_parallel_for: 11621 case OMPD_target_teams_distribute_parallel_for_simd: 11622 CaptureRegion = OMPD_target; 11623 break; 11624 case OMPD_teams_distribute_parallel_for: 11625 case OMPD_teams_distribute_parallel_for_simd: 11626 case OMPD_teams: 11627 case OMPD_teams_distribute: 11628 case OMPD_teams_distribute_simd: 11629 // Do not capture thread_limit-clause expressions. 11630 break; 11631 case OMPD_distribute_parallel_for: 11632 case OMPD_distribute_parallel_for_simd: 11633 case OMPD_task: 11634 case OMPD_taskloop: 11635 case OMPD_taskloop_simd: 11636 case OMPD_master_taskloop: 11637 case OMPD_master_taskloop_simd: 11638 case OMPD_parallel_master_taskloop: 11639 case OMPD_parallel_master_taskloop_simd: 11640 case OMPD_target_data: 11641 case OMPD_target_enter_data: 11642 case OMPD_target_exit_data: 11643 case OMPD_target_update: 11644 case OMPD_cancel: 11645 case OMPD_parallel: 11646 case OMPD_parallel_master: 11647 case OMPD_parallel_sections: 11648 case OMPD_parallel_for: 11649 case OMPD_parallel_for_simd: 11650 case OMPD_target: 11651 case OMPD_target_simd: 11652 case OMPD_target_parallel: 11653 case OMPD_target_parallel_for: 11654 case OMPD_target_parallel_for_simd: 11655 case OMPD_threadprivate: 11656 case OMPD_allocate: 11657 case OMPD_taskyield: 11658 case OMPD_barrier: 11659 case OMPD_taskwait: 11660 case OMPD_cancellation_point: 11661 case OMPD_flush: 11662 case OMPD_depobj: 11663 case OMPD_scan: 11664 case OMPD_declare_reduction: 11665 case OMPD_declare_mapper: 11666 case OMPD_declare_simd: 11667 case OMPD_declare_variant: 11668 case OMPD_begin_declare_variant: 11669 case OMPD_end_declare_variant: 11670 case OMPD_declare_target: 11671 case OMPD_end_declare_target: 11672 case OMPD_simd: 11673 case OMPD_for: 11674 case OMPD_for_simd: 11675 case OMPD_sections: 11676 case OMPD_section: 11677 case OMPD_single: 11678 case OMPD_master: 11679 case OMPD_critical: 11680 case OMPD_taskgroup: 11681 case OMPD_distribute: 11682 case OMPD_ordered: 11683 case OMPD_atomic: 11684 case OMPD_distribute_simd: 11685 case OMPD_requires: 11686 llvm_unreachable("Unexpected OpenMP directive with thread_limit-clause"); 11687 case OMPD_unknown: 11688 llvm_unreachable("Unknown OpenMP directive"); 11689 } 11690 break; 11691 case OMPC_schedule: 11692 switch (DKind) { 11693 case OMPD_parallel_for: 11694 case OMPD_parallel_for_simd: 11695 case OMPD_distribute_parallel_for: 11696 case OMPD_distribute_parallel_for_simd: 11697 case OMPD_teams_distribute_parallel_for: 11698 case OMPD_teams_distribute_parallel_for_simd: 11699 case OMPD_target_parallel_for: 11700 case OMPD_target_parallel_for_simd: 11701 case OMPD_target_teams_distribute_parallel_for: 11702 case OMPD_target_teams_distribute_parallel_for_simd: 11703 CaptureRegion = OMPD_parallel; 11704 break; 11705 case OMPD_for: 11706 case OMPD_for_simd: 11707 // Do not capture schedule-clause expressions. 11708 break; 11709 case OMPD_task: 11710 case OMPD_taskloop: 11711 case OMPD_taskloop_simd: 11712 case OMPD_master_taskloop: 11713 case OMPD_master_taskloop_simd: 11714 case OMPD_parallel_master_taskloop: 11715 case OMPD_parallel_master_taskloop_simd: 11716 case OMPD_target_data: 11717 case OMPD_target_enter_data: 11718 case OMPD_target_exit_data: 11719 case OMPD_target_update: 11720 case OMPD_teams: 11721 case OMPD_teams_distribute: 11722 case OMPD_teams_distribute_simd: 11723 case OMPD_target_teams_distribute: 11724 case OMPD_target_teams_distribute_simd: 11725 case OMPD_target: 11726 case OMPD_target_simd: 11727 case OMPD_target_parallel: 11728 case OMPD_cancel: 11729 case OMPD_parallel: 11730 case OMPD_parallel_master: 11731 case OMPD_parallel_sections: 11732 case OMPD_threadprivate: 11733 case OMPD_allocate: 11734 case OMPD_taskyield: 11735 case OMPD_barrier: 11736 case OMPD_taskwait: 11737 case OMPD_cancellation_point: 11738 case OMPD_flush: 11739 case OMPD_depobj: 11740 case OMPD_scan: 11741 case OMPD_declare_reduction: 11742 case OMPD_declare_mapper: 11743 case OMPD_declare_simd: 11744 case OMPD_declare_variant: 11745 case OMPD_begin_declare_variant: 11746 case OMPD_end_declare_variant: 11747 case OMPD_declare_target: 11748 case OMPD_end_declare_target: 11749 case OMPD_simd: 11750 case OMPD_sections: 11751 case OMPD_section: 11752 case OMPD_single: 11753 case OMPD_master: 11754 case OMPD_critical: 11755 case OMPD_taskgroup: 11756 case OMPD_distribute: 11757 case OMPD_ordered: 11758 case OMPD_atomic: 11759 case OMPD_distribute_simd: 11760 case OMPD_target_teams: 11761 case OMPD_requires: 11762 llvm_unreachable("Unexpected OpenMP directive with schedule clause"); 11763 case OMPD_unknown: 11764 llvm_unreachable("Unknown OpenMP directive"); 11765 } 11766 break; 11767 case OMPC_dist_schedule: 11768 switch (DKind) { 11769 case OMPD_teams_distribute_parallel_for: 11770 case OMPD_teams_distribute_parallel_for_simd: 11771 case OMPD_teams_distribute: 11772 case OMPD_teams_distribute_simd: 11773 case OMPD_target_teams_distribute_parallel_for: 11774 case OMPD_target_teams_distribute_parallel_for_simd: 11775 case OMPD_target_teams_distribute: 11776 case OMPD_target_teams_distribute_simd: 11777 CaptureRegion = OMPD_teams; 11778 break; 11779 case OMPD_distribute_parallel_for: 11780 case OMPD_distribute_parallel_for_simd: 11781 case OMPD_distribute: 11782 case OMPD_distribute_simd: 11783 // Do not capture thread_limit-clause expressions. 11784 break; 11785 case OMPD_parallel_for: 11786 case OMPD_parallel_for_simd: 11787 case OMPD_target_parallel_for_simd: 11788 case OMPD_target_parallel_for: 11789 case OMPD_task: 11790 case OMPD_taskloop: 11791 case OMPD_taskloop_simd: 11792 case OMPD_master_taskloop: 11793 case OMPD_master_taskloop_simd: 11794 case OMPD_parallel_master_taskloop: 11795 case OMPD_parallel_master_taskloop_simd: 11796 case OMPD_target_data: 11797 case OMPD_target_enter_data: 11798 case OMPD_target_exit_data: 11799 case OMPD_target_update: 11800 case OMPD_teams: 11801 case OMPD_target: 11802 case OMPD_target_simd: 11803 case OMPD_target_parallel: 11804 case OMPD_cancel: 11805 case OMPD_parallel: 11806 case OMPD_parallel_master: 11807 case OMPD_parallel_sections: 11808 case OMPD_threadprivate: 11809 case OMPD_allocate: 11810 case OMPD_taskyield: 11811 case OMPD_barrier: 11812 case OMPD_taskwait: 11813 case OMPD_cancellation_point: 11814 case OMPD_flush: 11815 case OMPD_depobj: 11816 case OMPD_scan: 11817 case OMPD_declare_reduction: 11818 case OMPD_declare_mapper: 11819 case OMPD_declare_simd: 11820 case OMPD_declare_variant: 11821 case OMPD_begin_declare_variant: 11822 case OMPD_end_declare_variant: 11823 case OMPD_declare_target: 11824 case OMPD_end_declare_target: 11825 case OMPD_simd: 11826 case OMPD_for: 11827 case OMPD_for_simd: 11828 case OMPD_sections: 11829 case OMPD_section: 11830 case OMPD_single: 11831 case OMPD_master: 11832 case OMPD_critical: 11833 case OMPD_taskgroup: 11834 case OMPD_ordered: 11835 case OMPD_atomic: 11836 case OMPD_target_teams: 11837 case OMPD_requires: 11838 llvm_unreachable("Unexpected OpenMP directive with schedule clause"); 11839 case OMPD_unknown: 11840 llvm_unreachable("Unknown OpenMP directive"); 11841 } 11842 break; 11843 case OMPC_device: 11844 switch (DKind) { 11845 case OMPD_target_update: 11846 case OMPD_target_enter_data: 11847 case OMPD_target_exit_data: 11848 case OMPD_target: 11849 case OMPD_target_simd: 11850 case OMPD_target_teams: 11851 case OMPD_target_parallel: 11852 case OMPD_target_teams_distribute: 11853 case OMPD_target_teams_distribute_simd: 11854 case OMPD_target_parallel_for: 11855 case OMPD_target_parallel_for_simd: 11856 case OMPD_target_teams_distribute_parallel_for: 11857 case OMPD_target_teams_distribute_parallel_for_simd: 11858 CaptureRegion = OMPD_task; 11859 break; 11860 case OMPD_target_data: 11861 // Do not capture device-clause expressions. 11862 break; 11863 case OMPD_teams_distribute_parallel_for: 11864 case OMPD_teams_distribute_parallel_for_simd: 11865 case OMPD_teams: 11866 case OMPD_teams_distribute: 11867 case OMPD_teams_distribute_simd: 11868 case OMPD_distribute_parallel_for: 11869 case OMPD_distribute_parallel_for_simd: 11870 case OMPD_task: 11871 case OMPD_taskloop: 11872 case OMPD_taskloop_simd: 11873 case OMPD_master_taskloop: 11874 case OMPD_master_taskloop_simd: 11875 case OMPD_parallel_master_taskloop: 11876 case OMPD_parallel_master_taskloop_simd: 11877 case OMPD_cancel: 11878 case OMPD_parallel: 11879 case OMPD_parallel_master: 11880 case OMPD_parallel_sections: 11881 case OMPD_parallel_for: 11882 case OMPD_parallel_for_simd: 11883 case OMPD_threadprivate: 11884 case OMPD_allocate: 11885 case OMPD_taskyield: 11886 case OMPD_barrier: 11887 case OMPD_taskwait: 11888 case OMPD_cancellation_point: 11889 case OMPD_flush: 11890 case OMPD_depobj: 11891 case OMPD_scan: 11892 case OMPD_declare_reduction: 11893 case OMPD_declare_mapper: 11894 case OMPD_declare_simd: 11895 case OMPD_declare_variant: 11896 case OMPD_begin_declare_variant: 11897 case OMPD_end_declare_variant: 11898 case OMPD_declare_target: 11899 case OMPD_end_declare_target: 11900 case OMPD_simd: 11901 case OMPD_for: 11902 case OMPD_for_simd: 11903 case OMPD_sections: 11904 case OMPD_section: 11905 case OMPD_single: 11906 case OMPD_master: 11907 case OMPD_critical: 11908 case OMPD_taskgroup: 11909 case OMPD_distribute: 11910 case OMPD_ordered: 11911 case OMPD_atomic: 11912 case OMPD_distribute_simd: 11913 case OMPD_requires: 11914 llvm_unreachable("Unexpected OpenMP directive with num_teams-clause"); 11915 case OMPD_unknown: 11916 llvm_unreachable("Unknown OpenMP directive"); 11917 } 11918 break; 11919 case OMPC_grainsize: 11920 case OMPC_num_tasks: 11921 case OMPC_final: 11922 case OMPC_priority: 11923 switch (DKind) { 11924 case OMPD_task: 11925 case OMPD_taskloop: 11926 case OMPD_taskloop_simd: 11927 case OMPD_master_taskloop: 11928 case OMPD_master_taskloop_simd: 11929 break; 11930 case OMPD_parallel_master_taskloop: 11931 case OMPD_parallel_master_taskloop_simd: 11932 CaptureRegion = OMPD_parallel; 11933 break; 11934 case OMPD_target_update: 11935 case OMPD_target_enter_data: 11936 case OMPD_target_exit_data: 11937 case OMPD_target: 11938 case OMPD_target_simd: 11939 case OMPD_target_teams: 11940 case OMPD_target_parallel: 11941 case OMPD_target_teams_distribute: 11942 case OMPD_target_teams_distribute_simd: 11943 case OMPD_target_parallel_for: 11944 case OMPD_target_parallel_for_simd: 11945 case OMPD_target_teams_distribute_parallel_for: 11946 case OMPD_target_teams_distribute_parallel_for_simd: 11947 case OMPD_target_data: 11948 case OMPD_teams_distribute_parallel_for: 11949 case OMPD_teams_distribute_parallel_for_simd: 11950 case OMPD_teams: 11951 case OMPD_teams_distribute: 11952 case OMPD_teams_distribute_simd: 11953 case OMPD_distribute_parallel_for: 11954 case OMPD_distribute_parallel_for_simd: 11955 case OMPD_cancel: 11956 case OMPD_parallel: 11957 case OMPD_parallel_master: 11958 case OMPD_parallel_sections: 11959 case OMPD_parallel_for: 11960 case OMPD_parallel_for_simd: 11961 case OMPD_threadprivate: 11962 case OMPD_allocate: 11963 case OMPD_taskyield: 11964 case OMPD_barrier: 11965 case OMPD_taskwait: 11966 case OMPD_cancellation_point: 11967 case OMPD_flush: 11968 case OMPD_depobj: 11969 case OMPD_scan: 11970 case OMPD_declare_reduction: 11971 case OMPD_declare_mapper: 11972 case OMPD_declare_simd: 11973 case OMPD_declare_variant: 11974 case OMPD_begin_declare_variant: 11975 case OMPD_end_declare_variant: 11976 case OMPD_declare_target: 11977 case OMPD_end_declare_target: 11978 case OMPD_simd: 11979 case OMPD_for: 11980 case OMPD_for_simd: 11981 case OMPD_sections: 11982 case OMPD_section: 11983 case OMPD_single: 11984 case OMPD_master: 11985 case OMPD_critical: 11986 case OMPD_taskgroup: 11987 case OMPD_distribute: 11988 case OMPD_ordered: 11989 case OMPD_atomic: 11990 case OMPD_distribute_simd: 11991 case OMPD_requires: 11992 llvm_unreachable("Unexpected OpenMP directive with grainsize-clause"); 11993 case OMPD_unknown: 11994 llvm_unreachable("Unknown OpenMP directive"); 11995 } 11996 break; 11997 case OMPC_firstprivate: 11998 case OMPC_lastprivate: 11999 case OMPC_reduction: 12000 case OMPC_task_reduction: 12001 case OMPC_in_reduction: 12002 case OMPC_linear: 12003 case OMPC_default: 12004 case OMPC_proc_bind: 12005 case OMPC_safelen: 12006 case OMPC_simdlen: 12007 case OMPC_allocator: 12008 case OMPC_collapse: 12009 case OMPC_private: 12010 case OMPC_shared: 12011 case OMPC_aligned: 12012 case OMPC_copyin: 12013 case OMPC_copyprivate: 12014 case OMPC_ordered: 12015 case OMPC_nowait: 12016 case OMPC_untied: 12017 case OMPC_mergeable: 12018 case OMPC_threadprivate: 12019 case OMPC_allocate: 12020 case OMPC_flush: 12021 case OMPC_depobj: 12022 case OMPC_read: 12023 case OMPC_write: 12024 case OMPC_update: 12025 case OMPC_capture: 12026 case OMPC_seq_cst: 12027 case OMPC_acq_rel: 12028 case OMPC_acquire: 12029 case OMPC_release: 12030 case OMPC_relaxed: 12031 case OMPC_depend: 12032 case OMPC_threads: 12033 case OMPC_simd: 12034 case OMPC_map: 12035 case OMPC_nogroup: 12036 case OMPC_hint: 12037 case OMPC_defaultmap: 12038 case OMPC_unknown: 12039 case OMPC_uniform: 12040 case OMPC_to: 12041 case OMPC_from: 12042 case OMPC_use_device_ptr: 12043 case OMPC_is_device_ptr: 12044 case OMPC_unified_address: 12045 case OMPC_unified_shared_memory: 12046 case OMPC_reverse_offload: 12047 case OMPC_dynamic_allocators: 12048 case OMPC_atomic_default_mem_order: 12049 case OMPC_device_type: 12050 case OMPC_match: 12051 case OMPC_nontemporal: 12052 case OMPC_order: 12053 case OMPC_destroy: 12054 case OMPC_detach: 12055 case OMPC_inclusive: 12056 case OMPC_exclusive: 12057 llvm_unreachable("Unexpected OpenMP clause."); 12058 } 12059 return CaptureRegion; 12060 } 12061 12062 OMPClause *Sema::ActOnOpenMPIfClause(OpenMPDirectiveKind NameModifier, 12063 Expr *Condition, SourceLocation StartLoc, 12064 SourceLocation LParenLoc, 12065 SourceLocation NameModifierLoc, 12066 SourceLocation ColonLoc, 12067 SourceLocation EndLoc) { 12068 Expr *ValExpr = Condition; 12069 Stmt *HelperValStmt = nullptr; 12070 OpenMPDirectiveKind CaptureRegion = OMPD_unknown; 12071 if (!Condition->isValueDependent() && !Condition->isTypeDependent() && 12072 !Condition->isInstantiationDependent() && 12073 !Condition->containsUnexpandedParameterPack()) { 12074 ExprResult Val = CheckBooleanCondition(StartLoc, Condition); 12075 if (Val.isInvalid()) 12076 return nullptr; 12077 12078 ValExpr = Val.get(); 12079 12080 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 12081 CaptureRegion = getOpenMPCaptureRegionForClause( 12082 DKind, OMPC_if, LangOpts.OpenMP, NameModifier); 12083 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 12084 ValExpr = MakeFullExpr(ValExpr).get(); 12085 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 12086 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 12087 HelperValStmt = buildPreInits(Context, Captures); 12088 } 12089 } 12090 12091 return new (Context) 12092 OMPIfClause(NameModifier, ValExpr, HelperValStmt, CaptureRegion, StartLoc, 12093 LParenLoc, NameModifierLoc, ColonLoc, EndLoc); 12094 } 12095 12096 OMPClause *Sema::ActOnOpenMPFinalClause(Expr *Condition, 12097 SourceLocation StartLoc, 12098 SourceLocation LParenLoc, 12099 SourceLocation EndLoc) { 12100 Expr *ValExpr = Condition; 12101 Stmt *HelperValStmt = nullptr; 12102 OpenMPDirectiveKind CaptureRegion = OMPD_unknown; 12103 if (!Condition->isValueDependent() && !Condition->isTypeDependent() && 12104 !Condition->isInstantiationDependent() && 12105 !Condition->containsUnexpandedParameterPack()) { 12106 ExprResult Val = CheckBooleanCondition(StartLoc, Condition); 12107 if (Val.isInvalid()) 12108 return nullptr; 12109 12110 ValExpr = MakeFullExpr(Val.get()).get(); 12111 12112 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 12113 CaptureRegion = 12114 getOpenMPCaptureRegionForClause(DKind, OMPC_final, LangOpts.OpenMP); 12115 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 12116 ValExpr = MakeFullExpr(ValExpr).get(); 12117 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 12118 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 12119 HelperValStmt = buildPreInits(Context, Captures); 12120 } 12121 } 12122 12123 return new (Context) OMPFinalClause(ValExpr, HelperValStmt, CaptureRegion, 12124 StartLoc, LParenLoc, EndLoc); 12125 } 12126 12127 ExprResult Sema::PerformOpenMPImplicitIntegerConversion(SourceLocation Loc, 12128 Expr *Op) { 12129 if (!Op) 12130 return ExprError(); 12131 12132 class IntConvertDiagnoser : public ICEConvertDiagnoser { 12133 public: 12134 IntConvertDiagnoser() 12135 : ICEConvertDiagnoser(/*AllowScopedEnumerations*/ false, false, true) {} 12136 SemaDiagnosticBuilder diagnoseNotInt(Sema &S, SourceLocation Loc, 12137 QualType T) override { 12138 return S.Diag(Loc, diag::err_omp_not_integral) << T; 12139 } 12140 SemaDiagnosticBuilder diagnoseIncomplete(Sema &S, SourceLocation Loc, 12141 QualType T) override { 12142 return S.Diag(Loc, diag::err_omp_incomplete_type) << T; 12143 } 12144 SemaDiagnosticBuilder diagnoseExplicitConv(Sema &S, SourceLocation Loc, 12145 QualType T, 12146 QualType ConvTy) override { 12147 return S.Diag(Loc, diag::err_omp_explicit_conversion) << T << ConvTy; 12148 } 12149 SemaDiagnosticBuilder noteExplicitConv(Sema &S, CXXConversionDecl *Conv, 12150 QualType ConvTy) override { 12151 return S.Diag(Conv->getLocation(), diag::note_omp_conversion_here) 12152 << ConvTy->isEnumeralType() << ConvTy; 12153 } 12154 SemaDiagnosticBuilder diagnoseAmbiguous(Sema &S, SourceLocation Loc, 12155 QualType T) override { 12156 return S.Diag(Loc, diag::err_omp_ambiguous_conversion) << T; 12157 } 12158 SemaDiagnosticBuilder noteAmbiguous(Sema &S, CXXConversionDecl *Conv, 12159 QualType ConvTy) override { 12160 return S.Diag(Conv->getLocation(), diag::note_omp_conversion_here) 12161 << ConvTy->isEnumeralType() << ConvTy; 12162 } 12163 SemaDiagnosticBuilder diagnoseConversion(Sema &, SourceLocation, QualType, 12164 QualType) override { 12165 llvm_unreachable("conversion functions are permitted"); 12166 } 12167 } ConvertDiagnoser; 12168 return PerformContextualImplicitConversion(Loc, Op, ConvertDiagnoser); 12169 } 12170 12171 static bool 12172 isNonNegativeIntegerValue(Expr *&ValExpr, Sema &SemaRef, OpenMPClauseKind CKind, 12173 bool StrictlyPositive, bool BuildCapture = false, 12174 OpenMPDirectiveKind DKind = OMPD_unknown, 12175 OpenMPDirectiveKind *CaptureRegion = nullptr, 12176 Stmt **HelperValStmt = nullptr) { 12177 if (!ValExpr->isTypeDependent() && !ValExpr->isValueDependent() && 12178 !ValExpr->isInstantiationDependent()) { 12179 SourceLocation Loc = ValExpr->getExprLoc(); 12180 ExprResult Value = 12181 SemaRef.PerformOpenMPImplicitIntegerConversion(Loc, ValExpr); 12182 if (Value.isInvalid()) 12183 return false; 12184 12185 ValExpr = Value.get(); 12186 // The expression must evaluate to a non-negative integer value. 12187 llvm::APSInt Result; 12188 if (ValExpr->isIntegerConstantExpr(Result, SemaRef.Context) && 12189 Result.isSigned() && 12190 !((!StrictlyPositive && Result.isNonNegative()) || 12191 (StrictlyPositive && Result.isStrictlyPositive()))) { 12192 SemaRef.Diag(Loc, diag::err_omp_negative_expression_in_clause) 12193 << getOpenMPClauseName(CKind) << (StrictlyPositive ? 1 : 0) 12194 << ValExpr->getSourceRange(); 12195 return false; 12196 } 12197 if (!BuildCapture) 12198 return true; 12199 *CaptureRegion = 12200 getOpenMPCaptureRegionForClause(DKind, CKind, SemaRef.LangOpts.OpenMP); 12201 if (*CaptureRegion != OMPD_unknown && 12202 !SemaRef.CurContext->isDependentContext()) { 12203 ValExpr = SemaRef.MakeFullExpr(ValExpr).get(); 12204 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 12205 ValExpr = tryBuildCapture(SemaRef, ValExpr, Captures).get(); 12206 *HelperValStmt = buildPreInits(SemaRef.Context, Captures); 12207 } 12208 } 12209 return true; 12210 } 12211 12212 OMPClause *Sema::ActOnOpenMPNumThreadsClause(Expr *NumThreads, 12213 SourceLocation StartLoc, 12214 SourceLocation LParenLoc, 12215 SourceLocation EndLoc) { 12216 Expr *ValExpr = NumThreads; 12217 Stmt *HelperValStmt = nullptr; 12218 12219 // OpenMP [2.5, Restrictions] 12220 // The num_threads expression must evaluate to a positive integer value. 12221 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_num_threads, 12222 /*StrictlyPositive=*/true)) 12223 return nullptr; 12224 12225 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 12226 OpenMPDirectiveKind CaptureRegion = 12227 getOpenMPCaptureRegionForClause(DKind, OMPC_num_threads, LangOpts.OpenMP); 12228 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 12229 ValExpr = MakeFullExpr(ValExpr).get(); 12230 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 12231 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 12232 HelperValStmt = buildPreInits(Context, Captures); 12233 } 12234 12235 return new (Context) OMPNumThreadsClause( 12236 ValExpr, HelperValStmt, CaptureRegion, StartLoc, LParenLoc, EndLoc); 12237 } 12238 12239 ExprResult Sema::VerifyPositiveIntegerConstantInClause(Expr *E, 12240 OpenMPClauseKind CKind, 12241 bool StrictlyPositive) { 12242 if (!E) 12243 return ExprError(); 12244 if (E->isValueDependent() || E->isTypeDependent() || 12245 E->isInstantiationDependent() || E->containsUnexpandedParameterPack()) 12246 return E; 12247 llvm::APSInt Result; 12248 ExprResult ICE = VerifyIntegerConstantExpression(E, &Result); 12249 if (ICE.isInvalid()) 12250 return ExprError(); 12251 if ((StrictlyPositive && !Result.isStrictlyPositive()) || 12252 (!StrictlyPositive && !Result.isNonNegative())) { 12253 Diag(E->getExprLoc(), diag::err_omp_negative_expression_in_clause) 12254 << getOpenMPClauseName(CKind) << (StrictlyPositive ? 1 : 0) 12255 << E->getSourceRange(); 12256 return ExprError(); 12257 } 12258 if (CKind == OMPC_aligned && !Result.isPowerOf2()) { 12259 Diag(E->getExprLoc(), diag::warn_omp_alignment_not_power_of_two) 12260 << E->getSourceRange(); 12261 return ExprError(); 12262 } 12263 if (CKind == OMPC_collapse && DSAStack->getAssociatedLoops() == 1) 12264 DSAStack->setAssociatedLoops(Result.getExtValue()); 12265 else if (CKind == OMPC_ordered) 12266 DSAStack->setAssociatedLoops(Result.getExtValue()); 12267 return ICE; 12268 } 12269 12270 OMPClause *Sema::ActOnOpenMPSafelenClause(Expr *Len, SourceLocation StartLoc, 12271 SourceLocation LParenLoc, 12272 SourceLocation EndLoc) { 12273 // OpenMP [2.8.1, simd construct, Description] 12274 // The parameter of the safelen clause must be a constant 12275 // positive integer expression. 12276 ExprResult Safelen = VerifyPositiveIntegerConstantInClause(Len, OMPC_safelen); 12277 if (Safelen.isInvalid()) 12278 return nullptr; 12279 return new (Context) 12280 OMPSafelenClause(Safelen.get(), StartLoc, LParenLoc, EndLoc); 12281 } 12282 12283 OMPClause *Sema::ActOnOpenMPSimdlenClause(Expr *Len, SourceLocation StartLoc, 12284 SourceLocation LParenLoc, 12285 SourceLocation EndLoc) { 12286 // OpenMP [2.8.1, simd construct, Description] 12287 // The parameter of the simdlen clause must be a constant 12288 // positive integer expression. 12289 ExprResult Simdlen = VerifyPositiveIntegerConstantInClause(Len, OMPC_simdlen); 12290 if (Simdlen.isInvalid()) 12291 return nullptr; 12292 return new (Context) 12293 OMPSimdlenClause(Simdlen.get(), StartLoc, LParenLoc, EndLoc); 12294 } 12295 12296 /// Tries to find omp_allocator_handle_t type. 12297 static bool findOMPAllocatorHandleT(Sema &S, SourceLocation Loc, 12298 DSAStackTy *Stack) { 12299 QualType OMPAllocatorHandleT = Stack->getOMPAllocatorHandleT(); 12300 if (!OMPAllocatorHandleT.isNull()) 12301 return true; 12302 // Build the predefined allocator expressions. 12303 bool ErrorFound = false; 12304 for (int I = OMPAllocateDeclAttr::OMPDefaultMemAlloc; 12305 I < OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; ++I) { 12306 auto AllocatorKind = static_cast<OMPAllocateDeclAttr::AllocatorTypeTy>(I); 12307 StringRef Allocator = 12308 OMPAllocateDeclAttr::ConvertAllocatorTypeTyToStr(AllocatorKind); 12309 DeclarationName AllocatorName = &S.getASTContext().Idents.get(Allocator); 12310 auto *VD = dyn_cast_or_null<ValueDecl>( 12311 S.LookupSingleName(S.TUScope, AllocatorName, Loc, Sema::LookupAnyName)); 12312 if (!VD) { 12313 ErrorFound = true; 12314 break; 12315 } 12316 QualType AllocatorType = 12317 VD->getType().getNonLValueExprType(S.getASTContext()); 12318 ExprResult Res = S.BuildDeclRefExpr(VD, AllocatorType, VK_LValue, Loc); 12319 if (!Res.isUsable()) { 12320 ErrorFound = true; 12321 break; 12322 } 12323 if (OMPAllocatorHandleT.isNull()) 12324 OMPAllocatorHandleT = AllocatorType; 12325 if (!S.getASTContext().hasSameType(OMPAllocatorHandleT, AllocatorType)) { 12326 ErrorFound = true; 12327 break; 12328 } 12329 Stack->setAllocator(AllocatorKind, Res.get()); 12330 } 12331 if (ErrorFound) { 12332 S.Diag(Loc, diag::err_omp_implied_type_not_found) 12333 << "omp_allocator_handle_t"; 12334 return false; 12335 } 12336 OMPAllocatorHandleT.addConst(); 12337 Stack->setOMPAllocatorHandleT(OMPAllocatorHandleT); 12338 return true; 12339 } 12340 12341 OMPClause *Sema::ActOnOpenMPAllocatorClause(Expr *A, SourceLocation StartLoc, 12342 SourceLocation LParenLoc, 12343 SourceLocation EndLoc) { 12344 // OpenMP [2.11.3, allocate Directive, Description] 12345 // allocator is an expression of omp_allocator_handle_t type. 12346 if (!findOMPAllocatorHandleT(*this, A->getExprLoc(), DSAStack)) 12347 return nullptr; 12348 12349 ExprResult Allocator = DefaultLvalueConversion(A); 12350 if (Allocator.isInvalid()) 12351 return nullptr; 12352 Allocator = PerformImplicitConversion(Allocator.get(), 12353 DSAStack->getOMPAllocatorHandleT(), 12354 Sema::AA_Initializing, 12355 /*AllowExplicit=*/true); 12356 if (Allocator.isInvalid()) 12357 return nullptr; 12358 return new (Context) 12359 OMPAllocatorClause(Allocator.get(), StartLoc, LParenLoc, EndLoc); 12360 } 12361 12362 OMPClause *Sema::ActOnOpenMPCollapseClause(Expr *NumForLoops, 12363 SourceLocation StartLoc, 12364 SourceLocation LParenLoc, 12365 SourceLocation EndLoc) { 12366 // OpenMP [2.7.1, loop construct, Description] 12367 // OpenMP [2.8.1, simd construct, Description] 12368 // OpenMP [2.9.6, distribute construct, Description] 12369 // The parameter of the collapse clause must be a constant 12370 // positive integer expression. 12371 ExprResult NumForLoopsResult = 12372 VerifyPositiveIntegerConstantInClause(NumForLoops, OMPC_collapse); 12373 if (NumForLoopsResult.isInvalid()) 12374 return nullptr; 12375 return new (Context) 12376 OMPCollapseClause(NumForLoopsResult.get(), StartLoc, LParenLoc, EndLoc); 12377 } 12378 12379 OMPClause *Sema::ActOnOpenMPOrderedClause(SourceLocation StartLoc, 12380 SourceLocation EndLoc, 12381 SourceLocation LParenLoc, 12382 Expr *NumForLoops) { 12383 // OpenMP [2.7.1, loop construct, Description] 12384 // OpenMP [2.8.1, simd construct, Description] 12385 // OpenMP [2.9.6, distribute construct, Description] 12386 // The parameter of the ordered clause must be a constant 12387 // positive integer expression if any. 12388 if (NumForLoops && LParenLoc.isValid()) { 12389 ExprResult NumForLoopsResult = 12390 VerifyPositiveIntegerConstantInClause(NumForLoops, OMPC_ordered); 12391 if (NumForLoopsResult.isInvalid()) 12392 return nullptr; 12393 NumForLoops = NumForLoopsResult.get(); 12394 } else { 12395 NumForLoops = nullptr; 12396 } 12397 auto *Clause = OMPOrderedClause::Create( 12398 Context, NumForLoops, NumForLoops ? DSAStack->getAssociatedLoops() : 0, 12399 StartLoc, LParenLoc, EndLoc); 12400 DSAStack->setOrderedRegion(/*IsOrdered=*/true, NumForLoops, Clause); 12401 return Clause; 12402 } 12403 12404 OMPClause *Sema::ActOnOpenMPSimpleClause( 12405 OpenMPClauseKind Kind, unsigned Argument, SourceLocation ArgumentLoc, 12406 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) { 12407 OMPClause *Res = nullptr; 12408 switch (Kind) { 12409 case OMPC_default: 12410 Res = ActOnOpenMPDefaultClause(static_cast<DefaultKind>(Argument), 12411 ArgumentLoc, StartLoc, LParenLoc, EndLoc); 12412 break; 12413 case OMPC_proc_bind: 12414 Res = ActOnOpenMPProcBindClause(static_cast<ProcBindKind>(Argument), 12415 ArgumentLoc, StartLoc, LParenLoc, EndLoc); 12416 break; 12417 case OMPC_atomic_default_mem_order: 12418 Res = ActOnOpenMPAtomicDefaultMemOrderClause( 12419 static_cast<OpenMPAtomicDefaultMemOrderClauseKind>(Argument), 12420 ArgumentLoc, StartLoc, LParenLoc, EndLoc); 12421 break; 12422 case OMPC_order: 12423 Res = ActOnOpenMPOrderClause(static_cast<OpenMPOrderClauseKind>(Argument), 12424 ArgumentLoc, StartLoc, LParenLoc, EndLoc); 12425 break; 12426 case OMPC_update: 12427 Res = ActOnOpenMPUpdateClause(static_cast<OpenMPDependClauseKind>(Argument), 12428 ArgumentLoc, StartLoc, LParenLoc, EndLoc); 12429 break; 12430 case OMPC_if: 12431 case OMPC_final: 12432 case OMPC_num_threads: 12433 case OMPC_safelen: 12434 case OMPC_simdlen: 12435 case OMPC_allocator: 12436 case OMPC_collapse: 12437 case OMPC_schedule: 12438 case OMPC_private: 12439 case OMPC_firstprivate: 12440 case OMPC_lastprivate: 12441 case OMPC_shared: 12442 case OMPC_reduction: 12443 case OMPC_task_reduction: 12444 case OMPC_in_reduction: 12445 case OMPC_linear: 12446 case OMPC_aligned: 12447 case OMPC_copyin: 12448 case OMPC_copyprivate: 12449 case OMPC_ordered: 12450 case OMPC_nowait: 12451 case OMPC_untied: 12452 case OMPC_mergeable: 12453 case OMPC_threadprivate: 12454 case OMPC_allocate: 12455 case OMPC_flush: 12456 case OMPC_depobj: 12457 case OMPC_read: 12458 case OMPC_write: 12459 case OMPC_capture: 12460 case OMPC_seq_cst: 12461 case OMPC_acq_rel: 12462 case OMPC_acquire: 12463 case OMPC_release: 12464 case OMPC_relaxed: 12465 case OMPC_depend: 12466 case OMPC_device: 12467 case OMPC_threads: 12468 case OMPC_simd: 12469 case OMPC_map: 12470 case OMPC_num_teams: 12471 case OMPC_thread_limit: 12472 case OMPC_priority: 12473 case OMPC_grainsize: 12474 case OMPC_nogroup: 12475 case OMPC_num_tasks: 12476 case OMPC_hint: 12477 case OMPC_dist_schedule: 12478 case OMPC_defaultmap: 12479 case OMPC_unknown: 12480 case OMPC_uniform: 12481 case OMPC_to: 12482 case OMPC_from: 12483 case OMPC_use_device_ptr: 12484 case OMPC_is_device_ptr: 12485 case OMPC_unified_address: 12486 case OMPC_unified_shared_memory: 12487 case OMPC_reverse_offload: 12488 case OMPC_dynamic_allocators: 12489 case OMPC_device_type: 12490 case OMPC_match: 12491 case OMPC_nontemporal: 12492 case OMPC_destroy: 12493 case OMPC_detach: 12494 case OMPC_inclusive: 12495 case OMPC_exclusive: 12496 llvm_unreachable("Clause is not allowed."); 12497 } 12498 return Res; 12499 } 12500 12501 static std::string 12502 getListOfPossibleValues(OpenMPClauseKind K, unsigned First, unsigned Last, 12503 ArrayRef<unsigned> Exclude = llvm::None) { 12504 SmallString<256> Buffer; 12505 llvm::raw_svector_ostream Out(Buffer); 12506 unsigned Skipped = Exclude.size(); 12507 auto S = Exclude.begin(), E = Exclude.end(); 12508 for (unsigned I = First; I < Last; ++I) { 12509 if (std::find(S, E, I) != E) { 12510 --Skipped; 12511 continue; 12512 } 12513 Out << "'" << getOpenMPSimpleClauseTypeName(K, I) << "'"; 12514 if (I + Skipped + 2 == Last) 12515 Out << " or "; 12516 else if (I + Skipped + 1 != Last) 12517 Out << ", "; 12518 } 12519 return std::string(Out.str()); 12520 } 12521 12522 OMPClause *Sema::ActOnOpenMPDefaultClause(DefaultKind Kind, 12523 SourceLocation KindKwLoc, 12524 SourceLocation StartLoc, 12525 SourceLocation LParenLoc, 12526 SourceLocation EndLoc) { 12527 if (Kind == OMP_DEFAULT_unknown) { 12528 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value) 12529 << getListOfPossibleValues(OMPC_default, /*First=*/0, 12530 /*Last=*/unsigned(OMP_DEFAULT_unknown)) 12531 << getOpenMPClauseName(OMPC_default); 12532 return nullptr; 12533 } 12534 if (Kind == OMP_DEFAULT_none) 12535 DSAStack->setDefaultDSANone(KindKwLoc); 12536 else if (Kind == OMP_DEFAULT_shared) 12537 DSAStack->setDefaultDSAShared(KindKwLoc); 12538 12539 return new (Context) 12540 OMPDefaultClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc); 12541 } 12542 12543 OMPClause *Sema::ActOnOpenMPProcBindClause(ProcBindKind Kind, 12544 SourceLocation KindKwLoc, 12545 SourceLocation StartLoc, 12546 SourceLocation LParenLoc, 12547 SourceLocation EndLoc) { 12548 if (Kind == OMP_PROC_BIND_unknown) { 12549 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value) 12550 << getListOfPossibleValues(OMPC_proc_bind, 12551 /*First=*/unsigned(OMP_PROC_BIND_master), 12552 /*Last=*/5) 12553 << getOpenMPClauseName(OMPC_proc_bind); 12554 return nullptr; 12555 } 12556 return new (Context) 12557 OMPProcBindClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc); 12558 } 12559 12560 OMPClause *Sema::ActOnOpenMPAtomicDefaultMemOrderClause( 12561 OpenMPAtomicDefaultMemOrderClauseKind Kind, SourceLocation KindKwLoc, 12562 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) { 12563 if (Kind == OMPC_ATOMIC_DEFAULT_MEM_ORDER_unknown) { 12564 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value) 12565 << getListOfPossibleValues( 12566 OMPC_atomic_default_mem_order, /*First=*/0, 12567 /*Last=*/OMPC_ATOMIC_DEFAULT_MEM_ORDER_unknown) 12568 << getOpenMPClauseName(OMPC_atomic_default_mem_order); 12569 return nullptr; 12570 } 12571 return new (Context) OMPAtomicDefaultMemOrderClause(Kind, KindKwLoc, StartLoc, 12572 LParenLoc, EndLoc); 12573 } 12574 12575 OMPClause *Sema::ActOnOpenMPOrderClause(OpenMPOrderClauseKind Kind, 12576 SourceLocation KindKwLoc, 12577 SourceLocation StartLoc, 12578 SourceLocation LParenLoc, 12579 SourceLocation EndLoc) { 12580 if (Kind == OMPC_ORDER_unknown) { 12581 static_assert(OMPC_ORDER_unknown > 0, 12582 "OMPC_ORDER_unknown not greater than 0"); 12583 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value) 12584 << getListOfPossibleValues(OMPC_order, /*First=*/0, 12585 /*Last=*/OMPC_ORDER_unknown) 12586 << getOpenMPClauseName(OMPC_order); 12587 return nullptr; 12588 } 12589 return new (Context) 12590 OMPOrderClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc); 12591 } 12592 12593 OMPClause *Sema::ActOnOpenMPUpdateClause(OpenMPDependClauseKind Kind, 12594 SourceLocation KindKwLoc, 12595 SourceLocation StartLoc, 12596 SourceLocation LParenLoc, 12597 SourceLocation EndLoc) { 12598 if (Kind == OMPC_DEPEND_unknown || Kind == OMPC_DEPEND_source || 12599 Kind == OMPC_DEPEND_sink || Kind == OMPC_DEPEND_depobj) { 12600 unsigned Except[] = {OMPC_DEPEND_source, OMPC_DEPEND_sink, 12601 OMPC_DEPEND_depobj}; 12602 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value) 12603 << getListOfPossibleValues(OMPC_depend, /*First=*/0, 12604 /*Last=*/OMPC_DEPEND_unknown, Except) 12605 << getOpenMPClauseName(OMPC_update); 12606 return nullptr; 12607 } 12608 return OMPUpdateClause::Create(Context, StartLoc, LParenLoc, KindKwLoc, Kind, 12609 EndLoc); 12610 } 12611 12612 OMPClause *Sema::ActOnOpenMPSingleExprWithArgClause( 12613 OpenMPClauseKind Kind, ArrayRef<unsigned> Argument, Expr *Expr, 12614 SourceLocation StartLoc, SourceLocation LParenLoc, 12615 ArrayRef<SourceLocation> ArgumentLoc, SourceLocation DelimLoc, 12616 SourceLocation EndLoc) { 12617 OMPClause *Res = nullptr; 12618 switch (Kind) { 12619 case OMPC_schedule: 12620 enum { Modifier1, Modifier2, ScheduleKind, NumberOfElements }; 12621 assert(Argument.size() == NumberOfElements && 12622 ArgumentLoc.size() == NumberOfElements); 12623 Res = ActOnOpenMPScheduleClause( 12624 static_cast<OpenMPScheduleClauseModifier>(Argument[Modifier1]), 12625 static_cast<OpenMPScheduleClauseModifier>(Argument[Modifier2]), 12626 static_cast<OpenMPScheduleClauseKind>(Argument[ScheduleKind]), Expr, 12627 StartLoc, LParenLoc, ArgumentLoc[Modifier1], ArgumentLoc[Modifier2], 12628 ArgumentLoc[ScheduleKind], DelimLoc, EndLoc); 12629 break; 12630 case OMPC_if: 12631 assert(Argument.size() == 1 && ArgumentLoc.size() == 1); 12632 Res = ActOnOpenMPIfClause(static_cast<OpenMPDirectiveKind>(Argument.back()), 12633 Expr, StartLoc, LParenLoc, ArgumentLoc.back(), 12634 DelimLoc, EndLoc); 12635 break; 12636 case OMPC_dist_schedule: 12637 Res = ActOnOpenMPDistScheduleClause( 12638 static_cast<OpenMPDistScheduleClauseKind>(Argument.back()), Expr, 12639 StartLoc, LParenLoc, ArgumentLoc.back(), DelimLoc, EndLoc); 12640 break; 12641 case OMPC_defaultmap: 12642 enum { Modifier, DefaultmapKind }; 12643 Res = ActOnOpenMPDefaultmapClause( 12644 static_cast<OpenMPDefaultmapClauseModifier>(Argument[Modifier]), 12645 static_cast<OpenMPDefaultmapClauseKind>(Argument[DefaultmapKind]), 12646 StartLoc, LParenLoc, ArgumentLoc[Modifier], ArgumentLoc[DefaultmapKind], 12647 EndLoc); 12648 break; 12649 case OMPC_device: 12650 assert(Argument.size() == 1 && ArgumentLoc.size() == 1); 12651 Res = ActOnOpenMPDeviceClause( 12652 static_cast<OpenMPDeviceClauseModifier>(Argument.back()), Expr, 12653 StartLoc, LParenLoc, ArgumentLoc.back(), EndLoc); 12654 break; 12655 case OMPC_final: 12656 case OMPC_num_threads: 12657 case OMPC_safelen: 12658 case OMPC_simdlen: 12659 case OMPC_allocator: 12660 case OMPC_collapse: 12661 case OMPC_default: 12662 case OMPC_proc_bind: 12663 case OMPC_private: 12664 case OMPC_firstprivate: 12665 case OMPC_lastprivate: 12666 case OMPC_shared: 12667 case OMPC_reduction: 12668 case OMPC_task_reduction: 12669 case OMPC_in_reduction: 12670 case OMPC_linear: 12671 case OMPC_aligned: 12672 case OMPC_copyin: 12673 case OMPC_copyprivate: 12674 case OMPC_ordered: 12675 case OMPC_nowait: 12676 case OMPC_untied: 12677 case OMPC_mergeable: 12678 case OMPC_threadprivate: 12679 case OMPC_allocate: 12680 case OMPC_flush: 12681 case OMPC_depobj: 12682 case OMPC_read: 12683 case OMPC_write: 12684 case OMPC_update: 12685 case OMPC_capture: 12686 case OMPC_seq_cst: 12687 case OMPC_acq_rel: 12688 case OMPC_acquire: 12689 case OMPC_release: 12690 case OMPC_relaxed: 12691 case OMPC_depend: 12692 case OMPC_threads: 12693 case OMPC_simd: 12694 case OMPC_map: 12695 case OMPC_num_teams: 12696 case OMPC_thread_limit: 12697 case OMPC_priority: 12698 case OMPC_grainsize: 12699 case OMPC_nogroup: 12700 case OMPC_num_tasks: 12701 case OMPC_hint: 12702 case OMPC_unknown: 12703 case OMPC_uniform: 12704 case OMPC_to: 12705 case OMPC_from: 12706 case OMPC_use_device_ptr: 12707 case OMPC_is_device_ptr: 12708 case OMPC_unified_address: 12709 case OMPC_unified_shared_memory: 12710 case OMPC_reverse_offload: 12711 case OMPC_dynamic_allocators: 12712 case OMPC_atomic_default_mem_order: 12713 case OMPC_device_type: 12714 case OMPC_match: 12715 case OMPC_nontemporal: 12716 case OMPC_order: 12717 case OMPC_destroy: 12718 case OMPC_detach: 12719 case OMPC_inclusive: 12720 case OMPC_exclusive: 12721 llvm_unreachable("Clause is not allowed."); 12722 } 12723 return Res; 12724 } 12725 12726 static bool checkScheduleModifiers(Sema &S, OpenMPScheduleClauseModifier M1, 12727 OpenMPScheduleClauseModifier M2, 12728 SourceLocation M1Loc, SourceLocation M2Loc) { 12729 if (M1 == OMPC_SCHEDULE_MODIFIER_unknown && M1Loc.isValid()) { 12730 SmallVector<unsigned, 2> Excluded; 12731 if (M2 != OMPC_SCHEDULE_MODIFIER_unknown) 12732 Excluded.push_back(M2); 12733 if (M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) 12734 Excluded.push_back(OMPC_SCHEDULE_MODIFIER_monotonic); 12735 if (M2 == OMPC_SCHEDULE_MODIFIER_monotonic) 12736 Excluded.push_back(OMPC_SCHEDULE_MODIFIER_nonmonotonic); 12737 S.Diag(M1Loc, diag::err_omp_unexpected_clause_value) 12738 << getListOfPossibleValues(OMPC_schedule, 12739 /*First=*/OMPC_SCHEDULE_MODIFIER_unknown + 1, 12740 /*Last=*/OMPC_SCHEDULE_MODIFIER_last, 12741 Excluded) 12742 << getOpenMPClauseName(OMPC_schedule); 12743 return true; 12744 } 12745 return false; 12746 } 12747 12748 OMPClause *Sema::ActOnOpenMPScheduleClause( 12749 OpenMPScheduleClauseModifier M1, OpenMPScheduleClauseModifier M2, 12750 OpenMPScheduleClauseKind Kind, Expr *ChunkSize, SourceLocation StartLoc, 12751 SourceLocation LParenLoc, SourceLocation M1Loc, SourceLocation M2Loc, 12752 SourceLocation KindLoc, SourceLocation CommaLoc, SourceLocation EndLoc) { 12753 if (checkScheduleModifiers(*this, M1, M2, M1Loc, M2Loc) || 12754 checkScheduleModifiers(*this, M2, M1, M2Loc, M1Loc)) 12755 return nullptr; 12756 // OpenMP, 2.7.1, Loop Construct, Restrictions 12757 // Either the monotonic modifier or the nonmonotonic modifier can be specified 12758 // but not both. 12759 if ((M1 == M2 && M1 != OMPC_SCHEDULE_MODIFIER_unknown) || 12760 (M1 == OMPC_SCHEDULE_MODIFIER_monotonic && 12761 M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) || 12762 (M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic && 12763 M2 == OMPC_SCHEDULE_MODIFIER_monotonic)) { 12764 Diag(M2Loc, diag::err_omp_unexpected_schedule_modifier) 12765 << getOpenMPSimpleClauseTypeName(OMPC_schedule, M2) 12766 << getOpenMPSimpleClauseTypeName(OMPC_schedule, M1); 12767 return nullptr; 12768 } 12769 if (Kind == OMPC_SCHEDULE_unknown) { 12770 std::string Values; 12771 if (M1Loc.isInvalid() && M2Loc.isInvalid()) { 12772 unsigned Exclude[] = {OMPC_SCHEDULE_unknown}; 12773 Values = getListOfPossibleValues(OMPC_schedule, /*First=*/0, 12774 /*Last=*/OMPC_SCHEDULE_MODIFIER_last, 12775 Exclude); 12776 } else { 12777 Values = getListOfPossibleValues(OMPC_schedule, /*First=*/0, 12778 /*Last=*/OMPC_SCHEDULE_unknown); 12779 } 12780 Diag(KindLoc, diag::err_omp_unexpected_clause_value) 12781 << Values << getOpenMPClauseName(OMPC_schedule); 12782 return nullptr; 12783 } 12784 // OpenMP, 2.7.1, Loop Construct, Restrictions 12785 // The nonmonotonic modifier can only be specified with schedule(dynamic) or 12786 // schedule(guided). 12787 if ((M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic || 12788 M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) && 12789 Kind != OMPC_SCHEDULE_dynamic && Kind != OMPC_SCHEDULE_guided) { 12790 Diag(M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic ? M1Loc : M2Loc, 12791 diag::err_omp_schedule_nonmonotonic_static); 12792 return nullptr; 12793 } 12794 Expr *ValExpr = ChunkSize; 12795 Stmt *HelperValStmt = nullptr; 12796 if (ChunkSize) { 12797 if (!ChunkSize->isValueDependent() && !ChunkSize->isTypeDependent() && 12798 !ChunkSize->isInstantiationDependent() && 12799 !ChunkSize->containsUnexpandedParameterPack()) { 12800 SourceLocation ChunkSizeLoc = ChunkSize->getBeginLoc(); 12801 ExprResult Val = 12802 PerformOpenMPImplicitIntegerConversion(ChunkSizeLoc, ChunkSize); 12803 if (Val.isInvalid()) 12804 return nullptr; 12805 12806 ValExpr = Val.get(); 12807 12808 // OpenMP [2.7.1, Restrictions] 12809 // chunk_size must be a loop invariant integer expression with a positive 12810 // value. 12811 llvm::APSInt Result; 12812 if (ValExpr->isIntegerConstantExpr(Result, Context)) { 12813 if (Result.isSigned() && !Result.isStrictlyPositive()) { 12814 Diag(ChunkSizeLoc, diag::err_omp_negative_expression_in_clause) 12815 << "schedule" << 1 << ChunkSize->getSourceRange(); 12816 return nullptr; 12817 } 12818 } else if (getOpenMPCaptureRegionForClause( 12819 DSAStack->getCurrentDirective(), OMPC_schedule, 12820 LangOpts.OpenMP) != OMPD_unknown && 12821 !CurContext->isDependentContext()) { 12822 ValExpr = MakeFullExpr(ValExpr).get(); 12823 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 12824 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 12825 HelperValStmt = buildPreInits(Context, Captures); 12826 } 12827 } 12828 } 12829 12830 return new (Context) 12831 OMPScheduleClause(StartLoc, LParenLoc, KindLoc, CommaLoc, EndLoc, Kind, 12832 ValExpr, HelperValStmt, M1, M1Loc, M2, M2Loc); 12833 } 12834 12835 OMPClause *Sema::ActOnOpenMPClause(OpenMPClauseKind Kind, 12836 SourceLocation StartLoc, 12837 SourceLocation EndLoc) { 12838 OMPClause *Res = nullptr; 12839 switch (Kind) { 12840 case OMPC_ordered: 12841 Res = ActOnOpenMPOrderedClause(StartLoc, EndLoc); 12842 break; 12843 case OMPC_nowait: 12844 Res = ActOnOpenMPNowaitClause(StartLoc, EndLoc); 12845 break; 12846 case OMPC_untied: 12847 Res = ActOnOpenMPUntiedClause(StartLoc, EndLoc); 12848 break; 12849 case OMPC_mergeable: 12850 Res = ActOnOpenMPMergeableClause(StartLoc, EndLoc); 12851 break; 12852 case OMPC_read: 12853 Res = ActOnOpenMPReadClause(StartLoc, EndLoc); 12854 break; 12855 case OMPC_write: 12856 Res = ActOnOpenMPWriteClause(StartLoc, EndLoc); 12857 break; 12858 case OMPC_update: 12859 Res = ActOnOpenMPUpdateClause(StartLoc, EndLoc); 12860 break; 12861 case OMPC_capture: 12862 Res = ActOnOpenMPCaptureClause(StartLoc, EndLoc); 12863 break; 12864 case OMPC_seq_cst: 12865 Res = ActOnOpenMPSeqCstClause(StartLoc, EndLoc); 12866 break; 12867 case OMPC_acq_rel: 12868 Res = ActOnOpenMPAcqRelClause(StartLoc, EndLoc); 12869 break; 12870 case OMPC_acquire: 12871 Res = ActOnOpenMPAcquireClause(StartLoc, EndLoc); 12872 break; 12873 case OMPC_release: 12874 Res = ActOnOpenMPReleaseClause(StartLoc, EndLoc); 12875 break; 12876 case OMPC_relaxed: 12877 Res = ActOnOpenMPRelaxedClause(StartLoc, EndLoc); 12878 break; 12879 case OMPC_threads: 12880 Res = ActOnOpenMPThreadsClause(StartLoc, EndLoc); 12881 break; 12882 case OMPC_simd: 12883 Res = ActOnOpenMPSIMDClause(StartLoc, EndLoc); 12884 break; 12885 case OMPC_nogroup: 12886 Res = ActOnOpenMPNogroupClause(StartLoc, EndLoc); 12887 break; 12888 case OMPC_unified_address: 12889 Res = ActOnOpenMPUnifiedAddressClause(StartLoc, EndLoc); 12890 break; 12891 case OMPC_unified_shared_memory: 12892 Res = ActOnOpenMPUnifiedSharedMemoryClause(StartLoc, EndLoc); 12893 break; 12894 case OMPC_reverse_offload: 12895 Res = ActOnOpenMPReverseOffloadClause(StartLoc, EndLoc); 12896 break; 12897 case OMPC_dynamic_allocators: 12898 Res = ActOnOpenMPDynamicAllocatorsClause(StartLoc, EndLoc); 12899 break; 12900 case OMPC_destroy: 12901 Res = ActOnOpenMPDestroyClause(StartLoc, EndLoc); 12902 break; 12903 case OMPC_if: 12904 case OMPC_final: 12905 case OMPC_num_threads: 12906 case OMPC_safelen: 12907 case OMPC_simdlen: 12908 case OMPC_allocator: 12909 case OMPC_collapse: 12910 case OMPC_schedule: 12911 case OMPC_private: 12912 case OMPC_firstprivate: 12913 case OMPC_lastprivate: 12914 case OMPC_shared: 12915 case OMPC_reduction: 12916 case OMPC_task_reduction: 12917 case OMPC_in_reduction: 12918 case OMPC_linear: 12919 case OMPC_aligned: 12920 case OMPC_copyin: 12921 case OMPC_copyprivate: 12922 case OMPC_default: 12923 case OMPC_proc_bind: 12924 case OMPC_threadprivate: 12925 case OMPC_allocate: 12926 case OMPC_flush: 12927 case OMPC_depobj: 12928 case OMPC_depend: 12929 case OMPC_device: 12930 case OMPC_map: 12931 case OMPC_num_teams: 12932 case OMPC_thread_limit: 12933 case OMPC_priority: 12934 case OMPC_grainsize: 12935 case OMPC_num_tasks: 12936 case OMPC_hint: 12937 case OMPC_dist_schedule: 12938 case OMPC_defaultmap: 12939 case OMPC_unknown: 12940 case OMPC_uniform: 12941 case OMPC_to: 12942 case OMPC_from: 12943 case OMPC_use_device_ptr: 12944 case OMPC_is_device_ptr: 12945 case OMPC_atomic_default_mem_order: 12946 case OMPC_device_type: 12947 case OMPC_match: 12948 case OMPC_nontemporal: 12949 case OMPC_order: 12950 case OMPC_detach: 12951 case OMPC_inclusive: 12952 case OMPC_exclusive: 12953 llvm_unreachable("Clause is not allowed."); 12954 } 12955 return Res; 12956 } 12957 12958 OMPClause *Sema::ActOnOpenMPNowaitClause(SourceLocation StartLoc, 12959 SourceLocation EndLoc) { 12960 DSAStack->setNowaitRegion(); 12961 return new (Context) OMPNowaitClause(StartLoc, EndLoc); 12962 } 12963 12964 OMPClause *Sema::ActOnOpenMPUntiedClause(SourceLocation StartLoc, 12965 SourceLocation EndLoc) { 12966 return new (Context) OMPUntiedClause(StartLoc, EndLoc); 12967 } 12968 12969 OMPClause *Sema::ActOnOpenMPMergeableClause(SourceLocation StartLoc, 12970 SourceLocation EndLoc) { 12971 return new (Context) OMPMergeableClause(StartLoc, EndLoc); 12972 } 12973 12974 OMPClause *Sema::ActOnOpenMPReadClause(SourceLocation StartLoc, 12975 SourceLocation EndLoc) { 12976 return new (Context) OMPReadClause(StartLoc, EndLoc); 12977 } 12978 12979 OMPClause *Sema::ActOnOpenMPWriteClause(SourceLocation StartLoc, 12980 SourceLocation EndLoc) { 12981 return new (Context) OMPWriteClause(StartLoc, EndLoc); 12982 } 12983 12984 OMPClause *Sema::ActOnOpenMPUpdateClause(SourceLocation StartLoc, 12985 SourceLocation EndLoc) { 12986 return OMPUpdateClause::Create(Context, StartLoc, EndLoc); 12987 } 12988 12989 OMPClause *Sema::ActOnOpenMPCaptureClause(SourceLocation StartLoc, 12990 SourceLocation EndLoc) { 12991 return new (Context) OMPCaptureClause(StartLoc, EndLoc); 12992 } 12993 12994 OMPClause *Sema::ActOnOpenMPSeqCstClause(SourceLocation StartLoc, 12995 SourceLocation EndLoc) { 12996 return new (Context) OMPSeqCstClause(StartLoc, EndLoc); 12997 } 12998 12999 OMPClause *Sema::ActOnOpenMPAcqRelClause(SourceLocation StartLoc, 13000 SourceLocation EndLoc) { 13001 return new (Context) OMPAcqRelClause(StartLoc, EndLoc); 13002 } 13003 13004 OMPClause *Sema::ActOnOpenMPAcquireClause(SourceLocation StartLoc, 13005 SourceLocation EndLoc) { 13006 return new (Context) OMPAcquireClause(StartLoc, EndLoc); 13007 } 13008 13009 OMPClause *Sema::ActOnOpenMPReleaseClause(SourceLocation StartLoc, 13010 SourceLocation EndLoc) { 13011 return new (Context) OMPReleaseClause(StartLoc, EndLoc); 13012 } 13013 13014 OMPClause *Sema::ActOnOpenMPRelaxedClause(SourceLocation StartLoc, 13015 SourceLocation EndLoc) { 13016 return new (Context) OMPRelaxedClause(StartLoc, EndLoc); 13017 } 13018 13019 OMPClause *Sema::ActOnOpenMPThreadsClause(SourceLocation StartLoc, 13020 SourceLocation EndLoc) { 13021 return new (Context) OMPThreadsClause(StartLoc, EndLoc); 13022 } 13023 13024 OMPClause *Sema::ActOnOpenMPSIMDClause(SourceLocation StartLoc, 13025 SourceLocation EndLoc) { 13026 return new (Context) OMPSIMDClause(StartLoc, EndLoc); 13027 } 13028 13029 OMPClause *Sema::ActOnOpenMPNogroupClause(SourceLocation StartLoc, 13030 SourceLocation EndLoc) { 13031 return new (Context) OMPNogroupClause(StartLoc, EndLoc); 13032 } 13033 13034 OMPClause *Sema::ActOnOpenMPUnifiedAddressClause(SourceLocation StartLoc, 13035 SourceLocation EndLoc) { 13036 return new (Context) OMPUnifiedAddressClause(StartLoc, EndLoc); 13037 } 13038 13039 OMPClause *Sema::ActOnOpenMPUnifiedSharedMemoryClause(SourceLocation StartLoc, 13040 SourceLocation EndLoc) { 13041 return new (Context) OMPUnifiedSharedMemoryClause(StartLoc, EndLoc); 13042 } 13043 13044 OMPClause *Sema::ActOnOpenMPReverseOffloadClause(SourceLocation StartLoc, 13045 SourceLocation EndLoc) { 13046 return new (Context) OMPReverseOffloadClause(StartLoc, EndLoc); 13047 } 13048 13049 OMPClause *Sema::ActOnOpenMPDynamicAllocatorsClause(SourceLocation StartLoc, 13050 SourceLocation EndLoc) { 13051 return new (Context) OMPDynamicAllocatorsClause(StartLoc, EndLoc); 13052 } 13053 13054 OMPClause *Sema::ActOnOpenMPDestroyClause(SourceLocation StartLoc, 13055 SourceLocation EndLoc) { 13056 return new (Context) OMPDestroyClause(StartLoc, EndLoc); 13057 } 13058 13059 OMPClause *Sema::ActOnOpenMPVarListClause( 13060 OpenMPClauseKind Kind, ArrayRef<Expr *> VarList, Expr *DepModOrTailExpr, 13061 const OMPVarListLocTy &Locs, SourceLocation ColonLoc, 13062 CXXScopeSpec &ReductionOrMapperIdScopeSpec, 13063 DeclarationNameInfo &ReductionOrMapperId, int ExtraModifier, 13064 ArrayRef<OpenMPMapModifierKind> MapTypeModifiers, 13065 ArrayRef<SourceLocation> MapTypeModifiersLoc, bool IsMapTypeImplicit, 13066 SourceLocation ExtraModifierLoc) { 13067 SourceLocation StartLoc = Locs.StartLoc; 13068 SourceLocation LParenLoc = Locs.LParenLoc; 13069 SourceLocation EndLoc = Locs.EndLoc; 13070 OMPClause *Res = nullptr; 13071 switch (Kind) { 13072 case OMPC_private: 13073 Res = ActOnOpenMPPrivateClause(VarList, StartLoc, LParenLoc, EndLoc); 13074 break; 13075 case OMPC_firstprivate: 13076 Res = ActOnOpenMPFirstprivateClause(VarList, StartLoc, LParenLoc, EndLoc); 13077 break; 13078 case OMPC_lastprivate: 13079 assert(0 <= ExtraModifier && ExtraModifier <= OMPC_LASTPRIVATE_unknown && 13080 "Unexpected lastprivate modifier."); 13081 Res = ActOnOpenMPLastprivateClause( 13082 VarList, static_cast<OpenMPLastprivateModifier>(ExtraModifier), 13083 ExtraModifierLoc, ColonLoc, StartLoc, LParenLoc, EndLoc); 13084 break; 13085 case OMPC_shared: 13086 Res = ActOnOpenMPSharedClause(VarList, StartLoc, LParenLoc, EndLoc); 13087 break; 13088 case OMPC_reduction: 13089 assert(0 <= ExtraModifier && ExtraModifier <= OMPC_REDUCTION_unknown && 13090 "Unexpected lastprivate modifier."); 13091 Res = ActOnOpenMPReductionClause( 13092 VarList, static_cast<OpenMPReductionClauseModifier>(ExtraModifier), 13093 StartLoc, LParenLoc, ExtraModifierLoc, ColonLoc, EndLoc, 13094 ReductionOrMapperIdScopeSpec, ReductionOrMapperId); 13095 break; 13096 case OMPC_task_reduction: 13097 Res = ActOnOpenMPTaskReductionClause(VarList, StartLoc, LParenLoc, ColonLoc, 13098 EndLoc, ReductionOrMapperIdScopeSpec, 13099 ReductionOrMapperId); 13100 break; 13101 case OMPC_in_reduction: 13102 Res = ActOnOpenMPInReductionClause(VarList, StartLoc, LParenLoc, ColonLoc, 13103 EndLoc, ReductionOrMapperIdScopeSpec, 13104 ReductionOrMapperId); 13105 break; 13106 case OMPC_linear: 13107 assert(0 <= ExtraModifier && ExtraModifier <= OMPC_LINEAR_unknown && 13108 "Unexpected linear modifier."); 13109 Res = ActOnOpenMPLinearClause( 13110 VarList, DepModOrTailExpr, StartLoc, LParenLoc, 13111 static_cast<OpenMPLinearClauseKind>(ExtraModifier), ExtraModifierLoc, 13112 ColonLoc, EndLoc); 13113 break; 13114 case OMPC_aligned: 13115 Res = ActOnOpenMPAlignedClause(VarList, DepModOrTailExpr, StartLoc, 13116 LParenLoc, ColonLoc, EndLoc); 13117 break; 13118 case OMPC_copyin: 13119 Res = ActOnOpenMPCopyinClause(VarList, StartLoc, LParenLoc, EndLoc); 13120 break; 13121 case OMPC_copyprivate: 13122 Res = ActOnOpenMPCopyprivateClause(VarList, StartLoc, LParenLoc, EndLoc); 13123 break; 13124 case OMPC_flush: 13125 Res = ActOnOpenMPFlushClause(VarList, StartLoc, LParenLoc, EndLoc); 13126 break; 13127 case OMPC_depend: 13128 assert(0 <= ExtraModifier && ExtraModifier <= OMPC_DEPEND_unknown && 13129 "Unexpected depend modifier."); 13130 Res = ActOnOpenMPDependClause( 13131 DepModOrTailExpr, static_cast<OpenMPDependClauseKind>(ExtraModifier), 13132 ExtraModifierLoc, ColonLoc, VarList, StartLoc, LParenLoc, EndLoc); 13133 break; 13134 case OMPC_map: 13135 assert(0 <= ExtraModifier && ExtraModifier <= OMPC_MAP_unknown && 13136 "Unexpected map modifier."); 13137 Res = ActOnOpenMPMapClause( 13138 MapTypeModifiers, MapTypeModifiersLoc, ReductionOrMapperIdScopeSpec, 13139 ReductionOrMapperId, static_cast<OpenMPMapClauseKind>(ExtraModifier), 13140 IsMapTypeImplicit, ExtraModifierLoc, ColonLoc, VarList, Locs); 13141 break; 13142 case OMPC_to: 13143 Res = ActOnOpenMPToClause(VarList, ReductionOrMapperIdScopeSpec, 13144 ReductionOrMapperId, Locs); 13145 break; 13146 case OMPC_from: 13147 Res = ActOnOpenMPFromClause(VarList, ReductionOrMapperIdScopeSpec, 13148 ReductionOrMapperId, Locs); 13149 break; 13150 case OMPC_use_device_ptr: 13151 Res = ActOnOpenMPUseDevicePtrClause(VarList, Locs); 13152 break; 13153 case OMPC_is_device_ptr: 13154 Res = ActOnOpenMPIsDevicePtrClause(VarList, Locs); 13155 break; 13156 case OMPC_allocate: 13157 Res = ActOnOpenMPAllocateClause(DepModOrTailExpr, VarList, StartLoc, 13158 LParenLoc, ColonLoc, EndLoc); 13159 break; 13160 case OMPC_nontemporal: 13161 Res = ActOnOpenMPNontemporalClause(VarList, StartLoc, LParenLoc, EndLoc); 13162 break; 13163 case OMPC_inclusive: 13164 Res = ActOnOpenMPInclusiveClause(VarList, StartLoc, LParenLoc, EndLoc); 13165 break; 13166 case OMPC_exclusive: 13167 Res = ActOnOpenMPExclusiveClause(VarList, StartLoc, LParenLoc, EndLoc); 13168 break; 13169 case OMPC_if: 13170 case OMPC_depobj: 13171 case OMPC_final: 13172 case OMPC_num_threads: 13173 case OMPC_safelen: 13174 case OMPC_simdlen: 13175 case OMPC_allocator: 13176 case OMPC_collapse: 13177 case OMPC_default: 13178 case OMPC_proc_bind: 13179 case OMPC_schedule: 13180 case OMPC_ordered: 13181 case OMPC_nowait: 13182 case OMPC_untied: 13183 case OMPC_mergeable: 13184 case OMPC_threadprivate: 13185 case OMPC_read: 13186 case OMPC_write: 13187 case OMPC_update: 13188 case OMPC_capture: 13189 case OMPC_seq_cst: 13190 case OMPC_acq_rel: 13191 case OMPC_acquire: 13192 case OMPC_release: 13193 case OMPC_relaxed: 13194 case OMPC_device: 13195 case OMPC_threads: 13196 case OMPC_simd: 13197 case OMPC_num_teams: 13198 case OMPC_thread_limit: 13199 case OMPC_priority: 13200 case OMPC_grainsize: 13201 case OMPC_nogroup: 13202 case OMPC_num_tasks: 13203 case OMPC_hint: 13204 case OMPC_dist_schedule: 13205 case OMPC_defaultmap: 13206 case OMPC_unknown: 13207 case OMPC_uniform: 13208 case OMPC_unified_address: 13209 case OMPC_unified_shared_memory: 13210 case OMPC_reverse_offload: 13211 case OMPC_dynamic_allocators: 13212 case OMPC_atomic_default_mem_order: 13213 case OMPC_device_type: 13214 case OMPC_match: 13215 case OMPC_order: 13216 case OMPC_destroy: 13217 case OMPC_detach: 13218 llvm_unreachable("Clause is not allowed."); 13219 } 13220 return Res; 13221 } 13222 13223 ExprResult Sema::getOpenMPCapturedExpr(VarDecl *Capture, ExprValueKind VK, 13224 ExprObjectKind OK, SourceLocation Loc) { 13225 ExprResult Res = BuildDeclRefExpr( 13226 Capture, Capture->getType().getNonReferenceType(), VK_LValue, Loc); 13227 if (!Res.isUsable()) 13228 return ExprError(); 13229 if (OK == OK_Ordinary && !getLangOpts().CPlusPlus) { 13230 Res = CreateBuiltinUnaryOp(Loc, UO_Deref, Res.get()); 13231 if (!Res.isUsable()) 13232 return ExprError(); 13233 } 13234 if (VK != VK_LValue && Res.get()->isGLValue()) { 13235 Res = DefaultLvalueConversion(Res.get()); 13236 if (!Res.isUsable()) 13237 return ExprError(); 13238 } 13239 return Res; 13240 } 13241 13242 OMPClause *Sema::ActOnOpenMPPrivateClause(ArrayRef<Expr *> VarList, 13243 SourceLocation StartLoc, 13244 SourceLocation LParenLoc, 13245 SourceLocation EndLoc) { 13246 SmallVector<Expr *, 8> Vars; 13247 SmallVector<Expr *, 8> PrivateCopies; 13248 for (Expr *RefExpr : VarList) { 13249 assert(RefExpr && "NULL expr in OpenMP private clause."); 13250 SourceLocation ELoc; 13251 SourceRange ERange; 13252 Expr *SimpleRefExpr = RefExpr; 13253 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 13254 if (Res.second) { 13255 // It will be analyzed later. 13256 Vars.push_back(RefExpr); 13257 PrivateCopies.push_back(nullptr); 13258 } 13259 ValueDecl *D = Res.first; 13260 if (!D) 13261 continue; 13262 13263 QualType Type = D->getType(); 13264 auto *VD = dyn_cast<VarDecl>(D); 13265 13266 // OpenMP [2.9.3.3, Restrictions, C/C++, p.3] 13267 // A variable that appears in a private clause must not have an incomplete 13268 // type or a reference type. 13269 if (RequireCompleteType(ELoc, Type, diag::err_omp_private_incomplete_type)) 13270 continue; 13271 Type = Type.getNonReferenceType(); 13272 13273 // OpenMP 5.0 [2.19.3, List Item Privatization, Restrictions] 13274 // A variable that is privatized must not have a const-qualified type 13275 // unless it is of class type with a mutable member. This restriction does 13276 // not apply to the firstprivate clause. 13277 // 13278 // OpenMP 3.1 [2.9.3.3, private clause, Restrictions] 13279 // A variable that appears in a private clause must not have a 13280 // const-qualified type unless it is of class type with a mutable member. 13281 if (rejectConstNotMutableType(*this, D, Type, OMPC_private, ELoc)) 13282 continue; 13283 13284 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 13285 // in a Construct] 13286 // Variables with the predetermined data-sharing attributes may not be 13287 // listed in data-sharing attributes clauses, except for the cases 13288 // listed below. For these exceptions only, listing a predetermined 13289 // variable in a data-sharing attribute clause is allowed and overrides 13290 // the variable's predetermined data-sharing attributes. 13291 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false); 13292 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_private) { 13293 Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind) 13294 << getOpenMPClauseName(OMPC_private); 13295 reportOriginalDsa(*this, DSAStack, D, DVar); 13296 continue; 13297 } 13298 13299 OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective(); 13300 // Variably modified types are not supported for tasks. 13301 if (!Type->isAnyPointerType() && Type->isVariablyModifiedType() && 13302 isOpenMPTaskingDirective(CurrDir)) { 13303 Diag(ELoc, diag::err_omp_variably_modified_type_not_supported) 13304 << getOpenMPClauseName(OMPC_private) << Type 13305 << getOpenMPDirectiveName(CurrDir); 13306 bool IsDecl = 13307 !VD || 13308 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 13309 Diag(D->getLocation(), 13310 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 13311 << D; 13312 continue; 13313 } 13314 13315 // OpenMP 4.5 [2.15.5.1, Restrictions, p.3] 13316 // A list item cannot appear in both a map clause and a data-sharing 13317 // attribute clause on the same construct 13318 // 13319 // OpenMP 5.0 [2.19.7.1, Restrictions, p.7] 13320 // A list item cannot appear in both a map clause and a data-sharing 13321 // attribute clause on the same construct unless the construct is a 13322 // combined construct. 13323 if ((LangOpts.OpenMP <= 45 && isOpenMPTargetExecutionDirective(CurrDir)) || 13324 CurrDir == OMPD_target) { 13325 OpenMPClauseKind ConflictKind; 13326 if (DSAStack->checkMappableExprComponentListsForDecl( 13327 VD, /*CurrentRegionOnly=*/true, 13328 [&](OMPClauseMappableExprCommon::MappableExprComponentListRef, 13329 OpenMPClauseKind WhereFoundClauseKind) -> bool { 13330 ConflictKind = WhereFoundClauseKind; 13331 return true; 13332 })) { 13333 Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa) 13334 << getOpenMPClauseName(OMPC_private) 13335 << getOpenMPClauseName(ConflictKind) 13336 << getOpenMPDirectiveName(CurrDir); 13337 reportOriginalDsa(*this, DSAStack, D, DVar); 13338 continue; 13339 } 13340 } 13341 13342 // OpenMP [2.9.3.3, Restrictions, C/C++, p.1] 13343 // A variable of class type (or array thereof) that appears in a private 13344 // clause requires an accessible, unambiguous default constructor for the 13345 // class type. 13346 // Generate helper private variable and initialize it with the default 13347 // value. The address of the original variable is replaced by the address of 13348 // the new private variable in CodeGen. This new variable is not added to 13349 // IdResolver, so the code in the OpenMP region uses original variable for 13350 // proper diagnostics. 13351 Type = Type.getUnqualifiedType(); 13352 VarDecl *VDPrivate = 13353 buildVarDecl(*this, ELoc, Type, D->getName(), 13354 D->hasAttrs() ? &D->getAttrs() : nullptr, 13355 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr); 13356 ActOnUninitializedDecl(VDPrivate); 13357 if (VDPrivate->isInvalidDecl()) 13358 continue; 13359 DeclRefExpr *VDPrivateRefExpr = buildDeclRefExpr( 13360 *this, VDPrivate, RefExpr->getType().getUnqualifiedType(), ELoc); 13361 13362 DeclRefExpr *Ref = nullptr; 13363 if (!VD && !CurContext->isDependentContext()) 13364 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false); 13365 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_private, Ref); 13366 Vars.push_back((VD || CurContext->isDependentContext()) 13367 ? RefExpr->IgnoreParens() 13368 : Ref); 13369 PrivateCopies.push_back(VDPrivateRefExpr); 13370 } 13371 13372 if (Vars.empty()) 13373 return nullptr; 13374 13375 return OMPPrivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars, 13376 PrivateCopies); 13377 } 13378 13379 namespace { 13380 class DiagsUninitializedSeveretyRAII { 13381 private: 13382 DiagnosticsEngine &Diags; 13383 SourceLocation SavedLoc; 13384 bool IsIgnored = false; 13385 13386 public: 13387 DiagsUninitializedSeveretyRAII(DiagnosticsEngine &Diags, SourceLocation Loc, 13388 bool IsIgnored) 13389 : Diags(Diags), SavedLoc(Loc), IsIgnored(IsIgnored) { 13390 if (!IsIgnored) { 13391 Diags.setSeverity(/*Diag*/ diag::warn_uninit_self_reference_in_init, 13392 /*Map*/ diag::Severity::Ignored, Loc); 13393 } 13394 } 13395 ~DiagsUninitializedSeveretyRAII() { 13396 if (!IsIgnored) 13397 Diags.popMappings(SavedLoc); 13398 } 13399 }; 13400 } 13401 13402 OMPClause *Sema::ActOnOpenMPFirstprivateClause(ArrayRef<Expr *> VarList, 13403 SourceLocation StartLoc, 13404 SourceLocation LParenLoc, 13405 SourceLocation EndLoc) { 13406 SmallVector<Expr *, 8> Vars; 13407 SmallVector<Expr *, 8> PrivateCopies; 13408 SmallVector<Expr *, 8> Inits; 13409 SmallVector<Decl *, 4> ExprCaptures; 13410 bool IsImplicitClause = 13411 StartLoc.isInvalid() && LParenLoc.isInvalid() && EndLoc.isInvalid(); 13412 SourceLocation ImplicitClauseLoc = DSAStack->getConstructLoc(); 13413 13414 for (Expr *RefExpr : VarList) { 13415 assert(RefExpr && "NULL expr in OpenMP firstprivate clause."); 13416 SourceLocation ELoc; 13417 SourceRange ERange; 13418 Expr *SimpleRefExpr = RefExpr; 13419 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 13420 if (Res.second) { 13421 // It will be analyzed later. 13422 Vars.push_back(RefExpr); 13423 PrivateCopies.push_back(nullptr); 13424 Inits.push_back(nullptr); 13425 } 13426 ValueDecl *D = Res.first; 13427 if (!D) 13428 continue; 13429 13430 ELoc = IsImplicitClause ? ImplicitClauseLoc : ELoc; 13431 QualType Type = D->getType(); 13432 auto *VD = dyn_cast<VarDecl>(D); 13433 13434 // OpenMP [2.9.3.3, Restrictions, C/C++, p.3] 13435 // A variable that appears in a private clause must not have an incomplete 13436 // type or a reference type. 13437 if (RequireCompleteType(ELoc, Type, 13438 diag::err_omp_firstprivate_incomplete_type)) 13439 continue; 13440 Type = Type.getNonReferenceType(); 13441 13442 // OpenMP [2.9.3.4, Restrictions, C/C++, p.1] 13443 // A variable of class type (or array thereof) that appears in a private 13444 // clause requires an accessible, unambiguous copy constructor for the 13445 // class type. 13446 QualType ElemType = Context.getBaseElementType(Type).getNonReferenceType(); 13447 13448 // If an implicit firstprivate variable found it was checked already. 13449 DSAStackTy::DSAVarData TopDVar; 13450 if (!IsImplicitClause) { 13451 DSAStackTy::DSAVarData DVar = 13452 DSAStack->getTopDSA(D, /*FromParent=*/false); 13453 TopDVar = DVar; 13454 OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective(); 13455 bool IsConstant = ElemType.isConstant(Context); 13456 // OpenMP [2.4.13, Data-sharing Attribute Clauses] 13457 // A list item that specifies a given variable may not appear in more 13458 // than one clause on the same directive, except that a variable may be 13459 // specified in both firstprivate and lastprivate clauses. 13460 // OpenMP 4.5 [2.10.8, Distribute Construct, p.3] 13461 // A list item may appear in a firstprivate or lastprivate clause but not 13462 // both. 13463 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_firstprivate && 13464 (isOpenMPDistributeDirective(CurrDir) || 13465 DVar.CKind != OMPC_lastprivate) && 13466 DVar.RefExpr) { 13467 Diag(ELoc, diag::err_omp_wrong_dsa) 13468 << getOpenMPClauseName(DVar.CKind) 13469 << getOpenMPClauseName(OMPC_firstprivate); 13470 reportOriginalDsa(*this, DSAStack, D, DVar); 13471 continue; 13472 } 13473 13474 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 13475 // in a Construct] 13476 // Variables with the predetermined data-sharing attributes may not be 13477 // listed in data-sharing attributes clauses, except for the cases 13478 // listed below. For these exceptions only, listing a predetermined 13479 // variable in a data-sharing attribute clause is allowed and overrides 13480 // the variable's predetermined data-sharing attributes. 13481 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 13482 // in a Construct, C/C++, p.2] 13483 // Variables with const-qualified type having no mutable member may be 13484 // listed in a firstprivate clause, even if they are static data members. 13485 if (!(IsConstant || (VD && VD->isStaticDataMember())) && !DVar.RefExpr && 13486 DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_shared) { 13487 Diag(ELoc, diag::err_omp_wrong_dsa) 13488 << getOpenMPClauseName(DVar.CKind) 13489 << getOpenMPClauseName(OMPC_firstprivate); 13490 reportOriginalDsa(*this, DSAStack, D, DVar); 13491 continue; 13492 } 13493 13494 // OpenMP [2.9.3.4, Restrictions, p.2] 13495 // A list item that is private within a parallel region must not appear 13496 // in a firstprivate clause on a worksharing construct if any of the 13497 // worksharing regions arising from the worksharing construct ever bind 13498 // to any of the parallel regions arising from the parallel construct. 13499 // OpenMP 4.5 [2.15.3.4, Restrictions, p.3] 13500 // A list item that is private within a teams region must not appear in a 13501 // firstprivate clause on a distribute construct if any of the distribute 13502 // regions arising from the distribute construct ever bind to any of the 13503 // teams regions arising from the teams construct. 13504 // OpenMP 4.5 [2.15.3.4, Restrictions, p.3] 13505 // A list item that appears in a reduction clause of a teams construct 13506 // must not appear in a firstprivate clause on a distribute construct if 13507 // any of the distribute regions arising from the distribute construct 13508 // ever bind to any of the teams regions arising from the teams construct. 13509 if ((isOpenMPWorksharingDirective(CurrDir) || 13510 isOpenMPDistributeDirective(CurrDir)) && 13511 !isOpenMPParallelDirective(CurrDir) && 13512 !isOpenMPTeamsDirective(CurrDir)) { 13513 DVar = DSAStack->getImplicitDSA(D, true); 13514 if (DVar.CKind != OMPC_shared && 13515 (isOpenMPParallelDirective(DVar.DKind) || 13516 isOpenMPTeamsDirective(DVar.DKind) || 13517 DVar.DKind == OMPD_unknown)) { 13518 Diag(ELoc, diag::err_omp_required_access) 13519 << getOpenMPClauseName(OMPC_firstprivate) 13520 << getOpenMPClauseName(OMPC_shared); 13521 reportOriginalDsa(*this, DSAStack, D, DVar); 13522 continue; 13523 } 13524 } 13525 // OpenMP [2.9.3.4, Restrictions, p.3] 13526 // A list item that appears in a reduction clause of a parallel construct 13527 // must not appear in a firstprivate clause on a worksharing or task 13528 // construct if any of the worksharing or task regions arising from the 13529 // worksharing or task construct ever bind to any of the parallel regions 13530 // arising from the parallel construct. 13531 // OpenMP [2.9.3.4, Restrictions, p.4] 13532 // A list item that appears in a reduction clause in worksharing 13533 // construct must not appear in a firstprivate clause in a task construct 13534 // encountered during execution of any of the worksharing regions arising 13535 // from the worksharing construct. 13536 if (isOpenMPTaskingDirective(CurrDir)) { 13537 DVar = DSAStack->hasInnermostDSA( 13538 D, [](OpenMPClauseKind C) { return C == OMPC_reduction; }, 13539 [](OpenMPDirectiveKind K) { 13540 return isOpenMPParallelDirective(K) || 13541 isOpenMPWorksharingDirective(K) || 13542 isOpenMPTeamsDirective(K); 13543 }, 13544 /*FromParent=*/true); 13545 if (DVar.CKind == OMPC_reduction && 13546 (isOpenMPParallelDirective(DVar.DKind) || 13547 isOpenMPWorksharingDirective(DVar.DKind) || 13548 isOpenMPTeamsDirective(DVar.DKind))) { 13549 Diag(ELoc, diag::err_omp_parallel_reduction_in_task_firstprivate) 13550 << getOpenMPDirectiveName(DVar.DKind); 13551 reportOriginalDsa(*this, DSAStack, D, DVar); 13552 continue; 13553 } 13554 } 13555 13556 // OpenMP 4.5 [2.15.5.1, Restrictions, p.3] 13557 // A list item cannot appear in both a map clause and a data-sharing 13558 // attribute clause on the same construct 13559 // 13560 // OpenMP 5.0 [2.19.7.1, Restrictions, p.7] 13561 // A list item cannot appear in both a map clause and a data-sharing 13562 // attribute clause on the same construct unless the construct is a 13563 // combined construct. 13564 if ((LangOpts.OpenMP <= 45 && 13565 isOpenMPTargetExecutionDirective(CurrDir)) || 13566 CurrDir == OMPD_target) { 13567 OpenMPClauseKind ConflictKind; 13568 if (DSAStack->checkMappableExprComponentListsForDecl( 13569 VD, /*CurrentRegionOnly=*/true, 13570 [&ConflictKind]( 13571 OMPClauseMappableExprCommon::MappableExprComponentListRef, 13572 OpenMPClauseKind WhereFoundClauseKind) { 13573 ConflictKind = WhereFoundClauseKind; 13574 return true; 13575 })) { 13576 Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa) 13577 << getOpenMPClauseName(OMPC_firstprivate) 13578 << getOpenMPClauseName(ConflictKind) 13579 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 13580 reportOriginalDsa(*this, DSAStack, D, DVar); 13581 continue; 13582 } 13583 } 13584 } 13585 13586 // Variably modified types are not supported for tasks. 13587 if (!Type->isAnyPointerType() && Type->isVariablyModifiedType() && 13588 isOpenMPTaskingDirective(DSAStack->getCurrentDirective())) { 13589 Diag(ELoc, diag::err_omp_variably_modified_type_not_supported) 13590 << getOpenMPClauseName(OMPC_firstprivate) << Type 13591 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 13592 bool IsDecl = 13593 !VD || 13594 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 13595 Diag(D->getLocation(), 13596 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 13597 << D; 13598 continue; 13599 } 13600 13601 Type = Type.getUnqualifiedType(); 13602 VarDecl *VDPrivate = 13603 buildVarDecl(*this, ELoc, Type, D->getName(), 13604 D->hasAttrs() ? &D->getAttrs() : nullptr, 13605 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr); 13606 // Generate helper private variable and initialize it with the value of the 13607 // original variable. The address of the original variable is replaced by 13608 // the address of the new private variable in the CodeGen. This new variable 13609 // is not added to IdResolver, so the code in the OpenMP region uses 13610 // original variable for proper diagnostics and variable capturing. 13611 Expr *VDInitRefExpr = nullptr; 13612 // For arrays generate initializer for single element and replace it by the 13613 // original array element in CodeGen. 13614 if (Type->isArrayType()) { 13615 VarDecl *VDInit = 13616 buildVarDecl(*this, RefExpr->getExprLoc(), ElemType, D->getName()); 13617 VDInitRefExpr = buildDeclRefExpr(*this, VDInit, ElemType, ELoc); 13618 Expr *Init = DefaultLvalueConversion(VDInitRefExpr).get(); 13619 ElemType = ElemType.getUnqualifiedType(); 13620 VarDecl *VDInitTemp = buildVarDecl(*this, RefExpr->getExprLoc(), ElemType, 13621 ".firstprivate.temp"); 13622 InitializedEntity Entity = 13623 InitializedEntity::InitializeVariable(VDInitTemp); 13624 InitializationKind Kind = InitializationKind::CreateCopy(ELoc, ELoc); 13625 13626 InitializationSequence InitSeq(*this, Entity, Kind, Init); 13627 ExprResult Result = InitSeq.Perform(*this, Entity, Kind, Init); 13628 if (Result.isInvalid()) 13629 VDPrivate->setInvalidDecl(); 13630 else 13631 VDPrivate->setInit(Result.getAs<Expr>()); 13632 // Remove temp variable declaration. 13633 Context.Deallocate(VDInitTemp); 13634 } else { 13635 VarDecl *VDInit = buildVarDecl(*this, RefExpr->getExprLoc(), Type, 13636 ".firstprivate.temp"); 13637 VDInitRefExpr = buildDeclRefExpr(*this, VDInit, RefExpr->getType(), 13638 RefExpr->getExprLoc()); 13639 AddInitializerToDecl(VDPrivate, 13640 DefaultLvalueConversion(VDInitRefExpr).get(), 13641 /*DirectInit=*/false); 13642 } 13643 if (VDPrivate->isInvalidDecl()) { 13644 if (IsImplicitClause) { 13645 Diag(RefExpr->getExprLoc(), 13646 diag::note_omp_task_predetermined_firstprivate_here); 13647 } 13648 continue; 13649 } 13650 CurContext->addDecl(VDPrivate); 13651 DeclRefExpr *VDPrivateRefExpr = buildDeclRefExpr( 13652 *this, VDPrivate, RefExpr->getType().getUnqualifiedType(), 13653 RefExpr->getExprLoc()); 13654 DeclRefExpr *Ref = nullptr; 13655 if (!VD && !CurContext->isDependentContext()) { 13656 if (TopDVar.CKind == OMPC_lastprivate) { 13657 Ref = TopDVar.PrivateCopy; 13658 } else { 13659 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true); 13660 if (!isOpenMPCapturedDecl(D)) 13661 ExprCaptures.push_back(Ref->getDecl()); 13662 } 13663 } 13664 if (!IsImplicitClause) 13665 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_firstprivate, Ref); 13666 Vars.push_back((VD || CurContext->isDependentContext()) 13667 ? RefExpr->IgnoreParens() 13668 : Ref); 13669 PrivateCopies.push_back(VDPrivateRefExpr); 13670 Inits.push_back(VDInitRefExpr); 13671 } 13672 13673 if (Vars.empty()) 13674 return nullptr; 13675 13676 return OMPFirstprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, 13677 Vars, PrivateCopies, Inits, 13678 buildPreInits(Context, ExprCaptures)); 13679 } 13680 13681 OMPClause *Sema::ActOnOpenMPLastprivateClause( 13682 ArrayRef<Expr *> VarList, OpenMPLastprivateModifier LPKind, 13683 SourceLocation LPKindLoc, SourceLocation ColonLoc, SourceLocation StartLoc, 13684 SourceLocation LParenLoc, SourceLocation EndLoc) { 13685 if (LPKind == OMPC_LASTPRIVATE_unknown && LPKindLoc.isValid()) { 13686 assert(ColonLoc.isValid() && "Colon location must be valid."); 13687 Diag(LPKindLoc, diag::err_omp_unexpected_clause_value) 13688 << getListOfPossibleValues(OMPC_lastprivate, /*First=*/0, 13689 /*Last=*/OMPC_LASTPRIVATE_unknown) 13690 << getOpenMPClauseName(OMPC_lastprivate); 13691 return nullptr; 13692 } 13693 13694 SmallVector<Expr *, 8> Vars; 13695 SmallVector<Expr *, 8> SrcExprs; 13696 SmallVector<Expr *, 8> DstExprs; 13697 SmallVector<Expr *, 8> AssignmentOps; 13698 SmallVector<Decl *, 4> ExprCaptures; 13699 SmallVector<Expr *, 4> ExprPostUpdates; 13700 for (Expr *RefExpr : VarList) { 13701 assert(RefExpr && "NULL expr in OpenMP lastprivate clause."); 13702 SourceLocation ELoc; 13703 SourceRange ERange; 13704 Expr *SimpleRefExpr = RefExpr; 13705 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 13706 if (Res.second) { 13707 // It will be analyzed later. 13708 Vars.push_back(RefExpr); 13709 SrcExprs.push_back(nullptr); 13710 DstExprs.push_back(nullptr); 13711 AssignmentOps.push_back(nullptr); 13712 } 13713 ValueDecl *D = Res.first; 13714 if (!D) 13715 continue; 13716 13717 QualType Type = D->getType(); 13718 auto *VD = dyn_cast<VarDecl>(D); 13719 13720 // OpenMP [2.14.3.5, Restrictions, C/C++, p.2] 13721 // A variable that appears in a lastprivate clause must not have an 13722 // incomplete type or a reference type. 13723 if (RequireCompleteType(ELoc, Type, 13724 diag::err_omp_lastprivate_incomplete_type)) 13725 continue; 13726 Type = Type.getNonReferenceType(); 13727 13728 // OpenMP 5.0 [2.19.3, List Item Privatization, Restrictions] 13729 // A variable that is privatized must not have a const-qualified type 13730 // unless it is of class type with a mutable member. This restriction does 13731 // not apply to the firstprivate clause. 13732 // 13733 // OpenMP 3.1 [2.9.3.5, lastprivate clause, Restrictions] 13734 // A variable that appears in a lastprivate clause must not have a 13735 // const-qualified type unless it is of class type with a mutable member. 13736 if (rejectConstNotMutableType(*this, D, Type, OMPC_lastprivate, ELoc)) 13737 continue; 13738 13739 // OpenMP 5.0 [2.19.4.5 lastprivate Clause, Restrictions] 13740 // A list item that appears in a lastprivate clause with the conditional 13741 // modifier must be a scalar variable. 13742 if (LPKind == OMPC_LASTPRIVATE_conditional && !Type->isScalarType()) { 13743 Diag(ELoc, diag::err_omp_lastprivate_conditional_non_scalar); 13744 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) == 13745 VarDecl::DeclarationOnly; 13746 Diag(D->getLocation(), 13747 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 13748 << D; 13749 continue; 13750 } 13751 13752 OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective(); 13753 // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables Referenced 13754 // in a Construct] 13755 // Variables with the predetermined data-sharing attributes may not be 13756 // listed in data-sharing attributes clauses, except for the cases 13757 // listed below. 13758 // OpenMP 4.5 [2.10.8, Distribute Construct, p.3] 13759 // A list item may appear in a firstprivate or lastprivate clause but not 13760 // both. 13761 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false); 13762 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_lastprivate && 13763 (isOpenMPDistributeDirective(CurrDir) || 13764 DVar.CKind != OMPC_firstprivate) && 13765 (DVar.CKind != OMPC_private || DVar.RefExpr != nullptr)) { 13766 Diag(ELoc, diag::err_omp_wrong_dsa) 13767 << getOpenMPClauseName(DVar.CKind) 13768 << getOpenMPClauseName(OMPC_lastprivate); 13769 reportOriginalDsa(*this, DSAStack, D, DVar); 13770 continue; 13771 } 13772 13773 // OpenMP [2.14.3.5, Restrictions, p.2] 13774 // A list item that is private within a parallel region, or that appears in 13775 // the reduction clause of a parallel construct, must not appear in a 13776 // lastprivate clause on a worksharing construct if any of the corresponding 13777 // worksharing regions ever binds to any of the corresponding parallel 13778 // regions. 13779 DSAStackTy::DSAVarData TopDVar = DVar; 13780 if (isOpenMPWorksharingDirective(CurrDir) && 13781 !isOpenMPParallelDirective(CurrDir) && 13782 !isOpenMPTeamsDirective(CurrDir)) { 13783 DVar = DSAStack->getImplicitDSA(D, true); 13784 if (DVar.CKind != OMPC_shared) { 13785 Diag(ELoc, diag::err_omp_required_access) 13786 << getOpenMPClauseName(OMPC_lastprivate) 13787 << getOpenMPClauseName(OMPC_shared); 13788 reportOriginalDsa(*this, DSAStack, D, DVar); 13789 continue; 13790 } 13791 } 13792 13793 // OpenMP [2.14.3.5, Restrictions, C++, p.1,2] 13794 // A variable of class type (or array thereof) that appears in a 13795 // lastprivate clause requires an accessible, unambiguous default 13796 // constructor for the class type, unless the list item is also specified 13797 // in a firstprivate clause. 13798 // A variable of class type (or array thereof) that appears in a 13799 // lastprivate clause requires an accessible, unambiguous copy assignment 13800 // operator for the class type. 13801 Type = Context.getBaseElementType(Type).getNonReferenceType(); 13802 VarDecl *SrcVD = buildVarDecl(*this, ERange.getBegin(), 13803 Type.getUnqualifiedType(), ".lastprivate.src", 13804 D->hasAttrs() ? &D->getAttrs() : nullptr); 13805 DeclRefExpr *PseudoSrcExpr = 13806 buildDeclRefExpr(*this, SrcVD, Type.getUnqualifiedType(), ELoc); 13807 VarDecl *DstVD = 13808 buildVarDecl(*this, ERange.getBegin(), Type, ".lastprivate.dst", 13809 D->hasAttrs() ? &D->getAttrs() : nullptr); 13810 DeclRefExpr *PseudoDstExpr = buildDeclRefExpr(*this, DstVD, Type, ELoc); 13811 // For arrays generate assignment operation for single element and replace 13812 // it by the original array element in CodeGen. 13813 ExprResult AssignmentOp = BuildBinOp(/*S=*/nullptr, ELoc, BO_Assign, 13814 PseudoDstExpr, PseudoSrcExpr); 13815 if (AssignmentOp.isInvalid()) 13816 continue; 13817 AssignmentOp = 13818 ActOnFinishFullExpr(AssignmentOp.get(), ELoc, /*DiscardedValue*/ false); 13819 if (AssignmentOp.isInvalid()) 13820 continue; 13821 13822 DeclRefExpr *Ref = nullptr; 13823 if (!VD && !CurContext->isDependentContext()) { 13824 if (TopDVar.CKind == OMPC_firstprivate) { 13825 Ref = TopDVar.PrivateCopy; 13826 } else { 13827 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false); 13828 if (!isOpenMPCapturedDecl(D)) 13829 ExprCaptures.push_back(Ref->getDecl()); 13830 } 13831 if (TopDVar.CKind == OMPC_firstprivate || 13832 (!isOpenMPCapturedDecl(D) && 13833 Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>())) { 13834 ExprResult RefRes = DefaultLvalueConversion(Ref); 13835 if (!RefRes.isUsable()) 13836 continue; 13837 ExprResult PostUpdateRes = 13838 BuildBinOp(DSAStack->getCurScope(), ELoc, BO_Assign, SimpleRefExpr, 13839 RefRes.get()); 13840 if (!PostUpdateRes.isUsable()) 13841 continue; 13842 ExprPostUpdates.push_back( 13843 IgnoredValueConversions(PostUpdateRes.get()).get()); 13844 } 13845 } 13846 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_lastprivate, Ref); 13847 Vars.push_back((VD || CurContext->isDependentContext()) 13848 ? RefExpr->IgnoreParens() 13849 : Ref); 13850 SrcExprs.push_back(PseudoSrcExpr); 13851 DstExprs.push_back(PseudoDstExpr); 13852 AssignmentOps.push_back(AssignmentOp.get()); 13853 } 13854 13855 if (Vars.empty()) 13856 return nullptr; 13857 13858 return OMPLastprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, 13859 Vars, SrcExprs, DstExprs, AssignmentOps, 13860 LPKind, LPKindLoc, ColonLoc, 13861 buildPreInits(Context, ExprCaptures), 13862 buildPostUpdate(*this, ExprPostUpdates)); 13863 } 13864 13865 OMPClause *Sema::ActOnOpenMPSharedClause(ArrayRef<Expr *> VarList, 13866 SourceLocation StartLoc, 13867 SourceLocation LParenLoc, 13868 SourceLocation EndLoc) { 13869 SmallVector<Expr *, 8> Vars; 13870 for (Expr *RefExpr : VarList) { 13871 assert(RefExpr && "NULL expr in OpenMP lastprivate clause."); 13872 SourceLocation ELoc; 13873 SourceRange ERange; 13874 Expr *SimpleRefExpr = RefExpr; 13875 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 13876 if (Res.second) { 13877 // It will be analyzed later. 13878 Vars.push_back(RefExpr); 13879 } 13880 ValueDecl *D = Res.first; 13881 if (!D) 13882 continue; 13883 13884 auto *VD = dyn_cast<VarDecl>(D); 13885 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 13886 // in a Construct] 13887 // Variables with the predetermined data-sharing attributes may not be 13888 // listed in data-sharing attributes clauses, except for the cases 13889 // listed below. For these exceptions only, listing a predetermined 13890 // variable in a data-sharing attribute clause is allowed and overrides 13891 // the variable's predetermined data-sharing attributes. 13892 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false); 13893 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_shared && 13894 DVar.RefExpr) { 13895 Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind) 13896 << getOpenMPClauseName(OMPC_shared); 13897 reportOriginalDsa(*this, DSAStack, D, DVar); 13898 continue; 13899 } 13900 13901 DeclRefExpr *Ref = nullptr; 13902 if (!VD && isOpenMPCapturedDecl(D) && !CurContext->isDependentContext()) 13903 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true); 13904 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_shared, Ref); 13905 Vars.push_back((VD || !Ref || CurContext->isDependentContext()) 13906 ? RefExpr->IgnoreParens() 13907 : Ref); 13908 } 13909 13910 if (Vars.empty()) 13911 return nullptr; 13912 13913 return OMPSharedClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars); 13914 } 13915 13916 namespace { 13917 class DSARefChecker : public StmtVisitor<DSARefChecker, bool> { 13918 DSAStackTy *Stack; 13919 13920 public: 13921 bool VisitDeclRefExpr(DeclRefExpr *E) { 13922 if (auto *VD = dyn_cast<VarDecl>(E->getDecl())) { 13923 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(VD, /*FromParent=*/false); 13924 if (DVar.CKind == OMPC_shared && !DVar.RefExpr) 13925 return false; 13926 if (DVar.CKind != OMPC_unknown) 13927 return true; 13928 DSAStackTy::DSAVarData DVarPrivate = Stack->hasDSA( 13929 VD, isOpenMPPrivate, [](OpenMPDirectiveKind) { return true; }, 13930 /*FromParent=*/true); 13931 return DVarPrivate.CKind != OMPC_unknown; 13932 } 13933 return false; 13934 } 13935 bool VisitStmt(Stmt *S) { 13936 for (Stmt *Child : S->children()) { 13937 if (Child && Visit(Child)) 13938 return true; 13939 } 13940 return false; 13941 } 13942 explicit DSARefChecker(DSAStackTy *S) : Stack(S) {} 13943 }; 13944 } // namespace 13945 13946 namespace { 13947 // Transform MemberExpression for specified FieldDecl of current class to 13948 // DeclRefExpr to specified OMPCapturedExprDecl. 13949 class TransformExprToCaptures : public TreeTransform<TransformExprToCaptures> { 13950 typedef TreeTransform<TransformExprToCaptures> BaseTransform; 13951 ValueDecl *Field = nullptr; 13952 DeclRefExpr *CapturedExpr = nullptr; 13953 13954 public: 13955 TransformExprToCaptures(Sema &SemaRef, ValueDecl *FieldDecl) 13956 : BaseTransform(SemaRef), Field(FieldDecl), CapturedExpr(nullptr) {} 13957 13958 ExprResult TransformMemberExpr(MemberExpr *E) { 13959 if (isa<CXXThisExpr>(E->getBase()->IgnoreParenImpCasts()) && 13960 E->getMemberDecl() == Field) { 13961 CapturedExpr = buildCapture(SemaRef, Field, E, /*WithInit=*/false); 13962 return CapturedExpr; 13963 } 13964 return BaseTransform::TransformMemberExpr(E); 13965 } 13966 DeclRefExpr *getCapturedExpr() { return CapturedExpr; } 13967 }; 13968 } // namespace 13969 13970 template <typename T, typename U> 13971 static T filterLookupForUDReductionAndMapper( 13972 SmallVectorImpl<U> &Lookups, const llvm::function_ref<T(ValueDecl *)> Gen) { 13973 for (U &Set : Lookups) { 13974 for (auto *D : Set) { 13975 if (T Res = Gen(cast<ValueDecl>(D))) 13976 return Res; 13977 } 13978 } 13979 return T(); 13980 } 13981 13982 static NamedDecl *findAcceptableDecl(Sema &SemaRef, NamedDecl *D) { 13983 assert(!LookupResult::isVisible(SemaRef, D) && "not in slow case"); 13984 13985 for (auto RD : D->redecls()) { 13986 // Don't bother with extra checks if we already know this one isn't visible. 13987 if (RD == D) 13988 continue; 13989 13990 auto ND = cast<NamedDecl>(RD); 13991 if (LookupResult::isVisible(SemaRef, ND)) 13992 return ND; 13993 } 13994 13995 return nullptr; 13996 } 13997 13998 static void 13999 argumentDependentLookup(Sema &SemaRef, const DeclarationNameInfo &Id, 14000 SourceLocation Loc, QualType Ty, 14001 SmallVectorImpl<UnresolvedSet<8>> &Lookups) { 14002 // Find all of the associated namespaces and classes based on the 14003 // arguments we have. 14004 Sema::AssociatedNamespaceSet AssociatedNamespaces; 14005 Sema::AssociatedClassSet AssociatedClasses; 14006 OpaqueValueExpr OVE(Loc, Ty, VK_LValue); 14007 SemaRef.FindAssociatedClassesAndNamespaces(Loc, &OVE, AssociatedNamespaces, 14008 AssociatedClasses); 14009 14010 // C++ [basic.lookup.argdep]p3: 14011 // Let X be the lookup set produced by unqualified lookup (3.4.1) 14012 // and let Y be the lookup set produced by argument dependent 14013 // lookup (defined as follows). If X contains [...] then Y is 14014 // empty. Otherwise Y is the set of declarations found in the 14015 // namespaces associated with the argument types as described 14016 // below. The set of declarations found by the lookup of the name 14017 // is the union of X and Y. 14018 // 14019 // Here, we compute Y and add its members to the overloaded 14020 // candidate set. 14021 for (auto *NS : AssociatedNamespaces) { 14022 // When considering an associated namespace, the lookup is the 14023 // same as the lookup performed when the associated namespace is 14024 // used as a qualifier (3.4.3.2) except that: 14025 // 14026 // -- Any using-directives in the associated namespace are 14027 // ignored. 14028 // 14029 // -- Any namespace-scope friend functions declared in 14030 // associated classes are visible within their respective 14031 // namespaces even if they are not visible during an ordinary 14032 // lookup (11.4). 14033 DeclContext::lookup_result R = NS->lookup(Id.getName()); 14034 for (auto *D : R) { 14035 auto *Underlying = D; 14036 if (auto *USD = dyn_cast<UsingShadowDecl>(D)) 14037 Underlying = USD->getTargetDecl(); 14038 14039 if (!isa<OMPDeclareReductionDecl>(Underlying) && 14040 !isa<OMPDeclareMapperDecl>(Underlying)) 14041 continue; 14042 14043 if (!SemaRef.isVisible(D)) { 14044 D = findAcceptableDecl(SemaRef, D); 14045 if (!D) 14046 continue; 14047 if (auto *USD = dyn_cast<UsingShadowDecl>(D)) 14048 Underlying = USD->getTargetDecl(); 14049 } 14050 Lookups.emplace_back(); 14051 Lookups.back().addDecl(Underlying); 14052 } 14053 } 14054 } 14055 14056 static ExprResult 14057 buildDeclareReductionRef(Sema &SemaRef, SourceLocation Loc, SourceRange Range, 14058 Scope *S, CXXScopeSpec &ReductionIdScopeSpec, 14059 const DeclarationNameInfo &ReductionId, QualType Ty, 14060 CXXCastPath &BasePath, Expr *UnresolvedReduction) { 14061 if (ReductionIdScopeSpec.isInvalid()) 14062 return ExprError(); 14063 SmallVector<UnresolvedSet<8>, 4> Lookups; 14064 if (S) { 14065 LookupResult Lookup(SemaRef, ReductionId, Sema::LookupOMPReductionName); 14066 Lookup.suppressDiagnostics(); 14067 while (S && SemaRef.LookupParsedName(Lookup, S, &ReductionIdScopeSpec)) { 14068 NamedDecl *D = Lookup.getRepresentativeDecl(); 14069 do { 14070 S = S->getParent(); 14071 } while (S && !S->isDeclScope(D)); 14072 if (S) 14073 S = S->getParent(); 14074 Lookups.emplace_back(); 14075 Lookups.back().append(Lookup.begin(), Lookup.end()); 14076 Lookup.clear(); 14077 } 14078 } else if (auto *ULE = 14079 cast_or_null<UnresolvedLookupExpr>(UnresolvedReduction)) { 14080 Lookups.push_back(UnresolvedSet<8>()); 14081 Decl *PrevD = nullptr; 14082 for (NamedDecl *D : ULE->decls()) { 14083 if (D == PrevD) 14084 Lookups.push_back(UnresolvedSet<8>()); 14085 else if (auto *DRD = dyn_cast<OMPDeclareReductionDecl>(D)) 14086 Lookups.back().addDecl(DRD); 14087 PrevD = D; 14088 } 14089 } 14090 if (SemaRef.CurContext->isDependentContext() || Ty->isDependentType() || 14091 Ty->isInstantiationDependentType() || 14092 Ty->containsUnexpandedParameterPack() || 14093 filterLookupForUDReductionAndMapper<bool>(Lookups, [](ValueDecl *D) { 14094 return !D->isInvalidDecl() && 14095 (D->getType()->isDependentType() || 14096 D->getType()->isInstantiationDependentType() || 14097 D->getType()->containsUnexpandedParameterPack()); 14098 })) { 14099 UnresolvedSet<8> ResSet; 14100 for (const UnresolvedSet<8> &Set : Lookups) { 14101 if (Set.empty()) 14102 continue; 14103 ResSet.append(Set.begin(), Set.end()); 14104 // The last item marks the end of all declarations at the specified scope. 14105 ResSet.addDecl(Set[Set.size() - 1]); 14106 } 14107 return UnresolvedLookupExpr::Create( 14108 SemaRef.Context, /*NamingClass=*/nullptr, 14109 ReductionIdScopeSpec.getWithLocInContext(SemaRef.Context), ReductionId, 14110 /*ADL=*/true, /*Overloaded=*/true, ResSet.begin(), ResSet.end()); 14111 } 14112 // Lookup inside the classes. 14113 // C++ [over.match.oper]p3: 14114 // For a unary operator @ with an operand of a type whose 14115 // cv-unqualified version is T1, and for a binary operator @ with 14116 // a left operand of a type whose cv-unqualified version is T1 and 14117 // a right operand of a type whose cv-unqualified version is T2, 14118 // three sets of candidate functions, designated member 14119 // candidates, non-member candidates and built-in candidates, are 14120 // constructed as follows: 14121 // -- If T1 is a complete class type or a class currently being 14122 // defined, the set of member candidates is the result of the 14123 // qualified lookup of T1::operator@ (13.3.1.1.1); otherwise, 14124 // the set of member candidates is empty. 14125 LookupResult Lookup(SemaRef, ReductionId, Sema::LookupOMPReductionName); 14126 Lookup.suppressDiagnostics(); 14127 if (const auto *TyRec = Ty->getAs<RecordType>()) { 14128 // Complete the type if it can be completed. 14129 // If the type is neither complete nor being defined, bail out now. 14130 if (SemaRef.isCompleteType(Loc, Ty) || TyRec->isBeingDefined() || 14131 TyRec->getDecl()->getDefinition()) { 14132 Lookup.clear(); 14133 SemaRef.LookupQualifiedName(Lookup, TyRec->getDecl()); 14134 if (Lookup.empty()) { 14135 Lookups.emplace_back(); 14136 Lookups.back().append(Lookup.begin(), Lookup.end()); 14137 } 14138 } 14139 } 14140 // Perform ADL. 14141 if (SemaRef.getLangOpts().CPlusPlus) 14142 argumentDependentLookup(SemaRef, ReductionId, Loc, Ty, Lookups); 14143 if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>( 14144 Lookups, [&SemaRef, Ty](ValueDecl *D) -> ValueDecl * { 14145 if (!D->isInvalidDecl() && 14146 SemaRef.Context.hasSameType(D->getType(), Ty)) 14147 return D; 14148 return nullptr; 14149 })) 14150 return SemaRef.BuildDeclRefExpr(VD, VD->getType().getNonReferenceType(), 14151 VK_LValue, Loc); 14152 if (SemaRef.getLangOpts().CPlusPlus) { 14153 if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>( 14154 Lookups, [&SemaRef, Ty, Loc](ValueDecl *D) -> ValueDecl * { 14155 if (!D->isInvalidDecl() && 14156 SemaRef.IsDerivedFrom(Loc, Ty, D->getType()) && 14157 !Ty.isMoreQualifiedThan(D->getType())) 14158 return D; 14159 return nullptr; 14160 })) { 14161 CXXBasePaths Paths(/*FindAmbiguities=*/true, /*RecordPaths=*/true, 14162 /*DetectVirtual=*/false); 14163 if (SemaRef.IsDerivedFrom(Loc, Ty, VD->getType(), Paths)) { 14164 if (!Paths.isAmbiguous(SemaRef.Context.getCanonicalType( 14165 VD->getType().getUnqualifiedType()))) { 14166 if (SemaRef.CheckBaseClassAccess( 14167 Loc, VD->getType(), Ty, Paths.front(), 14168 /*DiagID=*/0) != Sema::AR_inaccessible) { 14169 SemaRef.BuildBasePathArray(Paths, BasePath); 14170 return SemaRef.BuildDeclRefExpr( 14171 VD, VD->getType().getNonReferenceType(), VK_LValue, Loc); 14172 } 14173 } 14174 } 14175 } 14176 } 14177 if (ReductionIdScopeSpec.isSet()) { 14178 SemaRef.Diag(Loc, diag::err_omp_not_resolved_reduction_identifier) 14179 << Ty << Range; 14180 return ExprError(); 14181 } 14182 return ExprEmpty(); 14183 } 14184 14185 namespace { 14186 /// Data for the reduction-based clauses. 14187 struct ReductionData { 14188 /// List of original reduction items. 14189 SmallVector<Expr *, 8> Vars; 14190 /// List of private copies of the reduction items. 14191 SmallVector<Expr *, 8> Privates; 14192 /// LHS expressions for the reduction_op expressions. 14193 SmallVector<Expr *, 8> LHSs; 14194 /// RHS expressions for the reduction_op expressions. 14195 SmallVector<Expr *, 8> RHSs; 14196 /// Reduction operation expression. 14197 SmallVector<Expr *, 8> ReductionOps; 14198 /// Taskgroup descriptors for the corresponding reduction items in 14199 /// in_reduction clauses. 14200 SmallVector<Expr *, 8> TaskgroupDescriptors; 14201 /// List of captures for clause. 14202 SmallVector<Decl *, 4> ExprCaptures; 14203 /// List of postupdate expressions. 14204 SmallVector<Expr *, 4> ExprPostUpdates; 14205 /// Reduction modifier. 14206 unsigned RedModifier = 0; 14207 ReductionData() = delete; 14208 /// Reserves required memory for the reduction data. 14209 ReductionData(unsigned Size, unsigned Modifier = 0) : RedModifier(Modifier) { 14210 Vars.reserve(Size); 14211 Privates.reserve(Size); 14212 LHSs.reserve(Size); 14213 RHSs.reserve(Size); 14214 ReductionOps.reserve(Size); 14215 TaskgroupDescriptors.reserve(Size); 14216 ExprCaptures.reserve(Size); 14217 ExprPostUpdates.reserve(Size); 14218 } 14219 /// Stores reduction item and reduction operation only (required for dependent 14220 /// reduction item). 14221 void push(Expr *Item, Expr *ReductionOp) { 14222 Vars.emplace_back(Item); 14223 Privates.emplace_back(nullptr); 14224 LHSs.emplace_back(nullptr); 14225 RHSs.emplace_back(nullptr); 14226 ReductionOps.emplace_back(ReductionOp); 14227 TaskgroupDescriptors.emplace_back(nullptr); 14228 } 14229 /// Stores reduction data. 14230 void push(Expr *Item, Expr *Private, Expr *LHS, Expr *RHS, Expr *ReductionOp, 14231 Expr *TaskgroupDescriptor) { 14232 Vars.emplace_back(Item); 14233 Privates.emplace_back(Private); 14234 LHSs.emplace_back(LHS); 14235 RHSs.emplace_back(RHS); 14236 ReductionOps.emplace_back(ReductionOp); 14237 TaskgroupDescriptors.emplace_back(TaskgroupDescriptor); 14238 } 14239 }; 14240 } // namespace 14241 14242 static bool checkOMPArraySectionConstantForReduction( 14243 ASTContext &Context, const OMPArraySectionExpr *OASE, bool &SingleElement, 14244 SmallVectorImpl<llvm::APSInt> &ArraySizes) { 14245 const Expr *Length = OASE->getLength(); 14246 if (Length == nullptr) { 14247 // For array sections of the form [1:] or [:], we would need to analyze 14248 // the lower bound... 14249 if (OASE->getColonLoc().isValid()) 14250 return false; 14251 14252 // This is an array subscript which has implicit length 1! 14253 SingleElement = true; 14254 ArraySizes.push_back(llvm::APSInt::get(1)); 14255 } else { 14256 Expr::EvalResult Result; 14257 if (!Length->EvaluateAsInt(Result, Context)) 14258 return false; 14259 14260 llvm::APSInt ConstantLengthValue = Result.Val.getInt(); 14261 SingleElement = (ConstantLengthValue.getSExtValue() == 1); 14262 ArraySizes.push_back(ConstantLengthValue); 14263 } 14264 14265 // Get the base of this array section and walk up from there. 14266 const Expr *Base = OASE->getBase()->IgnoreParenImpCasts(); 14267 14268 // We require length = 1 for all array sections except the right-most to 14269 // guarantee that the memory region is contiguous and has no holes in it. 14270 while (const auto *TempOASE = dyn_cast<OMPArraySectionExpr>(Base)) { 14271 Length = TempOASE->getLength(); 14272 if (Length == nullptr) { 14273 // For array sections of the form [1:] or [:], we would need to analyze 14274 // the lower bound... 14275 if (OASE->getColonLoc().isValid()) 14276 return false; 14277 14278 // This is an array subscript which has implicit length 1! 14279 ArraySizes.push_back(llvm::APSInt::get(1)); 14280 } else { 14281 Expr::EvalResult Result; 14282 if (!Length->EvaluateAsInt(Result, Context)) 14283 return false; 14284 14285 llvm::APSInt ConstantLengthValue = Result.Val.getInt(); 14286 if (ConstantLengthValue.getSExtValue() != 1) 14287 return false; 14288 14289 ArraySizes.push_back(ConstantLengthValue); 14290 } 14291 Base = TempOASE->getBase()->IgnoreParenImpCasts(); 14292 } 14293 14294 // If we have a single element, we don't need to add the implicit lengths. 14295 if (!SingleElement) { 14296 while (const auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base)) { 14297 // Has implicit length 1! 14298 ArraySizes.push_back(llvm::APSInt::get(1)); 14299 Base = TempASE->getBase()->IgnoreParenImpCasts(); 14300 } 14301 } 14302 14303 // This array section can be privatized as a single value or as a constant 14304 // sized array. 14305 return true; 14306 } 14307 14308 static bool actOnOMPReductionKindClause( 14309 Sema &S, DSAStackTy *Stack, OpenMPClauseKind ClauseKind, 14310 ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, 14311 SourceLocation ColonLoc, SourceLocation EndLoc, 14312 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, 14313 ArrayRef<Expr *> UnresolvedReductions, ReductionData &RD) { 14314 DeclarationName DN = ReductionId.getName(); 14315 OverloadedOperatorKind OOK = DN.getCXXOverloadedOperator(); 14316 BinaryOperatorKind BOK = BO_Comma; 14317 14318 ASTContext &Context = S.Context; 14319 // OpenMP [2.14.3.6, reduction clause] 14320 // C 14321 // reduction-identifier is either an identifier or one of the following 14322 // operators: +, -, *, &, |, ^, && and || 14323 // C++ 14324 // reduction-identifier is either an id-expression or one of the following 14325 // operators: +, -, *, &, |, ^, && and || 14326 switch (OOK) { 14327 case OO_Plus: 14328 case OO_Minus: 14329 BOK = BO_Add; 14330 break; 14331 case OO_Star: 14332 BOK = BO_Mul; 14333 break; 14334 case OO_Amp: 14335 BOK = BO_And; 14336 break; 14337 case OO_Pipe: 14338 BOK = BO_Or; 14339 break; 14340 case OO_Caret: 14341 BOK = BO_Xor; 14342 break; 14343 case OO_AmpAmp: 14344 BOK = BO_LAnd; 14345 break; 14346 case OO_PipePipe: 14347 BOK = BO_LOr; 14348 break; 14349 case OO_New: 14350 case OO_Delete: 14351 case OO_Array_New: 14352 case OO_Array_Delete: 14353 case OO_Slash: 14354 case OO_Percent: 14355 case OO_Tilde: 14356 case OO_Exclaim: 14357 case OO_Equal: 14358 case OO_Less: 14359 case OO_Greater: 14360 case OO_LessEqual: 14361 case OO_GreaterEqual: 14362 case OO_PlusEqual: 14363 case OO_MinusEqual: 14364 case OO_StarEqual: 14365 case OO_SlashEqual: 14366 case OO_PercentEqual: 14367 case OO_CaretEqual: 14368 case OO_AmpEqual: 14369 case OO_PipeEqual: 14370 case OO_LessLess: 14371 case OO_GreaterGreater: 14372 case OO_LessLessEqual: 14373 case OO_GreaterGreaterEqual: 14374 case OO_EqualEqual: 14375 case OO_ExclaimEqual: 14376 case OO_Spaceship: 14377 case OO_PlusPlus: 14378 case OO_MinusMinus: 14379 case OO_Comma: 14380 case OO_ArrowStar: 14381 case OO_Arrow: 14382 case OO_Call: 14383 case OO_Subscript: 14384 case OO_Conditional: 14385 case OO_Coawait: 14386 case NUM_OVERLOADED_OPERATORS: 14387 llvm_unreachable("Unexpected reduction identifier"); 14388 case OO_None: 14389 if (IdentifierInfo *II = DN.getAsIdentifierInfo()) { 14390 if (II->isStr("max")) 14391 BOK = BO_GT; 14392 else if (II->isStr("min")) 14393 BOK = BO_LT; 14394 } 14395 break; 14396 } 14397 SourceRange ReductionIdRange; 14398 if (ReductionIdScopeSpec.isValid()) 14399 ReductionIdRange.setBegin(ReductionIdScopeSpec.getBeginLoc()); 14400 else 14401 ReductionIdRange.setBegin(ReductionId.getBeginLoc()); 14402 ReductionIdRange.setEnd(ReductionId.getEndLoc()); 14403 14404 auto IR = UnresolvedReductions.begin(), ER = UnresolvedReductions.end(); 14405 bool FirstIter = true; 14406 for (Expr *RefExpr : VarList) { 14407 assert(RefExpr && "nullptr expr in OpenMP reduction clause."); 14408 // OpenMP [2.1, C/C++] 14409 // A list item is a variable or array section, subject to the restrictions 14410 // specified in Section 2.4 on page 42 and in each of the sections 14411 // describing clauses and directives for which a list appears. 14412 // OpenMP [2.14.3.3, Restrictions, p.1] 14413 // A variable that is part of another variable (as an array or 14414 // structure element) cannot appear in a private clause. 14415 if (!FirstIter && IR != ER) 14416 ++IR; 14417 FirstIter = false; 14418 SourceLocation ELoc; 14419 SourceRange ERange; 14420 Expr *SimpleRefExpr = RefExpr; 14421 auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange, 14422 /*AllowArraySection=*/true); 14423 if (Res.second) { 14424 // Try to find 'declare reduction' corresponding construct before using 14425 // builtin/overloaded operators. 14426 QualType Type = Context.DependentTy; 14427 CXXCastPath BasePath; 14428 ExprResult DeclareReductionRef = buildDeclareReductionRef( 14429 S, ELoc, ERange, Stack->getCurScope(), ReductionIdScopeSpec, 14430 ReductionId, Type, BasePath, IR == ER ? nullptr : *IR); 14431 Expr *ReductionOp = nullptr; 14432 if (S.CurContext->isDependentContext() && 14433 (DeclareReductionRef.isUnset() || 14434 isa<UnresolvedLookupExpr>(DeclareReductionRef.get()))) 14435 ReductionOp = DeclareReductionRef.get(); 14436 // It will be analyzed later. 14437 RD.push(RefExpr, ReductionOp); 14438 } 14439 ValueDecl *D = Res.first; 14440 if (!D) 14441 continue; 14442 14443 Expr *TaskgroupDescriptor = nullptr; 14444 QualType Type; 14445 auto *ASE = dyn_cast<ArraySubscriptExpr>(RefExpr->IgnoreParens()); 14446 auto *OASE = dyn_cast<OMPArraySectionExpr>(RefExpr->IgnoreParens()); 14447 if (ASE) { 14448 Type = ASE->getType().getNonReferenceType(); 14449 } else if (OASE) { 14450 QualType BaseType = 14451 OMPArraySectionExpr::getBaseOriginalType(OASE->getBase()); 14452 if (const auto *ATy = BaseType->getAsArrayTypeUnsafe()) 14453 Type = ATy->getElementType(); 14454 else 14455 Type = BaseType->getPointeeType(); 14456 Type = Type.getNonReferenceType(); 14457 } else { 14458 Type = Context.getBaseElementType(D->getType().getNonReferenceType()); 14459 } 14460 auto *VD = dyn_cast<VarDecl>(D); 14461 14462 // OpenMP [2.9.3.3, Restrictions, C/C++, p.3] 14463 // A variable that appears in a private clause must not have an incomplete 14464 // type or a reference type. 14465 if (S.RequireCompleteType(ELoc, D->getType(), 14466 diag::err_omp_reduction_incomplete_type)) 14467 continue; 14468 // OpenMP [2.14.3.6, reduction clause, Restrictions] 14469 // A list item that appears in a reduction clause must not be 14470 // const-qualified. 14471 if (rejectConstNotMutableType(S, D, Type, ClauseKind, ELoc, 14472 /*AcceptIfMutable*/ false, ASE || OASE)) 14473 continue; 14474 14475 OpenMPDirectiveKind CurrDir = Stack->getCurrentDirective(); 14476 // OpenMP [2.9.3.6, Restrictions, C/C++, p.4] 14477 // If a list-item is a reference type then it must bind to the same object 14478 // for all threads of the team. 14479 if (!ASE && !OASE) { 14480 if (VD) { 14481 VarDecl *VDDef = VD->getDefinition(); 14482 if (VD->getType()->isReferenceType() && VDDef && VDDef->hasInit()) { 14483 DSARefChecker Check(Stack); 14484 if (Check.Visit(VDDef->getInit())) { 14485 S.Diag(ELoc, diag::err_omp_reduction_ref_type_arg) 14486 << getOpenMPClauseName(ClauseKind) << ERange; 14487 S.Diag(VDDef->getLocation(), diag::note_defined_here) << VDDef; 14488 continue; 14489 } 14490 } 14491 } 14492 14493 // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables Referenced 14494 // in a Construct] 14495 // Variables with the predetermined data-sharing attributes may not be 14496 // listed in data-sharing attributes clauses, except for the cases 14497 // listed below. For these exceptions only, listing a predetermined 14498 // variable in a data-sharing attribute clause is allowed and overrides 14499 // the variable's predetermined data-sharing attributes. 14500 // OpenMP [2.14.3.6, Restrictions, p.3] 14501 // Any number of reduction clauses can be specified on the directive, 14502 // but a list item can appear only once in the reduction clauses for that 14503 // directive. 14504 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(D, /*FromParent=*/false); 14505 if (DVar.CKind == OMPC_reduction) { 14506 S.Diag(ELoc, diag::err_omp_once_referenced) 14507 << getOpenMPClauseName(ClauseKind); 14508 if (DVar.RefExpr) 14509 S.Diag(DVar.RefExpr->getExprLoc(), diag::note_omp_referenced); 14510 continue; 14511 } 14512 if (DVar.CKind != OMPC_unknown) { 14513 S.Diag(ELoc, diag::err_omp_wrong_dsa) 14514 << getOpenMPClauseName(DVar.CKind) 14515 << getOpenMPClauseName(OMPC_reduction); 14516 reportOriginalDsa(S, Stack, D, DVar); 14517 continue; 14518 } 14519 14520 // OpenMP [2.14.3.6, Restrictions, p.1] 14521 // A list item that appears in a reduction clause of a worksharing 14522 // construct must be shared in the parallel regions to which any of the 14523 // worksharing regions arising from the worksharing construct bind. 14524 if (isOpenMPWorksharingDirective(CurrDir) && 14525 !isOpenMPParallelDirective(CurrDir) && 14526 !isOpenMPTeamsDirective(CurrDir)) { 14527 DVar = Stack->getImplicitDSA(D, true); 14528 if (DVar.CKind != OMPC_shared) { 14529 S.Diag(ELoc, diag::err_omp_required_access) 14530 << getOpenMPClauseName(OMPC_reduction) 14531 << getOpenMPClauseName(OMPC_shared); 14532 reportOriginalDsa(S, Stack, D, DVar); 14533 continue; 14534 } 14535 } 14536 } 14537 14538 // Try to find 'declare reduction' corresponding construct before using 14539 // builtin/overloaded operators. 14540 CXXCastPath BasePath; 14541 ExprResult DeclareReductionRef = buildDeclareReductionRef( 14542 S, ELoc, ERange, Stack->getCurScope(), ReductionIdScopeSpec, 14543 ReductionId, Type, BasePath, IR == ER ? nullptr : *IR); 14544 if (DeclareReductionRef.isInvalid()) 14545 continue; 14546 if (S.CurContext->isDependentContext() && 14547 (DeclareReductionRef.isUnset() || 14548 isa<UnresolvedLookupExpr>(DeclareReductionRef.get()))) { 14549 RD.push(RefExpr, DeclareReductionRef.get()); 14550 continue; 14551 } 14552 if (BOK == BO_Comma && DeclareReductionRef.isUnset()) { 14553 // Not allowed reduction identifier is found. 14554 S.Diag(ReductionId.getBeginLoc(), 14555 diag::err_omp_unknown_reduction_identifier) 14556 << Type << ReductionIdRange; 14557 continue; 14558 } 14559 14560 // OpenMP [2.14.3.6, reduction clause, Restrictions] 14561 // The type of a list item that appears in a reduction clause must be valid 14562 // for the reduction-identifier. For a max or min reduction in C, the type 14563 // of the list item must be an allowed arithmetic data type: char, int, 14564 // float, double, or _Bool, possibly modified with long, short, signed, or 14565 // unsigned. For a max or min reduction in C++, the type of the list item 14566 // must be an allowed arithmetic data type: char, wchar_t, int, float, 14567 // double, or bool, possibly modified with long, short, signed, or unsigned. 14568 if (DeclareReductionRef.isUnset()) { 14569 if ((BOK == BO_GT || BOK == BO_LT) && 14570 !(Type->isScalarType() || 14571 (S.getLangOpts().CPlusPlus && Type->isArithmeticType()))) { 14572 S.Diag(ELoc, diag::err_omp_clause_not_arithmetic_type_arg) 14573 << getOpenMPClauseName(ClauseKind) << S.getLangOpts().CPlusPlus; 14574 if (!ASE && !OASE) { 14575 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) == 14576 VarDecl::DeclarationOnly; 14577 S.Diag(D->getLocation(), 14578 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 14579 << D; 14580 } 14581 continue; 14582 } 14583 if ((BOK == BO_OrAssign || BOK == BO_AndAssign || BOK == BO_XorAssign) && 14584 !S.getLangOpts().CPlusPlus && Type->isFloatingType()) { 14585 S.Diag(ELoc, diag::err_omp_clause_floating_type_arg) 14586 << getOpenMPClauseName(ClauseKind); 14587 if (!ASE && !OASE) { 14588 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) == 14589 VarDecl::DeclarationOnly; 14590 S.Diag(D->getLocation(), 14591 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 14592 << D; 14593 } 14594 continue; 14595 } 14596 } 14597 14598 Type = Type.getNonLValueExprType(Context).getUnqualifiedType(); 14599 VarDecl *LHSVD = buildVarDecl(S, ELoc, Type, ".reduction.lhs", 14600 D->hasAttrs() ? &D->getAttrs() : nullptr); 14601 VarDecl *RHSVD = buildVarDecl(S, ELoc, Type, D->getName(), 14602 D->hasAttrs() ? &D->getAttrs() : nullptr); 14603 QualType PrivateTy = Type; 14604 14605 // Try if we can determine constant lengths for all array sections and avoid 14606 // the VLA. 14607 bool ConstantLengthOASE = false; 14608 if (OASE) { 14609 bool SingleElement; 14610 llvm::SmallVector<llvm::APSInt, 4> ArraySizes; 14611 ConstantLengthOASE = checkOMPArraySectionConstantForReduction( 14612 Context, OASE, SingleElement, ArraySizes); 14613 14614 // If we don't have a single element, we must emit a constant array type. 14615 if (ConstantLengthOASE && !SingleElement) { 14616 for (llvm::APSInt &Size : ArraySizes) 14617 PrivateTy = Context.getConstantArrayType(PrivateTy, Size, nullptr, 14618 ArrayType::Normal, 14619 /*IndexTypeQuals=*/0); 14620 } 14621 } 14622 14623 if ((OASE && !ConstantLengthOASE) || 14624 (!OASE && !ASE && 14625 D->getType().getNonReferenceType()->isVariablyModifiedType())) { 14626 if (!Context.getTargetInfo().isVLASupported()) { 14627 if (isOpenMPTargetExecutionDirective(Stack->getCurrentDirective())) { 14628 S.Diag(ELoc, diag::err_omp_reduction_vla_unsupported) << !!OASE; 14629 S.Diag(ELoc, diag::note_vla_unsupported); 14630 } else { 14631 S.targetDiag(ELoc, diag::err_omp_reduction_vla_unsupported) << !!OASE; 14632 S.targetDiag(ELoc, diag::note_vla_unsupported); 14633 } 14634 continue; 14635 } 14636 // For arrays/array sections only: 14637 // Create pseudo array type for private copy. The size for this array will 14638 // be generated during codegen. 14639 // For array subscripts or single variables Private Ty is the same as Type 14640 // (type of the variable or single array element). 14641 PrivateTy = Context.getVariableArrayType( 14642 Type, 14643 new (Context) OpaqueValueExpr(ELoc, Context.getSizeType(), VK_RValue), 14644 ArrayType::Normal, /*IndexTypeQuals=*/0, SourceRange()); 14645 } else if (!ASE && !OASE && 14646 Context.getAsArrayType(D->getType().getNonReferenceType())) { 14647 PrivateTy = D->getType().getNonReferenceType(); 14648 } 14649 // Private copy. 14650 VarDecl *PrivateVD = 14651 buildVarDecl(S, ELoc, PrivateTy, D->getName(), 14652 D->hasAttrs() ? &D->getAttrs() : nullptr, 14653 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr); 14654 // Add initializer for private variable. 14655 Expr *Init = nullptr; 14656 DeclRefExpr *LHSDRE = buildDeclRefExpr(S, LHSVD, Type, ELoc); 14657 DeclRefExpr *RHSDRE = buildDeclRefExpr(S, RHSVD, Type, ELoc); 14658 if (DeclareReductionRef.isUsable()) { 14659 auto *DRDRef = DeclareReductionRef.getAs<DeclRefExpr>(); 14660 auto *DRD = cast<OMPDeclareReductionDecl>(DRDRef->getDecl()); 14661 if (DRD->getInitializer()) { 14662 Init = DRDRef; 14663 RHSVD->setInit(DRDRef); 14664 RHSVD->setInitStyle(VarDecl::CallInit); 14665 } 14666 } else { 14667 switch (BOK) { 14668 case BO_Add: 14669 case BO_Xor: 14670 case BO_Or: 14671 case BO_LOr: 14672 // '+', '-', '^', '|', '||' reduction ops - initializer is '0'. 14673 if (Type->isScalarType() || Type->isAnyComplexType()) 14674 Init = S.ActOnIntegerConstant(ELoc, /*Val=*/0).get(); 14675 break; 14676 case BO_Mul: 14677 case BO_LAnd: 14678 if (Type->isScalarType() || Type->isAnyComplexType()) { 14679 // '*' and '&&' reduction ops - initializer is '1'. 14680 Init = S.ActOnIntegerConstant(ELoc, /*Val=*/1).get(); 14681 } 14682 break; 14683 case BO_And: { 14684 // '&' reduction op - initializer is '~0'. 14685 QualType OrigType = Type; 14686 if (auto *ComplexTy = OrigType->getAs<ComplexType>()) 14687 Type = ComplexTy->getElementType(); 14688 if (Type->isRealFloatingType()) { 14689 llvm::APFloat InitValue = 14690 llvm::APFloat::getAllOnesValue(Context.getTypeSize(Type), 14691 /*isIEEE=*/true); 14692 Init = FloatingLiteral::Create(Context, InitValue, /*isexact=*/true, 14693 Type, ELoc); 14694 } else if (Type->isScalarType()) { 14695 uint64_t Size = Context.getTypeSize(Type); 14696 QualType IntTy = Context.getIntTypeForBitwidth(Size, /*Signed=*/0); 14697 llvm::APInt InitValue = llvm::APInt::getAllOnesValue(Size); 14698 Init = IntegerLiteral::Create(Context, InitValue, IntTy, ELoc); 14699 } 14700 if (Init && OrigType->isAnyComplexType()) { 14701 // Init = 0xFFFF + 0xFFFFi; 14702 auto *Im = new (Context) ImaginaryLiteral(Init, OrigType); 14703 Init = S.CreateBuiltinBinOp(ELoc, BO_Add, Init, Im).get(); 14704 } 14705 Type = OrigType; 14706 break; 14707 } 14708 case BO_LT: 14709 case BO_GT: { 14710 // 'min' reduction op - initializer is 'Largest representable number in 14711 // the reduction list item type'. 14712 // 'max' reduction op - initializer is 'Least representable number in 14713 // the reduction list item type'. 14714 if (Type->isIntegerType() || Type->isPointerType()) { 14715 bool IsSigned = Type->hasSignedIntegerRepresentation(); 14716 uint64_t Size = Context.getTypeSize(Type); 14717 QualType IntTy = 14718 Context.getIntTypeForBitwidth(Size, /*Signed=*/IsSigned); 14719 llvm::APInt InitValue = 14720 (BOK != BO_LT) ? IsSigned ? llvm::APInt::getSignedMinValue(Size) 14721 : llvm::APInt::getMinValue(Size) 14722 : IsSigned ? llvm::APInt::getSignedMaxValue(Size) 14723 : llvm::APInt::getMaxValue(Size); 14724 Init = IntegerLiteral::Create(Context, InitValue, IntTy, ELoc); 14725 if (Type->isPointerType()) { 14726 // Cast to pointer type. 14727 ExprResult CastExpr = S.BuildCStyleCastExpr( 14728 ELoc, Context.getTrivialTypeSourceInfo(Type, ELoc), ELoc, Init); 14729 if (CastExpr.isInvalid()) 14730 continue; 14731 Init = CastExpr.get(); 14732 } 14733 } else if (Type->isRealFloatingType()) { 14734 llvm::APFloat InitValue = llvm::APFloat::getLargest( 14735 Context.getFloatTypeSemantics(Type), BOK != BO_LT); 14736 Init = FloatingLiteral::Create(Context, InitValue, /*isexact=*/true, 14737 Type, ELoc); 14738 } 14739 break; 14740 } 14741 case BO_PtrMemD: 14742 case BO_PtrMemI: 14743 case BO_MulAssign: 14744 case BO_Div: 14745 case BO_Rem: 14746 case BO_Sub: 14747 case BO_Shl: 14748 case BO_Shr: 14749 case BO_LE: 14750 case BO_GE: 14751 case BO_EQ: 14752 case BO_NE: 14753 case BO_Cmp: 14754 case BO_AndAssign: 14755 case BO_XorAssign: 14756 case BO_OrAssign: 14757 case BO_Assign: 14758 case BO_AddAssign: 14759 case BO_SubAssign: 14760 case BO_DivAssign: 14761 case BO_RemAssign: 14762 case BO_ShlAssign: 14763 case BO_ShrAssign: 14764 case BO_Comma: 14765 llvm_unreachable("Unexpected reduction operation"); 14766 } 14767 } 14768 if (Init && DeclareReductionRef.isUnset()) 14769 S.AddInitializerToDecl(RHSVD, Init, /*DirectInit=*/false); 14770 else if (!Init) 14771 S.ActOnUninitializedDecl(RHSVD); 14772 if (RHSVD->isInvalidDecl()) 14773 continue; 14774 if (!RHSVD->hasInit() && 14775 (DeclareReductionRef.isUnset() || !S.LangOpts.CPlusPlus)) { 14776 S.Diag(ELoc, diag::err_omp_reduction_id_not_compatible) 14777 << Type << ReductionIdRange; 14778 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) == 14779 VarDecl::DeclarationOnly; 14780 S.Diag(D->getLocation(), 14781 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 14782 << D; 14783 continue; 14784 } 14785 // Store initializer for single element in private copy. Will be used during 14786 // codegen. 14787 PrivateVD->setInit(RHSVD->getInit()); 14788 PrivateVD->setInitStyle(RHSVD->getInitStyle()); 14789 DeclRefExpr *PrivateDRE = buildDeclRefExpr(S, PrivateVD, PrivateTy, ELoc); 14790 ExprResult ReductionOp; 14791 if (DeclareReductionRef.isUsable()) { 14792 QualType RedTy = DeclareReductionRef.get()->getType(); 14793 QualType PtrRedTy = Context.getPointerType(RedTy); 14794 ExprResult LHS = S.CreateBuiltinUnaryOp(ELoc, UO_AddrOf, LHSDRE); 14795 ExprResult RHS = S.CreateBuiltinUnaryOp(ELoc, UO_AddrOf, RHSDRE); 14796 if (!BasePath.empty()) { 14797 LHS = S.DefaultLvalueConversion(LHS.get()); 14798 RHS = S.DefaultLvalueConversion(RHS.get()); 14799 LHS = ImplicitCastExpr::Create(Context, PtrRedTy, 14800 CK_UncheckedDerivedToBase, LHS.get(), 14801 &BasePath, LHS.get()->getValueKind()); 14802 RHS = ImplicitCastExpr::Create(Context, PtrRedTy, 14803 CK_UncheckedDerivedToBase, RHS.get(), 14804 &BasePath, RHS.get()->getValueKind()); 14805 } 14806 FunctionProtoType::ExtProtoInfo EPI; 14807 QualType Params[] = {PtrRedTy, PtrRedTy}; 14808 QualType FnTy = Context.getFunctionType(Context.VoidTy, Params, EPI); 14809 auto *OVE = new (Context) OpaqueValueExpr( 14810 ELoc, Context.getPointerType(FnTy), VK_RValue, OK_Ordinary, 14811 S.DefaultLvalueConversion(DeclareReductionRef.get()).get()); 14812 Expr *Args[] = {LHS.get(), RHS.get()}; 14813 ReductionOp = 14814 CallExpr::Create(Context, OVE, Args, Context.VoidTy, VK_RValue, ELoc); 14815 } else { 14816 ReductionOp = S.BuildBinOp( 14817 Stack->getCurScope(), ReductionId.getBeginLoc(), BOK, LHSDRE, RHSDRE); 14818 if (ReductionOp.isUsable()) { 14819 if (BOK != BO_LT && BOK != BO_GT) { 14820 ReductionOp = 14821 S.BuildBinOp(Stack->getCurScope(), ReductionId.getBeginLoc(), 14822 BO_Assign, LHSDRE, ReductionOp.get()); 14823 } else { 14824 auto *ConditionalOp = new (Context) 14825 ConditionalOperator(ReductionOp.get(), ELoc, LHSDRE, ELoc, RHSDRE, 14826 Type, VK_LValue, OK_Ordinary); 14827 ReductionOp = 14828 S.BuildBinOp(Stack->getCurScope(), ReductionId.getBeginLoc(), 14829 BO_Assign, LHSDRE, ConditionalOp); 14830 } 14831 if (ReductionOp.isUsable()) 14832 ReductionOp = S.ActOnFinishFullExpr(ReductionOp.get(), 14833 /*DiscardedValue*/ false); 14834 } 14835 if (!ReductionOp.isUsable()) 14836 continue; 14837 } 14838 14839 // OpenMP [2.15.4.6, Restrictions, p.2] 14840 // A list item that appears in an in_reduction clause of a task construct 14841 // must appear in a task_reduction clause of a construct associated with a 14842 // taskgroup region that includes the participating task in its taskgroup 14843 // set. The construct associated with the innermost region that meets this 14844 // condition must specify the same reduction-identifier as the in_reduction 14845 // clause. 14846 if (ClauseKind == OMPC_in_reduction) { 14847 SourceRange ParentSR; 14848 BinaryOperatorKind ParentBOK; 14849 const Expr *ParentReductionOp = nullptr; 14850 Expr *ParentBOKTD = nullptr, *ParentReductionOpTD = nullptr; 14851 DSAStackTy::DSAVarData ParentBOKDSA = 14852 Stack->getTopMostTaskgroupReductionData(D, ParentSR, ParentBOK, 14853 ParentBOKTD); 14854 DSAStackTy::DSAVarData ParentReductionOpDSA = 14855 Stack->getTopMostTaskgroupReductionData( 14856 D, ParentSR, ParentReductionOp, ParentReductionOpTD); 14857 bool IsParentBOK = ParentBOKDSA.DKind != OMPD_unknown; 14858 bool IsParentReductionOp = ParentReductionOpDSA.DKind != OMPD_unknown; 14859 if ((DeclareReductionRef.isUnset() && IsParentReductionOp) || 14860 (DeclareReductionRef.isUsable() && IsParentBOK) || 14861 (IsParentBOK && BOK != ParentBOK) || IsParentReductionOp) { 14862 bool EmitError = true; 14863 if (IsParentReductionOp && DeclareReductionRef.isUsable()) { 14864 llvm::FoldingSetNodeID RedId, ParentRedId; 14865 ParentReductionOp->Profile(ParentRedId, Context, /*Canonical=*/true); 14866 DeclareReductionRef.get()->Profile(RedId, Context, 14867 /*Canonical=*/true); 14868 EmitError = RedId != ParentRedId; 14869 } 14870 if (EmitError) { 14871 S.Diag(ReductionId.getBeginLoc(), 14872 diag::err_omp_reduction_identifier_mismatch) 14873 << ReductionIdRange << RefExpr->getSourceRange(); 14874 S.Diag(ParentSR.getBegin(), 14875 diag::note_omp_previous_reduction_identifier) 14876 << ParentSR 14877 << (IsParentBOK ? ParentBOKDSA.RefExpr 14878 : ParentReductionOpDSA.RefExpr) 14879 ->getSourceRange(); 14880 continue; 14881 } 14882 } 14883 TaskgroupDescriptor = IsParentBOK ? ParentBOKTD : ParentReductionOpTD; 14884 } 14885 14886 DeclRefExpr *Ref = nullptr; 14887 Expr *VarsExpr = RefExpr->IgnoreParens(); 14888 if (!VD && !S.CurContext->isDependentContext()) { 14889 if (ASE || OASE) { 14890 TransformExprToCaptures RebuildToCapture(S, D); 14891 VarsExpr = 14892 RebuildToCapture.TransformExpr(RefExpr->IgnoreParens()).get(); 14893 Ref = RebuildToCapture.getCapturedExpr(); 14894 } else { 14895 VarsExpr = Ref = buildCapture(S, D, SimpleRefExpr, /*WithInit=*/false); 14896 } 14897 if (!S.isOpenMPCapturedDecl(D)) { 14898 RD.ExprCaptures.emplace_back(Ref->getDecl()); 14899 if (Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>()) { 14900 ExprResult RefRes = S.DefaultLvalueConversion(Ref); 14901 if (!RefRes.isUsable()) 14902 continue; 14903 ExprResult PostUpdateRes = 14904 S.BuildBinOp(Stack->getCurScope(), ELoc, BO_Assign, SimpleRefExpr, 14905 RefRes.get()); 14906 if (!PostUpdateRes.isUsable()) 14907 continue; 14908 if (isOpenMPTaskingDirective(Stack->getCurrentDirective()) || 14909 Stack->getCurrentDirective() == OMPD_taskgroup) { 14910 S.Diag(RefExpr->getExprLoc(), 14911 diag::err_omp_reduction_non_addressable_expression) 14912 << RefExpr->getSourceRange(); 14913 continue; 14914 } 14915 RD.ExprPostUpdates.emplace_back( 14916 S.IgnoredValueConversions(PostUpdateRes.get()).get()); 14917 } 14918 } 14919 } 14920 // All reduction items are still marked as reduction (to do not increase 14921 // code base size). 14922 Stack->addDSA(D, RefExpr->IgnoreParens(), OMPC_reduction, Ref, 14923 RD.RedModifier); 14924 if (CurrDir == OMPD_taskgroup) { 14925 if (DeclareReductionRef.isUsable()) 14926 Stack->addTaskgroupReductionData(D, ReductionIdRange, 14927 DeclareReductionRef.get()); 14928 else 14929 Stack->addTaskgroupReductionData(D, ReductionIdRange, BOK); 14930 } 14931 RD.push(VarsExpr, PrivateDRE, LHSDRE, RHSDRE, ReductionOp.get(), 14932 TaskgroupDescriptor); 14933 } 14934 return RD.Vars.empty(); 14935 } 14936 14937 OMPClause *Sema::ActOnOpenMPReductionClause( 14938 ArrayRef<Expr *> VarList, OpenMPReductionClauseModifier Modifier, 14939 SourceLocation StartLoc, SourceLocation LParenLoc, 14940 SourceLocation ModifierLoc, SourceLocation ColonLoc, SourceLocation EndLoc, 14941 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, 14942 ArrayRef<Expr *> UnresolvedReductions) { 14943 if (ModifierLoc.isValid() && Modifier == OMPC_REDUCTION_unknown) { 14944 Diag(LParenLoc, diag::err_omp_unexpected_clause_value) 14945 << getListOfPossibleValues(OMPC_reduction, /*First=*/0, 14946 /*Last=*/OMPC_REDUCTION_unknown) 14947 << getOpenMPClauseName(OMPC_reduction); 14948 return nullptr; 14949 } 14950 // OpenMP 5.0, 2.19.5.4 reduction Clause, Restrictions 14951 // A reduction clause with the inscan reduction-modifier may only appear on a 14952 // worksharing-loop construct, a worksharing-loop SIMD construct, a simd 14953 // construct, a parallel worksharing-loop construct or a parallel 14954 // worksharing-loop SIMD construct. 14955 if (Modifier == OMPC_REDUCTION_inscan && 14956 (DSAStack->getCurrentDirective() != OMPD_for && 14957 DSAStack->getCurrentDirective() != OMPD_for_simd && 14958 DSAStack->getCurrentDirective() != OMPD_simd && 14959 DSAStack->getCurrentDirective() != OMPD_parallel_for && 14960 DSAStack->getCurrentDirective() != OMPD_parallel_for_simd)) { 14961 Diag(ModifierLoc, diag::err_omp_wrong_inscan_reduction); 14962 return nullptr; 14963 } 14964 14965 ReductionData RD(VarList.size(), Modifier); 14966 if (actOnOMPReductionKindClause(*this, DSAStack, OMPC_reduction, VarList, 14967 StartLoc, LParenLoc, ColonLoc, EndLoc, 14968 ReductionIdScopeSpec, ReductionId, 14969 UnresolvedReductions, RD)) 14970 return nullptr; 14971 14972 return OMPReductionClause::Create( 14973 Context, StartLoc, LParenLoc, ModifierLoc, ColonLoc, EndLoc, Modifier, 14974 RD.Vars, ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId, 14975 RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps, 14976 buildPreInits(Context, RD.ExprCaptures), 14977 buildPostUpdate(*this, RD.ExprPostUpdates)); 14978 } 14979 14980 OMPClause *Sema::ActOnOpenMPTaskReductionClause( 14981 ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, 14982 SourceLocation ColonLoc, SourceLocation EndLoc, 14983 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, 14984 ArrayRef<Expr *> UnresolvedReductions) { 14985 ReductionData RD(VarList.size()); 14986 if (actOnOMPReductionKindClause(*this, DSAStack, OMPC_task_reduction, VarList, 14987 StartLoc, LParenLoc, ColonLoc, EndLoc, 14988 ReductionIdScopeSpec, ReductionId, 14989 UnresolvedReductions, RD)) 14990 return nullptr; 14991 14992 return OMPTaskReductionClause::Create( 14993 Context, StartLoc, LParenLoc, ColonLoc, EndLoc, RD.Vars, 14994 ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId, 14995 RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps, 14996 buildPreInits(Context, RD.ExprCaptures), 14997 buildPostUpdate(*this, RD.ExprPostUpdates)); 14998 } 14999 15000 OMPClause *Sema::ActOnOpenMPInReductionClause( 15001 ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, 15002 SourceLocation ColonLoc, SourceLocation EndLoc, 15003 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, 15004 ArrayRef<Expr *> UnresolvedReductions) { 15005 ReductionData RD(VarList.size()); 15006 if (actOnOMPReductionKindClause(*this, DSAStack, OMPC_in_reduction, VarList, 15007 StartLoc, LParenLoc, ColonLoc, EndLoc, 15008 ReductionIdScopeSpec, ReductionId, 15009 UnresolvedReductions, RD)) 15010 return nullptr; 15011 15012 return OMPInReductionClause::Create( 15013 Context, StartLoc, LParenLoc, ColonLoc, EndLoc, RD.Vars, 15014 ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId, 15015 RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps, RD.TaskgroupDescriptors, 15016 buildPreInits(Context, RD.ExprCaptures), 15017 buildPostUpdate(*this, RD.ExprPostUpdates)); 15018 } 15019 15020 bool Sema::CheckOpenMPLinearModifier(OpenMPLinearClauseKind LinKind, 15021 SourceLocation LinLoc) { 15022 if ((!LangOpts.CPlusPlus && LinKind != OMPC_LINEAR_val) || 15023 LinKind == OMPC_LINEAR_unknown) { 15024 Diag(LinLoc, diag::err_omp_wrong_linear_modifier) << LangOpts.CPlusPlus; 15025 return true; 15026 } 15027 return false; 15028 } 15029 15030 bool Sema::CheckOpenMPLinearDecl(const ValueDecl *D, SourceLocation ELoc, 15031 OpenMPLinearClauseKind LinKind, QualType Type, 15032 bool IsDeclareSimd) { 15033 const auto *VD = dyn_cast_or_null<VarDecl>(D); 15034 // A variable must not have an incomplete type or a reference type. 15035 if (RequireCompleteType(ELoc, Type, diag::err_omp_linear_incomplete_type)) 15036 return true; 15037 if ((LinKind == OMPC_LINEAR_uval || LinKind == OMPC_LINEAR_ref) && 15038 !Type->isReferenceType()) { 15039 Diag(ELoc, diag::err_omp_wrong_linear_modifier_non_reference) 15040 << Type << getOpenMPSimpleClauseTypeName(OMPC_linear, LinKind); 15041 return true; 15042 } 15043 Type = Type.getNonReferenceType(); 15044 15045 // OpenMP 5.0 [2.19.3, List Item Privatization, Restrictions] 15046 // A variable that is privatized must not have a const-qualified type 15047 // unless it is of class type with a mutable member. This restriction does 15048 // not apply to the firstprivate clause, nor to the linear clause on 15049 // declarative directives (like declare simd). 15050 if (!IsDeclareSimd && 15051 rejectConstNotMutableType(*this, D, Type, OMPC_linear, ELoc)) 15052 return true; 15053 15054 // A list item must be of integral or pointer type. 15055 Type = Type.getUnqualifiedType().getCanonicalType(); 15056 const auto *Ty = Type.getTypePtrOrNull(); 15057 if (!Ty || (LinKind != OMPC_LINEAR_ref && !Ty->isDependentType() && 15058 !Ty->isIntegralType(Context) && !Ty->isPointerType())) { 15059 Diag(ELoc, diag::err_omp_linear_expected_int_or_ptr) << Type; 15060 if (D) { 15061 bool IsDecl = 15062 !VD || 15063 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 15064 Diag(D->getLocation(), 15065 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 15066 << D; 15067 } 15068 return true; 15069 } 15070 return false; 15071 } 15072 15073 OMPClause *Sema::ActOnOpenMPLinearClause( 15074 ArrayRef<Expr *> VarList, Expr *Step, SourceLocation StartLoc, 15075 SourceLocation LParenLoc, OpenMPLinearClauseKind LinKind, 15076 SourceLocation LinLoc, SourceLocation ColonLoc, SourceLocation EndLoc) { 15077 SmallVector<Expr *, 8> Vars; 15078 SmallVector<Expr *, 8> Privates; 15079 SmallVector<Expr *, 8> Inits; 15080 SmallVector<Decl *, 4> ExprCaptures; 15081 SmallVector<Expr *, 4> ExprPostUpdates; 15082 if (CheckOpenMPLinearModifier(LinKind, LinLoc)) 15083 LinKind = OMPC_LINEAR_val; 15084 for (Expr *RefExpr : VarList) { 15085 assert(RefExpr && "NULL expr in OpenMP linear clause."); 15086 SourceLocation ELoc; 15087 SourceRange ERange; 15088 Expr *SimpleRefExpr = RefExpr; 15089 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 15090 if (Res.second) { 15091 // It will be analyzed later. 15092 Vars.push_back(RefExpr); 15093 Privates.push_back(nullptr); 15094 Inits.push_back(nullptr); 15095 } 15096 ValueDecl *D = Res.first; 15097 if (!D) 15098 continue; 15099 15100 QualType Type = D->getType(); 15101 auto *VD = dyn_cast<VarDecl>(D); 15102 15103 // OpenMP [2.14.3.7, linear clause] 15104 // A list-item cannot appear in more than one linear clause. 15105 // A list-item that appears in a linear clause cannot appear in any 15106 // other data-sharing attribute clause. 15107 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false); 15108 if (DVar.RefExpr) { 15109 Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind) 15110 << getOpenMPClauseName(OMPC_linear); 15111 reportOriginalDsa(*this, DSAStack, D, DVar); 15112 continue; 15113 } 15114 15115 if (CheckOpenMPLinearDecl(D, ELoc, LinKind, Type)) 15116 continue; 15117 Type = Type.getNonReferenceType().getUnqualifiedType().getCanonicalType(); 15118 15119 // Build private copy of original var. 15120 VarDecl *Private = 15121 buildVarDecl(*this, ELoc, Type, D->getName(), 15122 D->hasAttrs() ? &D->getAttrs() : nullptr, 15123 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr); 15124 DeclRefExpr *PrivateRef = buildDeclRefExpr(*this, Private, Type, ELoc); 15125 // Build var to save initial value. 15126 VarDecl *Init = buildVarDecl(*this, ELoc, Type, ".linear.start"); 15127 Expr *InitExpr; 15128 DeclRefExpr *Ref = nullptr; 15129 if (!VD && !CurContext->isDependentContext()) { 15130 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false); 15131 if (!isOpenMPCapturedDecl(D)) { 15132 ExprCaptures.push_back(Ref->getDecl()); 15133 if (Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>()) { 15134 ExprResult RefRes = DefaultLvalueConversion(Ref); 15135 if (!RefRes.isUsable()) 15136 continue; 15137 ExprResult PostUpdateRes = 15138 BuildBinOp(DSAStack->getCurScope(), ELoc, BO_Assign, 15139 SimpleRefExpr, RefRes.get()); 15140 if (!PostUpdateRes.isUsable()) 15141 continue; 15142 ExprPostUpdates.push_back( 15143 IgnoredValueConversions(PostUpdateRes.get()).get()); 15144 } 15145 } 15146 } 15147 if (LinKind == OMPC_LINEAR_uval) 15148 InitExpr = VD ? VD->getInit() : SimpleRefExpr; 15149 else 15150 InitExpr = VD ? SimpleRefExpr : Ref; 15151 AddInitializerToDecl(Init, DefaultLvalueConversion(InitExpr).get(), 15152 /*DirectInit=*/false); 15153 DeclRefExpr *InitRef = buildDeclRefExpr(*this, Init, Type, ELoc); 15154 15155 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_linear, Ref); 15156 Vars.push_back((VD || CurContext->isDependentContext()) 15157 ? RefExpr->IgnoreParens() 15158 : Ref); 15159 Privates.push_back(PrivateRef); 15160 Inits.push_back(InitRef); 15161 } 15162 15163 if (Vars.empty()) 15164 return nullptr; 15165 15166 Expr *StepExpr = Step; 15167 Expr *CalcStepExpr = nullptr; 15168 if (Step && !Step->isValueDependent() && !Step->isTypeDependent() && 15169 !Step->isInstantiationDependent() && 15170 !Step->containsUnexpandedParameterPack()) { 15171 SourceLocation StepLoc = Step->getBeginLoc(); 15172 ExprResult Val = PerformOpenMPImplicitIntegerConversion(StepLoc, Step); 15173 if (Val.isInvalid()) 15174 return nullptr; 15175 StepExpr = Val.get(); 15176 15177 // Build var to save the step value. 15178 VarDecl *SaveVar = 15179 buildVarDecl(*this, StepLoc, StepExpr->getType(), ".linear.step"); 15180 ExprResult SaveRef = 15181 buildDeclRefExpr(*this, SaveVar, StepExpr->getType(), StepLoc); 15182 ExprResult CalcStep = 15183 BuildBinOp(CurScope, StepLoc, BO_Assign, SaveRef.get(), StepExpr); 15184 CalcStep = ActOnFinishFullExpr(CalcStep.get(), /*DiscardedValue*/ false); 15185 15186 // Warn about zero linear step (it would be probably better specified as 15187 // making corresponding variables 'const'). 15188 llvm::APSInt Result; 15189 bool IsConstant = StepExpr->isIntegerConstantExpr(Result, Context); 15190 if (IsConstant && !Result.isNegative() && !Result.isStrictlyPositive()) 15191 Diag(StepLoc, diag::warn_omp_linear_step_zero) << Vars[0] 15192 << (Vars.size() > 1); 15193 if (!IsConstant && CalcStep.isUsable()) { 15194 // Calculate the step beforehand instead of doing this on each iteration. 15195 // (This is not used if the number of iterations may be kfold-ed). 15196 CalcStepExpr = CalcStep.get(); 15197 } 15198 } 15199 15200 return OMPLinearClause::Create(Context, StartLoc, LParenLoc, LinKind, LinLoc, 15201 ColonLoc, EndLoc, Vars, Privates, Inits, 15202 StepExpr, CalcStepExpr, 15203 buildPreInits(Context, ExprCaptures), 15204 buildPostUpdate(*this, ExprPostUpdates)); 15205 } 15206 15207 static bool FinishOpenMPLinearClause(OMPLinearClause &Clause, DeclRefExpr *IV, 15208 Expr *NumIterations, Sema &SemaRef, 15209 Scope *S, DSAStackTy *Stack) { 15210 // Walk the vars and build update/final expressions for the CodeGen. 15211 SmallVector<Expr *, 8> Updates; 15212 SmallVector<Expr *, 8> Finals; 15213 SmallVector<Expr *, 8> UsedExprs; 15214 Expr *Step = Clause.getStep(); 15215 Expr *CalcStep = Clause.getCalcStep(); 15216 // OpenMP [2.14.3.7, linear clause] 15217 // If linear-step is not specified it is assumed to be 1. 15218 if (!Step) 15219 Step = SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get(); 15220 else if (CalcStep) 15221 Step = cast<BinaryOperator>(CalcStep)->getLHS(); 15222 bool HasErrors = false; 15223 auto CurInit = Clause.inits().begin(); 15224 auto CurPrivate = Clause.privates().begin(); 15225 OpenMPLinearClauseKind LinKind = Clause.getModifier(); 15226 for (Expr *RefExpr : Clause.varlists()) { 15227 SourceLocation ELoc; 15228 SourceRange ERange; 15229 Expr *SimpleRefExpr = RefExpr; 15230 auto Res = getPrivateItem(SemaRef, SimpleRefExpr, ELoc, ERange); 15231 ValueDecl *D = Res.first; 15232 if (Res.second || !D) { 15233 Updates.push_back(nullptr); 15234 Finals.push_back(nullptr); 15235 HasErrors = true; 15236 continue; 15237 } 15238 auto &&Info = Stack->isLoopControlVariable(D); 15239 // OpenMP [2.15.11, distribute simd Construct] 15240 // A list item may not appear in a linear clause, unless it is the loop 15241 // iteration variable. 15242 if (isOpenMPDistributeDirective(Stack->getCurrentDirective()) && 15243 isOpenMPSimdDirective(Stack->getCurrentDirective()) && !Info.first) { 15244 SemaRef.Diag(ELoc, 15245 diag::err_omp_linear_distribute_var_non_loop_iteration); 15246 Updates.push_back(nullptr); 15247 Finals.push_back(nullptr); 15248 HasErrors = true; 15249 continue; 15250 } 15251 Expr *InitExpr = *CurInit; 15252 15253 // Build privatized reference to the current linear var. 15254 auto *DE = cast<DeclRefExpr>(SimpleRefExpr); 15255 Expr *CapturedRef; 15256 if (LinKind == OMPC_LINEAR_uval) 15257 CapturedRef = cast<VarDecl>(DE->getDecl())->getInit(); 15258 else 15259 CapturedRef = 15260 buildDeclRefExpr(SemaRef, cast<VarDecl>(DE->getDecl()), 15261 DE->getType().getUnqualifiedType(), DE->getExprLoc(), 15262 /*RefersToCapture=*/true); 15263 15264 // Build update: Var = InitExpr + IV * Step 15265 ExprResult Update; 15266 if (!Info.first) 15267 Update = buildCounterUpdate( 15268 SemaRef, S, RefExpr->getExprLoc(), *CurPrivate, InitExpr, IV, Step, 15269 /*Subtract=*/false, /*IsNonRectangularLB=*/false); 15270 else 15271 Update = *CurPrivate; 15272 Update = SemaRef.ActOnFinishFullExpr(Update.get(), DE->getBeginLoc(), 15273 /*DiscardedValue*/ false); 15274 15275 // Build final: Var = InitExpr + NumIterations * Step 15276 ExprResult Final; 15277 if (!Info.first) 15278 Final = 15279 buildCounterUpdate(SemaRef, S, RefExpr->getExprLoc(), CapturedRef, 15280 InitExpr, NumIterations, Step, /*Subtract=*/false, 15281 /*IsNonRectangularLB=*/false); 15282 else 15283 Final = *CurPrivate; 15284 Final = SemaRef.ActOnFinishFullExpr(Final.get(), DE->getBeginLoc(), 15285 /*DiscardedValue*/ false); 15286 15287 if (!Update.isUsable() || !Final.isUsable()) { 15288 Updates.push_back(nullptr); 15289 Finals.push_back(nullptr); 15290 UsedExprs.push_back(nullptr); 15291 HasErrors = true; 15292 } else { 15293 Updates.push_back(Update.get()); 15294 Finals.push_back(Final.get()); 15295 if (!Info.first) 15296 UsedExprs.push_back(SimpleRefExpr); 15297 } 15298 ++CurInit; 15299 ++CurPrivate; 15300 } 15301 if (Expr *S = Clause.getStep()) 15302 UsedExprs.push_back(S); 15303 // Fill the remaining part with the nullptr. 15304 UsedExprs.append(Clause.varlist_size() + 1 - UsedExprs.size(), nullptr); 15305 Clause.setUpdates(Updates); 15306 Clause.setFinals(Finals); 15307 Clause.setUsedExprs(UsedExprs); 15308 return HasErrors; 15309 } 15310 15311 OMPClause *Sema::ActOnOpenMPAlignedClause( 15312 ArrayRef<Expr *> VarList, Expr *Alignment, SourceLocation StartLoc, 15313 SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc) { 15314 SmallVector<Expr *, 8> Vars; 15315 for (Expr *RefExpr : VarList) { 15316 assert(RefExpr && "NULL expr in OpenMP linear clause."); 15317 SourceLocation ELoc; 15318 SourceRange ERange; 15319 Expr *SimpleRefExpr = RefExpr; 15320 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 15321 if (Res.second) { 15322 // It will be analyzed later. 15323 Vars.push_back(RefExpr); 15324 } 15325 ValueDecl *D = Res.first; 15326 if (!D) 15327 continue; 15328 15329 QualType QType = D->getType(); 15330 auto *VD = dyn_cast<VarDecl>(D); 15331 15332 // OpenMP [2.8.1, simd construct, Restrictions] 15333 // The type of list items appearing in the aligned clause must be 15334 // array, pointer, reference to array, or reference to pointer. 15335 QType = QType.getNonReferenceType().getUnqualifiedType().getCanonicalType(); 15336 const Type *Ty = QType.getTypePtrOrNull(); 15337 if (!Ty || (!Ty->isArrayType() && !Ty->isPointerType())) { 15338 Diag(ELoc, diag::err_omp_aligned_expected_array_or_ptr) 15339 << QType << getLangOpts().CPlusPlus << ERange; 15340 bool IsDecl = 15341 !VD || 15342 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 15343 Diag(D->getLocation(), 15344 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 15345 << D; 15346 continue; 15347 } 15348 15349 // OpenMP [2.8.1, simd construct, Restrictions] 15350 // A list-item cannot appear in more than one aligned clause. 15351 if (const Expr *PrevRef = DSAStack->addUniqueAligned(D, SimpleRefExpr)) { 15352 Diag(ELoc, diag::err_omp_used_in_clause_twice) 15353 << 0 << getOpenMPClauseName(OMPC_aligned) << ERange; 15354 Diag(PrevRef->getExprLoc(), diag::note_omp_explicit_dsa) 15355 << getOpenMPClauseName(OMPC_aligned); 15356 continue; 15357 } 15358 15359 DeclRefExpr *Ref = nullptr; 15360 if (!VD && isOpenMPCapturedDecl(D)) 15361 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true); 15362 Vars.push_back(DefaultFunctionArrayConversion( 15363 (VD || !Ref) ? RefExpr->IgnoreParens() : Ref) 15364 .get()); 15365 } 15366 15367 // OpenMP [2.8.1, simd construct, Description] 15368 // The parameter of the aligned clause, alignment, must be a constant 15369 // positive integer expression. 15370 // If no optional parameter is specified, implementation-defined default 15371 // alignments for SIMD instructions on the target platforms are assumed. 15372 if (Alignment != nullptr) { 15373 ExprResult AlignResult = 15374 VerifyPositiveIntegerConstantInClause(Alignment, OMPC_aligned); 15375 if (AlignResult.isInvalid()) 15376 return nullptr; 15377 Alignment = AlignResult.get(); 15378 } 15379 if (Vars.empty()) 15380 return nullptr; 15381 15382 return OMPAlignedClause::Create(Context, StartLoc, LParenLoc, ColonLoc, 15383 EndLoc, Vars, Alignment); 15384 } 15385 15386 OMPClause *Sema::ActOnOpenMPCopyinClause(ArrayRef<Expr *> VarList, 15387 SourceLocation StartLoc, 15388 SourceLocation LParenLoc, 15389 SourceLocation EndLoc) { 15390 SmallVector<Expr *, 8> Vars; 15391 SmallVector<Expr *, 8> SrcExprs; 15392 SmallVector<Expr *, 8> DstExprs; 15393 SmallVector<Expr *, 8> AssignmentOps; 15394 for (Expr *RefExpr : VarList) { 15395 assert(RefExpr && "NULL expr in OpenMP copyin clause."); 15396 if (isa<DependentScopeDeclRefExpr>(RefExpr)) { 15397 // It will be analyzed later. 15398 Vars.push_back(RefExpr); 15399 SrcExprs.push_back(nullptr); 15400 DstExprs.push_back(nullptr); 15401 AssignmentOps.push_back(nullptr); 15402 continue; 15403 } 15404 15405 SourceLocation ELoc = RefExpr->getExprLoc(); 15406 // OpenMP [2.1, C/C++] 15407 // A list item is a variable name. 15408 // OpenMP [2.14.4.1, Restrictions, p.1] 15409 // A list item that appears in a copyin clause must be threadprivate. 15410 auto *DE = dyn_cast<DeclRefExpr>(RefExpr); 15411 if (!DE || !isa<VarDecl>(DE->getDecl())) { 15412 Diag(ELoc, diag::err_omp_expected_var_name_member_expr) 15413 << 0 << RefExpr->getSourceRange(); 15414 continue; 15415 } 15416 15417 Decl *D = DE->getDecl(); 15418 auto *VD = cast<VarDecl>(D); 15419 15420 QualType Type = VD->getType(); 15421 if (Type->isDependentType() || Type->isInstantiationDependentType()) { 15422 // It will be analyzed later. 15423 Vars.push_back(DE); 15424 SrcExprs.push_back(nullptr); 15425 DstExprs.push_back(nullptr); 15426 AssignmentOps.push_back(nullptr); 15427 continue; 15428 } 15429 15430 // OpenMP [2.14.4.1, Restrictions, C/C++, p.1] 15431 // A list item that appears in a copyin clause must be threadprivate. 15432 if (!DSAStack->isThreadPrivate(VD)) { 15433 Diag(ELoc, diag::err_omp_required_access) 15434 << getOpenMPClauseName(OMPC_copyin) 15435 << getOpenMPDirectiveName(OMPD_threadprivate); 15436 continue; 15437 } 15438 15439 // OpenMP [2.14.4.1, Restrictions, C/C++, p.2] 15440 // A variable of class type (or array thereof) that appears in a 15441 // copyin clause requires an accessible, unambiguous copy assignment 15442 // operator for the class type. 15443 QualType ElemType = Context.getBaseElementType(Type).getNonReferenceType(); 15444 VarDecl *SrcVD = 15445 buildVarDecl(*this, DE->getBeginLoc(), ElemType.getUnqualifiedType(), 15446 ".copyin.src", VD->hasAttrs() ? &VD->getAttrs() : nullptr); 15447 DeclRefExpr *PseudoSrcExpr = buildDeclRefExpr( 15448 *this, SrcVD, ElemType.getUnqualifiedType(), DE->getExprLoc()); 15449 VarDecl *DstVD = 15450 buildVarDecl(*this, DE->getBeginLoc(), ElemType, ".copyin.dst", 15451 VD->hasAttrs() ? &VD->getAttrs() : nullptr); 15452 DeclRefExpr *PseudoDstExpr = 15453 buildDeclRefExpr(*this, DstVD, ElemType, DE->getExprLoc()); 15454 // For arrays generate assignment operation for single element and replace 15455 // it by the original array element in CodeGen. 15456 ExprResult AssignmentOp = 15457 BuildBinOp(/*S=*/nullptr, DE->getExprLoc(), BO_Assign, PseudoDstExpr, 15458 PseudoSrcExpr); 15459 if (AssignmentOp.isInvalid()) 15460 continue; 15461 AssignmentOp = ActOnFinishFullExpr(AssignmentOp.get(), DE->getExprLoc(), 15462 /*DiscardedValue*/ false); 15463 if (AssignmentOp.isInvalid()) 15464 continue; 15465 15466 DSAStack->addDSA(VD, DE, OMPC_copyin); 15467 Vars.push_back(DE); 15468 SrcExprs.push_back(PseudoSrcExpr); 15469 DstExprs.push_back(PseudoDstExpr); 15470 AssignmentOps.push_back(AssignmentOp.get()); 15471 } 15472 15473 if (Vars.empty()) 15474 return nullptr; 15475 15476 return OMPCopyinClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars, 15477 SrcExprs, DstExprs, AssignmentOps); 15478 } 15479 15480 OMPClause *Sema::ActOnOpenMPCopyprivateClause(ArrayRef<Expr *> VarList, 15481 SourceLocation StartLoc, 15482 SourceLocation LParenLoc, 15483 SourceLocation EndLoc) { 15484 SmallVector<Expr *, 8> Vars; 15485 SmallVector<Expr *, 8> SrcExprs; 15486 SmallVector<Expr *, 8> DstExprs; 15487 SmallVector<Expr *, 8> AssignmentOps; 15488 for (Expr *RefExpr : VarList) { 15489 assert(RefExpr && "NULL expr in OpenMP linear clause."); 15490 SourceLocation ELoc; 15491 SourceRange ERange; 15492 Expr *SimpleRefExpr = RefExpr; 15493 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 15494 if (Res.second) { 15495 // It will be analyzed later. 15496 Vars.push_back(RefExpr); 15497 SrcExprs.push_back(nullptr); 15498 DstExprs.push_back(nullptr); 15499 AssignmentOps.push_back(nullptr); 15500 } 15501 ValueDecl *D = Res.first; 15502 if (!D) 15503 continue; 15504 15505 QualType Type = D->getType(); 15506 auto *VD = dyn_cast<VarDecl>(D); 15507 15508 // OpenMP [2.14.4.2, Restrictions, p.2] 15509 // A list item that appears in a copyprivate clause may not appear in a 15510 // private or firstprivate clause on the single construct. 15511 if (!VD || !DSAStack->isThreadPrivate(VD)) { 15512 DSAStackTy::DSAVarData DVar = 15513 DSAStack->getTopDSA(D, /*FromParent=*/false); 15514 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_copyprivate && 15515 DVar.RefExpr) { 15516 Diag(ELoc, diag::err_omp_wrong_dsa) 15517 << getOpenMPClauseName(DVar.CKind) 15518 << getOpenMPClauseName(OMPC_copyprivate); 15519 reportOriginalDsa(*this, DSAStack, D, DVar); 15520 continue; 15521 } 15522 15523 // OpenMP [2.11.4.2, Restrictions, p.1] 15524 // All list items that appear in a copyprivate clause must be either 15525 // threadprivate or private in the enclosing context. 15526 if (DVar.CKind == OMPC_unknown) { 15527 DVar = DSAStack->getImplicitDSA(D, false); 15528 if (DVar.CKind == OMPC_shared) { 15529 Diag(ELoc, diag::err_omp_required_access) 15530 << getOpenMPClauseName(OMPC_copyprivate) 15531 << "threadprivate or private in the enclosing context"; 15532 reportOriginalDsa(*this, DSAStack, D, DVar); 15533 continue; 15534 } 15535 } 15536 } 15537 15538 // Variably modified types are not supported. 15539 if (!Type->isAnyPointerType() && Type->isVariablyModifiedType()) { 15540 Diag(ELoc, diag::err_omp_variably_modified_type_not_supported) 15541 << getOpenMPClauseName(OMPC_copyprivate) << Type 15542 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 15543 bool IsDecl = 15544 !VD || 15545 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 15546 Diag(D->getLocation(), 15547 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 15548 << D; 15549 continue; 15550 } 15551 15552 // OpenMP [2.14.4.1, Restrictions, C/C++, p.2] 15553 // A variable of class type (or array thereof) that appears in a 15554 // copyin clause requires an accessible, unambiguous copy assignment 15555 // operator for the class type. 15556 Type = Context.getBaseElementType(Type.getNonReferenceType()) 15557 .getUnqualifiedType(); 15558 VarDecl *SrcVD = 15559 buildVarDecl(*this, RefExpr->getBeginLoc(), Type, ".copyprivate.src", 15560 D->hasAttrs() ? &D->getAttrs() : nullptr); 15561 DeclRefExpr *PseudoSrcExpr = buildDeclRefExpr(*this, SrcVD, Type, ELoc); 15562 VarDecl *DstVD = 15563 buildVarDecl(*this, RefExpr->getBeginLoc(), Type, ".copyprivate.dst", 15564 D->hasAttrs() ? &D->getAttrs() : nullptr); 15565 DeclRefExpr *PseudoDstExpr = buildDeclRefExpr(*this, DstVD, Type, ELoc); 15566 ExprResult AssignmentOp = BuildBinOp( 15567 DSAStack->getCurScope(), ELoc, BO_Assign, PseudoDstExpr, PseudoSrcExpr); 15568 if (AssignmentOp.isInvalid()) 15569 continue; 15570 AssignmentOp = 15571 ActOnFinishFullExpr(AssignmentOp.get(), ELoc, /*DiscardedValue*/ false); 15572 if (AssignmentOp.isInvalid()) 15573 continue; 15574 15575 // No need to mark vars as copyprivate, they are already threadprivate or 15576 // implicitly private. 15577 assert(VD || isOpenMPCapturedDecl(D)); 15578 Vars.push_back( 15579 VD ? RefExpr->IgnoreParens() 15580 : buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false)); 15581 SrcExprs.push_back(PseudoSrcExpr); 15582 DstExprs.push_back(PseudoDstExpr); 15583 AssignmentOps.push_back(AssignmentOp.get()); 15584 } 15585 15586 if (Vars.empty()) 15587 return nullptr; 15588 15589 return OMPCopyprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, 15590 Vars, SrcExprs, DstExprs, AssignmentOps); 15591 } 15592 15593 OMPClause *Sema::ActOnOpenMPFlushClause(ArrayRef<Expr *> VarList, 15594 SourceLocation StartLoc, 15595 SourceLocation LParenLoc, 15596 SourceLocation EndLoc) { 15597 if (VarList.empty()) 15598 return nullptr; 15599 15600 return OMPFlushClause::Create(Context, StartLoc, LParenLoc, EndLoc, VarList); 15601 } 15602 15603 /// Tries to find omp_depend_t. type. 15604 static bool findOMPDependT(Sema &S, SourceLocation Loc, DSAStackTy *Stack, 15605 bool Diagnose = true) { 15606 QualType OMPDependT = Stack->getOMPDependT(); 15607 if (!OMPDependT.isNull()) 15608 return true; 15609 IdentifierInfo *II = &S.PP.getIdentifierTable().get("omp_depend_t"); 15610 ParsedType PT = S.getTypeName(*II, Loc, S.getCurScope()); 15611 if (!PT.getAsOpaquePtr() || PT.get().isNull()) { 15612 if (Diagnose) 15613 S.Diag(Loc, diag::err_omp_implied_type_not_found) << "omp_depend_t"; 15614 return false; 15615 } 15616 Stack->setOMPDependT(PT.get()); 15617 return true; 15618 } 15619 15620 OMPClause *Sema::ActOnOpenMPDepobjClause(Expr *Depobj, SourceLocation StartLoc, 15621 SourceLocation LParenLoc, 15622 SourceLocation EndLoc) { 15623 if (!Depobj) 15624 return nullptr; 15625 15626 bool OMPDependTFound = findOMPDependT(*this, StartLoc, DSAStack); 15627 15628 // OpenMP 5.0, 2.17.10.1 depobj Construct 15629 // depobj is an lvalue expression of type omp_depend_t. 15630 if (!Depobj->isTypeDependent() && !Depobj->isValueDependent() && 15631 !Depobj->isInstantiationDependent() && 15632 !Depobj->containsUnexpandedParameterPack() && 15633 (OMPDependTFound && 15634 !Context.typesAreCompatible(DSAStack->getOMPDependT(), Depobj->getType(), 15635 /*CompareUnqualified=*/true))) { 15636 Diag(Depobj->getExprLoc(), diag::err_omp_expected_omp_depend_t_lvalue) 15637 << 0 << Depobj->getType() << Depobj->getSourceRange(); 15638 } 15639 15640 if (!Depobj->isLValue()) { 15641 Diag(Depobj->getExprLoc(), diag::err_omp_expected_omp_depend_t_lvalue) 15642 << 1 << Depobj->getSourceRange(); 15643 } 15644 15645 return OMPDepobjClause::Create(Context, StartLoc, LParenLoc, EndLoc, Depobj); 15646 } 15647 15648 OMPClause * 15649 Sema::ActOnOpenMPDependClause(Expr *DepModifier, OpenMPDependClauseKind DepKind, 15650 SourceLocation DepLoc, SourceLocation ColonLoc, 15651 ArrayRef<Expr *> VarList, SourceLocation StartLoc, 15652 SourceLocation LParenLoc, SourceLocation EndLoc) { 15653 if (DSAStack->getCurrentDirective() == OMPD_ordered && 15654 DepKind != OMPC_DEPEND_source && DepKind != OMPC_DEPEND_sink) { 15655 Diag(DepLoc, diag::err_omp_unexpected_clause_value) 15656 << "'source' or 'sink'" << getOpenMPClauseName(OMPC_depend); 15657 return nullptr; 15658 } 15659 if ((DSAStack->getCurrentDirective() != OMPD_ordered || 15660 DSAStack->getCurrentDirective() == OMPD_depobj) && 15661 (DepKind == OMPC_DEPEND_unknown || DepKind == OMPC_DEPEND_source || 15662 DepKind == OMPC_DEPEND_sink || 15663 ((LangOpts.OpenMP < 50 || 15664 DSAStack->getCurrentDirective() == OMPD_depobj) && 15665 DepKind == OMPC_DEPEND_depobj))) { 15666 SmallVector<unsigned, 3> Except; 15667 Except.push_back(OMPC_DEPEND_source); 15668 Except.push_back(OMPC_DEPEND_sink); 15669 if (LangOpts.OpenMP < 50 || DSAStack->getCurrentDirective() == OMPD_depobj) 15670 Except.push_back(OMPC_DEPEND_depobj); 15671 std::string Expected = (LangOpts.OpenMP >= 50 && !DepModifier) 15672 ? "depend modifier(iterator) or " 15673 : ""; 15674 Diag(DepLoc, diag::err_omp_unexpected_clause_value) 15675 << Expected + getListOfPossibleValues(OMPC_depend, /*First=*/0, 15676 /*Last=*/OMPC_DEPEND_unknown, 15677 Except) 15678 << getOpenMPClauseName(OMPC_depend); 15679 return nullptr; 15680 } 15681 if (DepModifier && 15682 (DepKind == OMPC_DEPEND_source || DepKind == OMPC_DEPEND_sink)) { 15683 Diag(DepModifier->getExprLoc(), 15684 diag::err_omp_depend_sink_source_with_modifier); 15685 return nullptr; 15686 } 15687 if (DepModifier && 15688 !DepModifier->getType()->isSpecificBuiltinType(BuiltinType::OMPIterator)) 15689 Diag(DepModifier->getExprLoc(), diag::err_omp_depend_modifier_not_iterator); 15690 15691 SmallVector<Expr *, 8> Vars; 15692 DSAStackTy::OperatorOffsetTy OpsOffs; 15693 llvm::APSInt DepCounter(/*BitWidth=*/32); 15694 llvm::APSInt TotalDepCount(/*BitWidth=*/32); 15695 if (DepKind == OMPC_DEPEND_sink || DepKind == OMPC_DEPEND_source) { 15696 if (const Expr *OrderedCountExpr = 15697 DSAStack->getParentOrderedRegionParam().first) { 15698 TotalDepCount = OrderedCountExpr->EvaluateKnownConstInt(Context); 15699 TotalDepCount.setIsUnsigned(/*Val=*/true); 15700 } 15701 } 15702 for (Expr *RefExpr : VarList) { 15703 assert(RefExpr && "NULL expr in OpenMP shared clause."); 15704 if (isa<DependentScopeDeclRefExpr>(RefExpr)) { 15705 // It will be analyzed later. 15706 Vars.push_back(RefExpr); 15707 continue; 15708 } 15709 15710 SourceLocation ELoc = RefExpr->getExprLoc(); 15711 Expr *SimpleExpr = RefExpr->IgnoreParenCasts(); 15712 if (DepKind == OMPC_DEPEND_sink) { 15713 if (DSAStack->getParentOrderedRegionParam().first && 15714 DepCounter >= TotalDepCount) { 15715 Diag(ELoc, diag::err_omp_depend_sink_unexpected_expr); 15716 continue; 15717 } 15718 ++DepCounter; 15719 // OpenMP [2.13.9, Summary] 15720 // depend(dependence-type : vec), where dependence-type is: 15721 // 'sink' and where vec is the iteration vector, which has the form: 15722 // x1 [+- d1], x2 [+- d2 ], . . . , xn [+- dn] 15723 // where n is the value specified by the ordered clause in the loop 15724 // directive, xi denotes the loop iteration variable of the i-th nested 15725 // loop associated with the loop directive, and di is a constant 15726 // non-negative integer. 15727 if (CurContext->isDependentContext()) { 15728 // It will be analyzed later. 15729 Vars.push_back(RefExpr); 15730 continue; 15731 } 15732 SimpleExpr = SimpleExpr->IgnoreImplicit(); 15733 OverloadedOperatorKind OOK = OO_None; 15734 SourceLocation OOLoc; 15735 Expr *LHS = SimpleExpr; 15736 Expr *RHS = nullptr; 15737 if (auto *BO = dyn_cast<BinaryOperator>(SimpleExpr)) { 15738 OOK = BinaryOperator::getOverloadedOperator(BO->getOpcode()); 15739 OOLoc = BO->getOperatorLoc(); 15740 LHS = BO->getLHS()->IgnoreParenImpCasts(); 15741 RHS = BO->getRHS()->IgnoreParenImpCasts(); 15742 } else if (auto *OCE = dyn_cast<CXXOperatorCallExpr>(SimpleExpr)) { 15743 OOK = OCE->getOperator(); 15744 OOLoc = OCE->getOperatorLoc(); 15745 LHS = OCE->getArg(/*Arg=*/0)->IgnoreParenImpCasts(); 15746 RHS = OCE->getArg(/*Arg=*/1)->IgnoreParenImpCasts(); 15747 } else if (auto *MCE = dyn_cast<CXXMemberCallExpr>(SimpleExpr)) { 15748 OOK = MCE->getMethodDecl() 15749 ->getNameInfo() 15750 .getName() 15751 .getCXXOverloadedOperator(); 15752 OOLoc = MCE->getCallee()->getExprLoc(); 15753 LHS = MCE->getImplicitObjectArgument()->IgnoreParenImpCasts(); 15754 RHS = MCE->getArg(/*Arg=*/0)->IgnoreParenImpCasts(); 15755 } 15756 SourceLocation ELoc; 15757 SourceRange ERange; 15758 auto Res = getPrivateItem(*this, LHS, ELoc, ERange); 15759 if (Res.second) { 15760 // It will be analyzed later. 15761 Vars.push_back(RefExpr); 15762 } 15763 ValueDecl *D = Res.first; 15764 if (!D) 15765 continue; 15766 15767 if (OOK != OO_Plus && OOK != OO_Minus && (RHS || OOK != OO_None)) { 15768 Diag(OOLoc, diag::err_omp_depend_sink_expected_plus_minus); 15769 continue; 15770 } 15771 if (RHS) { 15772 ExprResult RHSRes = VerifyPositiveIntegerConstantInClause( 15773 RHS, OMPC_depend, /*StrictlyPositive=*/false); 15774 if (RHSRes.isInvalid()) 15775 continue; 15776 } 15777 if (!CurContext->isDependentContext() && 15778 DSAStack->getParentOrderedRegionParam().first && 15779 DepCounter != DSAStack->isParentLoopControlVariable(D).first) { 15780 const ValueDecl *VD = 15781 DSAStack->getParentLoopControlVariable(DepCounter.getZExtValue()); 15782 if (VD) 15783 Diag(ELoc, diag::err_omp_depend_sink_expected_loop_iteration) 15784 << 1 << VD; 15785 else 15786 Diag(ELoc, diag::err_omp_depend_sink_expected_loop_iteration) << 0; 15787 continue; 15788 } 15789 OpsOffs.emplace_back(RHS, OOK); 15790 } else { 15791 bool OMPDependTFound = LangOpts.OpenMP >= 50; 15792 if (OMPDependTFound) 15793 OMPDependTFound = findOMPDependT(*this, StartLoc, DSAStack, 15794 DepKind == OMPC_DEPEND_depobj); 15795 if (DepKind == OMPC_DEPEND_depobj) { 15796 // OpenMP 5.0, 2.17.11 depend Clause, Restrictions, C/C++ 15797 // List items used in depend clauses with the depobj dependence type 15798 // must be expressions of the omp_depend_t type. 15799 if (!RefExpr->isValueDependent() && !RefExpr->isTypeDependent() && 15800 !RefExpr->isInstantiationDependent() && 15801 !RefExpr->containsUnexpandedParameterPack() && 15802 (OMPDependTFound && 15803 !Context.hasSameUnqualifiedType(DSAStack->getOMPDependT(), 15804 RefExpr->getType()))) { 15805 Diag(ELoc, diag::err_omp_expected_omp_depend_t_lvalue) 15806 << 0 << RefExpr->getType() << RefExpr->getSourceRange(); 15807 continue; 15808 } 15809 if (!RefExpr->isLValue()) { 15810 Diag(ELoc, diag::err_omp_expected_omp_depend_t_lvalue) 15811 << 1 << RefExpr->getType() << RefExpr->getSourceRange(); 15812 continue; 15813 } 15814 } else { 15815 // OpenMP 5.0 [2.17.11, Restrictions] 15816 // List items used in depend clauses cannot be zero-length array 15817 // sections. 15818 QualType ExprTy = RefExpr->getType().getNonReferenceType(); 15819 const auto *OASE = dyn_cast<OMPArraySectionExpr>(SimpleExpr); 15820 if (OASE) { 15821 QualType BaseType = 15822 OMPArraySectionExpr::getBaseOriginalType(OASE->getBase()); 15823 if (const auto *ATy = BaseType->getAsArrayTypeUnsafe()) 15824 ExprTy = ATy->getElementType(); 15825 else 15826 ExprTy = BaseType->getPointeeType(); 15827 ExprTy = ExprTy.getNonReferenceType(); 15828 const Expr *Length = OASE->getLength(); 15829 Expr::EvalResult Result; 15830 if (Length && !Length->isValueDependent() && 15831 Length->EvaluateAsInt(Result, Context) && 15832 Result.Val.getInt().isNullValue()) { 15833 Diag(ELoc, 15834 diag::err_omp_depend_zero_length_array_section_not_allowed) 15835 << SimpleExpr->getSourceRange(); 15836 continue; 15837 } 15838 } 15839 15840 // OpenMP 5.0, 2.17.11 depend Clause, Restrictions, C/C++ 15841 // List items used in depend clauses with the in, out, inout or 15842 // mutexinoutset dependence types cannot be expressions of the 15843 // omp_depend_t type. 15844 if (!RefExpr->isValueDependent() && !RefExpr->isTypeDependent() && 15845 !RefExpr->isInstantiationDependent() && 15846 !RefExpr->containsUnexpandedParameterPack() && 15847 (OMPDependTFound && 15848 DSAStack->getOMPDependT().getTypePtr() == ExprTy.getTypePtr())) { 15849 Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item) 15850 << (LangOpts.OpenMP >= 50 ? 1 : 0) << 1 15851 << RefExpr->getSourceRange(); 15852 continue; 15853 } 15854 15855 auto *ASE = dyn_cast<ArraySubscriptExpr>(SimpleExpr); 15856 if (!RefExpr->IgnoreParenImpCasts()->isLValue() || 15857 (ASE && 15858 !ASE->getBase() 15859 ->getType() 15860 .getNonReferenceType() 15861 ->isPointerType() && 15862 !ASE->getBase()->getType().getNonReferenceType()->isArrayType())) { 15863 Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item) 15864 << (LangOpts.OpenMP >= 50 ? 1 : 0) 15865 << (LangOpts.OpenMP >= 50 ? 1 : 0) << RefExpr->getSourceRange(); 15866 continue; 15867 } 15868 15869 ExprResult Res; 15870 { 15871 Sema::TentativeAnalysisScope Trap(*this); 15872 Res = CreateBuiltinUnaryOp(ELoc, UO_AddrOf, 15873 RefExpr->IgnoreParenImpCasts()); 15874 } 15875 if (!Res.isUsable() && !isa<OMPArraySectionExpr>(SimpleExpr) && 15876 !isa<OMPArrayShapingExpr>(SimpleExpr)) { 15877 Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item) 15878 << (LangOpts.OpenMP >= 50 ? 1 : 0) 15879 << (LangOpts.OpenMP >= 50 ? 1 : 0) << RefExpr->getSourceRange(); 15880 continue; 15881 } 15882 } 15883 } 15884 Vars.push_back(RefExpr->IgnoreParenImpCasts()); 15885 } 15886 15887 if (!CurContext->isDependentContext() && DepKind == OMPC_DEPEND_sink && 15888 TotalDepCount > VarList.size() && 15889 DSAStack->getParentOrderedRegionParam().first && 15890 DSAStack->getParentLoopControlVariable(VarList.size() + 1)) { 15891 Diag(EndLoc, diag::err_omp_depend_sink_expected_loop_iteration) 15892 << 1 << DSAStack->getParentLoopControlVariable(VarList.size() + 1); 15893 } 15894 if (DepKind != OMPC_DEPEND_source && DepKind != OMPC_DEPEND_sink && 15895 Vars.empty()) 15896 return nullptr; 15897 15898 auto *C = OMPDependClause::Create(Context, StartLoc, LParenLoc, EndLoc, 15899 DepModifier, DepKind, DepLoc, ColonLoc, 15900 Vars, TotalDepCount.getZExtValue()); 15901 if ((DepKind == OMPC_DEPEND_sink || DepKind == OMPC_DEPEND_source) && 15902 DSAStack->isParentOrderedRegion()) 15903 DSAStack->addDoacrossDependClause(C, OpsOffs); 15904 return C; 15905 } 15906 15907 OMPClause *Sema::ActOnOpenMPDeviceClause(OpenMPDeviceClauseModifier Modifier, 15908 Expr *Device, SourceLocation StartLoc, 15909 SourceLocation LParenLoc, 15910 SourceLocation ModifierLoc, 15911 SourceLocation EndLoc) { 15912 assert((ModifierLoc.isInvalid() || LangOpts.OpenMP >= 50) && 15913 "Unexpected device modifier in OpenMP < 50."); 15914 15915 bool ErrorFound = false; 15916 if (ModifierLoc.isValid() && Modifier == OMPC_DEVICE_unknown) { 15917 std::string Values = 15918 getListOfPossibleValues(OMPC_device, /*First=*/0, OMPC_DEVICE_unknown); 15919 Diag(ModifierLoc, diag::err_omp_unexpected_clause_value) 15920 << Values << getOpenMPClauseName(OMPC_device); 15921 ErrorFound = true; 15922 } 15923 15924 Expr *ValExpr = Device; 15925 Stmt *HelperValStmt = nullptr; 15926 15927 // OpenMP [2.9.1, Restrictions] 15928 // The device expression must evaluate to a non-negative integer value. 15929 ErrorFound = !isNonNegativeIntegerValue(ValExpr, *this, OMPC_device, 15930 /*StrictlyPositive=*/false) || 15931 ErrorFound; 15932 if (ErrorFound) 15933 return nullptr; 15934 15935 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 15936 OpenMPDirectiveKind CaptureRegion = 15937 getOpenMPCaptureRegionForClause(DKind, OMPC_device, LangOpts.OpenMP); 15938 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 15939 ValExpr = MakeFullExpr(ValExpr).get(); 15940 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 15941 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 15942 HelperValStmt = buildPreInits(Context, Captures); 15943 } 15944 15945 return new (Context) 15946 OMPDeviceClause(Modifier, ValExpr, HelperValStmt, CaptureRegion, StartLoc, 15947 LParenLoc, ModifierLoc, EndLoc); 15948 } 15949 15950 static bool checkTypeMappable(SourceLocation SL, SourceRange SR, Sema &SemaRef, 15951 DSAStackTy *Stack, QualType QTy, 15952 bool FullCheck = true) { 15953 NamedDecl *ND; 15954 if (QTy->isIncompleteType(&ND)) { 15955 SemaRef.Diag(SL, diag::err_incomplete_type) << QTy << SR; 15956 return false; 15957 } 15958 if (FullCheck && !SemaRef.CurContext->isDependentContext() && 15959 !QTy.isTriviallyCopyableType(SemaRef.Context)) 15960 SemaRef.Diag(SL, diag::warn_omp_non_trivial_type_mapped) << QTy << SR; 15961 return true; 15962 } 15963 15964 /// Return true if it can be proven that the provided array expression 15965 /// (array section or array subscript) does NOT specify the whole size of the 15966 /// array whose base type is \a BaseQTy. 15967 static bool checkArrayExpressionDoesNotReferToWholeSize(Sema &SemaRef, 15968 const Expr *E, 15969 QualType BaseQTy) { 15970 const auto *OASE = dyn_cast<OMPArraySectionExpr>(E); 15971 15972 // If this is an array subscript, it refers to the whole size if the size of 15973 // the dimension is constant and equals 1. Also, an array section assumes the 15974 // format of an array subscript if no colon is used. 15975 if (isa<ArraySubscriptExpr>(E) || (OASE && OASE->getColonLoc().isInvalid())) { 15976 if (const auto *ATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr())) 15977 return ATy->getSize().getSExtValue() != 1; 15978 // Size can't be evaluated statically. 15979 return false; 15980 } 15981 15982 assert(OASE && "Expecting array section if not an array subscript."); 15983 const Expr *LowerBound = OASE->getLowerBound(); 15984 const Expr *Length = OASE->getLength(); 15985 15986 // If there is a lower bound that does not evaluates to zero, we are not 15987 // covering the whole dimension. 15988 if (LowerBound) { 15989 Expr::EvalResult Result; 15990 if (!LowerBound->EvaluateAsInt(Result, SemaRef.getASTContext())) 15991 return false; // Can't get the integer value as a constant. 15992 15993 llvm::APSInt ConstLowerBound = Result.Val.getInt(); 15994 if (ConstLowerBound.getSExtValue()) 15995 return true; 15996 } 15997 15998 // If we don't have a length we covering the whole dimension. 15999 if (!Length) 16000 return false; 16001 16002 // If the base is a pointer, we don't have a way to get the size of the 16003 // pointee. 16004 if (BaseQTy->isPointerType()) 16005 return false; 16006 16007 // We can only check if the length is the same as the size of the dimension 16008 // if we have a constant array. 16009 const auto *CATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr()); 16010 if (!CATy) 16011 return false; 16012 16013 Expr::EvalResult Result; 16014 if (!Length->EvaluateAsInt(Result, SemaRef.getASTContext())) 16015 return false; // Can't get the integer value as a constant. 16016 16017 llvm::APSInt ConstLength = Result.Val.getInt(); 16018 return CATy->getSize().getSExtValue() != ConstLength.getSExtValue(); 16019 } 16020 16021 // Return true if it can be proven that the provided array expression (array 16022 // section or array subscript) does NOT specify a single element of the array 16023 // whose base type is \a BaseQTy. 16024 static bool checkArrayExpressionDoesNotReferToUnitySize(Sema &SemaRef, 16025 const Expr *E, 16026 QualType BaseQTy) { 16027 const auto *OASE = dyn_cast<OMPArraySectionExpr>(E); 16028 16029 // An array subscript always refer to a single element. Also, an array section 16030 // assumes the format of an array subscript if no colon is used. 16031 if (isa<ArraySubscriptExpr>(E) || (OASE && OASE->getColonLoc().isInvalid())) 16032 return false; 16033 16034 assert(OASE && "Expecting array section if not an array subscript."); 16035 const Expr *Length = OASE->getLength(); 16036 16037 // If we don't have a length we have to check if the array has unitary size 16038 // for this dimension. Also, we should always expect a length if the base type 16039 // is pointer. 16040 if (!Length) { 16041 if (const auto *ATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr())) 16042 return ATy->getSize().getSExtValue() != 1; 16043 // We cannot assume anything. 16044 return false; 16045 } 16046 16047 // Check if the length evaluates to 1. 16048 Expr::EvalResult Result; 16049 if (!Length->EvaluateAsInt(Result, SemaRef.getASTContext())) 16050 return false; // Can't get the integer value as a constant. 16051 16052 llvm::APSInt ConstLength = Result.Val.getInt(); 16053 return ConstLength.getSExtValue() != 1; 16054 } 16055 16056 // The base of elements of list in a map clause have to be either: 16057 // - a reference to variable or field. 16058 // - a member expression. 16059 // - an array expression. 16060 // 16061 // E.g. if we have the expression 'r.S.Arr[:12]', we want to retrieve the 16062 // reference to 'r'. 16063 // 16064 // If we have: 16065 // 16066 // struct SS { 16067 // Bla S; 16068 // foo() { 16069 // #pragma omp target map (S.Arr[:12]); 16070 // } 16071 // } 16072 // 16073 // We want to retrieve the member expression 'this->S'; 16074 16075 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.2] 16076 // If a list item is an array section, it must specify contiguous storage. 16077 // 16078 // For this restriction it is sufficient that we make sure only references 16079 // to variables or fields and array expressions, and that no array sections 16080 // exist except in the rightmost expression (unless they cover the whole 16081 // dimension of the array). E.g. these would be invalid: 16082 // 16083 // r.ArrS[3:5].Arr[6:7] 16084 // 16085 // r.ArrS[3:5].x 16086 // 16087 // but these would be valid: 16088 // r.ArrS[3].Arr[6:7] 16089 // 16090 // r.ArrS[3].x 16091 namespace { 16092 class MapBaseChecker final : public StmtVisitor<MapBaseChecker, bool> { 16093 Sema &SemaRef; 16094 OpenMPClauseKind CKind = OMPC_unknown; 16095 OMPClauseMappableExprCommon::MappableExprComponentList &Components; 16096 bool NoDiagnose = false; 16097 const Expr *RelevantExpr = nullptr; 16098 bool AllowUnitySizeArraySection = true; 16099 bool AllowWholeSizeArraySection = true; 16100 SourceLocation ELoc; 16101 SourceRange ERange; 16102 16103 void emitErrorMsg() { 16104 // If nothing else worked, this is not a valid map clause expression. 16105 if (SemaRef.getLangOpts().OpenMP < 50) { 16106 SemaRef.Diag(ELoc, 16107 diag::err_omp_expected_named_var_member_or_array_expression) 16108 << ERange; 16109 } else { 16110 SemaRef.Diag(ELoc, diag::err_omp_non_lvalue_in_map_or_motion_clauses) 16111 << getOpenMPClauseName(CKind) << ERange; 16112 } 16113 } 16114 16115 public: 16116 bool VisitDeclRefExpr(DeclRefExpr *DRE) { 16117 if (!isa<VarDecl>(DRE->getDecl())) { 16118 emitErrorMsg(); 16119 return false; 16120 } 16121 assert(!RelevantExpr && "RelevantExpr is expected to be nullptr"); 16122 RelevantExpr = DRE; 16123 // Record the component. 16124 Components.emplace_back(DRE, DRE->getDecl()); 16125 return true; 16126 } 16127 16128 bool VisitMemberExpr(MemberExpr *ME) { 16129 Expr *E = ME; 16130 Expr *BaseE = ME->getBase()->IgnoreParenCasts(); 16131 16132 if (isa<CXXThisExpr>(BaseE)) { 16133 assert(!RelevantExpr && "RelevantExpr is expected to be nullptr"); 16134 // We found a base expression: this->Val. 16135 RelevantExpr = ME; 16136 } else { 16137 E = BaseE; 16138 } 16139 16140 if (!isa<FieldDecl>(ME->getMemberDecl())) { 16141 if (!NoDiagnose) { 16142 SemaRef.Diag(ELoc, diag::err_omp_expected_access_to_data_field) 16143 << ME->getSourceRange(); 16144 return false; 16145 } 16146 if (RelevantExpr) 16147 return false; 16148 return Visit(E); 16149 } 16150 16151 auto *FD = cast<FieldDecl>(ME->getMemberDecl()); 16152 16153 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.3] 16154 // A bit-field cannot appear in a map clause. 16155 // 16156 if (FD->isBitField()) { 16157 if (!NoDiagnose) { 16158 SemaRef.Diag(ELoc, diag::err_omp_bit_fields_forbidden_in_clause) 16159 << ME->getSourceRange() << getOpenMPClauseName(CKind); 16160 return false; 16161 } 16162 if (RelevantExpr) 16163 return false; 16164 return Visit(E); 16165 } 16166 16167 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1] 16168 // If the type of a list item is a reference to a type T then the type 16169 // will be considered to be T for all purposes of this clause. 16170 QualType CurType = BaseE->getType().getNonReferenceType(); 16171 16172 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.2] 16173 // A list item cannot be a variable that is a member of a structure with 16174 // a union type. 16175 // 16176 if (CurType->isUnionType()) { 16177 if (!NoDiagnose) { 16178 SemaRef.Diag(ELoc, diag::err_omp_union_type_not_allowed) 16179 << ME->getSourceRange(); 16180 return false; 16181 } 16182 return RelevantExpr || Visit(E); 16183 } 16184 16185 // If we got a member expression, we should not expect any array section 16186 // before that: 16187 // 16188 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.7] 16189 // If a list item is an element of a structure, only the rightmost symbol 16190 // of the variable reference can be an array section. 16191 // 16192 AllowUnitySizeArraySection = false; 16193 AllowWholeSizeArraySection = false; 16194 16195 // Record the component. 16196 Components.emplace_back(ME, FD); 16197 return RelevantExpr || Visit(E); 16198 } 16199 16200 bool VisitArraySubscriptExpr(ArraySubscriptExpr *AE) { 16201 Expr *E = AE->getBase()->IgnoreParenImpCasts(); 16202 16203 if (!E->getType()->isAnyPointerType() && !E->getType()->isArrayType()) { 16204 if (!NoDiagnose) { 16205 SemaRef.Diag(ELoc, diag::err_omp_expected_base_var_name) 16206 << 0 << AE->getSourceRange(); 16207 return false; 16208 } 16209 return RelevantExpr || Visit(E); 16210 } 16211 16212 // If we got an array subscript that express the whole dimension we 16213 // can have any array expressions before. If it only expressing part of 16214 // the dimension, we can only have unitary-size array expressions. 16215 if (checkArrayExpressionDoesNotReferToWholeSize(SemaRef, AE, 16216 E->getType())) 16217 AllowWholeSizeArraySection = false; 16218 16219 if (const auto *TE = dyn_cast<CXXThisExpr>(E->IgnoreParenCasts())) { 16220 Expr::EvalResult Result; 16221 if (!AE->getIdx()->isValueDependent() && 16222 AE->getIdx()->EvaluateAsInt(Result, SemaRef.getASTContext()) && 16223 !Result.Val.getInt().isNullValue()) { 16224 SemaRef.Diag(AE->getIdx()->getExprLoc(), 16225 diag::err_omp_invalid_map_this_expr); 16226 SemaRef.Diag(AE->getIdx()->getExprLoc(), 16227 diag::note_omp_invalid_subscript_on_this_ptr_map); 16228 } 16229 assert(!RelevantExpr && "RelevantExpr is expected to be nullptr"); 16230 RelevantExpr = TE; 16231 } 16232 16233 // Record the component - we don't have any declaration associated. 16234 Components.emplace_back(AE, nullptr); 16235 16236 return RelevantExpr || Visit(E); 16237 } 16238 16239 bool VisitOMPArraySectionExpr(OMPArraySectionExpr *OASE) { 16240 assert(!NoDiagnose && "Array sections cannot be implicitly mapped."); 16241 Expr *E = OASE->getBase()->IgnoreParenImpCasts(); 16242 QualType CurType = 16243 OMPArraySectionExpr::getBaseOriginalType(E).getCanonicalType(); 16244 16245 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1] 16246 // If the type of a list item is a reference to a type T then the type 16247 // will be considered to be T for all purposes of this clause. 16248 if (CurType->isReferenceType()) 16249 CurType = CurType->getPointeeType(); 16250 16251 bool IsPointer = CurType->isAnyPointerType(); 16252 16253 if (!IsPointer && !CurType->isArrayType()) { 16254 SemaRef.Diag(ELoc, diag::err_omp_expected_base_var_name) 16255 << 0 << OASE->getSourceRange(); 16256 return false; 16257 } 16258 16259 bool NotWhole = 16260 checkArrayExpressionDoesNotReferToWholeSize(SemaRef, OASE, CurType); 16261 bool NotUnity = 16262 checkArrayExpressionDoesNotReferToUnitySize(SemaRef, OASE, CurType); 16263 16264 if (AllowWholeSizeArraySection) { 16265 // Any array section is currently allowed. Allowing a whole size array 16266 // section implies allowing a unity array section as well. 16267 // 16268 // If this array section refers to the whole dimension we can still 16269 // accept other array sections before this one, except if the base is a 16270 // pointer. Otherwise, only unitary sections are accepted. 16271 if (NotWhole || IsPointer) 16272 AllowWholeSizeArraySection = false; 16273 } else if (AllowUnitySizeArraySection && NotUnity) { 16274 // A unity or whole array section is not allowed and that is not 16275 // compatible with the properties of the current array section. 16276 SemaRef.Diag( 16277 ELoc, diag::err_array_section_does_not_specify_contiguous_storage) 16278 << OASE->getSourceRange(); 16279 return false; 16280 } 16281 16282 if (const auto *TE = dyn_cast<CXXThisExpr>(E)) { 16283 Expr::EvalResult ResultR; 16284 Expr::EvalResult ResultL; 16285 if (!OASE->getLength()->isValueDependent() && 16286 OASE->getLength()->EvaluateAsInt(ResultR, SemaRef.getASTContext()) && 16287 !ResultR.Val.getInt().isOneValue()) { 16288 SemaRef.Diag(OASE->getLength()->getExprLoc(), 16289 diag::err_omp_invalid_map_this_expr); 16290 SemaRef.Diag(OASE->getLength()->getExprLoc(), 16291 diag::note_omp_invalid_length_on_this_ptr_mapping); 16292 } 16293 if (OASE->getLowerBound() && !OASE->getLowerBound()->isValueDependent() && 16294 OASE->getLowerBound()->EvaluateAsInt(ResultL, 16295 SemaRef.getASTContext()) && 16296 !ResultL.Val.getInt().isNullValue()) { 16297 SemaRef.Diag(OASE->getLowerBound()->getExprLoc(), 16298 diag::err_omp_invalid_map_this_expr); 16299 SemaRef.Diag(OASE->getLowerBound()->getExprLoc(), 16300 diag::note_omp_invalid_lower_bound_on_this_ptr_mapping); 16301 } 16302 assert(!RelevantExpr && "RelevantExpr is expected to be nullptr"); 16303 RelevantExpr = TE; 16304 } 16305 16306 // Record the component - we don't have any declaration associated. 16307 Components.emplace_back(OASE, nullptr); 16308 return RelevantExpr || Visit(E); 16309 } 16310 bool VisitOMPArrayShapingExpr(OMPArrayShapingExpr *E) { 16311 Expr *Base = E->getBase(); 16312 16313 // Record the component - we don't have any declaration associated. 16314 Components.emplace_back(E, nullptr); 16315 16316 return Visit(Base->IgnoreParenImpCasts()); 16317 } 16318 16319 bool VisitUnaryOperator(UnaryOperator *UO) { 16320 if (SemaRef.getLangOpts().OpenMP < 50 || !UO->isLValue() || 16321 UO->getOpcode() != UO_Deref) { 16322 emitErrorMsg(); 16323 return false; 16324 } 16325 if (!RelevantExpr) { 16326 // Record the component if haven't found base decl. 16327 Components.emplace_back(UO, nullptr); 16328 } 16329 return RelevantExpr || Visit(UO->getSubExpr()->IgnoreParenImpCasts()); 16330 } 16331 bool VisitBinaryOperator(BinaryOperator *BO) { 16332 if (SemaRef.getLangOpts().OpenMP < 50 || !BO->getType()->isPointerType()) { 16333 emitErrorMsg(); 16334 return false; 16335 } 16336 16337 // Pointer arithmetic is the only thing we expect to happen here so after we 16338 // make sure the binary operator is a pointer type, the we only thing need 16339 // to to is to visit the subtree that has the same type as root (so that we 16340 // know the other subtree is just an offset) 16341 Expr *LE = BO->getLHS()->IgnoreParenImpCasts(); 16342 Expr *RE = BO->getRHS()->IgnoreParenImpCasts(); 16343 Components.emplace_back(BO, nullptr); 16344 assert((LE->getType().getTypePtr() == BO->getType().getTypePtr() || 16345 RE->getType().getTypePtr() == BO->getType().getTypePtr()) && 16346 "Either LHS or RHS have base decl inside"); 16347 if (BO->getType().getTypePtr() == LE->getType().getTypePtr()) 16348 return RelevantExpr || Visit(LE); 16349 return RelevantExpr || Visit(RE); 16350 } 16351 bool VisitCXXThisExpr(CXXThisExpr *CTE) { 16352 assert(!RelevantExpr && "RelevantExpr is expected to be nullptr"); 16353 RelevantExpr = CTE; 16354 Components.emplace_back(CTE, nullptr); 16355 return true; 16356 } 16357 bool VisitStmt(Stmt *) { 16358 emitErrorMsg(); 16359 return false; 16360 } 16361 const Expr *getFoundBase() const { 16362 return RelevantExpr; 16363 } 16364 explicit MapBaseChecker( 16365 Sema &SemaRef, OpenMPClauseKind CKind, 16366 OMPClauseMappableExprCommon::MappableExprComponentList &Components, 16367 bool NoDiagnose, SourceLocation &ELoc, SourceRange &ERange) 16368 : SemaRef(SemaRef), CKind(CKind), Components(Components), 16369 NoDiagnose(NoDiagnose), ELoc(ELoc), ERange(ERange) {} 16370 }; 16371 } // namespace 16372 16373 /// Return the expression of the base of the mappable expression or null if it 16374 /// cannot be determined and do all the necessary checks to see if the expression 16375 /// is valid as a standalone mappable expression. In the process, record all the 16376 /// components of the expression. 16377 static const Expr *checkMapClauseExpressionBase( 16378 Sema &SemaRef, Expr *E, 16379 OMPClauseMappableExprCommon::MappableExprComponentList &CurComponents, 16380 OpenMPClauseKind CKind, bool NoDiagnose) { 16381 SourceLocation ELoc = E->getExprLoc(); 16382 SourceRange ERange = E->getSourceRange(); 16383 MapBaseChecker Checker(SemaRef, CKind, CurComponents, NoDiagnose, ELoc, 16384 ERange); 16385 if (Checker.Visit(E->IgnoreParens())) 16386 return Checker.getFoundBase(); 16387 return nullptr; 16388 } 16389 16390 // Return true if expression E associated with value VD has conflicts with other 16391 // map information. 16392 static bool checkMapConflicts( 16393 Sema &SemaRef, DSAStackTy *DSAS, const ValueDecl *VD, const Expr *E, 16394 bool CurrentRegionOnly, 16395 OMPClauseMappableExprCommon::MappableExprComponentListRef CurComponents, 16396 OpenMPClauseKind CKind) { 16397 assert(VD && E); 16398 SourceLocation ELoc = E->getExprLoc(); 16399 SourceRange ERange = E->getSourceRange(); 16400 16401 // In order to easily check the conflicts we need to match each component of 16402 // the expression under test with the components of the expressions that are 16403 // already in the stack. 16404 16405 assert(!CurComponents.empty() && "Map clause expression with no components!"); 16406 assert(CurComponents.back().getAssociatedDeclaration() == VD && 16407 "Map clause expression with unexpected base!"); 16408 16409 // Variables to help detecting enclosing problems in data environment nests. 16410 bool IsEnclosedByDataEnvironmentExpr = false; 16411 const Expr *EnclosingExpr = nullptr; 16412 16413 bool FoundError = DSAS->checkMappableExprComponentListsForDecl( 16414 VD, CurrentRegionOnly, 16415 [&IsEnclosedByDataEnvironmentExpr, &SemaRef, VD, CurrentRegionOnly, ELoc, 16416 ERange, CKind, &EnclosingExpr, 16417 CurComponents](OMPClauseMappableExprCommon::MappableExprComponentListRef 16418 StackComponents, 16419 OpenMPClauseKind) { 16420 assert(!StackComponents.empty() && 16421 "Map clause expression with no components!"); 16422 assert(StackComponents.back().getAssociatedDeclaration() == VD && 16423 "Map clause expression with unexpected base!"); 16424 (void)VD; 16425 16426 // The whole expression in the stack. 16427 const Expr *RE = StackComponents.front().getAssociatedExpression(); 16428 16429 // Expressions must start from the same base. Here we detect at which 16430 // point both expressions diverge from each other and see if we can 16431 // detect if the memory referred to both expressions is contiguous and 16432 // do not overlap. 16433 auto CI = CurComponents.rbegin(); 16434 auto CE = CurComponents.rend(); 16435 auto SI = StackComponents.rbegin(); 16436 auto SE = StackComponents.rend(); 16437 for (; CI != CE && SI != SE; ++CI, ++SI) { 16438 16439 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.3] 16440 // At most one list item can be an array item derived from a given 16441 // variable in map clauses of the same construct. 16442 if (CurrentRegionOnly && 16443 (isa<ArraySubscriptExpr>(CI->getAssociatedExpression()) || 16444 isa<OMPArraySectionExpr>(CI->getAssociatedExpression()) || 16445 isa<OMPArrayShapingExpr>(CI->getAssociatedExpression())) && 16446 (isa<ArraySubscriptExpr>(SI->getAssociatedExpression()) || 16447 isa<OMPArraySectionExpr>(SI->getAssociatedExpression()) || 16448 isa<OMPArrayShapingExpr>(SI->getAssociatedExpression()))) { 16449 SemaRef.Diag(CI->getAssociatedExpression()->getExprLoc(), 16450 diag::err_omp_multiple_array_items_in_map_clause) 16451 << CI->getAssociatedExpression()->getSourceRange(); 16452 SemaRef.Diag(SI->getAssociatedExpression()->getExprLoc(), 16453 diag::note_used_here) 16454 << SI->getAssociatedExpression()->getSourceRange(); 16455 return true; 16456 } 16457 16458 // Do both expressions have the same kind? 16459 if (CI->getAssociatedExpression()->getStmtClass() != 16460 SI->getAssociatedExpression()->getStmtClass()) 16461 break; 16462 16463 // Are we dealing with different variables/fields? 16464 if (CI->getAssociatedDeclaration() != SI->getAssociatedDeclaration()) 16465 break; 16466 } 16467 // Check if the extra components of the expressions in the enclosing 16468 // data environment are redundant for the current base declaration. 16469 // If they are, the maps completely overlap, which is legal. 16470 for (; SI != SE; ++SI) { 16471 QualType Type; 16472 if (const auto *ASE = 16473 dyn_cast<ArraySubscriptExpr>(SI->getAssociatedExpression())) { 16474 Type = ASE->getBase()->IgnoreParenImpCasts()->getType(); 16475 } else if (const auto *OASE = dyn_cast<OMPArraySectionExpr>( 16476 SI->getAssociatedExpression())) { 16477 const Expr *E = OASE->getBase()->IgnoreParenImpCasts(); 16478 Type = 16479 OMPArraySectionExpr::getBaseOriginalType(E).getCanonicalType(); 16480 } else if (const auto *OASE = dyn_cast<OMPArrayShapingExpr>( 16481 SI->getAssociatedExpression())) { 16482 Type = OASE->getBase()->getType()->getPointeeType(); 16483 } 16484 if (Type.isNull() || Type->isAnyPointerType() || 16485 checkArrayExpressionDoesNotReferToWholeSize( 16486 SemaRef, SI->getAssociatedExpression(), Type)) 16487 break; 16488 } 16489 16490 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.4] 16491 // List items of map clauses in the same construct must not share 16492 // original storage. 16493 // 16494 // If the expressions are exactly the same or one is a subset of the 16495 // other, it means they are sharing storage. 16496 if (CI == CE && SI == SE) { 16497 if (CurrentRegionOnly) { 16498 if (CKind == OMPC_map) { 16499 SemaRef.Diag(ELoc, diag::err_omp_map_shared_storage) << ERange; 16500 } else { 16501 assert(CKind == OMPC_to || CKind == OMPC_from); 16502 SemaRef.Diag(ELoc, diag::err_omp_once_referenced_in_target_update) 16503 << ERange; 16504 } 16505 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here) 16506 << RE->getSourceRange(); 16507 return true; 16508 } 16509 // If we find the same expression in the enclosing data environment, 16510 // that is legal. 16511 IsEnclosedByDataEnvironmentExpr = true; 16512 return false; 16513 } 16514 16515 QualType DerivedType = 16516 std::prev(CI)->getAssociatedDeclaration()->getType(); 16517 SourceLocation DerivedLoc = 16518 std::prev(CI)->getAssociatedExpression()->getExprLoc(); 16519 16520 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1] 16521 // If the type of a list item is a reference to a type T then the type 16522 // will be considered to be T for all purposes of this clause. 16523 DerivedType = DerivedType.getNonReferenceType(); 16524 16525 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.1] 16526 // A variable for which the type is pointer and an array section 16527 // derived from that variable must not appear as list items of map 16528 // clauses of the same construct. 16529 // 16530 // Also, cover one of the cases in: 16531 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.5] 16532 // If any part of the original storage of a list item has corresponding 16533 // storage in the device data environment, all of the original storage 16534 // must have corresponding storage in the device data environment. 16535 // 16536 if (DerivedType->isAnyPointerType()) { 16537 if (CI == CE || SI == SE) { 16538 SemaRef.Diag( 16539 DerivedLoc, 16540 diag::err_omp_pointer_mapped_along_with_derived_section) 16541 << DerivedLoc; 16542 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here) 16543 << RE->getSourceRange(); 16544 return true; 16545 } 16546 if (CI->getAssociatedExpression()->getStmtClass() != 16547 SI->getAssociatedExpression()->getStmtClass() || 16548 CI->getAssociatedDeclaration()->getCanonicalDecl() == 16549 SI->getAssociatedDeclaration()->getCanonicalDecl()) { 16550 assert(CI != CE && SI != SE); 16551 SemaRef.Diag(DerivedLoc, diag::err_omp_same_pointer_dereferenced) 16552 << DerivedLoc; 16553 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here) 16554 << RE->getSourceRange(); 16555 return true; 16556 } 16557 } 16558 16559 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.4] 16560 // List items of map clauses in the same construct must not share 16561 // original storage. 16562 // 16563 // An expression is a subset of the other. 16564 if (CurrentRegionOnly && (CI == CE || SI == SE)) { 16565 if (CKind == OMPC_map) { 16566 if (CI != CE || SI != SE) { 16567 // Allow constructs like this: map(s, s.ptr[0:1]), where s.ptr is 16568 // a pointer. 16569 auto Begin = 16570 CI != CE ? CurComponents.begin() : StackComponents.begin(); 16571 auto End = CI != CE ? CurComponents.end() : StackComponents.end(); 16572 auto It = Begin; 16573 while (It != End && !It->getAssociatedDeclaration()) 16574 std::advance(It, 1); 16575 assert(It != End && 16576 "Expected at least one component with the declaration."); 16577 if (It != Begin && It->getAssociatedDeclaration() 16578 ->getType() 16579 .getCanonicalType() 16580 ->isAnyPointerType()) { 16581 IsEnclosedByDataEnvironmentExpr = false; 16582 EnclosingExpr = nullptr; 16583 return false; 16584 } 16585 } 16586 SemaRef.Diag(ELoc, diag::err_omp_map_shared_storage) << ERange; 16587 } else { 16588 assert(CKind == OMPC_to || CKind == OMPC_from); 16589 SemaRef.Diag(ELoc, diag::err_omp_once_referenced_in_target_update) 16590 << ERange; 16591 } 16592 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here) 16593 << RE->getSourceRange(); 16594 return true; 16595 } 16596 16597 // The current expression uses the same base as other expression in the 16598 // data environment but does not contain it completely. 16599 if (!CurrentRegionOnly && SI != SE) 16600 EnclosingExpr = RE; 16601 16602 // The current expression is a subset of the expression in the data 16603 // environment. 16604 IsEnclosedByDataEnvironmentExpr |= 16605 (!CurrentRegionOnly && CI != CE && SI == SE); 16606 16607 return false; 16608 }); 16609 16610 if (CurrentRegionOnly) 16611 return FoundError; 16612 16613 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.5] 16614 // If any part of the original storage of a list item has corresponding 16615 // storage in the device data environment, all of the original storage must 16616 // have corresponding storage in the device data environment. 16617 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.6] 16618 // If a list item is an element of a structure, and a different element of 16619 // the structure has a corresponding list item in the device data environment 16620 // prior to a task encountering the construct associated with the map clause, 16621 // then the list item must also have a corresponding list item in the device 16622 // data environment prior to the task encountering the construct. 16623 // 16624 if (EnclosingExpr && !IsEnclosedByDataEnvironmentExpr) { 16625 SemaRef.Diag(ELoc, 16626 diag::err_omp_original_storage_is_shared_and_does_not_contain) 16627 << ERange; 16628 SemaRef.Diag(EnclosingExpr->getExprLoc(), diag::note_used_here) 16629 << EnclosingExpr->getSourceRange(); 16630 return true; 16631 } 16632 16633 return FoundError; 16634 } 16635 16636 // Look up the user-defined mapper given the mapper name and mapped type, and 16637 // build a reference to it. 16638 static ExprResult buildUserDefinedMapperRef(Sema &SemaRef, Scope *S, 16639 CXXScopeSpec &MapperIdScopeSpec, 16640 const DeclarationNameInfo &MapperId, 16641 QualType Type, 16642 Expr *UnresolvedMapper) { 16643 if (MapperIdScopeSpec.isInvalid()) 16644 return ExprError(); 16645 // Get the actual type for the array type. 16646 if (Type->isArrayType()) { 16647 assert(Type->getAsArrayTypeUnsafe() && "Expect to get a valid array type"); 16648 Type = Type->getAsArrayTypeUnsafe()->getElementType().getCanonicalType(); 16649 } 16650 // Find all user-defined mappers with the given MapperId. 16651 SmallVector<UnresolvedSet<8>, 4> Lookups; 16652 LookupResult Lookup(SemaRef, MapperId, Sema::LookupOMPMapperName); 16653 Lookup.suppressDiagnostics(); 16654 if (S) { 16655 while (S && SemaRef.LookupParsedName(Lookup, S, &MapperIdScopeSpec)) { 16656 NamedDecl *D = Lookup.getRepresentativeDecl(); 16657 while (S && !S->isDeclScope(D)) 16658 S = S->getParent(); 16659 if (S) 16660 S = S->getParent(); 16661 Lookups.emplace_back(); 16662 Lookups.back().append(Lookup.begin(), Lookup.end()); 16663 Lookup.clear(); 16664 } 16665 } else if (auto *ULE = cast_or_null<UnresolvedLookupExpr>(UnresolvedMapper)) { 16666 // Extract the user-defined mappers with the given MapperId. 16667 Lookups.push_back(UnresolvedSet<8>()); 16668 for (NamedDecl *D : ULE->decls()) { 16669 auto *DMD = cast<OMPDeclareMapperDecl>(D); 16670 assert(DMD && "Expect valid OMPDeclareMapperDecl during instantiation."); 16671 Lookups.back().addDecl(DMD); 16672 } 16673 } 16674 // Defer the lookup for dependent types. The results will be passed through 16675 // UnresolvedMapper on instantiation. 16676 if (SemaRef.CurContext->isDependentContext() || Type->isDependentType() || 16677 Type->isInstantiationDependentType() || 16678 Type->containsUnexpandedParameterPack() || 16679 filterLookupForUDReductionAndMapper<bool>(Lookups, [](ValueDecl *D) { 16680 return !D->isInvalidDecl() && 16681 (D->getType()->isDependentType() || 16682 D->getType()->isInstantiationDependentType() || 16683 D->getType()->containsUnexpandedParameterPack()); 16684 })) { 16685 UnresolvedSet<8> URS; 16686 for (const UnresolvedSet<8> &Set : Lookups) { 16687 if (Set.empty()) 16688 continue; 16689 URS.append(Set.begin(), Set.end()); 16690 } 16691 return UnresolvedLookupExpr::Create( 16692 SemaRef.Context, /*NamingClass=*/nullptr, 16693 MapperIdScopeSpec.getWithLocInContext(SemaRef.Context), MapperId, 16694 /*ADL=*/false, /*Overloaded=*/true, URS.begin(), URS.end()); 16695 } 16696 SourceLocation Loc = MapperId.getLoc(); 16697 // [OpenMP 5.0], 2.19.7.3 declare mapper Directive, Restrictions 16698 // The type must be of struct, union or class type in C and C++ 16699 if (!Type->isStructureOrClassType() && !Type->isUnionType() && 16700 (MapperIdScopeSpec.isSet() || MapperId.getAsString() != "default")) { 16701 SemaRef.Diag(Loc, diag::err_omp_mapper_wrong_type); 16702 return ExprError(); 16703 } 16704 // Perform argument dependent lookup. 16705 if (SemaRef.getLangOpts().CPlusPlus && !MapperIdScopeSpec.isSet()) 16706 argumentDependentLookup(SemaRef, MapperId, Loc, Type, Lookups); 16707 // Return the first user-defined mapper with the desired type. 16708 if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>( 16709 Lookups, [&SemaRef, Type](ValueDecl *D) -> ValueDecl * { 16710 if (!D->isInvalidDecl() && 16711 SemaRef.Context.hasSameType(D->getType(), Type)) 16712 return D; 16713 return nullptr; 16714 })) 16715 return SemaRef.BuildDeclRefExpr(VD, Type, VK_LValue, Loc); 16716 // Find the first user-defined mapper with a type derived from the desired 16717 // type. 16718 if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>( 16719 Lookups, [&SemaRef, Type, Loc](ValueDecl *D) -> ValueDecl * { 16720 if (!D->isInvalidDecl() && 16721 SemaRef.IsDerivedFrom(Loc, Type, D->getType()) && 16722 !Type.isMoreQualifiedThan(D->getType())) 16723 return D; 16724 return nullptr; 16725 })) { 16726 CXXBasePaths Paths(/*FindAmbiguities=*/true, /*RecordPaths=*/true, 16727 /*DetectVirtual=*/false); 16728 if (SemaRef.IsDerivedFrom(Loc, Type, VD->getType(), Paths)) { 16729 if (!Paths.isAmbiguous(SemaRef.Context.getCanonicalType( 16730 VD->getType().getUnqualifiedType()))) { 16731 if (SemaRef.CheckBaseClassAccess( 16732 Loc, VD->getType(), Type, Paths.front(), 16733 /*DiagID=*/0) != Sema::AR_inaccessible) { 16734 return SemaRef.BuildDeclRefExpr(VD, Type, VK_LValue, Loc); 16735 } 16736 } 16737 } 16738 } 16739 // Report error if a mapper is specified, but cannot be found. 16740 if (MapperIdScopeSpec.isSet() || MapperId.getAsString() != "default") { 16741 SemaRef.Diag(Loc, diag::err_omp_invalid_mapper) 16742 << Type << MapperId.getName(); 16743 return ExprError(); 16744 } 16745 return ExprEmpty(); 16746 } 16747 16748 namespace { 16749 // Utility struct that gathers all the related lists associated with a mappable 16750 // expression. 16751 struct MappableVarListInfo { 16752 // The list of expressions. 16753 ArrayRef<Expr *> VarList; 16754 // The list of processed expressions. 16755 SmallVector<Expr *, 16> ProcessedVarList; 16756 // The mappble components for each expression. 16757 OMPClauseMappableExprCommon::MappableExprComponentLists VarComponents; 16758 // The base declaration of the variable. 16759 SmallVector<ValueDecl *, 16> VarBaseDeclarations; 16760 // The reference to the user-defined mapper associated with every expression. 16761 SmallVector<Expr *, 16> UDMapperList; 16762 16763 MappableVarListInfo(ArrayRef<Expr *> VarList) : VarList(VarList) { 16764 // We have a list of components and base declarations for each entry in the 16765 // variable list. 16766 VarComponents.reserve(VarList.size()); 16767 VarBaseDeclarations.reserve(VarList.size()); 16768 } 16769 }; 16770 } 16771 16772 // Check the validity of the provided variable list for the provided clause kind 16773 // \a CKind. In the check process the valid expressions, mappable expression 16774 // components, variables, and user-defined mappers are extracted and used to 16775 // fill \a ProcessedVarList, \a VarComponents, \a VarBaseDeclarations, and \a 16776 // UDMapperList in MVLI. \a MapType, \a IsMapTypeImplicit, \a MapperIdScopeSpec, 16777 // and \a MapperId are expected to be valid if the clause kind is 'map'. 16778 static void checkMappableExpressionList( 16779 Sema &SemaRef, DSAStackTy *DSAS, OpenMPClauseKind CKind, 16780 MappableVarListInfo &MVLI, SourceLocation StartLoc, 16781 CXXScopeSpec &MapperIdScopeSpec, DeclarationNameInfo MapperId, 16782 ArrayRef<Expr *> UnresolvedMappers, 16783 OpenMPMapClauseKind MapType = OMPC_MAP_unknown, 16784 bool IsMapTypeImplicit = false) { 16785 // We only expect mappable expressions in 'to', 'from', and 'map' clauses. 16786 assert((CKind == OMPC_map || CKind == OMPC_to || CKind == OMPC_from) && 16787 "Unexpected clause kind with mappable expressions!"); 16788 16789 // If the identifier of user-defined mapper is not specified, it is "default". 16790 // We do not change the actual name in this clause to distinguish whether a 16791 // mapper is specified explicitly, i.e., it is not explicitly specified when 16792 // MapperId.getName() is empty. 16793 if (!MapperId.getName() || MapperId.getName().isEmpty()) { 16794 auto &DeclNames = SemaRef.getASTContext().DeclarationNames; 16795 MapperId.setName(DeclNames.getIdentifier( 16796 &SemaRef.getASTContext().Idents.get("default"))); 16797 } 16798 16799 // Iterators to find the current unresolved mapper expression. 16800 auto UMIt = UnresolvedMappers.begin(), UMEnd = UnresolvedMappers.end(); 16801 bool UpdateUMIt = false; 16802 Expr *UnresolvedMapper = nullptr; 16803 16804 // Keep track of the mappable components and base declarations in this clause. 16805 // Each entry in the list is going to have a list of components associated. We 16806 // record each set of the components so that we can build the clause later on. 16807 // In the end we should have the same amount of declarations and component 16808 // lists. 16809 16810 for (Expr *RE : MVLI.VarList) { 16811 assert(RE && "Null expr in omp to/from/map clause"); 16812 SourceLocation ELoc = RE->getExprLoc(); 16813 16814 // Find the current unresolved mapper expression. 16815 if (UpdateUMIt && UMIt != UMEnd) { 16816 UMIt++; 16817 assert( 16818 UMIt != UMEnd && 16819 "Expect the size of UnresolvedMappers to match with that of VarList"); 16820 } 16821 UpdateUMIt = true; 16822 if (UMIt != UMEnd) 16823 UnresolvedMapper = *UMIt; 16824 16825 const Expr *VE = RE->IgnoreParenLValueCasts(); 16826 16827 if (VE->isValueDependent() || VE->isTypeDependent() || 16828 VE->isInstantiationDependent() || 16829 VE->containsUnexpandedParameterPack()) { 16830 // Try to find the associated user-defined mapper. 16831 ExprResult ER = buildUserDefinedMapperRef( 16832 SemaRef, DSAS->getCurScope(), MapperIdScopeSpec, MapperId, 16833 VE->getType().getCanonicalType(), UnresolvedMapper); 16834 if (ER.isInvalid()) 16835 continue; 16836 MVLI.UDMapperList.push_back(ER.get()); 16837 // We can only analyze this information once the missing information is 16838 // resolved. 16839 MVLI.ProcessedVarList.push_back(RE); 16840 continue; 16841 } 16842 16843 Expr *SimpleExpr = RE->IgnoreParenCasts(); 16844 16845 if (!RE->isLValue()) { 16846 if (SemaRef.getLangOpts().OpenMP < 50) { 16847 SemaRef.Diag( 16848 ELoc, diag::err_omp_expected_named_var_member_or_array_expression) 16849 << RE->getSourceRange(); 16850 } else { 16851 SemaRef.Diag(ELoc, diag::err_omp_non_lvalue_in_map_or_motion_clauses) 16852 << getOpenMPClauseName(CKind) << RE->getSourceRange(); 16853 } 16854 continue; 16855 } 16856 16857 OMPClauseMappableExprCommon::MappableExprComponentList CurComponents; 16858 ValueDecl *CurDeclaration = nullptr; 16859 16860 // Obtain the array or member expression bases if required. Also, fill the 16861 // components array with all the components identified in the process. 16862 const Expr *BE = checkMapClauseExpressionBase( 16863 SemaRef, SimpleExpr, CurComponents, CKind, /*NoDiagnose=*/false); 16864 if (!BE) 16865 continue; 16866 16867 assert(!CurComponents.empty() && 16868 "Invalid mappable expression information."); 16869 16870 if (const auto *TE = dyn_cast<CXXThisExpr>(BE)) { 16871 // Add store "this" pointer to class in DSAStackTy for future checking 16872 DSAS->addMappedClassesQualTypes(TE->getType()); 16873 // Try to find the associated user-defined mapper. 16874 ExprResult ER = buildUserDefinedMapperRef( 16875 SemaRef, DSAS->getCurScope(), MapperIdScopeSpec, MapperId, 16876 VE->getType().getCanonicalType(), UnresolvedMapper); 16877 if (ER.isInvalid()) 16878 continue; 16879 MVLI.UDMapperList.push_back(ER.get()); 16880 // Skip restriction checking for variable or field declarations 16881 MVLI.ProcessedVarList.push_back(RE); 16882 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1); 16883 MVLI.VarComponents.back().append(CurComponents.begin(), 16884 CurComponents.end()); 16885 MVLI.VarBaseDeclarations.push_back(nullptr); 16886 continue; 16887 } 16888 16889 // For the following checks, we rely on the base declaration which is 16890 // expected to be associated with the last component. The declaration is 16891 // expected to be a variable or a field (if 'this' is being mapped). 16892 CurDeclaration = CurComponents.back().getAssociatedDeclaration(); 16893 assert(CurDeclaration && "Null decl on map clause."); 16894 assert( 16895 CurDeclaration->isCanonicalDecl() && 16896 "Expecting components to have associated only canonical declarations."); 16897 16898 auto *VD = dyn_cast<VarDecl>(CurDeclaration); 16899 const auto *FD = dyn_cast<FieldDecl>(CurDeclaration); 16900 16901 assert((VD || FD) && "Only variables or fields are expected here!"); 16902 (void)FD; 16903 16904 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.10] 16905 // threadprivate variables cannot appear in a map clause. 16906 // OpenMP 4.5 [2.10.5, target update Construct] 16907 // threadprivate variables cannot appear in a from clause. 16908 if (VD && DSAS->isThreadPrivate(VD)) { 16909 DSAStackTy::DSAVarData DVar = DSAS->getTopDSA(VD, /*FromParent=*/false); 16910 SemaRef.Diag(ELoc, diag::err_omp_threadprivate_in_clause) 16911 << getOpenMPClauseName(CKind); 16912 reportOriginalDsa(SemaRef, DSAS, VD, DVar); 16913 continue; 16914 } 16915 16916 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.9] 16917 // A list item cannot appear in both a map clause and a data-sharing 16918 // attribute clause on the same construct. 16919 16920 // Check conflicts with other map clause expressions. We check the conflicts 16921 // with the current construct separately from the enclosing data 16922 // environment, because the restrictions are different. We only have to 16923 // check conflicts across regions for the map clauses. 16924 if (checkMapConflicts(SemaRef, DSAS, CurDeclaration, SimpleExpr, 16925 /*CurrentRegionOnly=*/true, CurComponents, CKind)) 16926 break; 16927 if (CKind == OMPC_map && 16928 checkMapConflicts(SemaRef, DSAS, CurDeclaration, SimpleExpr, 16929 /*CurrentRegionOnly=*/false, CurComponents, CKind)) 16930 break; 16931 16932 // OpenMP 4.5 [2.10.5, target update Construct] 16933 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1] 16934 // If the type of a list item is a reference to a type T then the type will 16935 // be considered to be T for all purposes of this clause. 16936 auto I = llvm::find_if( 16937 CurComponents, 16938 [](const OMPClauseMappableExprCommon::MappableComponent &MC) { 16939 return MC.getAssociatedDeclaration(); 16940 }); 16941 assert(I != CurComponents.end() && "Null decl on map clause."); 16942 QualType Type; 16943 auto *ASE = dyn_cast<ArraySubscriptExpr>(VE->IgnoreParens()); 16944 auto *OASE = dyn_cast<OMPArraySectionExpr>(VE->IgnoreParens()); 16945 auto *OAShE = dyn_cast<OMPArrayShapingExpr>(VE->IgnoreParens()); 16946 if (ASE) { 16947 Type = ASE->getType().getNonReferenceType(); 16948 } else if (OASE) { 16949 QualType BaseType = 16950 OMPArraySectionExpr::getBaseOriginalType(OASE->getBase()); 16951 if (const auto *ATy = BaseType->getAsArrayTypeUnsafe()) 16952 Type = ATy->getElementType(); 16953 else 16954 Type = BaseType->getPointeeType(); 16955 Type = Type.getNonReferenceType(); 16956 } else if (OAShE) { 16957 Type = OAShE->getBase()->getType()->getPointeeType(); 16958 } else { 16959 Type = VE->getType(); 16960 } 16961 16962 // OpenMP 4.5 [2.10.5, target update Construct, Restrictions, p.4] 16963 // A list item in a to or from clause must have a mappable type. 16964 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.9] 16965 // A list item must have a mappable type. 16966 if (!checkTypeMappable(VE->getExprLoc(), VE->getSourceRange(), SemaRef, 16967 DSAS, Type)) 16968 continue; 16969 16970 Type = I->getAssociatedDeclaration()->getType().getNonReferenceType(); 16971 16972 if (CKind == OMPC_map) { 16973 // target enter data 16974 // OpenMP [2.10.2, Restrictions, p. 99] 16975 // A map-type must be specified in all map clauses and must be either 16976 // to or alloc. 16977 OpenMPDirectiveKind DKind = DSAS->getCurrentDirective(); 16978 if (DKind == OMPD_target_enter_data && 16979 !(MapType == OMPC_MAP_to || MapType == OMPC_MAP_alloc)) { 16980 SemaRef.Diag(StartLoc, diag::err_omp_invalid_map_type_for_directive) 16981 << (IsMapTypeImplicit ? 1 : 0) 16982 << getOpenMPSimpleClauseTypeName(OMPC_map, MapType) 16983 << getOpenMPDirectiveName(DKind); 16984 continue; 16985 } 16986 16987 // target exit_data 16988 // OpenMP [2.10.3, Restrictions, p. 102] 16989 // A map-type must be specified in all map clauses and must be either 16990 // from, release, or delete. 16991 if (DKind == OMPD_target_exit_data && 16992 !(MapType == OMPC_MAP_from || MapType == OMPC_MAP_release || 16993 MapType == OMPC_MAP_delete)) { 16994 SemaRef.Diag(StartLoc, diag::err_omp_invalid_map_type_for_directive) 16995 << (IsMapTypeImplicit ? 1 : 0) 16996 << getOpenMPSimpleClauseTypeName(OMPC_map, MapType) 16997 << getOpenMPDirectiveName(DKind); 16998 continue; 16999 } 17000 17001 // OpenMP 4.5 [2.15.5.1, Restrictions, p.3] 17002 // A list item cannot appear in both a map clause and a data-sharing 17003 // attribute clause on the same construct 17004 // 17005 // OpenMP 5.0 [2.19.7.1, Restrictions, p.7] 17006 // A list item cannot appear in both a map clause and a data-sharing 17007 // attribute clause on the same construct unless the construct is a 17008 // combined construct. 17009 if (VD && ((SemaRef.LangOpts.OpenMP <= 45 && 17010 isOpenMPTargetExecutionDirective(DKind)) || 17011 DKind == OMPD_target)) { 17012 DSAStackTy::DSAVarData DVar = DSAS->getTopDSA(VD, /*FromParent=*/false); 17013 if (isOpenMPPrivate(DVar.CKind)) { 17014 SemaRef.Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa) 17015 << getOpenMPClauseName(DVar.CKind) 17016 << getOpenMPClauseName(OMPC_map) 17017 << getOpenMPDirectiveName(DSAS->getCurrentDirective()); 17018 reportOriginalDsa(SemaRef, DSAS, CurDeclaration, DVar); 17019 continue; 17020 } 17021 } 17022 } 17023 17024 // Try to find the associated user-defined mapper. 17025 ExprResult ER = buildUserDefinedMapperRef( 17026 SemaRef, DSAS->getCurScope(), MapperIdScopeSpec, MapperId, 17027 Type.getCanonicalType(), UnresolvedMapper); 17028 if (ER.isInvalid()) 17029 continue; 17030 MVLI.UDMapperList.push_back(ER.get()); 17031 17032 // Save the current expression. 17033 MVLI.ProcessedVarList.push_back(RE); 17034 17035 // Store the components in the stack so that they can be used to check 17036 // against other clauses later on. 17037 DSAS->addMappableExpressionComponents(CurDeclaration, CurComponents, 17038 /*WhereFoundClauseKind=*/OMPC_map); 17039 17040 // Save the components and declaration to create the clause. For purposes of 17041 // the clause creation, any component list that has has base 'this' uses 17042 // null as base declaration. 17043 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1); 17044 MVLI.VarComponents.back().append(CurComponents.begin(), 17045 CurComponents.end()); 17046 MVLI.VarBaseDeclarations.push_back(isa<MemberExpr>(BE) ? nullptr 17047 : CurDeclaration); 17048 } 17049 } 17050 17051 OMPClause *Sema::ActOnOpenMPMapClause( 17052 ArrayRef<OpenMPMapModifierKind> MapTypeModifiers, 17053 ArrayRef<SourceLocation> MapTypeModifiersLoc, 17054 CXXScopeSpec &MapperIdScopeSpec, DeclarationNameInfo &MapperId, 17055 OpenMPMapClauseKind MapType, bool IsMapTypeImplicit, SourceLocation MapLoc, 17056 SourceLocation ColonLoc, ArrayRef<Expr *> VarList, 17057 const OMPVarListLocTy &Locs, ArrayRef<Expr *> UnresolvedMappers) { 17058 OpenMPMapModifierKind Modifiers[] = {OMPC_MAP_MODIFIER_unknown, 17059 OMPC_MAP_MODIFIER_unknown, 17060 OMPC_MAP_MODIFIER_unknown}; 17061 SourceLocation ModifiersLoc[NumberOfOMPMapClauseModifiers]; 17062 17063 // Process map-type-modifiers, flag errors for duplicate modifiers. 17064 unsigned Count = 0; 17065 for (unsigned I = 0, E = MapTypeModifiers.size(); I < E; ++I) { 17066 if (MapTypeModifiers[I] != OMPC_MAP_MODIFIER_unknown && 17067 llvm::find(Modifiers, MapTypeModifiers[I]) != std::end(Modifiers)) { 17068 Diag(MapTypeModifiersLoc[I], diag::err_omp_duplicate_map_type_modifier); 17069 continue; 17070 } 17071 assert(Count < NumberOfOMPMapClauseModifiers && 17072 "Modifiers exceed the allowed number of map type modifiers"); 17073 Modifiers[Count] = MapTypeModifiers[I]; 17074 ModifiersLoc[Count] = MapTypeModifiersLoc[I]; 17075 ++Count; 17076 } 17077 17078 MappableVarListInfo MVLI(VarList); 17079 checkMappableExpressionList(*this, DSAStack, OMPC_map, MVLI, Locs.StartLoc, 17080 MapperIdScopeSpec, MapperId, UnresolvedMappers, 17081 MapType, IsMapTypeImplicit); 17082 17083 // We need to produce a map clause even if we don't have variables so that 17084 // other diagnostics related with non-existing map clauses are accurate. 17085 return OMPMapClause::Create(Context, Locs, MVLI.ProcessedVarList, 17086 MVLI.VarBaseDeclarations, MVLI.VarComponents, 17087 MVLI.UDMapperList, Modifiers, ModifiersLoc, 17088 MapperIdScopeSpec.getWithLocInContext(Context), 17089 MapperId, MapType, IsMapTypeImplicit, MapLoc); 17090 } 17091 17092 QualType Sema::ActOnOpenMPDeclareReductionType(SourceLocation TyLoc, 17093 TypeResult ParsedType) { 17094 assert(ParsedType.isUsable()); 17095 17096 QualType ReductionType = GetTypeFromParser(ParsedType.get()); 17097 if (ReductionType.isNull()) 17098 return QualType(); 17099 17100 // [OpenMP 4.0], 2.15 declare reduction Directive, Restrictions, C\C++ 17101 // A type name in a declare reduction directive cannot be a function type, an 17102 // array type, a reference type, or a type qualified with const, volatile or 17103 // restrict. 17104 if (ReductionType.hasQualifiers()) { 17105 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 0; 17106 return QualType(); 17107 } 17108 17109 if (ReductionType->isFunctionType()) { 17110 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 1; 17111 return QualType(); 17112 } 17113 if (ReductionType->isReferenceType()) { 17114 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 2; 17115 return QualType(); 17116 } 17117 if (ReductionType->isArrayType()) { 17118 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 3; 17119 return QualType(); 17120 } 17121 return ReductionType; 17122 } 17123 17124 Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareReductionDirectiveStart( 17125 Scope *S, DeclContext *DC, DeclarationName Name, 17126 ArrayRef<std::pair<QualType, SourceLocation>> ReductionTypes, 17127 AccessSpecifier AS, Decl *PrevDeclInScope) { 17128 SmallVector<Decl *, 8> Decls; 17129 Decls.reserve(ReductionTypes.size()); 17130 17131 LookupResult Lookup(*this, Name, SourceLocation(), LookupOMPReductionName, 17132 forRedeclarationInCurContext()); 17133 // [OpenMP 4.0], 2.15 declare reduction Directive, Restrictions 17134 // A reduction-identifier may not be re-declared in the current scope for the 17135 // same type or for a type that is compatible according to the base language 17136 // rules. 17137 llvm::DenseMap<QualType, SourceLocation> PreviousRedeclTypes; 17138 OMPDeclareReductionDecl *PrevDRD = nullptr; 17139 bool InCompoundScope = true; 17140 if (S != nullptr) { 17141 // Find previous declaration with the same name not referenced in other 17142 // declarations. 17143 FunctionScopeInfo *ParentFn = getEnclosingFunction(); 17144 InCompoundScope = 17145 (ParentFn != nullptr) && !ParentFn->CompoundScopes.empty(); 17146 LookupName(Lookup, S); 17147 FilterLookupForScope(Lookup, DC, S, /*ConsiderLinkage=*/false, 17148 /*AllowInlineNamespace=*/false); 17149 llvm::DenseMap<OMPDeclareReductionDecl *, bool> UsedAsPrevious; 17150 LookupResult::Filter Filter = Lookup.makeFilter(); 17151 while (Filter.hasNext()) { 17152 auto *PrevDecl = cast<OMPDeclareReductionDecl>(Filter.next()); 17153 if (InCompoundScope) { 17154 auto I = UsedAsPrevious.find(PrevDecl); 17155 if (I == UsedAsPrevious.end()) 17156 UsedAsPrevious[PrevDecl] = false; 17157 if (OMPDeclareReductionDecl *D = PrevDecl->getPrevDeclInScope()) 17158 UsedAsPrevious[D] = true; 17159 } 17160 PreviousRedeclTypes[PrevDecl->getType().getCanonicalType()] = 17161 PrevDecl->getLocation(); 17162 } 17163 Filter.done(); 17164 if (InCompoundScope) { 17165 for (const auto &PrevData : UsedAsPrevious) { 17166 if (!PrevData.second) { 17167 PrevDRD = PrevData.first; 17168 break; 17169 } 17170 } 17171 } 17172 } else if (PrevDeclInScope != nullptr) { 17173 auto *PrevDRDInScope = PrevDRD = 17174 cast<OMPDeclareReductionDecl>(PrevDeclInScope); 17175 do { 17176 PreviousRedeclTypes[PrevDRDInScope->getType().getCanonicalType()] = 17177 PrevDRDInScope->getLocation(); 17178 PrevDRDInScope = PrevDRDInScope->getPrevDeclInScope(); 17179 } while (PrevDRDInScope != nullptr); 17180 } 17181 for (const auto &TyData : ReductionTypes) { 17182 const auto I = PreviousRedeclTypes.find(TyData.first.getCanonicalType()); 17183 bool Invalid = false; 17184 if (I != PreviousRedeclTypes.end()) { 17185 Diag(TyData.second, diag::err_omp_declare_reduction_redefinition) 17186 << TyData.first; 17187 Diag(I->second, diag::note_previous_definition); 17188 Invalid = true; 17189 } 17190 PreviousRedeclTypes[TyData.first.getCanonicalType()] = TyData.second; 17191 auto *DRD = OMPDeclareReductionDecl::Create(Context, DC, TyData.second, 17192 Name, TyData.first, PrevDRD); 17193 DC->addDecl(DRD); 17194 DRD->setAccess(AS); 17195 Decls.push_back(DRD); 17196 if (Invalid) 17197 DRD->setInvalidDecl(); 17198 else 17199 PrevDRD = DRD; 17200 } 17201 17202 return DeclGroupPtrTy::make( 17203 DeclGroupRef::Create(Context, Decls.begin(), Decls.size())); 17204 } 17205 17206 void Sema::ActOnOpenMPDeclareReductionCombinerStart(Scope *S, Decl *D) { 17207 auto *DRD = cast<OMPDeclareReductionDecl>(D); 17208 17209 // Enter new function scope. 17210 PushFunctionScope(); 17211 setFunctionHasBranchProtectedScope(); 17212 getCurFunction()->setHasOMPDeclareReductionCombiner(); 17213 17214 if (S != nullptr) 17215 PushDeclContext(S, DRD); 17216 else 17217 CurContext = DRD; 17218 17219 PushExpressionEvaluationContext( 17220 ExpressionEvaluationContext::PotentiallyEvaluated); 17221 17222 QualType ReductionType = DRD->getType(); 17223 // Create 'T* omp_parm;T omp_in;'. All references to 'omp_in' will 17224 // be replaced by '*omp_parm' during codegen. This required because 'omp_in' 17225 // uses semantics of argument handles by value, but it should be passed by 17226 // reference. C lang does not support references, so pass all parameters as 17227 // pointers. 17228 // Create 'T omp_in;' variable. 17229 VarDecl *OmpInParm = 17230 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_in"); 17231 // Create 'T* omp_parm;T omp_out;'. All references to 'omp_out' will 17232 // be replaced by '*omp_parm' during codegen. This required because 'omp_out' 17233 // uses semantics of argument handles by value, but it should be passed by 17234 // reference. C lang does not support references, so pass all parameters as 17235 // pointers. 17236 // Create 'T omp_out;' variable. 17237 VarDecl *OmpOutParm = 17238 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_out"); 17239 if (S != nullptr) { 17240 PushOnScopeChains(OmpInParm, S); 17241 PushOnScopeChains(OmpOutParm, S); 17242 } else { 17243 DRD->addDecl(OmpInParm); 17244 DRD->addDecl(OmpOutParm); 17245 } 17246 Expr *InE = 17247 ::buildDeclRefExpr(*this, OmpInParm, ReductionType, D->getLocation()); 17248 Expr *OutE = 17249 ::buildDeclRefExpr(*this, OmpOutParm, ReductionType, D->getLocation()); 17250 DRD->setCombinerData(InE, OutE); 17251 } 17252 17253 void Sema::ActOnOpenMPDeclareReductionCombinerEnd(Decl *D, Expr *Combiner) { 17254 auto *DRD = cast<OMPDeclareReductionDecl>(D); 17255 DiscardCleanupsInEvaluationContext(); 17256 PopExpressionEvaluationContext(); 17257 17258 PopDeclContext(); 17259 PopFunctionScopeInfo(); 17260 17261 if (Combiner != nullptr) 17262 DRD->setCombiner(Combiner); 17263 else 17264 DRD->setInvalidDecl(); 17265 } 17266 17267 VarDecl *Sema::ActOnOpenMPDeclareReductionInitializerStart(Scope *S, Decl *D) { 17268 auto *DRD = cast<OMPDeclareReductionDecl>(D); 17269 17270 // Enter new function scope. 17271 PushFunctionScope(); 17272 setFunctionHasBranchProtectedScope(); 17273 17274 if (S != nullptr) 17275 PushDeclContext(S, DRD); 17276 else 17277 CurContext = DRD; 17278 17279 PushExpressionEvaluationContext( 17280 ExpressionEvaluationContext::PotentiallyEvaluated); 17281 17282 QualType ReductionType = DRD->getType(); 17283 // Create 'T* omp_parm;T omp_priv;'. All references to 'omp_priv' will 17284 // be replaced by '*omp_parm' during codegen. This required because 'omp_priv' 17285 // uses semantics of argument handles by value, but it should be passed by 17286 // reference. C lang does not support references, so pass all parameters as 17287 // pointers. 17288 // Create 'T omp_priv;' variable. 17289 VarDecl *OmpPrivParm = 17290 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_priv"); 17291 // Create 'T* omp_parm;T omp_orig;'. All references to 'omp_orig' will 17292 // be replaced by '*omp_parm' during codegen. This required because 'omp_orig' 17293 // uses semantics of argument handles by value, but it should be passed by 17294 // reference. C lang does not support references, so pass all parameters as 17295 // pointers. 17296 // Create 'T omp_orig;' variable. 17297 VarDecl *OmpOrigParm = 17298 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_orig"); 17299 if (S != nullptr) { 17300 PushOnScopeChains(OmpPrivParm, S); 17301 PushOnScopeChains(OmpOrigParm, S); 17302 } else { 17303 DRD->addDecl(OmpPrivParm); 17304 DRD->addDecl(OmpOrigParm); 17305 } 17306 Expr *OrigE = 17307 ::buildDeclRefExpr(*this, OmpOrigParm, ReductionType, D->getLocation()); 17308 Expr *PrivE = 17309 ::buildDeclRefExpr(*this, OmpPrivParm, ReductionType, D->getLocation()); 17310 DRD->setInitializerData(OrigE, PrivE); 17311 return OmpPrivParm; 17312 } 17313 17314 void Sema::ActOnOpenMPDeclareReductionInitializerEnd(Decl *D, Expr *Initializer, 17315 VarDecl *OmpPrivParm) { 17316 auto *DRD = cast<OMPDeclareReductionDecl>(D); 17317 DiscardCleanupsInEvaluationContext(); 17318 PopExpressionEvaluationContext(); 17319 17320 PopDeclContext(); 17321 PopFunctionScopeInfo(); 17322 17323 if (Initializer != nullptr) { 17324 DRD->setInitializer(Initializer, OMPDeclareReductionDecl::CallInit); 17325 } else if (OmpPrivParm->hasInit()) { 17326 DRD->setInitializer(OmpPrivParm->getInit(), 17327 OmpPrivParm->isDirectInit() 17328 ? OMPDeclareReductionDecl::DirectInit 17329 : OMPDeclareReductionDecl::CopyInit); 17330 } else { 17331 DRD->setInvalidDecl(); 17332 } 17333 } 17334 17335 Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareReductionDirectiveEnd( 17336 Scope *S, DeclGroupPtrTy DeclReductions, bool IsValid) { 17337 for (Decl *D : DeclReductions.get()) { 17338 if (IsValid) { 17339 if (S) 17340 PushOnScopeChains(cast<OMPDeclareReductionDecl>(D), S, 17341 /*AddToContext=*/false); 17342 } else { 17343 D->setInvalidDecl(); 17344 } 17345 } 17346 return DeclReductions; 17347 } 17348 17349 TypeResult Sema::ActOnOpenMPDeclareMapperVarDecl(Scope *S, Declarator &D) { 17350 TypeSourceInfo *TInfo = GetTypeForDeclarator(D, S); 17351 QualType T = TInfo->getType(); 17352 if (D.isInvalidType()) 17353 return true; 17354 17355 if (getLangOpts().CPlusPlus) { 17356 // Check that there are no default arguments (C++ only). 17357 CheckExtraCXXDefaultArguments(D); 17358 } 17359 17360 return CreateParsedType(T, TInfo); 17361 } 17362 17363 QualType Sema::ActOnOpenMPDeclareMapperType(SourceLocation TyLoc, 17364 TypeResult ParsedType) { 17365 assert(ParsedType.isUsable() && "Expect usable parsed mapper type"); 17366 17367 QualType MapperType = GetTypeFromParser(ParsedType.get()); 17368 assert(!MapperType.isNull() && "Expect valid mapper type"); 17369 17370 // [OpenMP 5.0], 2.19.7.3 declare mapper Directive, Restrictions 17371 // The type must be of struct, union or class type in C and C++ 17372 if (!MapperType->isStructureOrClassType() && !MapperType->isUnionType()) { 17373 Diag(TyLoc, diag::err_omp_mapper_wrong_type); 17374 return QualType(); 17375 } 17376 return MapperType; 17377 } 17378 17379 OMPDeclareMapperDecl *Sema::ActOnOpenMPDeclareMapperDirectiveStart( 17380 Scope *S, DeclContext *DC, DeclarationName Name, QualType MapperType, 17381 SourceLocation StartLoc, DeclarationName VN, AccessSpecifier AS, 17382 Decl *PrevDeclInScope) { 17383 LookupResult Lookup(*this, Name, SourceLocation(), LookupOMPMapperName, 17384 forRedeclarationInCurContext()); 17385 // [OpenMP 5.0], 2.19.7.3 declare mapper Directive, Restrictions 17386 // A mapper-identifier may not be redeclared in the current scope for the 17387 // same type or for a type that is compatible according to the base language 17388 // rules. 17389 llvm::DenseMap<QualType, SourceLocation> PreviousRedeclTypes; 17390 OMPDeclareMapperDecl *PrevDMD = nullptr; 17391 bool InCompoundScope = true; 17392 if (S != nullptr) { 17393 // Find previous declaration with the same name not referenced in other 17394 // declarations. 17395 FunctionScopeInfo *ParentFn = getEnclosingFunction(); 17396 InCompoundScope = 17397 (ParentFn != nullptr) && !ParentFn->CompoundScopes.empty(); 17398 LookupName(Lookup, S); 17399 FilterLookupForScope(Lookup, DC, S, /*ConsiderLinkage=*/false, 17400 /*AllowInlineNamespace=*/false); 17401 llvm::DenseMap<OMPDeclareMapperDecl *, bool> UsedAsPrevious; 17402 LookupResult::Filter Filter = Lookup.makeFilter(); 17403 while (Filter.hasNext()) { 17404 auto *PrevDecl = cast<OMPDeclareMapperDecl>(Filter.next()); 17405 if (InCompoundScope) { 17406 auto I = UsedAsPrevious.find(PrevDecl); 17407 if (I == UsedAsPrevious.end()) 17408 UsedAsPrevious[PrevDecl] = false; 17409 if (OMPDeclareMapperDecl *D = PrevDecl->getPrevDeclInScope()) 17410 UsedAsPrevious[D] = true; 17411 } 17412 PreviousRedeclTypes[PrevDecl->getType().getCanonicalType()] = 17413 PrevDecl->getLocation(); 17414 } 17415 Filter.done(); 17416 if (InCompoundScope) { 17417 for (const auto &PrevData : UsedAsPrevious) { 17418 if (!PrevData.second) { 17419 PrevDMD = PrevData.first; 17420 break; 17421 } 17422 } 17423 } 17424 } else if (PrevDeclInScope) { 17425 auto *PrevDMDInScope = PrevDMD = 17426 cast<OMPDeclareMapperDecl>(PrevDeclInScope); 17427 do { 17428 PreviousRedeclTypes[PrevDMDInScope->getType().getCanonicalType()] = 17429 PrevDMDInScope->getLocation(); 17430 PrevDMDInScope = PrevDMDInScope->getPrevDeclInScope(); 17431 } while (PrevDMDInScope != nullptr); 17432 } 17433 const auto I = PreviousRedeclTypes.find(MapperType.getCanonicalType()); 17434 bool Invalid = false; 17435 if (I != PreviousRedeclTypes.end()) { 17436 Diag(StartLoc, diag::err_omp_declare_mapper_redefinition) 17437 << MapperType << Name; 17438 Diag(I->second, diag::note_previous_definition); 17439 Invalid = true; 17440 } 17441 auto *DMD = OMPDeclareMapperDecl::Create(Context, DC, StartLoc, Name, 17442 MapperType, VN, PrevDMD); 17443 DC->addDecl(DMD); 17444 DMD->setAccess(AS); 17445 if (Invalid) 17446 DMD->setInvalidDecl(); 17447 17448 // Enter new function scope. 17449 PushFunctionScope(); 17450 setFunctionHasBranchProtectedScope(); 17451 17452 CurContext = DMD; 17453 17454 return DMD; 17455 } 17456 17457 void Sema::ActOnOpenMPDeclareMapperDirectiveVarDecl(OMPDeclareMapperDecl *DMD, 17458 Scope *S, 17459 QualType MapperType, 17460 SourceLocation StartLoc, 17461 DeclarationName VN) { 17462 VarDecl *VD = buildVarDecl(*this, StartLoc, MapperType, VN.getAsString()); 17463 if (S) 17464 PushOnScopeChains(VD, S); 17465 else 17466 DMD->addDecl(VD); 17467 Expr *MapperVarRefExpr = buildDeclRefExpr(*this, VD, MapperType, StartLoc); 17468 DMD->setMapperVarRef(MapperVarRefExpr); 17469 } 17470 17471 Sema::DeclGroupPtrTy 17472 Sema::ActOnOpenMPDeclareMapperDirectiveEnd(OMPDeclareMapperDecl *D, Scope *S, 17473 ArrayRef<OMPClause *> ClauseList) { 17474 PopDeclContext(); 17475 PopFunctionScopeInfo(); 17476 17477 if (D) { 17478 if (S) 17479 PushOnScopeChains(D, S, /*AddToContext=*/false); 17480 D->CreateClauses(Context, ClauseList); 17481 } 17482 17483 return DeclGroupPtrTy::make(DeclGroupRef(D)); 17484 } 17485 17486 OMPClause *Sema::ActOnOpenMPNumTeamsClause(Expr *NumTeams, 17487 SourceLocation StartLoc, 17488 SourceLocation LParenLoc, 17489 SourceLocation EndLoc) { 17490 Expr *ValExpr = NumTeams; 17491 Stmt *HelperValStmt = nullptr; 17492 17493 // OpenMP [teams Constrcut, Restrictions] 17494 // The num_teams expression must evaluate to a positive integer value. 17495 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_num_teams, 17496 /*StrictlyPositive=*/true)) 17497 return nullptr; 17498 17499 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 17500 OpenMPDirectiveKind CaptureRegion = 17501 getOpenMPCaptureRegionForClause(DKind, OMPC_num_teams, LangOpts.OpenMP); 17502 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 17503 ValExpr = MakeFullExpr(ValExpr).get(); 17504 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 17505 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 17506 HelperValStmt = buildPreInits(Context, Captures); 17507 } 17508 17509 return new (Context) OMPNumTeamsClause(ValExpr, HelperValStmt, CaptureRegion, 17510 StartLoc, LParenLoc, EndLoc); 17511 } 17512 17513 OMPClause *Sema::ActOnOpenMPThreadLimitClause(Expr *ThreadLimit, 17514 SourceLocation StartLoc, 17515 SourceLocation LParenLoc, 17516 SourceLocation EndLoc) { 17517 Expr *ValExpr = ThreadLimit; 17518 Stmt *HelperValStmt = nullptr; 17519 17520 // OpenMP [teams Constrcut, Restrictions] 17521 // The thread_limit expression must evaluate to a positive integer value. 17522 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_thread_limit, 17523 /*StrictlyPositive=*/true)) 17524 return nullptr; 17525 17526 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 17527 OpenMPDirectiveKind CaptureRegion = getOpenMPCaptureRegionForClause( 17528 DKind, OMPC_thread_limit, LangOpts.OpenMP); 17529 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 17530 ValExpr = MakeFullExpr(ValExpr).get(); 17531 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 17532 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 17533 HelperValStmt = buildPreInits(Context, Captures); 17534 } 17535 17536 return new (Context) OMPThreadLimitClause( 17537 ValExpr, HelperValStmt, CaptureRegion, StartLoc, LParenLoc, EndLoc); 17538 } 17539 17540 OMPClause *Sema::ActOnOpenMPPriorityClause(Expr *Priority, 17541 SourceLocation StartLoc, 17542 SourceLocation LParenLoc, 17543 SourceLocation EndLoc) { 17544 Expr *ValExpr = Priority; 17545 Stmt *HelperValStmt = nullptr; 17546 OpenMPDirectiveKind CaptureRegion = OMPD_unknown; 17547 17548 // OpenMP [2.9.1, task Constrcut] 17549 // The priority-value is a non-negative numerical scalar expression. 17550 if (!isNonNegativeIntegerValue( 17551 ValExpr, *this, OMPC_priority, 17552 /*StrictlyPositive=*/false, /*BuildCapture=*/true, 17553 DSAStack->getCurrentDirective(), &CaptureRegion, &HelperValStmt)) 17554 return nullptr; 17555 17556 return new (Context) OMPPriorityClause(ValExpr, HelperValStmt, CaptureRegion, 17557 StartLoc, LParenLoc, EndLoc); 17558 } 17559 17560 OMPClause *Sema::ActOnOpenMPGrainsizeClause(Expr *Grainsize, 17561 SourceLocation StartLoc, 17562 SourceLocation LParenLoc, 17563 SourceLocation EndLoc) { 17564 Expr *ValExpr = Grainsize; 17565 Stmt *HelperValStmt = nullptr; 17566 OpenMPDirectiveKind CaptureRegion = OMPD_unknown; 17567 17568 // OpenMP [2.9.2, taskloop Constrcut] 17569 // The parameter of the grainsize clause must be a positive integer 17570 // expression. 17571 if (!isNonNegativeIntegerValue( 17572 ValExpr, *this, OMPC_grainsize, 17573 /*StrictlyPositive=*/true, /*BuildCapture=*/true, 17574 DSAStack->getCurrentDirective(), &CaptureRegion, &HelperValStmt)) 17575 return nullptr; 17576 17577 return new (Context) OMPGrainsizeClause(ValExpr, HelperValStmt, CaptureRegion, 17578 StartLoc, LParenLoc, EndLoc); 17579 } 17580 17581 OMPClause *Sema::ActOnOpenMPNumTasksClause(Expr *NumTasks, 17582 SourceLocation StartLoc, 17583 SourceLocation LParenLoc, 17584 SourceLocation EndLoc) { 17585 Expr *ValExpr = NumTasks; 17586 Stmt *HelperValStmt = nullptr; 17587 OpenMPDirectiveKind CaptureRegion = OMPD_unknown; 17588 17589 // OpenMP [2.9.2, taskloop Constrcut] 17590 // The parameter of the num_tasks clause must be a positive integer 17591 // expression. 17592 if (!isNonNegativeIntegerValue( 17593 ValExpr, *this, OMPC_num_tasks, 17594 /*StrictlyPositive=*/true, /*BuildCapture=*/true, 17595 DSAStack->getCurrentDirective(), &CaptureRegion, &HelperValStmt)) 17596 return nullptr; 17597 17598 return new (Context) OMPNumTasksClause(ValExpr, HelperValStmt, CaptureRegion, 17599 StartLoc, LParenLoc, EndLoc); 17600 } 17601 17602 OMPClause *Sema::ActOnOpenMPHintClause(Expr *Hint, SourceLocation StartLoc, 17603 SourceLocation LParenLoc, 17604 SourceLocation EndLoc) { 17605 // OpenMP [2.13.2, critical construct, Description] 17606 // ... where hint-expression is an integer constant expression that evaluates 17607 // to a valid lock hint. 17608 ExprResult HintExpr = VerifyPositiveIntegerConstantInClause(Hint, OMPC_hint); 17609 if (HintExpr.isInvalid()) 17610 return nullptr; 17611 return new (Context) 17612 OMPHintClause(HintExpr.get(), StartLoc, LParenLoc, EndLoc); 17613 } 17614 17615 /// Tries to find omp_event_handle_t type. 17616 static bool findOMPEventHandleT(Sema &S, SourceLocation Loc, 17617 DSAStackTy *Stack) { 17618 QualType OMPEventHandleT = Stack->getOMPEventHandleT(); 17619 if (!OMPEventHandleT.isNull()) 17620 return true; 17621 IdentifierInfo *II = &S.PP.getIdentifierTable().get("omp_event_handle_t"); 17622 ParsedType PT = S.getTypeName(*II, Loc, S.getCurScope()); 17623 if (!PT.getAsOpaquePtr() || PT.get().isNull()) { 17624 S.Diag(Loc, diag::err_omp_implied_type_not_found) << "omp_event_handle_t"; 17625 return false; 17626 } 17627 Stack->setOMPEventHandleT(PT.get()); 17628 return true; 17629 } 17630 17631 OMPClause *Sema::ActOnOpenMPDetachClause(Expr *Evt, SourceLocation StartLoc, 17632 SourceLocation LParenLoc, 17633 SourceLocation EndLoc) { 17634 if (!Evt->isValueDependent() && !Evt->isTypeDependent() && 17635 !Evt->isInstantiationDependent() && 17636 !Evt->containsUnexpandedParameterPack()) { 17637 if (!findOMPEventHandleT(*this, Evt->getExprLoc(), DSAStack)) 17638 return nullptr; 17639 // OpenMP 5.0, 2.10.1 task Construct. 17640 // event-handle is a variable of the omp_event_handle_t type. 17641 auto *Ref = dyn_cast<DeclRefExpr>(Evt->IgnoreParenImpCasts()); 17642 if (!Ref) { 17643 Diag(Evt->getExprLoc(), diag::err_omp_event_var_expected) 17644 << 0 << Evt->getSourceRange(); 17645 return nullptr; 17646 } 17647 auto *VD = dyn_cast_or_null<VarDecl>(Ref->getDecl()); 17648 if (!VD) { 17649 Diag(Evt->getExprLoc(), diag::err_omp_event_var_expected) 17650 << 0 << Evt->getSourceRange(); 17651 return nullptr; 17652 } 17653 if (!Context.hasSameUnqualifiedType(DSAStack->getOMPEventHandleT(), 17654 VD->getType()) || 17655 VD->getType().isConstant(Context)) { 17656 Diag(Evt->getExprLoc(), diag::err_omp_event_var_expected) 17657 << 1 << VD->getType() << Evt->getSourceRange(); 17658 return nullptr; 17659 } 17660 // OpenMP 5.0, 2.10.1 task Construct 17661 // [detach clause]... The event-handle will be considered as if it was 17662 // specified on a firstprivate clause. 17663 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(VD, /*FromParent=*/false); 17664 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_firstprivate && 17665 DVar.RefExpr) { 17666 Diag(Evt->getExprLoc(), diag::err_omp_wrong_dsa) 17667 << getOpenMPClauseName(DVar.CKind) 17668 << getOpenMPClauseName(OMPC_firstprivate); 17669 reportOriginalDsa(*this, DSAStack, VD, DVar); 17670 return nullptr; 17671 } 17672 } 17673 17674 return new (Context) OMPDetachClause(Evt, StartLoc, LParenLoc, EndLoc); 17675 } 17676 17677 OMPClause *Sema::ActOnOpenMPDistScheduleClause( 17678 OpenMPDistScheduleClauseKind Kind, Expr *ChunkSize, SourceLocation StartLoc, 17679 SourceLocation LParenLoc, SourceLocation KindLoc, SourceLocation CommaLoc, 17680 SourceLocation EndLoc) { 17681 if (Kind == OMPC_DIST_SCHEDULE_unknown) { 17682 std::string Values; 17683 Values += "'"; 17684 Values += getOpenMPSimpleClauseTypeName(OMPC_dist_schedule, 0); 17685 Values += "'"; 17686 Diag(KindLoc, diag::err_omp_unexpected_clause_value) 17687 << Values << getOpenMPClauseName(OMPC_dist_schedule); 17688 return nullptr; 17689 } 17690 Expr *ValExpr = ChunkSize; 17691 Stmt *HelperValStmt = nullptr; 17692 if (ChunkSize) { 17693 if (!ChunkSize->isValueDependent() && !ChunkSize->isTypeDependent() && 17694 !ChunkSize->isInstantiationDependent() && 17695 !ChunkSize->containsUnexpandedParameterPack()) { 17696 SourceLocation ChunkSizeLoc = ChunkSize->getBeginLoc(); 17697 ExprResult Val = 17698 PerformOpenMPImplicitIntegerConversion(ChunkSizeLoc, ChunkSize); 17699 if (Val.isInvalid()) 17700 return nullptr; 17701 17702 ValExpr = Val.get(); 17703 17704 // OpenMP [2.7.1, Restrictions] 17705 // chunk_size must be a loop invariant integer expression with a positive 17706 // value. 17707 llvm::APSInt Result; 17708 if (ValExpr->isIntegerConstantExpr(Result, Context)) { 17709 if (Result.isSigned() && !Result.isStrictlyPositive()) { 17710 Diag(ChunkSizeLoc, diag::err_omp_negative_expression_in_clause) 17711 << "dist_schedule" << ChunkSize->getSourceRange(); 17712 return nullptr; 17713 } 17714 } else if (getOpenMPCaptureRegionForClause( 17715 DSAStack->getCurrentDirective(), OMPC_dist_schedule, 17716 LangOpts.OpenMP) != OMPD_unknown && 17717 !CurContext->isDependentContext()) { 17718 ValExpr = MakeFullExpr(ValExpr).get(); 17719 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 17720 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 17721 HelperValStmt = buildPreInits(Context, Captures); 17722 } 17723 } 17724 } 17725 17726 return new (Context) 17727 OMPDistScheduleClause(StartLoc, LParenLoc, KindLoc, CommaLoc, EndLoc, 17728 Kind, ValExpr, HelperValStmt); 17729 } 17730 17731 OMPClause *Sema::ActOnOpenMPDefaultmapClause( 17732 OpenMPDefaultmapClauseModifier M, OpenMPDefaultmapClauseKind Kind, 17733 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation MLoc, 17734 SourceLocation KindLoc, SourceLocation EndLoc) { 17735 if (getLangOpts().OpenMP < 50) { 17736 if (M != OMPC_DEFAULTMAP_MODIFIER_tofrom || 17737 Kind != OMPC_DEFAULTMAP_scalar) { 17738 std::string Value; 17739 SourceLocation Loc; 17740 Value += "'"; 17741 if (M != OMPC_DEFAULTMAP_MODIFIER_tofrom) { 17742 Value += getOpenMPSimpleClauseTypeName(OMPC_defaultmap, 17743 OMPC_DEFAULTMAP_MODIFIER_tofrom); 17744 Loc = MLoc; 17745 } else { 17746 Value += getOpenMPSimpleClauseTypeName(OMPC_defaultmap, 17747 OMPC_DEFAULTMAP_scalar); 17748 Loc = KindLoc; 17749 } 17750 Value += "'"; 17751 Diag(Loc, diag::err_omp_unexpected_clause_value) 17752 << Value << getOpenMPClauseName(OMPC_defaultmap); 17753 return nullptr; 17754 } 17755 } else { 17756 bool isDefaultmapModifier = (M != OMPC_DEFAULTMAP_MODIFIER_unknown); 17757 bool isDefaultmapKind = (Kind != OMPC_DEFAULTMAP_unknown); 17758 if (!isDefaultmapKind || !isDefaultmapModifier) { 17759 std::string ModifierValue = "'alloc', 'from', 'to', 'tofrom', " 17760 "'firstprivate', 'none', 'default'"; 17761 std::string KindValue = "'scalar', 'aggregate', 'pointer'"; 17762 if (!isDefaultmapKind && isDefaultmapModifier) { 17763 Diag(KindLoc, diag::err_omp_unexpected_clause_value) 17764 << KindValue << getOpenMPClauseName(OMPC_defaultmap); 17765 } else if (isDefaultmapKind && !isDefaultmapModifier) { 17766 Diag(MLoc, diag::err_omp_unexpected_clause_value) 17767 << ModifierValue << getOpenMPClauseName(OMPC_defaultmap); 17768 } else { 17769 Diag(MLoc, diag::err_omp_unexpected_clause_value) 17770 << ModifierValue << getOpenMPClauseName(OMPC_defaultmap); 17771 Diag(KindLoc, diag::err_omp_unexpected_clause_value) 17772 << KindValue << getOpenMPClauseName(OMPC_defaultmap); 17773 } 17774 return nullptr; 17775 } 17776 17777 // OpenMP [5.0, 2.12.5, Restrictions, p. 174] 17778 // At most one defaultmap clause for each category can appear on the 17779 // directive. 17780 if (DSAStack->checkDefaultmapCategory(Kind)) { 17781 Diag(StartLoc, diag::err_omp_one_defaultmap_each_category); 17782 return nullptr; 17783 } 17784 } 17785 DSAStack->setDefaultDMAAttr(M, Kind, StartLoc); 17786 17787 return new (Context) 17788 OMPDefaultmapClause(StartLoc, LParenLoc, MLoc, KindLoc, EndLoc, Kind, M); 17789 } 17790 17791 bool Sema::ActOnStartOpenMPDeclareTargetDirective(SourceLocation Loc) { 17792 DeclContext *CurLexicalContext = getCurLexicalContext(); 17793 if (!CurLexicalContext->isFileContext() && 17794 !CurLexicalContext->isExternCContext() && 17795 !CurLexicalContext->isExternCXXContext() && 17796 !isa<CXXRecordDecl>(CurLexicalContext) && 17797 !isa<ClassTemplateDecl>(CurLexicalContext) && 17798 !isa<ClassTemplatePartialSpecializationDecl>(CurLexicalContext) && 17799 !isa<ClassTemplateSpecializationDecl>(CurLexicalContext)) { 17800 Diag(Loc, diag::err_omp_region_not_file_context); 17801 return false; 17802 } 17803 ++DeclareTargetNestingLevel; 17804 return true; 17805 } 17806 17807 void Sema::ActOnFinishOpenMPDeclareTargetDirective() { 17808 assert(DeclareTargetNestingLevel > 0 && 17809 "Unexpected ActOnFinishOpenMPDeclareTargetDirective"); 17810 --DeclareTargetNestingLevel; 17811 } 17812 17813 NamedDecl * 17814 Sema::lookupOpenMPDeclareTargetName(Scope *CurScope, CXXScopeSpec &ScopeSpec, 17815 const DeclarationNameInfo &Id, 17816 NamedDeclSetType &SameDirectiveDecls) { 17817 LookupResult Lookup(*this, Id, LookupOrdinaryName); 17818 LookupParsedName(Lookup, CurScope, &ScopeSpec, true); 17819 17820 if (Lookup.isAmbiguous()) 17821 return nullptr; 17822 Lookup.suppressDiagnostics(); 17823 17824 if (!Lookup.isSingleResult()) { 17825 VarOrFuncDeclFilterCCC CCC(*this); 17826 if (TypoCorrection Corrected = 17827 CorrectTypo(Id, LookupOrdinaryName, CurScope, nullptr, CCC, 17828 CTK_ErrorRecovery)) { 17829 diagnoseTypo(Corrected, PDiag(diag::err_undeclared_var_use_suggest) 17830 << Id.getName()); 17831 checkDeclIsAllowedInOpenMPTarget(nullptr, Corrected.getCorrectionDecl()); 17832 return nullptr; 17833 } 17834 17835 Diag(Id.getLoc(), diag::err_undeclared_var_use) << Id.getName(); 17836 return nullptr; 17837 } 17838 17839 NamedDecl *ND = Lookup.getAsSingle<NamedDecl>(); 17840 if (!isa<VarDecl>(ND) && !isa<FunctionDecl>(ND) && 17841 !isa<FunctionTemplateDecl>(ND)) { 17842 Diag(Id.getLoc(), diag::err_omp_invalid_target_decl) << Id.getName(); 17843 return nullptr; 17844 } 17845 if (!SameDirectiveDecls.insert(cast<NamedDecl>(ND->getCanonicalDecl()))) 17846 Diag(Id.getLoc(), diag::err_omp_declare_target_multiple) << Id.getName(); 17847 return ND; 17848 } 17849 17850 void Sema::ActOnOpenMPDeclareTargetName( 17851 NamedDecl *ND, SourceLocation Loc, OMPDeclareTargetDeclAttr::MapTypeTy MT, 17852 OMPDeclareTargetDeclAttr::DevTypeTy DT) { 17853 assert((isa<VarDecl>(ND) || isa<FunctionDecl>(ND) || 17854 isa<FunctionTemplateDecl>(ND)) && 17855 "Expected variable, function or function template."); 17856 17857 // Diagnose marking after use as it may lead to incorrect diagnosis and 17858 // codegen. 17859 if (LangOpts.OpenMP >= 50 && 17860 (ND->isUsed(/*CheckUsedAttr=*/false) || ND->isReferenced())) 17861 Diag(Loc, diag::warn_omp_declare_target_after_first_use); 17862 17863 Optional<OMPDeclareTargetDeclAttr::DevTypeTy> DevTy = 17864 OMPDeclareTargetDeclAttr::getDeviceType(cast<ValueDecl>(ND)); 17865 if (DevTy.hasValue() && *DevTy != DT) { 17866 Diag(Loc, diag::err_omp_device_type_mismatch) 17867 << OMPDeclareTargetDeclAttr::ConvertDevTypeTyToStr(DT) 17868 << OMPDeclareTargetDeclAttr::ConvertDevTypeTyToStr(*DevTy); 17869 return; 17870 } 17871 Optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res = 17872 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(cast<ValueDecl>(ND)); 17873 if (!Res) { 17874 auto *A = OMPDeclareTargetDeclAttr::CreateImplicit(Context, MT, DT, 17875 SourceRange(Loc, Loc)); 17876 ND->addAttr(A); 17877 if (ASTMutationListener *ML = Context.getASTMutationListener()) 17878 ML->DeclarationMarkedOpenMPDeclareTarget(ND, A); 17879 checkDeclIsAllowedInOpenMPTarget(nullptr, ND, Loc); 17880 } else if (*Res != MT) { 17881 Diag(Loc, diag::err_omp_declare_target_to_and_link) << ND; 17882 } 17883 } 17884 17885 static void checkDeclInTargetContext(SourceLocation SL, SourceRange SR, 17886 Sema &SemaRef, Decl *D) { 17887 if (!D || !isa<VarDecl>(D)) 17888 return; 17889 auto *VD = cast<VarDecl>(D); 17890 Optional<OMPDeclareTargetDeclAttr::MapTypeTy> MapTy = 17891 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD); 17892 if (SemaRef.LangOpts.OpenMP >= 50 && 17893 (SemaRef.getCurLambda(/*IgnoreNonLambdaCapturingScope=*/true) || 17894 SemaRef.getCurBlock() || SemaRef.getCurCapturedRegion()) && 17895 VD->hasGlobalStorage()) { 17896 llvm::Optional<OMPDeclareTargetDeclAttr::MapTypeTy> MapTy = 17897 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD); 17898 if (!MapTy || *MapTy != OMPDeclareTargetDeclAttr::MT_To) { 17899 // OpenMP 5.0, 2.12.7 declare target Directive, Restrictions 17900 // If a lambda declaration and definition appears between a 17901 // declare target directive and the matching end declare target 17902 // directive, all variables that are captured by the lambda 17903 // expression must also appear in a to clause. 17904 SemaRef.Diag(VD->getLocation(), 17905 diag::err_omp_lambda_capture_in_declare_target_not_to); 17906 SemaRef.Diag(SL, diag::note_var_explicitly_captured_here) 17907 << VD << 0 << SR; 17908 return; 17909 } 17910 } 17911 if (MapTy.hasValue()) 17912 return; 17913 SemaRef.Diag(VD->getLocation(), diag::warn_omp_not_in_target_context); 17914 SemaRef.Diag(SL, diag::note_used_here) << SR; 17915 } 17916 17917 static bool checkValueDeclInTarget(SourceLocation SL, SourceRange SR, 17918 Sema &SemaRef, DSAStackTy *Stack, 17919 ValueDecl *VD) { 17920 return OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD) || 17921 checkTypeMappable(SL, SR, SemaRef, Stack, VD->getType(), 17922 /*FullCheck=*/false); 17923 } 17924 17925 void Sema::checkDeclIsAllowedInOpenMPTarget(Expr *E, Decl *D, 17926 SourceLocation IdLoc) { 17927 if (!D || D->isInvalidDecl()) 17928 return; 17929 SourceRange SR = E ? E->getSourceRange() : D->getSourceRange(); 17930 SourceLocation SL = E ? E->getBeginLoc() : D->getLocation(); 17931 if (auto *VD = dyn_cast<VarDecl>(D)) { 17932 // Only global variables can be marked as declare target. 17933 if (!VD->isFileVarDecl() && !VD->isStaticLocal() && 17934 !VD->isStaticDataMember()) 17935 return; 17936 // 2.10.6: threadprivate variable cannot appear in a declare target 17937 // directive. 17938 if (DSAStack->isThreadPrivate(VD)) { 17939 Diag(SL, diag::err_omp_threadprivate_in_target); 17940 reportOriginalDsa(*this, DSAStack, VD, DSAStack->getTopDSA(VD, false)); 17941 return; 17942 } 17943 } 17944 if (const auto *FTD = dyn_cast<FunctionTemplateDecl>(D)) 17945 D = FTD->getTemplatedDecl(); 17946 if (auto *FD = dyn_cast<FunctionDecl>(D)) { 17947 llvm::Optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res = 17948 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(FD); 17949 if (IdLoc.isValid() && Res && *Res == OMPDeclareTargetDeclAttr::MT_Link) { 17950 Diag(IdLoc, diag::err_omp_function_in_link_clause); 17951 Diag(FD->getLocation(), diag::note_defined_here) << FD; 17952 return; 17953 } 17954 } 17955 if (auto *VD = dyn_cast<ValueDecl>(D)) { 17956 // Problem if any with var declared with incomplete type will be reported 17957 // as normal, so no need to check it here. 17958 if ((E || !VD->getType()->isIncompleteType()) && 17959 !checkValueDeclInTarget(SL, SR, *this, DSAStack, VD)) 17960 return; 17961 if (!E && !OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD)) { 17962 // Checking declaration inside declare target region. 17963 if (isa<VarDecl>(D) || isa<FunctionDecl>(D) || 17964 isa<FunctionTemplateDecl>(D)) { 17965 auto *A = OMPDeclareTargetDeclAttr::CreateImplicit( 17966 Context, OMPDeclareTargetDeclAttr::MT_To, 17967 OMPDeclareTargetDeclAttr::DT_Any, SourceRange(IdLoc, IdLoc)); 17968 D->addAttr(A); 17969 if (ASTMutationListener *ML = Context.getASTMutationListener()) 17970 ML->DeclarationMarkedOpenMPDeclareTarget(D, A); 17971 } 17972 return; 17973 } 17974 } 17975 if (!E) 17976 return; 17977 checkDeclInTargetContext(E->getExprLoc(), E->getSourceRange(), *this, D); 17978 } 17979 17980 OMPClause *Sema::ActOnOpenMPToClause(ArrayRef<Expr *> VarList, 17981 CXXScopeSpec &MapperIdScopeSpec, 17982 DeclarationNameInfo &MapperId, 17983 const OMPVarListLocTy &Locs, 17984 ArrayRef<Expr *> UnresolvedMappers) { 17985 MappableVarListInfo MVLI(VarList); 17986 checkMappableExpressionList(*this, DSAStack, OMPC_to, MVLI, Locs.StartLoc, 17987 MapperIdScopeSpec, MapperId, UnresolvedMappers); 17988 if (MVLI.ProcessedVarList.empty()) 17989 return nullptr; 17990 17991 return OMPToClause::Create( 17992 Context, Locs, MVLI.ProcessedVarList, MVLI.VarBaseDeclarations, 17993 MVLI.VarComponents, MVLI.UDMapperList, 17994 MapperIdScopeSpec.getWithLocInContext(Context), MapperId); 17995 } 17996 17997 OMPClause *Sema::ActOnOpenMPFromClause(ArrayRef<Expr *> VarList, 17998 CXXScopeSpec &MapperIdScopeSpec, 17999 DeclarationNameInfo &MapperId, 18000 const OMPVarListLocTy &Locs, 18001 ArrayRef<Expr *> UnresolvedMappers) { 18002 MappableVarListInfo MVLI(VarList); 18003 checkMappableExpressionList(*this, DSAStack, OMPC_from, MVLI, Locs.StartLoc, 18004 MapperIdScopeSpec, MapperId, UnresolvedMappers); 18005 if (MVLI.ProcessedVarList.empty()) 18006 return nullptr; 18007 18008 return OMPFromClause::Create( 18009 Context, Locs, MVLI.ProcessedVarList, MVLI.VarBaseDeclarations, 18010 MVLI.VarComponents, MVLI.UDMapperList, 18011 MapperIdScopeSpec.getWithLocInContext(Context), MapperId); 18012 } 18013 18014 OMPClause *Sema::ActOnOpenMPUseDevicePtrClause(ArrayRef<Expr *> VarList, 18015 const OMPVarListLocTy &Locs) { 18016 MappableVarListInfo MVLI(VarList); 18017 SmallVector<Expr *, 8> PrivateCopies; 18018 SmallVector<Expr *, 8> Inits; 18019 18020 for (Expr *RefExpr : VarList) { 18021 assert(RefExpr && "NULL expr in OpenMP use_device_ptr clause."); 18022 SourceLocation ELoc; 18023 SourceRange ERange; 18024 Expr *SimpleRefExpr = RefExpr; 18025 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 18026 if (Res.second) { 18027 // It will be analyzed later. 18028 MVLI.ProcessedVarList.push_back(RefExpr); 18029 PrivateCopies.push_back(nullptr); 18030 Inits.push_back(nullptr); 18031 } 18032 ValueDecl *D = Res.first; 18033 if (!D) 18034 continue; 18035 18036 QualType Type = D->getType(); 18037 Type = Type.getNonReferenceType().getUnqualifiedType(); 18038 18039 auto *VD = dyn_cast<VarDecl>(D); 18040 18041 // Item should be a pointer or reference to pointer. 18042 if (!Type->isPointerType()) { 18043 Diag(ELoc, diag::err_omp_usedeviceptr_not_a_pointer) 18044 << 0 << RefExpr->getSourceRange(); 18045 continue; 18046 } 18047 18048 // Build the private variable and the expression that refers to it. 18049 auto VDPrivate = 18050 buildVarDecl(*this, ELoc, Type, D->getName(), 18051 D->hasAttrs() ? &D->getAttrs() : nullptr, 18052 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr); 18053 if (VDPrivate->isInvalidDecl()) 18054 continue; 18055 18056 CurContext->addDecl(VDPrivate); 18057 DeclRefExpr *VDPrivateRefExpr = buildDeclRefExpr( 18058 *this, VDPrivate, RefExpr->getType().getUnqualifiedType(), ELoc); 18059 18060 // Add temporary variable to initialize the private copy of the pointer. 18061 VarDecl *VDInit = 18062 buildVarDecl(*this, RefExpr->getExprLoc(), Type, ".devptr.temp"); 18063 DeclRefExpr *VDInitRefExpr = buildDeclRefExpr( 18064 *this, VDInit, RefExpr->getType(), RefExpr->getExprLoc()); 18065 AddInitializerToDecl(VDPrivate, 18066 DefaultLvalueConversion(VDInitRefExpr).get(), 18067 /*DirectInit=*/false); 18068 18069 // If required, build a capture to implement the privatization initialized 18070 // with the current list item value. 18071 DeclRefExpr *Ref = nullptr; 18072 if (!VD) 18073 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true); 18074 MVLI.ProcessedVarList.push_back(VD ? RefExpr->IgnoreParens() : Ref); 18075 PrivateCopies.push_back(VDPrivateRefExpr); 18076 Inits.push_back(VDInitRefExpr); 18077 18078 // We need to add a data sharing attribute for this variable to make sure it 18079 // is correctly captured. A variable that shows up in a use_device_ptr has 18080 // similar properties of a first private variable. 18081 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_firstprivate, Ref); 18082 18083 // Create a mappable component for the list item. List items in this clause 18084 // only need a component. 18085 MVLI.VarBaseDeclarations.push_back(D); 18086 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1); 18087 MVLI.VarComponents.back().push_back( 18088 OMPClauseMappableExprCommon::MappableComponent(SimpleRefExpr, D)); 18089 } 18090 18091 if (MVLI.ProcessedVarList.empty()) 18092 return nullptr; 18093 18094 return OMPUseDevicePtrClause::Create( 18095 Context, Locs, MVLI.ProcessedVarList, PrivateCopies, Inits, 18096 MVLI.VarBaseDeclarations, MVLI.VarComponents); 18097 } 18098 18099 OMPClause *Sema::ActOnOpenMPIsDevicePtrClause(ArrayRef<Expr *> VarList, 18100 const OMPVarListLocTy &Locs) { 18101 MappableVarListInfo MVLI(VarList); 18102 for (Expr *RefExpr : VarList) { 18103 assert(RefExpr && "NULL expr in OpenMP is_device_ptr clause."); 18104 SourceLocation ELoc; 18105 SourceRange ERange; 18106 Expr *SimpleRefExpr = RefExpr; 18107 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 18108 if (Res.second) { 18109 // It will be analyzed later. 18110 MVLI.ProcessedVarList.push_back(RefExpr); 18111 } 18112 ValueDecl *D = Res.first; 18113 if (!D) 18114 continue; 18115 18116 QualType Type = D->getType(); 18117 // item should be a pointer or array or reference to pointer or array 18118 if (!Type.getNonReferenceType()->isPointerType() && 18119 !Type.getNonReferenceType()->isArrayType()) { 18120 Diag(ELoc, diag::err_omp_argument_type_isdeviceptr) 18121 << 0 << RefExpr->getSourceRange(); 18122 continue; 18123 } 18124 18125 // Check if the declaration in the clause does not show up in any data 18126 // sharing attribute. 18127 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false); 18128 if (isOpenMPPrivate(DVar.CKind)) { 18129 Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa) 18130 << getOpenMPClauseName(DVar.CKind) 18131 << getOpenMPClauseName(OMPC_is_device_ptr) 18132 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 18133 reportOriginalDsa(*this, DSAStack, D, DVar); 18134 continue; 18135 } 18136 18137 const Expr *ConflictExpr; 18138 if (DSAStack->checkMappableExprComponentListsForDecl( 18139 D, /*CurrentRegionOnly=*/true, 18140 [&ConflictExpr]( 18141 OMPClauseMappableExprCommon::MappableExprComponentListRef R, 18142 OpenMPClauseKind) -> bool { 18143 ConflictExpr = R.front().getAssociatedExpression(); 18144 return true; 18145 })) { 18146 Diag(ELoc, diag::err_omp_map_shared_storage) << RefExpr->getSourceRange(); 18147 Diag(ConflictExpr->getExprLoc(), diag::note_used_here) 18148 << ConflictExpr->getSourceRange(); 18149 continue; 18150 } 18151 18152 // Store the components in the stack so that they can be used to check 18153 // against other clauses later on. 18154 OMPClauseMappableExprCommon::MappableComponent MC(SimpleRefExpr, D); 18155 DSAStack->addMappableExpressionComponents( 18156 D, MC, /*WhereFoundClauseKind=*/OMPC_is_device_ptr); 18157 18158 // Record the expression we've just processed. 18159 MVLI.ProcessedVarList.push_back(SimpleRefExpr); 18160 18161 // Create a mappable component for the list item. List items in this clause 18162 // only need a component. We use a null declaration to signal fields in 18163 // 'this'. 18164 assert((isa<DeclRefExpr>(SimpleRefExpr) || 18165 isa<CXXThisExpr>(cast<MemberExpr>(SimpleRefExpr)->getBase())) && 18166 "Unexpected device pointer expression!"); 18167 MVLI.VarBaseDeclarations.push_back( 18168 isa<DeclRefExpr>(SimpleRefExpr) ? D : nullptr); 18169 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1); 18170 MVLI.VarComponents.back().push_back(MC); 18171 } 18172 18173 if (MVLI.ProcessedVarList.empty()) 18174 return nullptr; 18175 18176 return OMPIsDevicePtrClause::Create(Context, Locs, MVLI.ProcessedVarList, 18177 MVLI.VarBaseDeclarations, 18178 MVLI.VarComponents); 18179 } 18180 18181 OMPClause *Sema::ActOnOpenMPAllocateClause( 18182 Expr *Allocator, ArrayRef<Expr *> VarList, SourceLocation StartLoc, 18183 SourceLocation ColonLoc, SourceLocation LParenLoc, SourceLocation EndLoc) { 18184 if (Allocator) { 18185 // OpenMP [2.11.4 allocate Clause, Description] 18186 // allocator is an expression of omp_allocator_handle_t type. 18187 if (!findOMPAllocatorHandleT(*this, Allocator->getExprLoc(), DSAStack)) 18188 return nullptr; 18189 18190 ExprResult AllocatorRes = DefaultLvalueConversion(Allocator); 18191 if (AllocatorRes.isInvalid()) 18192 return nullptr; 18193 AllocatorRes = PerformImplicitConversion(AllocatorRes.get(), 18194 DSAStack->getOMPAllocatorHandleT(), 18195 Sema::AA_Initializing, 18196 /*AllowExplicit=*/true); 18197 if (AllocatorRes.isInvalid()) 18198 return nullptr; 18199 Allocator = AllocatorRes.get(); 18200 } else { 18201 // OpenMP 5.0, 2.11.4 allocate Clause, Restrictions. 18202 // allocate clauses that appear on a target construct or on constructs in a 18203 // target region must specify an allocator expression unless a requires 18204 // directive with the dynamic_allocators clause is present in the same 18205 // compilation unit. 18206 if (LangOpts.OpenMPIsDevice && 18207 !DSAStack->hasRequiresDeclWithClause<OMPDynamicAllocatorsClause>()) 18208 targetDiag(StartLoc, diag::err_expected_allocator_expression); 18209 } 18210 // Analyze and build list of variables. 18211 SmallVector<Expr *, 8> Vars; 18212 for (Expr *RefExpr : VarList) { 18213 assert(RefExpr && "NULL expr in OpenMP private clause."); 18214 SourceLocation ELoc; 18215 SourceRange ERange; 18216 Expr *SimpleRefExpr = RefExpr; 18217 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 18218 if (Res.second) { 18219 // It will be analyzed later. 18220 Vars.push_back(RefExpr); 18221 } 18222 ValueDecl *D = Res.first; 18223 if (!D) 18224 continue; 18225 18226 auto *VD = dyn_cast<VarDecl>(D); 18227 DeclRefExpr *Ref = nullptr; 18228 if (!VD && !CurContext->isDependentContext()) 18229 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false); 18230 Vars.push_back((VD || CurContext->isDependentContext()) 18231 ? RefExpr->IgnoreParens() 18232 : Ref); 18233 } 18234 18235 if (Vars.empty()) 18236 return nullptr; 18237 18238 if (Allocator) 18239 DSAStack->addInnerAllocatorExpr(Allocator); 18240 return OMPAllocateClause::Create(Context, StartLoc, LParenLoc, Allocator, 18241 ColonLoc, EndLoc, Vars); 18242 } 18243 18244 OMPClause *Sema::ActOnOpenMPNontemporalClause(ArrayRef<Expr *> VarList, 18245 SourceLocation StartLoc, 18246 SourceLocation LParenLoc, 18247 SourceLocation EndLoc) { 18248 SmallVector<Expr *, 8> Vars; 18249 for (Expr *RefExpr : VarList) { 18250 assert(RefExpr && "NULL expr in OpenMP nontemporal clause."); 18251 SourceLocation ELoc; 18252 SourceRange ERange; 18253 Expr *SimpleRefExpr = RefExpr; 18254 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 18255 if (Res.second) 18256 // It will be analyzed later. 18257 Vars.push_back(RefExpr); 18258 ValueDecl *D = Res.first; 18259 if (!D) 18260 continue; 18261 18262 // OpenMP 5.0, 2.9.3.1 simd Construct, Restrictions. 18263 // A list-item cannot appear in more than one nontemporal clause. 18264 if (const Expr *PrevRef = 18265 DSAStack->addUniqueNontemporal(D, SimpleRefExpr)) { 18266 Diag(ELoc, diag::err_omp_used_in_clause_twice) 18267 << 0 << getOpenMPClauseName(OMPC_nontemporal) << ERange; 18268 Diag(PrevRef->getExprLoc(), diag::note_omp_explicit_dsa) 18269 << getOpenMPClauseName(OMPC_nontemporal); 18270 continue; 18271 } 18272 18273 Vars.push_back(RefExpr); 18274 } 18275 18276 if (Vars.empty()) 18277 return nullptr; 18278 18279 return OMPNontemporalClause::Create(Context, StartLoc, LParenLoc, EndLoc, 18280 Vars); 18281 } 18282 18283 OMPClause *Sema::ActOnOpenMPInclusiveClause(ArrayRef<Expr *> VarList, 18284 SourceLocation StartLoc, 18285 SourceLocation LParenLoc, 18286 SourceLocation EndLoc) { 18287 SmallVector<Expr *, 8> Vars; 18288 for (Expr *RefExpr : VarList) { 18289 assert(RefExpr && "NULL expr in OpenMP nontemporal clause."); 18290 SourceLocation ELoc; 18291 SourceRange ERange; 18292 Expr *SimpleRefExpr = RefExpr; 18293 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange, 18294 /*AllowArraySection=*/true); 18295 if (Res.second) 18296 // It will be analyzed later. 18297 Vars.push_back(RefExpr); 18298 ValueDecl *D = Res.first; 18299 if (!D) 18300 continue; 18301 18302 const DSAStackTy::DSAVarData DVar = 18303 DSAStack->getTopDSA(D, /*FromParent=*/true); 18304 // OpenMP 5.0, 2.9.6, scan Directive, Restrictions. 18305 // A list item that appears in the inclusive or exclusive clause must appear 18306 // in a reduction clause with the inscan modifier on the enclosing 18307 // worksharing-loop, worksharing-loop SIMD, or simd construct. 18308 if (DVar.CKind != OMPC_reduction || 18309 DVar.Modifier != OMPC_REDUCTION_inscan) 18310 Diag(ELoc, diag::err_omp_inclusive_exclusive_not_reduction) 18311 << RefExpr->getSourceRange(); 18312 18313 if (DSAStack->getParentDirective() != OMPD_unknown) 18314 DSAStack->markDeclAsUsedInScanDirective(D); 18315 Vars.push_back(RefExpr); 18316 } 18317 18318 if (Vars.empty()) 18319 return nullptr; 18320 18321 return OMPInclusiveClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars); 18322 } 18323 18324 OMPClause *Sema::ActOnOpenMPExclusiveClause(ArrayRef<Expr *> VarList, 18325 SourceLocation StartLoc, 18326 SourceLocation LParenLoc, 18327 SourceLocation EndLoc) { 18328 SmallVector<Expr *, 8> Vars; 18329 for (Expr *RefExpr : VarList) { 18330 assert(RefExpr && "NULL expr in OpenMP nontemporal clause."); 18331 SourceLocation ELoc; 18332 SourceRange ERange; 18333 Expr *SimpleRefExpr = RefExpr; 18334 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange, 18335 /*AllowArraySection=*/true); 18336 if (Res.second) 18337 // It will be analyzed later. 18338 Vars.push_back(RefExpr); 18339 ValueDecl *D = Res.first; 18340 if (!D) 18341 continue; 18342 18343 OpenMPDirectiveKind ParentDirective = DSAStack->getParentDirective(); 18344 DSAStackTy::DSAVarData DVar; 18345 if (ParentDirective != OMPD_unknown) 18346 DVar = DSAStack->getTopDSA(D, /*FromParent=*/true); 18347 // OpenMP 5.0, 2.9.6, scan Directive, Restrictions. 18348 // A list item that appears in the inclusive or exclusive clause must appear 18349 // in a reduction clause with the inscan modifier on the enclosing 18350 // worksharing-loop, worksharing-loop SIMD, or simd construct. 18351 if (ParentDirective == OMPD_unknown || DVar.CKind != OMPC_reduction || 18352 DVar.Modifier != OMPC_REDUCTION_inscan) { 18353 Diag(ELoc, diag::err_omp_inclusive_exclusive_not_reduction) 18354 << RefExpr->getSourceRange(); 18355 } else { 18356 DSAStack->markDeclAsUsedInScanDirective(D); 18357 } 18358 Vars.push_back(RefExpr); 18359 } 18360 18361 if (Vars.empty()) 18362 return nullptr; 18363 18364 return OMPExclusiveClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars); 18365 } 18366