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, 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(Sema &S, 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 = S.getASTContext(); 5605 OMPContext OMPCtx(S.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 S.Context, MemberCall->getImplicitObjectArgument(), 5654 /* IsArrow */ false, SpecializedMethod, S.Context.BoundMemberTy, 5655 MemberCall->getValueKind(), MemberCall->getObjectKind()); 5656 } 5657 NewCall = S.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 5670 return PseudoObjectExpr::Create(Context, CE, {NewCall.get()}, 0); 5671 } 5672 5673 Optional<std::pair<FunctionDecl *, Expr *>> 5674 Sema::checkOpenMPDeclareVariantFunction(Sema::DeclGroupPtrTy DG, 5675 Expr *VariantRef, OMPTraitInfo &TI, 5676 SourceRange SR) { 5677 if (!DG || DG.get().isNull()) 5678 return None; 5679 5680 const int VariantId = 1; 5681 // Must be applied only to single decl. 5682 if (!DG.get().isSingleDecl()) { 5683 Diag(SR.getBegin(), diag::err_omp_single_decl_in_declare_simd_variant) 5684 << VariantId << SR; 5685 return None; 5686 } 5687 Decl *ADecl = DG.get().getSingleDecl(); 5688 if (auto *FTD = dyn_cast<FunctionTemplateDecl>(ADecl)) 5689 ADecl = FTD->getTemplatedDecl(); 5690 5691 // Decl must be a function. 5692 auto *FD = dyn_cast<FunctionDecl>(ADecl); 5693 if (!FD) { 5694 Diag(ADecl->getLocation(), diag::err_omp_function_expected) 5695 << VariantId << SR; 5696 return None; 5697 } 5698 5699 auto &&HasMultiVersionAttributes = [](const FunctionDecl *FD) { 5700 return FD->hasAttrs() && 5701 (FD->hasAttr<CPUDispatchAttr>() || FD->hasAttr<CPUSpecificAttr>() || 5702 FD->hasAttr<TargetAttr>()); 5703 }; 5704 // OpenMP is not compatible with CPU-specific attributes. 5705 if (HasMultiVersionAttributes(FD)) { 5706 Diag(FD->getLocation(), diag::err_omp_declare_variant_incompat_attributes) 5707 << SR; 5708 return None; 5709 } 5710 5711 // Allow #pragma omp declare variant only if the function is not used. 5712 if (FD->isUsed(false)) 5713 Diag(SR.getBegin(), diag::warn_omp_declare_variant_after_used) 5714 << FD->getLocation(); 5715 5716 // Check if the function was emitted already. 5717 const FunctionDecl *Definition; 5718 if (!FD->isThisDeclarationADefinition() && FD->isDefined(Definition) && 5719 (LangOpts.EmitAllDecls || Context.DeclMustBeEmitted(Definition))) 5720 Diag(SR.getBegin(), diag::warn_omp_declare_variant_after_emitted) 5721 << FD->getLocation(); 5722 5723 // The VariantRef must point to function. 5724 if (!VariantRef) { 5725 Diag(SR.getBegin(), diag::err_omp_function_expected) << VariantId; 5726 return None; 5727 } 5728 5729 auto ShouldDelayChecks = [](Expr *&E, bool) { 5730 return E && (E->isTypeDependent() || E->isValueDependent() || 5731 E->containsUnexpandedParameterPack() || 5732 E->isInstantiationDependent()); 5733 }; 5734 // Do not check templates, wait until instantiation. 5735 if (FD->isDependentContext() || ShouldDelayChecks(VariantRef, false) || 5736 TI.anyScoreOrCondition(ShouldDelayChecks)) 5737 return std::make_pair(FD, VariantRef); 5738 5739 // Deal with non-constant score and user condition expressions. 5740 auto HandleNonConstantScoresAndConditions = [this](Expr *&E, 5741 bool IsScore) -> bool { 5742 llvm::APSInt Result; 5743 if (!E || E->isIntegerConstantExpr(Result, Context)) 5744 return false; 5745 5746 if (IsScore) { 5747 // We warn on non-constant scores and pretend they were not present. 5748 Diag(E->getExprLoc(), diag::warn_omp_declare_variant_score_not_constant) 5749 << E; 5750 E = nullptr; 5751 } else { 5752 // We could replace a non-constant user condition with "false" but we 5753 // will soon need to handle these anyway for the dynamic version of 5754 // OpenMP context selectors. 5755 Diag(E->getExprLoc(), 5756 diag::err_omp_declare_variant_user_condition_not_constant) 5757 << E; 5758 } 5759 return true; 5760 }; 5761 if (TI.anyScoreOrCondition(HandleNonConstantScoresAndConditions)) 5762 return None; 5763 5764 // Convert VariantRef expression to the type of the original function to 5765 // resolve possible conflicts. 5766 ExprResult VariantRefCast; 5767 if (LangOpts.CPlusPlus) { 5768 QualType FnPtrType; 5769 auto *Method = dyn_cast<CXXMethodDecl>(FD); 5770 if (Method && !Method->isStatic()) { 5771 const Type *ClassType = 5772 Context.getTypeDeclType(Method->getParent()).getTypePtr(); 5773 FnPtrType = Context.getMemberPointerType(FD->getType(), ClassType); 5774 ExprResult ER; 5775 { 5776 // Build adrr_of unary op to correctly handle type checks for member 5777 // functions. 5778 Sema::TentativeAnalysisScope Trap(*this); 5779 ER = CreateBuiltinUnaryOp(VariantRef->getBeginLoc(), UO_AddrOf, 5780 VariantRef); 5781 } 5782 if (!ER.isUsable()) { 5783 Diag(VariantRef->getExprLoc(), diag::err_omp_function_expected) 5784 << VariantId << VariantRef->getSourceRange(); 5785 return None; 5786 } 5787 VariantRef = ER.get(); 5788 } else { 5789 FnPtrType = Context.getPointerType(FD->getType()); 5790 } 5791 ImplicitConversionSequence ICS = 5792 TryImplicitConversion(VariantRef, FnPtrType.getUnqualifiedType(), 5793 /*SuppressUserConversions=*/false, 5794 AllowedExplicit::None, 5795 /*InOverloadResolution=*/false, 5796 /*CStyle=*/false, 5797 /*AllowObjCWritebackConversion=*/false); 5798 if (ICS.isFailure()) { 5799 Diag(VariantRef->getExprLoc(), 5800 diag::err_omp_declare_variant_incompat_types) 5801 << VariantRef->getType() 5802 << ((Method && !Method->isStatic()) ? FnPtrType : FD->getType()) 5803 << VariantRef->getSourceRange(); 5804 return None; 5805 } 5806 VariantRefCast = PerformImplicitConversion( 5807 VariantRef, FnPtrType.getUnqualifiedType(), AA_Converting); 5808 if (!VariantRefCast.isUsable()) 5809 return None; 5810 // Drop previously built artificial addr_of unary op for member functions. 5811 if (Method && !Method->isStatic()) { 5812 Expr *PossibleAddrOfVariantRef = VariantRefCast.get(); 5813 if (auto *UO = dyn_cast<UnaryOperator>( 5814 PossibleAddrOfVariantRef->IgnoreImplicit())) 5815 VariantRefCast = UO->getSubExpr(); 5816 } 5817 } else { 5818 VariantRefCast = VariantRef; 5819 } 5820 5821 ExprResult ER = CheckPlaceholderExpr(VariantRefCast.get()); 5822 if (!ER.isUsable() || 5823 !ER.get()->IgnoreParenImpCasts()->getType()->isFunctionType()) { 5824 Diag(VariantRef->getExprLoc(), diag::err_omp_function_expected) 5825 << VariantId << VariantRef->getSourceRange(); 5826 return None; 5827 } 5828 5829 // The VariantRef must point to function. 5830 auto *DRE = dyn_cast<DeclRefExpr>(ER.get()->IgnoreParenImpCasts()); 5831 if (!DRE) { 5832 Diag(VariantRef->getExprLoc(), diag::err_omp_function_expected) 5833 << VariantId << VariantRef->getSourceRange(); 5834 return None; 5835 } 5836 auto *NewFD = dyn_cast_or_null<FunctionDecl>(DRE->getDecl()); 5837 if (!NewFD) { 5838 Diag(VariantRef->getExprLoc(), diag::err_omp_function_expected) 5839 << VariantId << VariantRef->getSourceRange(); 5840 return None; 5841 } 5842 5843 // Check if function types are compatible in C. 5844 if (!LangOpts.CPlusPlus) { 5845 QualType NewType = 5846 Context.mergeFunctionTypes(FD->getType(), NewFD->getType()); 5847 if (NewType.isNull()) { 5848 Diag(VariantRef->getExprLoc(), 5849 diag::err_omp_declare_variant_incompat_types) 5850 << NewFD->getType() << FD->getType() << VariantRef->getSourceRange(); 5851 return None; 5852 } 5853 if (NewType->isFunctionProtoType()) { 5854 if (FD->getType()->isFunctionNoProtoType()) 5855 setPrototype(*this, FD, NewFD, NewType); 5856 else if (NewFD->getType()->isFunctionNoProtoType()) 5857 setPrototype(*this, NewFD, FD, NewType); 5858 } 5859 } 5860 5861 // Check if variant function is not marked with declare variant directive. 5862 if (NewFD->hasAttrs() && NewFD->hasAttr<OMPDeclareVariantAttr>()) { 5863 Diag(VariantRef->getExprLoc(), 5864 diag::warn_omp_declare_variant_marked_as_declare_variant) 5865 << VariantRef->getSourceRange(); 5866 SourceRange SR = 5867 NewFD->specific_attr_begin<OMPDeclareVariantAttr>()->getRange(); 5868 Diag(SR.getBegin(), diag::note_omp_marked_declare_variant_here) << SR; 5869 return None; 5870 } 5871 5872 enum DoesntSupport { 5873 VirtFuncs = 1, 5874 Constructors = 3, 5875 Destructors = 4, 5876 DeletedFuncs = 5, 5877 DefaultedFuncs = 6, 5878 ConstexprFuncs = 7, 5879 ConstevalFuncs = 8, 5880 }; 5881 if (const auto *CXXFD = dyn_cast<CXXMethodDecl>(FD)) { 5882 if (CXXFD->isVirtual()) { 5883 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support) 5884 << VirtFuncs; 5885 return None; 5886 } 5887 5888 if (isa<CXXConstructorDecl>(FD)) { 5889 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support) 5890 << Constructors; 5891 return None; 5892 } 5893 5894 if (isa<CXXDestructorDecl>(FD)) { 5895 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support) 5896 << Destructors; 5897 return None; 5898 } 5899 } 5900 5901 if (FD->isDeleted()) { 5902 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support) 5903 << DeletedFuncs; 5904 return None; 5905 } 5906 5907 if (FD->isDefaulted()) { 5908 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support) 5909 << DefaultedFuncs; 5910 return None; 5911 } 5912 5913 if (FD->isConstexpr()) { 5914 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support) 5915 << (NewFD->isConsteval() ? ConstevalFuncs : ConstexprFuncs); 5916 return None; 5917 } 5918 5919 // Check general compatibility. 5920 if (areMultiversionVariantFunctionsCompatible( 5921 FD, NewFD, PartialDiagnostic::NullDiagnostic(), 5922 PartialDiagnosticAt(SourceLocation(), 5923 PartialDiagnostic::NullDiagnostic()), 5924 PartialDiagnosticAt( 5925 VariantRef->getExprLoc(), 5926 PDiag(diag::err_omp_declare_variant_doesnt_support)), 5927 PartialDiagnosticAt(VariantRef->getExprLoc(), 5928 PDiag(diag::err_omp_declare_variant_diff) 5929 << FD->getLocation()), 5930 /*TemplatesSupported=*/true, /*ConstexprSupported=*/false, 5931 /*CLinkageMayDiffer=*/true)) 5932 return None; 5933 return std::make_pair(FD, cast<Expr>(DRE)); 5934 } 5935 5936 void Sema::ActOnOpenMPDeclareVariantDirective(FunctionDecl *FD, 5937 Expr *VariantRef, 5938 OMPTraitInfo &TI, 5939 SourceRange SR) { 5940 auto *NewAttr = 5941 OMPDeclareVariantAttr::CreateImplicit(Context, VariantRef, &TI, SR); 5942 FD->addAttr(NewAttr); 5943 } 5944 5945 StmtResult Sema::ActOnOpenMPParallelDirective(ArrayRef<OMPClause *> Clauses, 5946 Stmt *AStmt, 5947 SourceLocation StartLoc, 5948 SourceLocation EndLoc) { 5949 if (!AStmt) 5950 return StmtError(); 5951 5952 auto *CS = cast<CapturedStmt>(AStmt); 5953 // 1.2.2 OpenMP Language Terminology 5954 // Structured block - An executable statement with a single entry at the 5955 // top and a single exit at the bottom. 5956 // The point of exit cannot be a branch out of the structured block. 5957 // longjmp() and throw() must not violate the entry/exit criteria. 5958 CS->getCapturedDecl()->setNothrow(); 5959 5960 setFunctionHasBranchProtectedScope(); 5961 5962 return OMPParallelDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt, 5963 DSAStack->isCancelRegion()); 5964 } 5965 5966 namespace { 5967 /// Iteration space of a single for loop. 5968 struct LoopIterationSpace final { 5969 /// True if the condition operator is the strict compare operator (<, > or 5970 /// !=). 5971 bool IsStrictCompare = false; 5972 /// Condition of the loop. 5973 Expr *PreCond = nullptr; 5974 /// This expression calculates the number of iterations in the loop. 5975 /// It is always possible to calculate it before starting the loop. 5976 Expr *NumIterations = nullptr; 5977 /// The loop counter variable. 5978 Expr *CounterVar = nullptr; 5979 /// Private loop counter variable. 5980 Expr *PrivateCounterVar = nullptr; 5981 /// This is initializer for the initial value of #CounterVar. 5982 Expr *CounterInit = nullptr; 5983 /// This is step for the #CounterVar used to generate its update: 5984 /// #CounterVar = #CounterInit + #CounterStep * CurrentIteration. 5985 Expr *CounterStep = nullptr; 5986 /// Should step be subtracted? 5987 bool Subtract = false; 5988 /// Source range of the loop init. 5989 SourceRange InitSrcRange; 5990 /// Source range of the loop condition. 5991 SourceRange CondSrcRange; 5992 /// Source range of the loop increment. 5993 SourceRange IncSrcRange; 5994 /// Minimum value that can have the loop control variable. Used to support 5995 /// non-rectangular loops. Applied only for LCV with the non-iterator types, 5996 /// since only such variables can be used in non-loop invariant expressions. 5997 Expr *MinValue = nullptr; 5998 /// Maximum value that can have the loop control variable. Used to support 5999 /// non-rectangular loops. Applied only for LCV with the non-iterator type, 6000 /// since only such variables can be used in non-loop invariant expressions. 6001 Expr *MaxValue = nullptr; 6002 /// true, if the lower bound depends on the outer loop control var. 6003 bool IsNonRectangularLB = false; 6004 /// true, if the upper bound depends on the outer loop control var. 6005 bool IsNonRectangularUB = false; 6006 /// Index of the loop this loop depends on and forms non-rectangular loop 6007 /// nest. 6008 unsigned LoopDependentIdx = 0; 6009 /// Final condition for the non-rectangular loop nest support. It is used to 6010 /// check that the number of iterations for this particular counter must be 6011 /// finished. 6012 Expr *FinalCondition = nullptr; 6013 }; 6014 6015 /// Helper class for checking canonical form of the OpenMP loops and 6016 /// extracting iteration space of each loop in the loop nest, that will be used 6017 /// for IR generation. 6018 class OpenMPIterationSpaceChecker { 6019 /// Reference to Sema. 6020 Sema &SemaRef; 6021 /// Data-sharing stack. 6022 DSAStackTy &Stack; 6023 /// A location for diagnostics (when there is no some better location). 6024 SourceLocation DefaultLoc; 6025 /// A location for diagnostics (when increment is not compatible). 6026 SourceLocation ConditionLoc; 6027 /// A source location for referring to loop init later. 6028 SourceRange InitSrcRange; 6029 /// A source location for referring to condition later. 6030 SourceRange ConditionSrcRange; 6031 /// A source location for referring to increment later. 6032 SourceRange IncrementSrcRange; 6033 /// Loop variable. 6034 ValueDecl *LCDecl = nullptr; 6035 /// Reference to loop variable. 6036 Expr *LCRef = nullptr; 6037 /// Lower bound (initializer for the var). 6038 Expr *LB = nullptr; 6039 /// Upper bound. 6040 Expr *UB = nullptr; 6041 /// Loop step (increment). 6042 Expr *Step = nullptr; 6043 /// This flag is true when condition is one of: 6044 /// Var < UB 6045 /// Var <= UB 6046 /// UB > Var 6047 /// UB >= Var 6048 /// This will have no value when the condition is != 6049 llvm::Optional<bool> TestIsLessOp; 6050 /// This flag is true when condition is strict ( < or > ). 6051 bool TestIsStrictOp = false; 6052 /// This flag is true when step is subtracted on each iteration. 6053 bool SubtractStep = false; 6054 /// The outer loop counter this loop depends on (if any). 6055 const ValueDecl *DepDecl = nullptr; 6056 /// Contains number of loop (starts from 1) on which loop counter init 6057 /// expression of this loop depends on. 6058 Optional<unsigned> InitDependOnLC; 6059 /// Contains number of loop (starts from 1) on which loop counter condition 6060 /// expression of this loop depends on. 6061 Optional<unsigned> CondDependOnLC; 6062 /// Checks if the provide statement depends on the loop counter. 6063 Optional<unsigned> doesDependOnLoopCounter(const Stmt *S, bool IsInitializer); 6064 /// Original condition required for checking of the exit condition for 6065 /// non-rectangular loop. 6066 Expr *Condition = nullptr; 6067 6068 public: 6069 OpenMPIterationSpaceChecker(Sema &SemaRef, DSAStackTy &Stack, 6070 SourceLocation DefaultLoc) 6071 : SemaRef(SemaRef), Stack(Stack), DefaultLoc(DefaultLoc), 6072 ConditionLoc(DefaultLoc) {} 6073 /// Check init-expr for canonical loop form and save loop counter 6074 /// variable - #Var and its initialization value - #LB. 6075 bool checkAndSetInit(Stmt *S, bool EmitDiags = true); 6076 /// Check test-expr for canonical form, save upper-bound (#UB), flags 6077 /// for less/greater and for strict/non-strict comparison. 6078 bool checkAndSetCond(Expr *S); 6079 /// Check incr-expr for canonical loop form and return true if it 6080 /// does not conform, otherwise save loop step (#Step). 6081 bool checkAndSetInc(Expr *S); 6082 /// Return the loop counter variable. 6083 ValueDecl *getLoopDecl() const { return LCDecl; } 6084 /// Return the reference expression to loop counter variable. 6085 Expr *getLoopDeclRefExpr() const { return LCRef; } 6086 /// Source range of the loop init. 6087 SourceRange getInitSrcRange() const { return InitSrcRange; } 6088 /// Source range of the loop condition. 6089 SourceRange getConditionSrcRange() const { return ConditionSrcRange; } 6090 /// Source range of the loop increment. 6091 SourceRange getIncrementSrcRange() const { return IncrementSrcRange; } 6092 /// True if the step should be subtracted. 6093 bool shouldSubtractStep() const { return SubtractStep; } 6094 /// True, if the compare operator is strict (<, > or !=). 6095 bool isStrictTestOp() const { return TestIsStrictOp; } 6096 /// Build the expression to calculate the number of iterations. 6097 Expr *buildNumIterations( 6098 Scope *S, ArrayRef<LoopIterationSpace> ResultIterSpaces, bool LimitedType, 6099 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const; 6100 /// Build the precondition expression for the loops. 6101 Expr * 6102 buildPreCond(Scope *S, Expr *Cond, 6103 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const; 6104 /// Build reference expression to the counter be used for codegen. 6105 DeclRefExpr * 6106 buildCounterVar(llvm::MapVector<const Expr *, DeclRefExpr *> &Captures, 6107 DSAStackTy &DSA) const; 6108 /// Build reference expression to the private counter be used for 6109 /// codegen. 6110 Expr *buildPrivateCounterVar() const; 6111 /// Build initialization of the counter be used for codegen. 6112 Expr *buildCounterInit() const; 6113 /// Build step of the counter be used for codegen. 6114 Expr *buildCounterStep() const; 6115 /// Build loop data with counter value for depend clauses in ordered 6116 /// directives. 6117 Expr * 6118 buildOrderedLoopData(Scope *S, Expr *Counter, 6119 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures, 6120 SourceLocation Loc, Expr *Inc = nullptr, 6121 OverloadedOperatorKind OOK = OO_Amp); 6122 /// Builds the minimum value for the loop counter. 6123 std::pair<Expr *, Expr *> buildMinMaxValues( 6124 Scope *S, llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const; 6125 /// Builds final condition for the non-rectangular loops. 6126 Expr *buildFinalCondition(Scope *S) const; 6127 /// Return true if any expression is dependent. 6128 bool dependent() const; 6129 /// Returns true if the initializer forms non-rectangular loop. 6130 bool doesInitDependOnLC() const { return InitDependOnLC.hasValue(); } 6131 /// Returns true if the condition forms non-rectangular loop. 6132 bool doesCondDependOnLC() const { return CondDependOnLC.hasValue(); } 6133 /// Returns index of the loop we depend on (starting from 1), or 0 otherwise. 6134 unsigned getLoopDependentIdx() const { 6135 return InitDependOnLC.getValueOr(CondDependOnLC.getValueOr(0)); 6136 } 6137 6138 private: 6139 /// Check the right-hand side of an assignment in the increment 6140 /// expression. 6141 bool checkAndSetIncRHS(Expr *RHS); 6142 /// Helper to set loop counter variable and its initializer. 6143 bool setLCDeclAndLB(ValueDecl *NewLCDecl, Expr *NewDeclRefExpr, Expr *NewLB, 6144 bool EmitDiags); 6145 /// Helper to set upper bound. 6146 bool setUB(Expr *NewUB, llvm::Optional<bool> LessOp, bool StrictOp, 6147 SourceRange SR, SourceLocation SL); 6148 /// Helper to set loop increment. 6149 bool setStep(Expr *NewStep, bool Subtract); 6150 }; 6151 6152 bool OpenMPIterationSpaceChecker::dependent() const { 6153 if (!LCDecl) { 6154 assert(!LB && !UB && !Step); 6155 return false; 6156 } 6157 return LCDecl->getType()->isDependentType() || 6158 (LB && LB->isValueDependent()) || (UB && UB->isValueDependent()) || 6159 (Step && Step->isValueDependent()); 6160 } 6161 6162 bool OpenMPIterationSpaceChecker::setLCDeclAndLB(ValueDecl *NewLCDecl, 6163 Expr *NewLCRefExpr, 6164 Expr *NewLB, bool EmitDiags) { 6165 // State consistency checking to ensure correct usage. 6166 assert(LCDecl == nullptr && LB == nullptr && LCRef == nullptr && 6167 UB == nullptr && Step == nullptr && !TestIsLessOp && !TestIsStrictOp); 6168 if (!NewLCDecl || !NewLB) 6169 return true; 6170 LCDecl = getCanonicalDecl(NewLCDecl); 6171 LCRef = NewLCRefExpr; 6172 if (auto *CE = dyn_cast_or_null<CXXConstructExpr>(NewLB)) 6173 if (const CXXConstructorDecl *Ctor = CE->getConstructor()) 6174 if ((Ctor->isCopyOrMoveConstructor() || 6175 Ctor->isConvertingConstructor(/*AllowExplicit=*/false)) && 6176 CE->getNumArgs() > 0 && CE->getArg(0) != nullptr) 6177 NewLB = CE->getArg(0)->IgnoreParenImpCasts(); 6178 LB = NewLB; 6179 if (EmitDiags) 6180 InitDependOnLC = doesDependOnLoopCounter(LB, /*IsInitializer=*/true); 6181 return false; 6182 } 6183 6184 bool OpenMPIterationSpaceChecker::setUB(Expr *NewUB, 6185 llvm::Optional<bool> LessOp, 6186 bool StrictOp, SourceRange SR, 6187 SourceLocation SL) { 6188 // State consistency checking to ensure correct usage. 6189 assert(LCDecl != nullptr && LB != nullptr && UB == nullptr && 6190 Step == nullptr && !TestIsLessOp && !TestIsStrictOp); 6191 if (!NewUB) 6192 return true; 6193 UB = NewUB; 6194 if (LessOp) 6195 TestIsLessOp = LessOp; 6196 TestIsStrictOp = StrictOp; 6197 ConditionSrcRange = SR; 6198 ConditionLoc = SL; 6199 CondDependOnLC = doesDependOnLoopCounter(UB, /*IsInitializer=*/false); 6200 return false; 6201 } 6202 6203 bool OpenMPIterationSpaceChecker::setStep(Expr *NewStep, bool Subtract) { 6204 // State consistency checking to ensure correct usage. 6205 assert(LCDecl != nullptr && LB != nullptr && Step == nullptr); 6206 if (!NewStep) 6207 return true; 6208 if (!NewStep->isValueDependent()) { 6209 // Check that the step is integer expression. 6210 SourceLocation StepLoc = NewStep->getBeginLoc(); 6211 ExprResult Val = SemaRef.PerformOpenMPImplicitIntegerConversion( 6212 StepLoc, getExprAsWritten(NewStep)); 6213 if (Val.isInvalid()) 6214 return true; 6215 NewStep = Val.get(); 6216 6217 // OpenMP [2.6, Canonical Loop Form, Restrictions] 6218 // If test-expr is of form var relational-op b and relational-op is < or 6219 // <= then incr-expr must cause var to increase on each iteration of the 6220 // loop. If test-expr is of form var relational-op b and relational-op is 6221 // > or >= then incr-expr must cause var to decrease on each iteration of 6222 // the loop. 6223 // If test-expr is of form b relational-op var and relational-op is < or 6224 // <= then incr-expr must cause var to decrease on each iteration of the 6225 // loop. If test-expr is of form b relational-op var and relational-op is 6226 // > or >= then incr-expr must cause var to increase on each iteration of 6227 // the loop. 6228 llvm::APSInt Result; 6229 bool IsConstant = NewStep->isIntegerConstantExpr(Result, SemaRef.Context); 6230 bool IsUnsigned = !NewStep->getType()->hasSignedIntegerRepresentation(); 6231 bool IsConstNeg = 6232 IsConstant && Result.isSigned() && (Subtract != Result.isNegative()); 6233 bool IsConstPos = 6234 IsConstant && Result.isSigned() && (Subtract == Result.isNegative()); 6235 bool IsConstZero = IsConstant && !Result.getBoolValue(); 6236 6237 // != with increment is treated as <; != with decrement is treated as > 6238 if (!TestIsLessOp.hasValue()) 6239 TestIsLessOp = IsConstPos || (IsUnsigned && !Subtract); 6240 if (UB && (IsConstZero || 6241 (TestIsLessOp.getValue() ? 6242 (IsConstNeg || (IsUnsigned && Subtract)) : 6243 (IsConstPos || (IsUnsigned && !Subtract))))) { 6244 SemaRef.Diag(NewStep->getExprLoc(), 6245 diag::err_omp_loop_incr_not_compatible) 6246 << LCDecl << TestIsLessOp.getValue() << NewStep->getSourceRange(); 6247 SemaRef.Diag(ConditionLoc, 6248 diag::note_omp_loop_cond_requres_compatible_incr) 6249 << TestIsLessOp.getValue() << ConditionSrcRange; 6250 return true; 6251 } 6252 if (TestIsLessOp.getValue() == Subtract) { 6253 NewStep = 6254 SemaRef.CreateBuiltinUnaryOp(NewStep->getExprLoc(), UO_Minus, NewStep) 6255 .get(); 6256 Subtract = !Subtract; 6257 } 6258 } 6259 6260 Step = NewStep; 6261 SubtractStep = Subtract; 6262 return false; 6263 } 6264 6265 namespace { 6266 /// Checker for the non-rectangular loops. Checks if the initializer or 6267 /// condition expression references loop counter variable. 6268 class LoopCounterRefChecker final 6269 : public ConstStmtVisitor<LoopCounterRefChecker, bool> { 6270 Sema &SemaRef; 6271 DSAStackTy &Stack; 6272 const ValueDecl *CurLCDecl = nullptr; 6273 const ValueDecl *DepDecl = nullptr; 6274 const ValueDecl *PrevDepDecl = nullptr; 6275 bool IsInitializer = true; 6276 unsigned BaseLoopId = 0; 6277 bool checkDecl(const Expr *E, const ValueDecl *VD) { 6278 if (getCanonicalDecl(VD) == getCanonicalDecl(CurLCDecl)) { 6279 SemaRef.Diag(E->getExprLoc(), diag::err_omp_stmt_depends_on_loop_counter) 6280 << (IsInitializer ? 0 : 1); 6281 return false; 6282 } 6283 const auto &&Data = Stack.isLoopControlVariable(VD); 6284 // OpenMP, 2.9.1 Canonical Loop Form, Restrictions. 6285 // The type of the loop iterator on which we depend may not have a random 6286 // access iterator type. 6287 if (Data.first && VD->getType()->isRecordType()) { 6288 SmallString<128> Name; 6289 llvm::raw_svector_ostream OS(Name); 6290 VD->getNameForDiagnostic(OS, SemaRef.getPrintingPolicy(), 6291 /*Qualified=*/true); 6292 SemaRef.Diag(E->getExprLoc(), 6293 diag::err_omp_wrong_dependency_iterator_type) 6294 << OS.str(); 6295 SemaRef.Diag(VD->getLocation(), diag::note_previous_decl) << VD; 6296 return false; 6297 } 6298 if (Data.first && 6299 (DepDecl || (PrevDepDecl && 6300 getCanonicalDecl(VD) != getCanonicalDecl(PrevDepDecl)))) { 6301 if (!DepDecl && PrevDepDecl) 6302 DepDecl = PrevDepDecl; 6303 SmallString<128> Name; 6304 llvm::raw_svector_ostream OS(Name); 6305 DepDecl->getNameForDiagnostic(OS, SemaRef.getPrintingPolicy(), 6306 /*Qualified=*/true); 6307 SemaRef.Diag(E->getExprLoc(), 6308 diag::err_omp_invariant_or_linear_dependency) 6309 << OS.str(); 6310 return false; 6311 } 6312 if (Data.first) { 6313 DepDecl = VD; 6314 BaseLoopId = Data.first; 6315 } 6316 return Data.first; 6317 } 6318 6319 public: 6320 bool VisitDeclRefExpr(const DeclRefExpr *E) { 6321 const ValueDecl *VD = E->getDecl(); 6322 if (isa<VarDecl>(VD)) 6323 return checkDecl(E, VD); 6324 return false; 6325 } 6326 bool VisitMemberExpr(const MemberExpr *E) { 6327 if (isa<CXXThisExpr>(E->getBase()->IgnoreParens())) { 6328 const ValueDecl *VD = E->getMemberDecl(); 6329 if (isa<VarDecl>(VD) || isa<FieldDecl>(VD)) 6330 return checkDecl(E, VD); 6331 } 6332 return false; 6333 } 6334 bool VisitStmt(const Stmt *S) { 6335 bool Res = false; 6336 for (const Stmt *Child : S->children()) 6337 Res = (Child && Visit(Child)) || Res; 6338 return Res; 6339 } 6340 explicit LoopCounterRefChecker(Sema &SemaRef, DSAStackTy &Stack, 6341 const ValueDecl *CurLCDecl, bool IsInitializer, 6342 const ValueDecl *PrevDepDecl = nullptr) 6343 : SemaRef(SemaRef), Stack(Stack), CurLCDecl(CurLCDecl), 6344 PrevDepDecl(PrevDepDecl), IsInitializer(IsInitializer) {} 6345 unsigned getBaseLoopId() const { 6346 assert(CurLCDecl && "Expected loop dependency."); 6347 return BaseLoopId; 6348 } 6349 const ValueDecl *getDepDecl() const { 6350 assert(CurLCDecl && "Expected loop dependency."); 6351 return DepDecl; 6352 } 6353 }; 6354 } // namespace 6355 6356 Optional<unsigned> 6357 OpenMPIterationSpaceChecker::doesDependOnLoopCounter(const Stmt *S, 6358 bool IsInitializer) { 6359 // Check for the non-rectangular loops. 6360 LoopCounterRefChecker LoopStmtChecker(SemaRef, Stack, LCDecl, IsInitializer, 6361 DepDecl); 6362 if (LoopStmtChecker.Visit(S)) { 6363 DepDecl = LoopStmtChecker.getDepDecl(); 6364 return LoopStmtChecker.getBaseLoopId(); 6365 } 6366 return llvm::None; 6367 } 6368 6369 bool OpenMPIterationSpaceChecker::checkAndSetInit(Stmt *S, bool EmitDiags) { 6370 // Check init-expr for canonical loop form and save loop counter 6371 // variable - #Var and its initialization value - #LB. 6372 // OpenMP [2.6] Canonical loop form. init-expr may be one of the following: 6373 // var = lb 6374 // integer-type var = lb 6375 // random-access-iterator-type var = lb 6376 // pointer-type var = lb 6377 // 6378 if (!S) { 6379 if (EmitDiags) { 6380 SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_init); 6381 } 6382 return true; 6383 } 6384 if (auto *ExprTemp = dyn_cast<ExprWithCleanups>(S)) 6385 if (!ExprTemp->cleanupsHaveSideEffects()) 6386 S = ExprTemp->getSubExpr(); 6387 6388 InitSrcRange = S->getSourceRange(); 6389 if (Expr *E = dyn_cast<Expr>(S)) 6390 S = E->IgnoreParens(); 6391 if (auto *BO = dyn_cast<BinaryOperator>(S)) { 6392 if (BO->getOpcode() == BO_Assign) { 6393 Expr *LHS = BO->getLHS()->IgnoreParens(); 6394 if (auto *DRE = dyn_cast<DeclRefExpr>(LHS)) { 6395 if (auto *CED = dyn_cast<OMPCapturedExprDecl>(DRE->getDecl())) 6396 if (auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit()))) 6397 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(), 6398 EmitDiags); 6399 return setLCDeclAndLB(DRE->getDecl(), DRE, BO->getRHS(), EmitDiags); 6400 } 6401 if (auto *ME = dyn_cast<MemberExpr>(LHS)) { 6402 if (ME->isArrow() && 6403 isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts())) 6404 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(), 6405 EmitDiags); 6406 } 6407 } 6408 } else if (auto *DS = dyn_cast<DeclStmt>(S)) { 6409 if (DS->isSingleDecl()) { 6410 if (auto *Var = dyn_cast_or_null<VarDecl>(DS->getSingleDecl())) { 6411 if (Var->hasInit() && !Var->getType()->isReferenceType()) { 6412 // Accept non-canonical init form here but emit ext. warning. 6413 if (Var->getInitStyle() != VarDecl::CInit && EmitDiags) 6414 SemaRef.Diag(S->getBeginLoc(), 6415 diag::ext_omp_loop_not_canonical_init) 6416 << S->getSourceRange(); 6417 return setLCDeclAndLB( 6418 Var, 6419 buildDeclRefExpr(SemaRef, Var, 6420 Var->getType().getNonReferenceType(), 6421 DS->getBeginLoc()), 6422 Var->getInit(), EmitDiags); 6423 } 6424 } 6425 } 6426 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) { 6427 if (CE->getOperator() == OO_Equal) { 6428 Expr *LHS = CE->getArg(0); 6429 if (auto *DRE = dyn_cast<DeclRefExpr>(LHS)) { 6430 if (auto *CED = dyn_cast<OMPCapturedExprDecl>(DRE->getDecl())) 6431 if (auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit()))) 6432 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(), 6433 EmitDiags); 6434 return setLCDeclAndLB(DRE->getDecl(), DRE, CE->getArg(1), EmitDiags); 6435 } 6436 if (auto *ME = dyn_cast<MemberExpr>(LHS)) { 6437 if (ME->isArrow() && 6438 isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts())) 6439 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(), 6440 EmitDiags); 6441 } 6442 } 6443 } 6444 6445 if (dependent() || SemaRef.CurContext->isDependentContext()) 6446 return false; 6447 if (EmitDiags) { 6448 SemaRef.Diag(S->getBeginLoc(), diag::err_omp_loop_not_canonical_init) 6449 << S->getSourceRange(); 6450 } 6451 return true; 6452 } 6453 6454 /// Ignore parenthesizes, implicit casts, copy constructor and return the 6455 /// variable (which may be the loop variable) if possible. 6456 static const ValueDecl *getInitLCDecl(const Expr *E) { 6457 if (!E) 6458 return nullptr; 6459 E = getExprAsWritten(E); 6460 if (const auto *CE = dyn_cast_or_null<CXXConstructExpr>(E)) 6461 if (const CXXConstructorDecl *Ctor = CE->getConstructor()) 6462 if ((Ctor->isCopyOrMoveConstructor() || 6463 Ctor->isConvertingConstructor(/*AllowExplicit=*/false)) && 6464 CE->getNumArgs() > 0 && CE->getArg(0) != nullptr) 6465 E = CE->getArg(0)->IgnoreParenImpCasts(); 6466 if (const auto *DRE = dyn_cast_or_null<DeclRefExpr>(E)) { 6467 if (const auto *VD = dyn_cast<VarDecl>(DRE->getDecl())) 6468 return getCanonicalDecl(VD); 6469 } 6470 if (const auto *ME = dyn_cast_or_null<MemberExpr>(E)) 6471 if (ME->isArrow() && isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts())) 6472 return getCanonicalDecl(ME->getMemberDecl()); 6473 return nullptr; 6474 } 6475 6476 bool OpenMPIterationSpaceChecker::checkAndSetCond(Expr *S) { 6477 // Check test-expr for canonical form, save upper-bound UB, flags for 6478 // less/greater and for strict/non-strict comparison. 6479 // OpenMP [2.9] Canonical loop form. Test-expr may be one of the following: 6480 // var relational-op b 6481 // b relational-op var 6482 // 6483 bool IneqCondIsCanonical = SemaRef.getLangOpts().OpenMP >= 50; 6484 if (!S) { 6485 SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_cond) 6486 << (IneqCondIsCanonical ? 1 : 0) << LCDecl; 6487 return true; 6488 } 6489 Condition = S; 6490 S = getExprAsWritten(S); 6491 SourceLocation CondLoc = S->getBeginLoc(); 6492 if (auto *BO = dyn_cast<BinaryOperator>(S)) { 6493 if (BO->isRelationalOp()) { 6494 if (getInitLCDecl(BO->getLHS()) == LCDecl) 6495 return setUB(BO->getRHS(), 6496 (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_LE), 6497 (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_GT), 6498 BO->getSourceRange(), BO->getOperatorLoc()); 6499 if (getInitLCDecl(BO->getRHS()) == LCDecl) 6500 return setUB(BO->getLHS(), 6501 (BO->getOpcode() == BO_GT || BO->getOpcode() == BO_GE), 6502 (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_GT), 6503 BO->getSourceRange(), BO->getOperatorLoc()); 6504 } else if (IneqCondIsCanonical && BO->getOpcode() == BO_NE) 6505 return setUB( 6506 getInitLCDecl(BO->getLHS()) == LCDecl ? BO->getRHS() : BO->getLHS(), 6507 /*LessOp=*/llvm::None, 6508 /*StrictOp=*/true, BO->getSourceRange(), BO->getOperatorLoc()); 6509 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) { 6510 if (CE->getNumArgs() == 2) { 6511 auto Op = CE->getOperator(); 6512 switch (Op) { 6513 case OO_Greater: 6514 case OO_GreaterEqual: 6515 case OO_Less: 6516 case OO_LessEqual: 6517 if (getInitLCDecl(CE->getArg(0)) == LCDecl) 6518 return setUB(CE->getArg(1), Op == OO_Less || Op == OO_LessEqual, 6519 Op == OO_Less || Op == OO_Greater, CE->getSourceRange(), 6520 CE->getOperatorLoc()); 6521 if (getInitLCDecl(CE->getArg(1)) == LCDecl) 6522 return setUB(CE->getArg(0), Op == OO_Greater || Op == OO_GreaterEqual, 6523 Op == OO_Less || Op == OO_Greater, CE->getSourceRange(), 6524 CE->getOperatorLoc()); 6525 break; 6526 case OO_ExclaimEqual: 6527 if (IneqCondIsCanonical) 6528 return setUB(getInitLCDecl(CE->getArg(0)) == LCDecl ? CE->getArg(1) 6529 : CE->getArg(0), 6530 /*LessOp=*/llvm::None, 6531 /*StrictOp=*/true, CE->getSourceRange(), 6532 CE->getOperatorLoc()); 6533 break; 6534 default: 6535 break; 6536 } 6537 } 6538 } 6539 if (dependent() || SemaRef.CurContext->isDependentContext()) 6540 return false; 6541 SemaRef.Diag(CondLoc, diag::err_omp_loop_not_canonical_cond) 6542 << (IneqCondIsCanonical ? 1 : 0) << S->getSourceRange() << LCDecl; 6543 return true; 6544 } 6545 6546 bool OpenMPIterationSpaceChecker::checkAndSetIncRHS(Expr *RHS) { 6547 // RHS of canonical loop form increment can be: 6548 // var + incr 6549 // incr + var 6550 // var - incr 6551 // 6552 RHS = RHS->IgnoreParenImpCasts(); 6553 if (auto *BO = dyn_cast<BinaryOperator>(RHS)) { 6554 if (BO->isAdditiveOp()) { 6555 bool IsAdd = BO->getOpcode() == BO_Add; 6556 if (getInitLCDecl(BO->getLHS()) == LCDecl) 6557 return setStep(BO->getRHS(), !IsAdd); 6558 if (IsAdd && getInitLCDecl(BO->getRHS()) == LCDecl) 6559 return setStep(BO->getLHS(), /*Subtract=*/false); 6560 } 6561 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(RHS)) { 6562 bool IsAdd = CE->getOperator() == OO_Plus; 6563 if ((IsAdd || CE->getOperator() == OO_Minus) && CE->getNumArgs() == 2) { 6564 if (getInitLCDecl(CE->getArg(0)) == LCDecl) 6565 return setStep(CE->getArg(1), !IsAdd); 6566 if (IsAdd && getInitLCDecl(CE->getArg(1)) == LCDecl) 6567 return setStep(CE->getArg(0), /*Subtract=*/false); 6568 } 6569 } 6570 if (dependent() || SemaRef.CurContext->isDependentContext()) 6571 return false; 6572 SemaRef.Diag(RHS->getBeginLoc(), diag::err_omp_loop_not_canonical_incr) 6573 << RHS->getSourceRange() << LCDecl; 6574 return true; 6575 } 6576 6577 bool OpenMPIterationSpaceChecker::checkAndSetInc(Expr *S) { 6578 // Check incr-expr for canonical loop form and return true if it 6579 // does not conform. 6580 // OpenMP [2.6] Canonical loop form. Test-expr may be one of the following: 6581 // ++var 6582 // var++ 6583 // --var 6584 // var-- 6585 // var += incr 6586 // var -= incr 6587 // var = var + incr 6588 // var = incr + var 6589 // var = var - incr 6590 // 6591 if (!S) { 6592 SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_incr) << LCDecl; 6593 return true; 6594 } 6595 if (auto *ExprTemp = dyn_cast<ExprWithCleanups>(S)) 6596 if (!ExprTemp->cleanupsHaveSideEffects()) 6597 S = ExprTemp->getSubExpr(); 6598 6599 IncrementSrcRange = S->getSourceRange(); 6600 S = S->IgnoreParens(); 6601 if (auto *UO = dyn_cast<UnaryOperator>(S)) { 6602 if (UO->isIncrementDecrementOp() && 6603 getInitLCDecl(UO->getSubExpr()) == LCDecl) 6604 return setStep(SemaRef 6605 .ActOnIntegerConstant(UO->getBeginLoc(), 6606 (UO->isDecrementOp() ? -1 : 1)) 6607 .get(), 6608 /*Subtract=*/false); 6609 } else if (auto *BO = dyn_cast<BinaryOperator>(S)) { 6610 switch (BO->getOpcode()) { 6611 case BO_AddAssign: 6612 case BO_SubAssign: 6613 if (getInitLCDecl(BO->getLHS()) == LCDecl) 6614 return setStep(BO->getRHS(), BO->getOpcode() == BO_SubAssign); 6615 break; 6616 case BO_Assign: 6617 if (getInitLCDecl(BO->getLHS()) == LCDecl) 6618 return checkAndSetIncRHS(BO->getRHS()); 6619 break; 6620 default: 6621 break; 6622 } 6623 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) { 6624 switch (CE->getOperator()) { 6625 case OO_PlusPlus: 6626 case OO_MinusMinus: 6627 if (getInitLCDecl(CE->getArg(0)) == LCDecl) 6628 return setStep(SemaRef 6629 .ActOnIntegerConstant( 6630 CE->getBeginLoc(), 6631 ((CE->getOperator() == OO_MinusMinus) ? -1 : 1)) 6632 .get(), 6633 /*Subtract=*/false); 6634 break; 6635 case OO_PlusEqual: 6636 case OO_MinusEqual: 6637 if (getInitLCDecl(CE->getArg(0)) == LCDecl) 6638 return setStep(CE->getArg(1), CE->getOperator() == OO_MinusEqual); 6639 break; 6640 case OO_Equal: 6641 if (getInitLCDecl(CE->getArg(0)) == LCDecl) 6642 return checkAndSetIncRHS(CE->getArg(1)); 6643 break; 6644 default: 6645 break; 6646 } 6647 } 6648 if (dependent() || SemaRef.CurContext->isDependentContext()) 6649 return false; 6650 SemaRef.Diag(S->getBeginLoc(), diag::err_omp_loop_not_canonical_incr) 6651 << S->getSourceRange() << LCDecl; 6652 return true; 6653 } 6654 6655 static ExprResult 6656 tryBuildCapture(Sema &SemaRef, Expr *Capture, 6657 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) { 6658 if (SemaRef.CurContext->isDependentContext()) 6659 return ExprResult(Capture); 6660 if (Capture->isEvaluatable(SemaRef.Context, Expr::SE_AllowSideEffects)) 6661 return SemaRef.PerformImplicitConversion( 6662 Capture->IgnoreImpCasts(), Capture->getType(), Sema::AA_Converting, 6663 /*AllowExplicit=*/true); 6664 auto I = Captures.find(Capture); 6665 if (I != Captures.end()) 6666 return buildCapture(SemaRef, Capture, I->second); 6667 DeclRefExpr *Ref = nullptr; 6668 ExprResult Res = buildCapture(SemaRef, Capture, Ref); 6669 Captures[Capture] = Ref; 6670 return Res; 6671 } 6672 6673 /// Build the expression to calculate the number of iterations. 6674 Expr *OpenMPIterationSpaceChecker::buildNumIterations( 6675 Scope *S, ArrayRef<LoopIterationSpace> ResultIterSpaces, bool LimitedType, 6676 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const { 6677 ExprResult Diff; 6678 QualType VarType = LCDecl->getType().getNonReferenceType(); 6679 if (VarType->isIntegerType() || VarType->isPointerType() || 6680 SemaRef.getLangOpts().CPlusPlus) { 6681 Expr *LBVal = LB; 6682 Expr *UBVal = UB; 6683 // LB = TestIsLessOp.getValue() ? min(LB(MinVal), LB(MaxVal)) : 6684 // max(LB(MinVal), LB(MaxVal)) 6685 if (InitDependOnLC) { 6686 const LoopIterationSpace &IS = 6687 ResultIterSpaces[ResultIterSpaces.size() - 1 - 6688 InitDependOnLC.getValueOr( 6689 CondDependOnLC.getValueOr(0))]; 6690 if (!IS.MinValue || !IS.MaxValue) 6691 return nullptr; 6692 // OuterVar = Min 6693 ExprResult MinValue = 6694 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MinValue); 6695 if (!MinValue.isUsable()) 6696 return nullptr; 6697 6698 ExprResult LBMinVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign, 6699 IS.CounterVar, MinValue.get()); 6700 if (!LBMinVal.isUsable()) 6701 return nullptr; 6702 // OuterVar = Min, LBVal 6703 LBMinVal = 6704 SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, LBMinVal.get(), LBVal); 6705 if (!LBMinVal.isUsable()) 6706 return nullptr; 6707 // (OuterVar = Min, LBVal) 6708 LBMinVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, LBMinVal.get()); 6709 if (!LBMinVal.isUsable()) 6710 return nullptr; 6711 6712 // OuterVar = Max 6713 ExprResult MaxValue = 6714 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MaxValue); 6715 if (!MaxValue.isUsable()) 6716 return nullptr; 6717 6718 ExprResult LBMaxVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign, 6719 IS.CounterVar, MaxValue.get()); 6720 if (!LBMaxVal.isUsable()) 6721 return nullptr; 6722 // OuterVar = Max, LBVal 6723 LBMaxVal = 6724 SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, LBMaxVal.get(), LBVal); 6725 if (!LBMaxVal.isUsable()) 6726 return nullptr; 6727 // (OuterVar = Max, LBVal) 6728 LBMaxVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, LBMaxVal.get()); 6729 if (!LBMaxVal.isUsable()) 6730 return nullptr; 6731 6732 Expr *LBMin = tryBuildCapture(SemaRef, LBMinVal.get(), Captures).get(); 6733 Expr *LBMax = tryBuildCapture(SemaRef, LBMaxVal.get(), Captures).get(); 6734 if (!LBMin || !LBMax) 6735 return nullptr; 6736 // LB(MinVal) < LB(MaxVal) 6737 ExprResult MinLessMaxRes = 6738 SemaRef.BuildBinOp(S, DefaultLoc, BO_LT, LBMin, LBMax); 6739 if (!MinLessMaxRes.isUsable()) 6740 return nullptr; 6741 Expr *MinLessMax = 6742 tryBuildCapture(SemaRef, MinLessMaxRes.get(), Captures).get(); 6743 if (!MinLessMax) 6744 return nullptr; 6745 if (TestIsLessOp.getValue()) { 6746 // LB(MinVal) < LB(MaxVal) ? LB(MinVal) : LB(MaxVal) - min(LB(MinVal), 6747 // LB(MaxVal)) 6748 ExprResult MinLB = SemaRef.ActOnConditionalOp(DefaultLoc, DefaultLoc, 6749 MinLessMax, LBMin, LBMax); 6750 if (!MinLB.isUsable()) 6751 return nullptr; 6752 LBVal = MinLB.get(); 6753 } else { 6754 // LB(MinVal) < LB(MaxVal) ? LB(MaxVal) : LB(MinVal) - max(LB(MinVal), 6755 // LB(MaxVal)) 6756 ExprResult MaxLB = SemaRef.ActOnConditionalOp(DefaultLoc, DefaultLoc, 6757 MinLessMax, LBMax, LBMin); 6758 if (!MaxLB.isUsable()) 6759 return nullptr; 6760 LBVal = MaxLB.get(); 6761 } 6762 } 6763 // UB = TestIsLessOp.getValue() ? max(UB(MinVal), UB(MaxVal)) : 6764 // min(UB(MinVal), UB(MaxVal)) 6765 if (CondDependOnLC) { 6766 const LoopIterationSpace &IS = 6767 ResultIterSpaces[ResultIterSpaces.size() - 1 - 6768 InitDependOnLC.getValueOr( 6769 CondDependOnLC.getValueOr(0))]; 6770 if (!IS.MinValue || !IS.MaxValue) 6771 return nullptr; 6772 // OuterVar = Min 6773 ExprResult MinValue = 6774 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MinValue); 6775 if (!MinValue.isUsable()) 6776 return nullptr; 6777 6778 ExprResult UBMinVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign, 6779 IS.CounterVar, MinValue.get()); 6780 if (!UBMinVal.isUsable()) 6781 return nullptr; 6782 // OuterVar = Min, UBVal 6783 UBMinVal = 6784 SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, UBMinVal.get(), UBVal); 6785 if (!UBMinVal.isUsable()) 6786 return nullptr; 6787 // (OuterVar = Min, UBVal) 6788 UBMinVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, UBMinVal.get()); 6789 if (!UBMinVal.isUsable()) 6790 return nullptr; 6791 6792 // OuterVar = Max 6793 ExprResult MaxValue = 6794 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MaxValue); 6795 if (!MaxValue.isUsable()) 6796 return nullptr; 6797 6798 ExprResult UBMaxVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign, 6799 IS.CounterVar, MaxValue.get()); 6800 if (!UBMaxVal.isUsable()) 6801 return nullptr; 6802 // OuterVar = Max, UBVal 6803 UBMaxVal = 6804 SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, UBMaxVal.get(), UBVal); 6805 if (!UBMaxVal.isUsable()) 6806 return nullptr; 6807 // (OuterVar = Max, UBVal) 6808 UBMaxVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, UBMaxVal.get()); 6809 if (!UBMaxVal.isUsable()) 6810 return nullptr; 6811 6812 Expr *UBMin = tryBuildCapture(SemaRef, UBMinVal.get(), Captures).get(); 6813 Expr *UBMax = tryBuildCapture(SemaRef, UBMaxVal.get(), Captures).get(); 6814 if (!UBMin || !UBMax) 6815 return nullptr; 6816 // UB(MinVal) > UB(MaxVal) 6817 ExprResult MinGreaterMaxRes = 6818 SemaRef.BuildBinOp(S, DefaultLoc, BO_GT, UBMin, UBMax); 6819 if (!MinGreaterMaxRes.isUsable()) 6820 return nullptr; 6821 Expr *MinGreaterMax = 6822 tryBuildCapture(SemaRef, MinGreaterMaxRes.get(), Captures).get(); 6823 if (!MinGreaterMax) 6824 return nullptr; 6825 if (TestIsLessOp.getValue()) { 6826 // UB(MinVal) > UB(MaxVal) ? UB(MinVal) : UB(MaxVal) - max(UB(MinVal), 6827 // UB(MaxVal)) 6828 ExprResult MaxUB = SemaRef.ActOnConditionalOp( 6829 DefaultLoc, DefaultLoc, MinGreaterMax, UBMin, UBMax); 6830 if (!MaxUB.isUsable()) 6831 return nullptr; 6832 UBVal = MaxUB.get(); 6833 } else { 6834 // UB(MinVal) > UB(MaxVal) ? UB(MaxVal) : UB(MinVal) - min(UB(MinVal), 6835 // UB(MaxVal)) 6836 ExprResult MinUB = SemaRef.ActOnConditionalOp( 6837 DefaultLoc, DefaultLoc, MinGreaterMax, UBMax, UBMin); 6838 if (!MinUB.isUsable()) 6839 return nullptr; 6840 UBVal = MinUB.get(); 6841 } 6842 } 6843 // Upper - Lower 6844 Expr *UBExpr = TestIsLessOp.getValue() ? UBVal : LBVal; 6845 Expr *LBExpr = TestIsLessOp.getValue() ? LBVal : UBVal; 6846 Expr *Upper = tryBuildCapture(SemaRef, UBExpr, Captures).get(); 6847 Expr *Lower = tryBuildCapture(SemaRef, LBExpr, Captures).get(); 6848 if (!Upper || !Lower) 6849 return nullptr; 6850 6851 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Lower); 6852 6853 if (!Diff.isUsable() && VarType->getAsCXXRecordDecl()) { 6854 // BuildBinOp already emitted error, this one is to point user to upper 6855 // and lower bound, and to tell what is passed to 'operator-'. 6856 SemaRef.Diag(Upper->getBeginLoc(), diag::err_omp_loop_diff_cxx) 6857 << Upper->getSourceRange() << Lower->getSourceRange(); 6858 return nullptr; 6859 } 6860 } 6861 6862 if (!Diff.isUsable()) 6863 return nullptr; 6864 6865 // Upper - Lower [- 1] 6866 if (TestIsStrictOp) 6867 Diff = SemaRef.BuildBinOp( 6868 S, DefaultLoc, BO_Sub, Diff.get(), 6869 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()); 6870 if (!Diff.isUsable()) 6871 return nullptr; 6872 6873 // Upper - Lower [- 1] + Step 6874 ExprResult NewStep = tryBuildCapture(SemaRef, Step, Captures); 6875 if (!NewStep.isUsable()) 6876 return nullptr; 6877 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Add, Diff.get(), NewStep.get()); 6878 if (!Diff.isUsable()) 6879 return nullptr; 6880 6881 // Parentheses (for dumping/debugging purposes only). 6882 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get()); 6883 if (!Diff.isUsable()) 6884 return nullptr; 6885 6886 // (Upper - Lower [- 1] + Step) / Step 6887 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Div, Diff.get(), NewStep.get()); 6888 if (!Diff.isUsable()) 6889 return nullptr; 6890 6891 // OpenMP runtime requires 32-bit or 64-bit loop variables. 6892 QualType Type = Diff.get()->getType(); 6893 ASTContext &C = SemaRef.Context; 6894 bool UseVarType = VarType->hasIntegerRepresentation() && 6895 C.getTypeSize(Type) > C.getTypeSize(VarType); 6896 if (!Type->isIntegerType() || UseVarType) { 6897 unsigned NewSize = 6898 UseVarType ? C.getTypeSize(VarType) : C.getTypeSize(Type); 6899 bool IsSigned = UseVarType ? VarType->hasSignedIntegerRepresentation() 6900 : Type->hasSignedIntegerRepresentation(); 6901 Type = C.getIntTypeForBitwidth(NewSize, IsSigned); 6902 if (!SemaRef.Context.hasSameType(Diff.get()->getType(), Type)) { 6903 Diff = SemaRef.PerformImplicitConversion( 6904 Diff.get(), Type, Sema::AA_Converting, /*AllowExplicit=*/true); 6905 if (!Diff.isUsable()) 6906 return nullptr; 6907 } 6908 } 6909 if (LimitedType) { 6910 unsigned NewSize = (C.getTypeSize(Type) > 32) ? 64 : 32; 6911 if (NewSize != C.getTypeSize(Type)) { 6912 if (NewSize < C.getTypeSize(Type)) { 6913 assert(NewSize == 64 && "incorrect loop var size"); 6914 SemaRef.Diag(DefaultLoc, diag::warn_omp_loop_64_bit_var) 6915 << InitSrcRange << ConditionSrcRange; 6916 } 6917 QualType NewType = C.getIntTypeForBitwidth( 6918 NewSize, Type->hasSignedIntegerRepresentation() || 6919 C.getTypeSize(Type) < NewSize); 6920 if (!SemaRef.Context.hasSameType(Diff.get()->getType(), NewType)) { 6921 Diff = SemaRef.PerformImplicitConversion(Diff.get(), NewType, 6922 Sema::AA_Converting, true); 6923 if (!Diff.isUsable()) 6924 return nullptr; 6925 } 6926 } 6927 } 6928 6929 return Diff.get(); 6930 } 6931 6932 std::pair<Expr *, Expr *> OpenMPIterationSpaceChecker::buildMinMaxValues( 6933 Scope *S, llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const { 6934 // Do not build for iterators, they cannot be used in non-rectangular loop 6935 // nests. 6936 if (LCDecl->getType()->isRecordType()) 6937 return std::make_pair(nullptr, nullptr); 6938 // If we subtract, the min is in the condition, otherwise the min is in the 6939 // init value. 6940 Expr *MinExpr = nullptr; 6941 Expr *MaxExpr = nullptr; 6942 Expr *LBExpr = TestIsLessOp.getValue() ? LB : UB; 6943 Expr *UBExpr = TestIsLessOp.getValue() ? UB : LB; 6944 bool LBNonRect = TestIsLessOp.getValue() ? InitDependOnLC.hasValue() 6945 : CondDependOnLC.hasValue(); 6946 bool UBNonRect = TestIsLessOp.getValue() ? CondDependOnLC.hasValue() 6947 : InitDependOnLC.hasValue(); 6948 Expr *Lower = 6949 LBNonRect ? LBExpr : tryBuildCapture(SemaRef, LBExpr, Captures).get(); 6950 Expr *Upper = 6951 UBNonRect ? UBExpr : tryBuildCapture(SemaRef, UBExpr, Captures).get(); 6952 if (!Upper || !Lower) 6953 return std::make_pair(nullptr, nullptr); 6954 6955 if (TestIsLessOp.getValue()) 6956 MinExpr = Lower; 6957 else 6958 MaxExpr = Upper; 6959 6960 // Build minimum/maximum value based on number of iterations. 6961 ExprResult Diff; 6962 QualType VarType = LCDecl->getType().getNonReferenceType(); 6963 6964 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Lower); 6965 if (!Diff.isUsable()) 6966 return std::make_pair(nullptr, nullptr); 6967 6968 // Upper - Lower [- 1] 6969 if (TestIsStrictOp) 6970 Diff = SemaRef.BuildBinOp( 6971 S, DefaultLoc, BO_Sub, Diff.get(), 6972 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()); 6973 if (!Diff.isUsable()) 6974 return std::make_pair(nullptr, nullptr); 6975 6976 // Upper - Lower [- 1] + Step 6977 ExprResult NewStep = tryBuildCapture(SemaRef, Step, Captures); 6978 if (!NewStep.isUsable()) 6979 return std::make_pair(nullptr, nullptr); 6980 6981 // Parentheses (for dumping/debugging purposes only). 6982 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get()); 6983 if (!Diff.isUsable()) 6984 return std::make_pair(nullptr, nullptr); 6985 6986 // (Upper - Lower [- 1]) / Step 6987 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Div, Diff.get(), NewStep.get()); 6988 if (!Diff.isUsable()) 6989 return std::make_pair(nullptr, nullptr); 6990 6991 // ((Upper - Lower [- 1]) / Step) * Step 6992 // Parentheses (for dumping/debugging purposes only). 6993 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get()); 6994 if (!Diff.isUsable()) 6995 return std::make_pair(nullptr, nullptr); 6996 6997 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Mul, Diff.get(), NewStep.get()); 6998 if (!Diff.isUsable()) 6999 return std::make_pair(nullptr, nullptr); 7000 7001 // Convert to the original type or ptrdiff_t, if original type is pointer. 7002 if (!VarType->isAnyPointerType() && 7003 !SemaRef.Context.hasSameType(Diff.get()->getType(), VarType)) { 7004 Diff = SemaRef.PerformImplicitConversion( 7005 Diff.get(), VarType, Sema::AA_Converting, /*AllowExplicit=*/true); 7006 } else if (VarType->isAnyPointerType() && 7007 !SemaRef.Context.hasSameType( 7008 Diff.get()->getType(), 7009 SemaRef.Context.getUnsignedPointerDiffType())) { 7010 Diff = SemaRef.PerformImplicitConversion( 7011 Diff.get(), SemaRef.Context.getUnsignedPointerDiffType(), 7012 Sema::AA_Converting, /*AllowExplicit=*/true); 7013 } 7014 if (!Diff.isUsable()) 7015 return std::make_pair(nullptr, nullptr); 7016 7017 // Parentheses (for dumping/debugging purposes only). 7018 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get()); 7019 if (!Diff.isUsable()) 7020 return std::make_pair(nullptr, nullptr); 7021 7022 if (TestIsLessOp.getValue()) { 7023 // MinExpr = Lower; 7024 // MaxExpr = Lower + (((Upper - Lower [- 1]) / Step) * Step) 7025 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Add, Lower, Diff.get()); 7026 if (!Diff.isUsable()) 7027 return std::make_pair(nullptr, nullptr); 7028 Diff = SemaRef.ActOnFinishFullExpr(Diff.get(), /*DiscardedValue*/ false); 7029 if (!Diff.isUsable()) 7030 return std::make_pair(nullptr, nullptr); 7031 MaxExpr = Diff.get(); 7032 } else { 7033 // MaxExpr = Upper; 7034 // MinExpr = Upper - (((Upper - Lower [- 1]) / Step) * Step) 7035 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Diff.get()); 7036 if (!Diff.isUsable()) 7037 return std::make_pair(nullptr, nullptr); 7038 Diff = SemaRef.ActOnFinishFullExpr(Diff.get(), /*DiscardedValue*/ false); 7039 if (!Diff.isUsable()) 7040 return std::make_pair(nullptr, nullptr); 7041 MinExpr = Diff.get(); 7042 } 7043 7044 return std::make_pair(MinExpr, MaxExpr); 7045 } 7046 7047 Expr *OpenMPIterationSpaceChecker::buildFinalCondition(Scope *S) const { 7048 if (InitDependOnLC || CondDependOnLC) 7049 return Condition; 7050 return nullptr; 7051 } 7052 7053 Expr *OpenMPIterationSpaceChecker::buildPreCond( 7054 Scope *S, Expr *Cond, 7055 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const { 7056 // Do not build a precondition when the condition/initialization is dependent 7057 // to prevent pessimistic early loop exit. 7058 // TODO: this can be improved by calculating min/max values but not sure that 7059 // it will be very effective. 7060 if (CondDependOnLC || InitDependOnLC) 7061 return SemaRef.PerformImplicitConversion( 7062 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get(), 7063 SemaRef.Context.BoolTy, /*Action=*/Sema::AA_Casting, 7064 /*AllowExplicit=*/true).get(); 7065 7066 // Try to build LB <op> UB, where <op> is <, >, <=, or >=. 7067 Sema::TentativeAnalysisScope Trap(SemaRef); 7068 7069 ExprResult NewLB = tryBuildCapture(SemaRef, LB, Captures); 7070 ExprResult NewUB = tryBuildCapture(SemaRef, UB, Captures); 7071 if (!NewLB.isUsable() || !NewUB.isUsable()) 7072 return nullptr; 7073 7074 ExprResult CondExpr = 7075 SemaRef.BuildBinOp(S, DefaultLoc, 7076 TestIsLessOp.getValue() ? 7077 (TestIsStrictOp ? BO_LT : BO_LE) : 7078 (TestIsStrictOp ? BO_GT : BO_GE), 7079 NewLB.get(), NewUB.get()); 7080 if (CondExpr.isUsable()) { 7081 if (!SemaRef.Context.hasSameUnqualifiedType(CondExpr.get()->getType(), 7082 SemaRef.Context.BoolTy)) 7083 CondExpr = SemaRef.PerformImplicitConversion( 7084 CondExpr.get(), SemaRef.Context.BoolTy, /*Action=*/Sema::AA_Casting, 7085 /*AllowExplicit=*/true); 7086 } 7087 7088 // Otherwise use original loop condition and evaluate it in runtime. 7089 return CondExpr.isUsable() ? CondExpr.get() : Cond; 7090 } 7091 7092 /// Build reference expression to the counter be used for codegen. 7093 DeclRefExpr *OpenMPIterationSpaceChecker::buildCounterVar( 7094 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures, 7095 DSAStackTy &DSA) const { 7096 auto *VD = dyn_cast<VarDecl>(LCDecl); 7097 if (!VD) { 7098 VD = SemaRef.isOpenMPCapturedDecl(LCDecl); 7099 DeclRefExpr *Ref = buildDeclRefExpr( 7100 SemaRef, VD, VD->getType().getNonReferenceType(), DefaultLoc); 7101 const DSAStackTy::DSAVarData Data = 7102 DSA.getTopDSA(LCDecl, /*FromParent=*/false); 7103 // If the loop control decl is explicitly marked as private, do not mark it 7104 // as captured again. 7105 if (!isOpenMPPrivate(Data.CKind) || !Data.RefExpr) 7106 Captures.insert(std::make_pair(LCRef, Ref)); 7107 return Ref; 7108 } 7109 return cast<DeclRefExpr>(LCRef); 7110 } 7111 7112 Expr *OpenMPIterationSpaceChecker::buildPrivateCounterVar() const { 7113 if (LCDecl && !LCDecl->isInvalidDecl()) { 7114 QualType Type = LCDecl->getType().getNonReferenceType(); 7115 VarDecl *PrivateVar = buildVarDecl( 7116 SemaRef, DefaultLoc, Type, LCDecl->getName(), 7117 LCDecl->hasAttrs() ? &LCDecl->getAttrs() : nullptr, 7118 isa<VarDecl>(LCDecl) 7119 ? buildDeclRefExpr(SemaRef, cast<VarDecl>(LCDecl), Type, DefaultLoc) 7120 : nullptr); 7121 if (PrivateVar->isInvalidDecl()) 7122 return nullptr; 7123 return buildDeclRefExpr(SemaRef, PrivateVar, Type, DefaultLoc); 7124 } 7125 return nullptr; 7126 } 7127 7128 /// Build initialization of the counter to be used for codegen. 7129 Expr *OpenMPIterationSpaceChecker::buildCounterInit() const { return LB; } 7130 7131 /// Build step of the counter be used for codegen. 7132 Expr *OpenMPIterationSpaceChecker::buildCounterStep() const { return Step; } 7133 7134 Expr *OpenMPIterationSpaceChecker::buildOrderedLoopData( 7135 Scope *S, Expr *Counter, 7136 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures, SourceLocation Loc, 7137 Expr *Inc, OverloadedOperatorKind OOK) { 7138 Expr *Cnt = SemaRef.DefaultLvalueConversion(Counter).get(); 7139 if (!Cnt) 7140 return nullptr; 7141 if (Inc) { 7142 assert((OOK == OO_Plus || OOK == OO_Minus) && 7143 "Expected only + or - operations for depend clauses."); 7144 BinaryOperatorKind BOK = (OOK == OO_Plus) ? BO_Add : BO_Sub; 7145 Cnt = SemaRef.BuildBinOp(S, Loc, BOK, Cnt, Inc).get(); 7146 if (!Cnt) 7147 return nullptr; 7148 } 7149 ExprResult Diff; 7150 QualType VarType = LCDecl->getType().getNonReferenceType(); 7151 if (VarType->isIntegerType() || VarType->isPointerType() || 7152 SemaRef.getLangOpts().CPlusPlus) { 7153 // Upper - Lower 7154 Expr *Upper = TestIsLessOp.getValue() 7155 ? Cnt 7156 : tryBuildCapture(SemaRef, LB, Captures).get(); 7157 Expr *Lower = TestIsLessOp.getValue() 7158 ? tryBuildCapture(SemaRef, LB, Captures).get() 7159 : Cnt; 7160 if (!Upper || !Lower) 7161 return nullptr; 7162 7163 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Lower); 7164 7165 if (!Diff.isUsable() && VarType->getAsCXXRecordDecl()) { 7166 // BuildBinOp already emitted error, this one is to point user to upper 7167 // and lower bound, and to tell what is passed to 'operator-'. 7168 SemaRef.Diag(Upper->getBeginLoc(), diag::err_omp_loop_diff_cxx) 7169 << Upper->getSourceRange() << Lower->getSourceRange(); 7170 return nullptr; 7171 } 7172 } 7173 7174 if (!Diff.isUsable()) 7175 return nullptr; 7176 7177 // Parentheses (for dumping/debugging purposes only). 7178 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get()); 7179 if (!Diff.isUsable()) 7180 return nullptr; 7181 7182 ExprResult NewStep = tryBuildCapture(SemaRef, Step, Captures); 7183 if (!NewStep.isUsable()) 7184 return nullptr; 7185 // (Upper - Lower) / Step 7186 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Div, Diff.get(), NewStep.get()); 7187 if (!Diff.isUsable()) 7188 return nullptr; 7189 7190 return Diff.get(); 7191 } 7192 } // namespace 7193 7194 void Sema::ActOnOpenMPLoopInitialization(SourceLocation ForLoc, Stmt *Init) { 7195 assert(getLangOpts().OpenMP && "OpenMP is not active."); 7196 assert(Init && "Expected loop in canonical form."); 7197 unsigned AssociatedLoops = DSAStack->getAssociatedLoops(); 7198 if (AssociatedLoops > 0 && 7199 isOpenMPLoopDirective(DSAStack->getCurrentDirective())) { 7200 DSAStack->loopStart(); 7201 OpenMPIterationSpaceChecker ISC(*this, *DSAStack, ForLoc); 7202 if (!ISC.checkAndSetInit(Init, /*EmitDiags=*/false)) { 7203 if (ValueDecl *D = ISC.getLoopDecl()) { 7204 auto *VD = dyn_cast<VarDecl>(D); 7205 DeclRefExpr *PrivateRef = nullptr; 7206 if (!VD) { 7207 if (VarDecl *Private = isOpenMPCapturedDecl(D)) { 7208 VD = Private; 7209 } else { 7210 PrivateRef = buildCapture(*this, D, ISC.getLoopDeclRefExpr(), 7211 /*WithInit=*/false); 7212 VD = cast<VarDecl>(PrivateRef->getDecl()); 7213 } 7214 } 7215 DSAStack->addLoopControlVariable(D, VD); 7216 const Decl *LD = DSAStack->getPossiblyLoopCunter(); 7217 if (LD != D->getCanonicalDecl()) { 7218 DSAStack->resetPossibleLoopCounter(); 7219 if (auto *Var = dyn_cast_or_null<VarDecl>(LD)) 7220 MarkDeclarationsReferencedInExpr( 7221 buildDeclRefExpr(*this, const_cast<VarDecl *>(Var), 7222 Var->getType().getNonLValueExprType(Context), 7223 ForLoc, /*RefersToCapture=*/true)); 7224 } 7225 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 7226 // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables 7227 // Referenced in a Construct, C/C++]. The loop iteration variable in the 7228 // associated for-loop of a simd construct with just one associated 7229 // for-loop may be listed in a linear clause with a constant-linear-step 7230 // that is the increment of the associated for-loop. The loop iteration 7231 // variable(s) in the associated for-loop(s) of a for or parallel for 7232 // construct may be listed in a private or lastprivate clause. 7233 DSAStackTy::DSAVarData DVar = 7234 DSAStack->getTopDSA(D, /*FromParent=*/false); 7235 // If LoopVarRefExpr is nullptr it means the corresponding loop variable 7236 // is declared in the loop and it is predetermined as a private. 7237 Expr *LoopDeclRefExpr = ISC.getLoopDeclRefExpr(); 7238 OpenMPClauseKind PredeterminedCKind = 7239 isOpenMPSimdDirective(DKind) 7240 ? (DSAStack->hasMutipleLoops() ? OMPC_lastprivate : OMPC_linear) 7241 : OMPC_private; 7242 if (((isOpenMPSimdDirective(DKind) && DVar.CKind != OMPC_unknown && 7243 DVar.CKind != PredeterminedCKind && DVar.RefExpr && 7244 (LangOpts.OpenMP <= 45 || (DVar.CKind != OMPC_lastprivate && 7245 DVar.CKind != OMPC_private))) || 7246 ((isOpenMPWorksharingDirective(DKind) || DKind == OMPD_taskloop || 7247 DKind == OMPD_master_taskloop || 7248 DKind == OMPD_parallel_master_taskloop || 7249 isOpenMPDistributeDirective(DKind)) && 7250 !isOpenMPSimdDirective(DKind) && DVar.CKind != OMPC_unknown && 7251 DVar.CKind != OMPC_private && DVar.CKind != OMPC_lastprivate)) && 7252 (DVar.CKind != OMPC_private || DVar.RefExpr)) { 7253 Diag(Init->getBeginLoc(), diag::err_omp_loop_var_dsa) 7254 << getOpenMPClauseName(DVar.CKind) 7255 << getOpenMPDirectiveName(DKind) 7256 << getOpenMPClauseName(PredeterminedCKind); 7257 if (DVar.RefExpr == nullptr) 7258 DVar.CKind = PredeterminedCKind; 7259 reportOriginalDsa(*this, DSAStack, D, DVar, 7260 /*IsLoopIterVar=*/true); 7261 } else if (LoopDeclRefExpr) { 7262 // Make the loop iteration variable private (for worksharing 7263 // constructs), linear (for simd directives with the only one 7264 // associated loop) or lastprivate (for simd directives with several 7265 // collapsed or ordered loops). 7266 if (DVar.CKind == OMPC_unknown) 7267 DSAStack->addDSA(D, LoopDeclRefExpr, PredeterminedCKind, 7268 PrivateRef); 7269 } 7270 } 7271 } 7272 DSAStack->setAssociatedLoops(AssociatedLoops - 1); 7273 } 7274 } 7275 7276 /// Called on a for stmt to check and extract its iteration space 7277 /// for further processing (such as collapsing). 7278 static bool checkOpenMPIterationSpace( 7279 OpenMPDirectiveKind DKind, Stmt *S, Sema &SemaRef, DSAStackTy &DSA, 7280 unsigned CurrentNestedLoopCount, unsigned NestedLoopCount, 7281 unsigned TotalNestedLoopCount, Expr *CollapseLoopCountExpr, 7282 Expr *OrderedLoopCountExpr, 7283 Sema::VarsWithInheritedDSAType &VarsWithImplicitDSA, 7284 llvm::MutableArrayRef<LoopIterationSpace> ResultIterSpaces, 7285 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) { 7286 // OpenMP [2.9.1, Canonical Loop Form] 7287 // for (init-expr; test-expr; incr-expr) structured-block 7288 // for (range-decl: range-expr) structured-block 7289 auto *For = dyn_cast_or_null<ForStmt>(S); 7290 auto *CXXFor = dyn_cast_or_null<CXXForRangeStmt>(S); 7291 // Ranged for is supported only in OpenMP 5.0. 7292 if (!For && (SemaRef.LangOpts.OpenMP <= 45 || !CXXFor)) { 7293 SemaRef.Diag(S->getBeginLoc(), diag::err_omp_not_for) 7294 << (CollapseLoopCountExpr != nullptr || OrderedLoopCountExpr != nullptr) 7295 << getOpenMPDirectiveName(DKind) << TotalNestedLoopCount 7296 << (CurrentNestedLoopCount > 0) << CurrentNestedLoopCount; 7297 if (TotalNestedLoopCount > 1) { 7298 if (CollapseLoopCountExpr && OrderedLoopCountExpr) 7299 SemaRef.Diag(DSA.getConstructLoc(), 7300 diag::note_omp_collapse_ordered_expr) 7301 << 2 << CollapseLoopCountExpr->getSourceRange() 7302 << OrderedLoopCountExpr->getSourceRange(); 7303 else if (CollapseLoopCountExpr) 7304 SemaRef.Diag(CollapseLoopCountExpr->getExprLoc(), 7305 diag::note_omp_collapse_ordered_expr) 7306 << 0 << CollapseLoopCountExpr->getSourceRange(); 7307 else 7308 SemaRef.Diag(OrderedLoopCountExpr->getExprLoc(), 7309 diag::note_omp_collapse_ordered_expr) 7310 << 1 << OrderedLoopCountExpr->getSourceRange(); 7311 } 7312 return true; 7313 } 7314 assert(((For && For->getBody()) || (CXXFor && CXXFor->getBody())) && 7315 "No loop body."); 7316 7317 OpenMPIterationSpaceChecker ISC(SemaRef, DSA, 7318 For ? For->getForLoc() : CXXFor->getForLoc()); 7319 7320 // Check init. 7321 Stmt *Init = For ? For->getInit() : CXXFor->getBeginStmt(); 7322 if (ISC.checkAndSetInit(Init)) 7323 return true; 7324 7325 bool HasErrors = false; 7326 7327 // Check loop variable's type. 7328 if (ValueDecl *LCDecl = ISC.getLoopDecl()) { 7329 // OpenMP [2.6, Canonical Loop Form] 7330 // Var is one of the following: 7331 // A variable of signed or unsigned integer type. 7332 // For C++, a variable of a random access iterator type. 7333 // For C, a variable of a pointer type. 7334 QualType VarType = LCDecl->getType().getNonReferenceType(); 7335 if (!VarType->isDependentType() && !VarType->isIntegerType() && 7336 !VarType->isPointerType() && 7337 !(SemaRef.getLangOpts().CPlusPlus && VarType->isOverloadableType())) { 7338 SemaRef.Diag(Init->getBeginLoc(), diag::err_omp_loop_variable_type) 7339 << SemaRef.getLangOpts().CPlusPlus; 7340 HasErrors = true; 7341 } 7342 7343 // OpenMP, 2.14.1.1 Data-sharing Attribute Rules for Variables Referenced in 7344 // a Construct 7345 // The loop iteration variable(s) in the associated for-loop(s) of a for or 7346 // parallel for construct is (are) private. 7347 // The loop iteration variable in the associated for-loop of a simd 7348 // construct with just one associated for-loop is linear with a 7349 // constant-linear-step that is the increment of the associated for-loop. 7350 // Exclude loop var from the list of variables with implicitly defined data 7351 // sharing attributes. 7352 VarsWithImplicitDSA.erase(LCDecl); 7353 7354 assert(isOpenMPLoopDirective(DKind) && "DSA for non-loop vars"); 7355 7356 // Check test-expr. 7357 HasErrors |= ISC.checkAndSetCond(For ? For->getCond() : CXXFor->getCond()); 7358 7359 // Check incr-expr. 7360 HasErrors |= ISC.checkAndSetInc(For ? For->getInc() : CXXFor->getInc()); 7361 } 7362 7363 if (ISC.dependent() || SemaRef.CurContext->isDependentContext() || HasErrors) 7364 return HasErrors; 7365 7366 // Build the loop's iteration space representation. 7367 ResultIterSpaces[CurrentNestedLoopCount].PreCond = ISC.buildPreCond( 7368 DSA.getCurScope(), For ? For->getCond() : CXXFor->getCond(), Captures); 7369 ResultIterSpaces[CurrentNestedLoopCount].NumIterations = 7370 ISC.buildNumIterations(DSA.getCurScope(), ResultIterSpaces, 7371 (isOpenMPWorksharingDirective(DKind) || 7372 isOpenMPTaskLoopDirective(DKind) || 7373 isOpenMPDistributeDirective(DKind)), 7374 Captures); 7375 ResultIterSpaces[CurrentNestedLoopCount].CounterVar = 7376 ISC.buildCounterVar(Captures, DSA); 7377 ResultIterSpaces[CurrentNestedLoopCount].PrivateCounterVar = 7378 ISC.buildPrivateCounterVar(); 7379 ResultIterSpaces[CurrentNestedLoopCount].CounterInit = ISC.buildCounterInit(); 7380 ResultIterSpaces[CurrentNestedLoopCount].CounterStep = ISC.buildCounterStep(); 7381 ResultIterSpaces[CurrentNestedLoopCount].InitSrcRange = ISC.getInitSrcRange(); 7382 ResultIterSpaces[CurrentNestedLoopCount].CondSrcRange = 7383 ISC.getConditionSrcRange(); 7384 ResultIterSpaces[CurrentNestedLoopCount].IncSrcRange = 7385 ISC.getIncrementSrcRange(); 7386 ResultIterSpaces[CurrentNestedLoopCount].Subtract = ISC.shouldSubtractStep(); 7387 ResultIterSpaces[CurrentNestedLoopCount].IsStrictCompare = 7388 ISC.isStrictTestOp(); 7389 std::tie(ResultIterSpaces[CurrentNestedLoopCount].MinValue, 7390 ResultIterSpaces[CurrentNestedLoopCount].MaxValue) = 7391 ISC.buildMinMaxValues(DSA.getCurScope(), Captures); 7392 ResultIterSpaces[CurrentNestedLoopCount].FinalCondition = 7393 ISC.buildFinalCondition(DSA.getCurScope()); 7394 ResultIterSpaces[CurrentNestedLoopCount].IsNonRectangularLB = 7395 ISC.doesInitDependOnLC(); 7396 ResultIterSpaces[CurrentNestedLoopCount].IsNonRectangularUB = 7397 ISC.doesCondDependOnLC(); 7398 ResultIterSpaces[CurrentNestedLoopCount].LoopDependentIdx = 7399 ISC.getLoopDependentIdx(); 7400 7401 HasErrors |= 7402 (ResultIterSpaces[CurrentNestedLoopCount].PreCond == nullptr || 7403 ResultIterSpaces[CurrentNestedLoopCount].NumIterations == nullptr || 7404 ResultIterSpaces[CurrentNestedLoopCount].CounterVar == nullptr || 7405 ResultIterSpaces[CurrentNestedLoopCount].PrivateCounterVar == nullptr || 7406 ResultIterSpaces[CurrentNestedLoopCount].CounterInit == nullptr || 7407 ResultIterSpaces[CurrentNestedLoopCount].CounterStep == nullptr); 7408 if (!HasErrors && DSA.isOrderedRegion()) { 7409 if (DSA.getOrderedRegionParam().second->getNumForLoops()) { 7410 if (CurrentNestedLoopCount < 7411 DSA.getOrderedRegionParam().second->getLoopNumIterations().size()) { 7412 DSA.getOrderedRegionParam().second->setLoopNumIterations( 7413 CurrentNestedLoopCount, 7414 ResultIterSpaces[CurrentNestedLoopCount].NumIterations); 7415 DSA.getOrderedRegionParam().second->setLoopCounter( 7416 CurrentNestedLoopCount, 7417 ResultIterSpaces[CurrentNestedLoopCount].CounterVar); 7418 } 7419 } 7420 for (auto &Pair : DSA.getDoacrossDependClauses()) { 7421 if (CurrentNestedLoopCount >= Pair.first->getNumLoops()) { 7422 // Erroneous case - clause has some problems. 7423 continue; 7424 } 7425 if (Pair.first->getDependencyKind() == OMPC_DEPEND_sink && 7426 Pair.second.size() <= CurrentNestedLoopCount) { 7427 // Erroneous case - clause has some problems. 7428 Pair.first->setLoopData(CurrentNestedLoopCount, nullptr); 7429 continue; 7430 } 7431 Expr *CntValue; 7432 if (Pair.first->getDependencyKind() == OMPC_DEPEND_source) 7433 CntValue = ISC.buildOrderedLoopData( 7434 DSA.getCurScope(), 7435 ResultIterSpaces[CurrentNestedLoopCount].CounterVar, Captures, 7436 Pair.first->getDependencyLoc()); 7437 else 7438 CntValue = ISC.buildOrderedLoopData( 7439 DSA.getCurScope(), 7440 ResultIterSpaces[CurrentNestedLoopCount].CounterVar, Captures, 7441 Pair.first->getDependencyLoc(), 7442 Pair.second[CurrentNestedLoopCount].first, 7443 Pair.second[CurrentNestedLoopCount].second); 7444 Pair.first->setLoopData(CurrentNestedLoopCount, CntValue); 7445 } 7446 } 7447 7448 return HasErrors; 7449 } 7450 7451 /// Build 'VarRef = Start. 7452 static ExprResult 7453 buildCounterInit(Sema &SemaRef, Scope *S, SourceLocation Loc, ExprResult VarRef, 7454 ExprResult Start, bool IsNonRectangularLB, 7455 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) { 7456 // Build 'VarRef = Start. 7457 ExprResult NewStart = IsNonRectangularLB 7458 ? Start.get() 7459 : tryBuildCapture(SemaRef, Start.get(), Captures); 7460 if (!NewStart.isUsable()) 7461 return ExprError(); 7462 if (!SemaRef.Context.hasSameType(NewStart.get()->getType(), 7463 VarRef.get()->getType())) { 7464 NewStart = SemaRef.PerformImplicitConversion( 7465 NewStart.get(), VarRef.get()->getType(), Sema::AA_Converting, 7466 /*AllowExplicit=*/true); 7467 if (!NewStart.isUsable()) 7468 return ExprError(); 7469 } 7470 7471 ExprResult Init = 7472 SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), NewStart.get()); 7473 return Init; 7474 } 7475 7476 /// Build 'VarRef = Start + Iter * Step'. 7477 static ExprResult buildCounterUpdate( 7478 Sema &SemaRef, Scope *S, SourceLocation Loc, ExprResult VarRef, 7479 ExprResult Start, ExprResult Iter, ExprResult Step, bool Subtract, 7480 bool IsNonRectangularLB, 7481 llvm::MapVector<const Expr *, DeclRefExpr *> *Captures = nullptr) { 7482 // Add parentheses (for debugging purposes only). 7483 Iter = SemaRef.ActOnParenExpr(Loc, Loc, Iter.get()); 7484 if (!VarRef.isUsable() || !Start.isUsable() || !Iter.isUsable() || 7485 !Step.isUsable()) 7486 return ExprError(); 7487 7488 ExprResult NewStep = Step; 7489 if (Captures) 7490 NewStep = tryBuildCapture(SemaRef, Step.get(), *Captures); 7491 if (NewStep.isInvalid()) 7492 return ExprError(); 7493 ExprResult Update = 7494 SemaRef.BuildBinOp(S, Loc, BO_Mul, Iter.get(), NewStep.get()); 7495 if (!Update.isUsable()) 7496 return ExprError(); 7497 7498 // Try to build 'VarRef = Start, VarRef (+|-)= Iter * Step' or 7499 // 'VarRef = Start (+|-) Iter * Step'. 7500 if (!Start.isUsable()) 7501 return ExprError(); 7502 ExprResult NewStart = SemaRef.ActOnParenExpr(Loc, Loc, Start.get()); 7503 if (!NewStart.isUsable()) 7504 return ExprError(); 7505 if (Captures && !IsNonRectangularLB) 7506 NewStart = tryBuildCapture(SemaRef, Start.get(), *Captures); 7507 if (NewStart.isInvalid()) 7508 return ExprError(); 7509 7510 // First attempt: try to build 'VarRef = Start, VarRef += Iter * Step'. 7511 ExprResult SavedUpdate = Update; 7512 ExprResult UpdateVal; 7513 if (VarRef.get()->getType()->isOverloadableType() || 7514 NewStart.get()->getType()->isOverloadableType() || 7515 Update.get()->getType()->isOverloadableType()) { 7516 Sema::TentativeAnalysisScope Trap(SemaRef); 7517 7518 Update = 7519 SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), NewStart.get()); 7520 if (Update.isUsable()) { 7521 UpdateVal = 7522 SemaRef.BuildBinOp(S, Loc, Subtract ? BO_SubAssign : BO_AddAssign, 7523 VarRef.get(), SavedUpdate.get()); 7524 if (UpdateVal.isUsable()) { 7525 Update = SemaRef.CreateBuiltinBinOp(Loc, BO_Comma, Update.get(), 7526 UpdateVal.get()); 7527 } 7528 } 7529 } 7530 7531 // Second attempt: try to build 'VarRef = Start (+|-) Iter * Step'. 7532 if (!Update.isUsable() || !UpdateVal.isUsable()) { 7533 Update = SemaRef.BuildBinOp(S, Loc, Subtract ? BO_Sub : BO_Add, 7534 NewStart.get(), SavedUpdate.get()); 7535 if (!Update.isUsable()) 7536 return ExprError(); 7537 7538 if (!SemaRef.Context.hasSameType(Update.get()->getType(), 7539 VarRef.get()->getType())) { 7540 Update = SemaRef.PerformImplicitConversion( 7541 Update.get(), VarRef.get()->getType(), Sema::AA_Converting, true); 7542 if (!Update.isUsable()) 7543 return ExprError(); 7544 } 7545 7546 Update = SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), Update.get()); 7547 } 7548 return Update; 7549 } 7550 7551 /// Convert integer expression \a E to make it have at least \a Bits 7552 /// bits. 7553 static ExprResult widenIterationCount(unsigned Bits, Expr *E, Sema &SemaRef) { 7554 if (E == nullptr) 7555 return ExprError(); 7556 ASTContext &C = SemaRef.Context; 7557 QualType OldType = E->getType(); 7558 unsigned HasBits = C.getTypeSize(OldType); 7559 if (HasBits >= Bits) 7560 return ExprResult(E); 7561 // OK to convert to signed, because new type has more bits than old. 7562 QualType NewType = C.getIntTypeForBitwidth(Bits, /* Signed */ true); 7563 return SemaRef.PerformImplicitConversion(E, NewType, Sema::AA_Converting, 7564 true); 7565 } 7566 7567 /// Check if the given expression \a E is a constant integer that fits 7568 /// into \a Bits bits. 7569 static bool fitsInto(unsigned Bits, bool Signed, const Expr *E, Sema &SemaRef) { 7570 if (E == nullptr) 7571 return false; 7572 llvm::APSInt Result; 7573 if (E->isIntegerConstantExpr(Result, SemaRef.Context)) 7574 return Signed ? Result.isSignedIntN(Bits) : Result.isIntN(Bits); 7575 return false; 7576 } 7577 7578 /// Build preinits statement for the given declarations. 7579 static Stmt *buildPreInits(ASTContext &Context, 7580 MutableArrayRef<Decl *> PreInits) { 7581 if (!PreInits.empty()) { 7582 return new (Context) DeclStmt( 7583 DeclGroupRef::Create(Context, PreInits.begin(), PreInits.size()), 7584 SourceLocation(), SourceLocation()); 7585 } 7586 return nullptr; 7587 } 7588 7589 /// Build preinits statement for the given declarations. 7590 static Stmt * 7591 buildPreInits(ASTContext &Context, 7592 const llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) { 7593 if (!Captures.empty()) { 7594 SmallVector<Decl *, 16> PreInits; 7595 for (const auto &Pair : Captures) 7596 PreInits.push_back(Pair.second->getDecl()); 7597 return buildPreInits(Context, PreInits); 7598 } 7599 return nullptr; 7600 } 7601 7602 /// Build postupdate expression for the given list of postupdates expressions. 7603 static Expr *buildPostUpdate(Sema &S, ArrayRef<Expr *> PostUpdates) { 7604 Expr *PostUpdate = nullptr; 7605 if (!PostUpdates.empty()) { 7606 for (Expr *E : PostUpdates) { 7607 Expr *ConvE = S.BuildCStyleCastExpr( 7608 E->getExprLoc(), 7609 S.Context.getTrivialTypeSourceInfo(S.Context.VoidTy), 7610 E->getExprLoc(), E) 7611 .get(); 7612 PostUpdate = PostUpdate 7613 ? S.CreateBuiltinBinOp(ConvE->getExprLoc(), BO_Comma, 7614 PostUpdate, ConvE) 7615 .get() 7616 : ConvE; 7617 } 7618 } 7619 return PostUpdate; 7620 } 7621 7622 /// Called on a for stmt to check itself and nested loops (if any). 7623 /// \return Returns 0 if one of the collapsed stmts is not canonical for loop, 7624 /// number of collapsed loops otherwise. 7625 static unsigned 7626 checkOpenMPLoop(OpenMPDirectiveKind DKind, Expr *CollapseLoopCountExpr, 7627 Expr *OrderedLoopCountExpr, Stmt *AStmt, Sema &SemaRef, 7628 DSAStackTy &DSA, 7629 Sema::VarsWithInheritedDSAType &VarsWithImplicitDSA, 7630 OMPLoopDirective::HelperExprs &Built) { 7631 unsigned NestedLoopCount = 1; 7632 if (CollapseLoopCountExpr) { 7633 // Found 'collapse' clause - calculate collapse number. 7634 Expr::EvalResult Result; 7635 if (!CollapseLoopCountExpr->isValueDependent() && 7636 CollapseLoopCountExpr->EvaluateAsInt(Result, SemaRef.getASTContext())) { 7637 NestedLoopCount = Result.Val.getInt().getLimitedValue(); 7638 } else { 7639 Built.clear(/*Size=*/1); 7640 return 1; 7641 } 7642 } 7643 unsigned OrderedLoopCount = 1; 7644 if (OrderedLoopCountExpr) { 7645 // Found 'ordered' clause - calculate collapse number. 7646 Expr::EvalResult EVResult; 7647 if (!OrderedLoopCountExpr->isValueDependent() && 7648 OrderedLoopCountExpr->EvaluateAsInt(EVResult, 7649 SemaRef.getASTContext())) { 7650 llvm::APSInt Result = EVResult.Val.getInt(); 7651 if (Result.getLimitedValue() < NestedLoopCount) { 7652 SemaRef.Diag(OrderedLoopCountExpr->getExprLoc(), 7653 diag::err_omp_wrong_ordered_loop_count) 7654 << OrderedLoopCountExpr->getSourceRange(); 7655 SemaRef.Diag(CollapseLoopCountExpr->getExprLoc(), 7656 diag::note_collapse_loop_count) 7657 << CollapseLoopCountExpr->getSourceRange(); 7658 } 7659 OrderedLoopCount = Result.getLimitedValue(); 7660 } else { 7661 Built.clear(/*Size=*/1); 7662 return 1; 7663 } 7664 } 7665 // This is helper routine for loop directives (e.g., 'for', 'simd', 7666 // 'for simd', etc.). 7667 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 7668 SmallVector<LoopIterationSpace, 4> IterSpaces( 7669 std::max(OrderedLoopCount, NestedLoopCount)); 7670 Stmt *CurStmt = AStmt->IgnoreContainers(/* IgnoreCaptured */ true); 7671 for (unsigned Cnt = 0; Cnt < NestedLoopCount; ++Cnt) { 7672 if (checkOpenMPIterationSpace( 7673 DKind, CurStmt, SemaRef, DSA, Cnt, NestedLoopCount, 7674 std::max(OrderedLoopCount, NestedLoopCount), CollapseLoopCountExpr, 7675 OrderedLoopCountExpr, VarsWithImplicitDSA, IterSpaces, Captures)) 7676 return 0; 7677 // Move on to the next nested for loop, or to the loop body. 7678 // OpenMP [2.8.1, simd construct, Restrictions] 7679 // All loops associated with the construct must be perfectly nested; that 7680 // is, there must be no intervening code nor any OpenMP directive between 7681 // any two loops. 7682 if (auto *For = dyn_cast<ForStmt>(CurStmt)) { 7683 CurStmt = For->getBody(); 7684 } else { 7685 assert(isa<CXXForRangeStmt>(CurStmt) && 7686 "Expected canonical for or range-based for loops."); 7687 CurStmt = cast<CXXForRangeStmt>(CurStmt)->getBody(); 7688 } 7689 CurStmt = OMPLoopDirective::tryToFindNextInnerLoop( 7690 CurStmt, SemaRef.LangOpts.OpenMP >= 50); 7691 } 7692 for (unsigned Cnt = NestedLoopCount; Cnt < OrderedLoopCount; ++Cnt) { 7693 if (checkOpenMPIterationSpace( 7694 DKind, CurStmt, SemaRef, DSA, Cnt, NestedLoopCount, 7695 std::max(OrderedLoopCount, NestedLoopCount), CollapseLoopCountExpr, 7696 OrderedLoopCountExpr, VarsWithImplicitDSA, IterSpaces, Captures)) 7697 return 0; 7698 if (Cnt > 0 && IterSpaces[Cnt].CounterVar) { 7699 // Handle initialization of captured loop iterator variables. 7700 auto *DRE = cast<DeclRefExpr>(IterSpaces[Cnt].CounterVar); 7701 if (isa<OMPCapturedExprDecl>(DRE->getDecl())) { 7702 Captures[DRE] = DRE; 7703 } 7704 } 7705 // Move on to the next nested for loop, or to the loop body. 7706 // OpenMP [2.8.1, simd construct, Restrictions] 7707 // All loops associated with the construct must be perfectly nested; that 7708 // is, there must be no intervening code nor any OpenMP directive between 7709 // any two loops. 7710 if (auto *For = dyn_cast<ForStmt>(CurStmt)) { 7711 CurStmt = For->getBody(); 7712 } else { 7713 assert(isa<CXXForRangeStmt>(CurStmt) && 7714 "Expected canonical for or range-based for loops."); 7715 CurStmt = cast<CXXForRangeStmt>(CurStmt)->getBody(); 7716 } 7717 CurStmt = OMPLoopDirective::tryToFindNextInnerLoop( 7718 CurStmt, SemaRef.LangOpts.OpenMP >= 50); 7719 } 7720 7721 Built.clear(/* size */ NestedLoopCount); 7722 7723 if (SemaRef.CurContext->isDependentContext()) 7724 return NestedLoopCount; 7725 7726 // An example of what is generated for the following code: 7727 // 7728 // #pragma omp simd collapse(2) ordered(2) 7729 // for (i = 0; i < NI; ++i) 7730 // for (k = 0; k < NK; ++k) 7731 // for (j = J0; j < NJ; j+=2) { 7732 // <loop body> 7733 // } 7734 // 7735 // We generate the code below. 7736 // Note: the loop body may be outlined in CodeGen. 7737 // Note: some counters may be C++ classes, operator- is used to find number of 7738 // iterations and operator+= to calculate counter value. 7739 // Note: decltype(NumIterations) must be integer type (in 'omp for', only i32 7740 // or i64 is currently supported). 7741 // 7742 // #define NumIterations (NI * ((NJ - J0 - 1 + 2) / 2)) 7743 // for (int[32|64]_t IV = 0; IV < NumIterations; ++IV ) { 7744 // .local.i = IV / ((NJ - J0 - 1 + 2) / 2); 7745 // .local.j = J0 + (IV % ((NJ - J0 - 1 + 2) / 2)) * 2; 7746 // // similar updates for vars in clauses (e.g. 'linear') 7747 // <loop body (using local i and j)> 7748 // } 7749 // i = NI; // assign final values of counters 7750 // j = NJ; 7751 // 7752 7753 // Last iteration number is (I1 * I2 * ... In) - 1, where I1, I2 ... In are 7754 // the iteration counts of the collapsed for loops. 7755 // Precondition tests if there is at least one iteration (all conditions are 7756 // true). 7757 auto PreCond = ExprResult(IterSpaces[0].PreCond); 7758 Expr *N0 = IterSpaces[0].NumIterations; 7759 ExprResult LastIteration32 = 7760 widenIterationCount(/*Bits=*/32, 7761 SemaRef 7762 .PerformImplicitConversion( 7763 N0->IgnoreImpCasts(), N0->getType(), 7764 Sema::AA_Converting, /*AllowExplicit=*/true) 7765 .get(), 7766 SemaRef); 7767 ExprResult LastIteration64 = widenIterationCount( 7768 /*Bits=*/64, 7769 SemaRef 7770 .PerformImplicitConversion(N0->IgnoreImpCasts(), N0->getType(), 7771 Sema::AA_Converting, 7772 /*AllowExplicit=*/true) 7773 .get(), 7774 SemaRef); 7775 7776 if (!LastIteration32.isUsable() || !LastIteration64.isUsable()) 7777 return NestedLoopCount; 7778 7779 ASTContext &C = SemaRef.Context; 7780 bool AllCountsNeedLessThan32Bits = C.getTypeSize(N0->getType()) < 32; 7781 7782 Scope *CurScope = DSA.getCurScope(); 7783 for (unsigned Cnt = 1; Cnt < NestedLoopCount; ++Cnt) { 7784 if (PreCond.isUsable()) { 7785 PreCond = 7786 SemaRef.BuildBinOp(CurScope, PreCond.get()->getExprLoc(), BO_LAnd, 7787 PreCond.get(), IterSpaces[Cnt].PreCond); 7788 } 7789 Expr *N = IterSpaces[Cnt].NumIterations; 7790 SourceLocation Loc = N->getExprLoc(); 7791 AllCountsNeedLessThan32Bits &= C.getTypeSize(N->getType()) < 32; 7792 if (LastIteration32.isUsable()) 7793 LastIteration32 = SemaRef.BuildBinOp( 7794 CurScope, Loc, BO_Mul, LastIteration32.get(), 7795 SemaRef 7796 .PerformImplicitConversion(N->IgnoreImpCasts(), N->getType(), 7797 Sema::AA_Converting, 7798 /*AllowExplicit=*/true) 7799 .get()); 7800 if (LastIteration64.isUsable()) 7801 LastIteration64 = SemaRef.BuildBinOp( 7802 CurScope, Loc, BO_Mul, LastIteration64.get(), 7803 SemaRef 7804 .PerformImplicitConversion(N->IgnoreImpCasts(), N->getType(), 7805 Sema::AA_Converting, 7806 /*AllowExplicit=*/true) 7807 .get()); 7808 } 7809 7810 // Choose either the 32-bit or 64-bit version. 7811 ExprResult LastIteration = LastIteration64; 7812 if (SemaRef.getLangOpts().OpenMPOptimisticCollapse || 7813 (LastIteration32.isUsable() && 7814 C.getTypeSize(LastIteration32.get()->getType()) == 32 && 7815 (AllCountsNeedLessThan32Bits || NestedLoopCount == 1 || 7816 fitsInto( 7817 /*Bits=*/32, 7818 LastIteration32.get()->getType()->hasSignedIntegerRepresentation(), 7819 LastIteration64.get(), SemaRef)))) 7820 LastIteration = LastIteration32; 7821 QualType VType = LastIteration.get()->getType(); 7822 QualType RealVType = VType; 7823 QualType StrideVType = VType; 7824 if (isOpenMPTaskLoopDirective(DKind)) { 7825 VType = 7826 SemaRef.Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/0); 7827 StrideVType = 7828 SemaRef.Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/1); 7829 } 7830 7831 if (!LastIteration.isUsable()) 7832 return 0; 7833 7834 // Save the number of iterations. 7835 ExprResult NumIterations = LastIteration; 7836 { 7837 LastIteration = SemaRef.BuildBinOp( 7838 CurScope, LastIteration.get()->getExprLoc(), BO_Sub, 7839 LastIteration.get(), 7840 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()); 7841 if (!LastIteration.isUsable()) 7842 return 0; 7843 } 7844 7845 // Calculate the last iteration number beforehand instead of doing this on 7846 // each iteration. Do not do this if the number of iterations may be kfold-ed. 7847 llvm::APSInt Result; 7848 bool IsConstant = 7849 LastIteration.get()->isIntegerConstantExpr(Result, SemaRef.Context); 7850 ExprResult CalcLastIteration; 7851 if (!IsConstant) { 7852 ExprResult SaveRef = 7853 tryBuildCapture(SemaRef, LastIteration.get(), Captures); 7854 LastIteration = SaveRef; 7855 7856 // Prepare SaveRef + 1. 7857 NumIterations = SemaRef.BuildBinOp( 7858 CurScope, SaveRef.get()->getExprLoc(), BO_Add, SaveRef.get(), 7859 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()); 7860 if (!NumIterations.isUsable()) 7861 return 0; 7862 } 7863 7864 SourceLocation InitLoc = IterSpaces[0].InitSrcRange.getBegin(); 7865 7866 // Build variables passed into runtime, necessary for worksharing directives. 7867 ExprResult LB, UB, IL, ST, EUB, CombLB, CombUB, PrevLB, PrevUB, CombEUB; 7868 if (isOpenMPWorksharingDirective(DKind) || isOpenMPTaskLoopDirective(DKind) || 7869 isOpenMPDistributeDirective(DKind)) { 7870 // Lower bound variable, initialized with zero. 7871 VarDecl *LBDecl = buildVarDecl(SemaRef, InitLoc, VType, ".omp.lb"); 7872 LB = buildDeclRefExpr(SemaRef, LBDecl, VType, InitLoc); 7873 SemaRef.AddInitializerToDecl(LBDecl, 7874 SemaRef.ActOnIntegerConstant(InitLoc, 0).get(), 7875 /*DirectInit*/ false); 7876 7877 // Upper bound variable, initialized with last iteration number. 7878 VarDecl *UBDecl = buildVarDecl(SemaRef, InitLoc, VType, ".omp.ub"); 7879 UB = buildDeclRefExpr(SemaRef, UBDecl, VType, InitLoc); 7880 SemaRef.AddInitializerToDecl(UBDecl, LastIteration.get(), 7881 /*DirectInit*/ false); 7882 7883 // A 32-bit variable-flag where runtime returns 1 for the last iteration. 7884 // This will be used to implement clause 'lastprivate'. 7885 QualType Int32Ty = SemaRef.Context.getIntTypeForBitwidth(32, true); 7886 VarDecl *ILDecl = buildVarDecl(SemaRef, InitLoc, Int32Ty, ".omp.is_last"); 7887 IL = buildDeclRefExpr(SemaRef, ILDecl, Int32Ty, InitLoc); 7888 SemaRef.AddInitializerToDecl(ILDecl, 7889 SemaRef.ActOnIntegerConstant(InitLoc, 0).get(), 7890 /*DirectInit*/ false); 7891 7892 // Stride variable returned by runtime (we initialize it to 1 by default). 7893 VarDecl *STDecl = 7894 buildVarDecl(SemaRef, InitLoc, StrideVType, ".omp.stride"); 7895 ST = buildDeclRefExpr(SemaRef, STDecl, StrideVType, InitLoc); 7896 SemaRef.AddInitializerToDecl(STDecl, 7897 SemaRef.ActOnIntegerConstant(InitLoc, 1).get(), 7898 /*DirectInit*/ false); 7899 7900 // Build expression: UB = min(UB, LastIteration) 7901 // It is necessary for CodeGen of directives with static scheduling. 7902 ExprResult IsUBGreater = SemaRef.BuildBinOp(CurScope, InitLoc, BO_GT, 7903 UB.get(), LastIteration.get()); 7904 ExprResult CondOp = SemaRef.ActOnConditionalOp( 7905 LastIteration.get()->getExprLoc(), InitLoc, IsUBGreater.get(), 7906 LastIteration.get(), UB.get()); 7907 EUB = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, UB.get(), 7908 CondOp.get()); 7909 EUB = SemaRef.ActOnFinishFullExpr(EUB.get(), /*DiscardedValue*/ false); 7910 7911 // If we have a combined directive that combines 'distribute', 'for' or 7912 // 'simd' we need to be able to access the bounds of the schedule of the 7913 // enclosing region. E.g. in 'distribute parallel for' the bounds obtained 7914 // by scheduling 'distribute' have to be passed to the schedule of 'for'. 7915 if (isOpenMPLoopBoundSharingDirective(DKind)) { 7916 // Lower bound variable, initialized with zero. 7917 VarDecl *CombLBDecl = 7918 buildVarDecl(SemaRef, InitLoc, VType, ".omp.comb.lb"); 7919 CombLB = buildDeclRefExpr(SemaRef, CombLBDecl, VType, InitLoc); 7920 SemaRef.AddInitializerToDecl( 7921 CombLBDecl, SemaRef.ActOnIntegerConstant(InitLoc, 0).get(), 7922 /*DirectInit*/ false); 7923 7924 // Upper bound variable, initialized with last iteration number. 7925 VarDecl *CombUBDecl = 7926 buildVarDecl(SemaRef, InitLoc, VType, ".omp.comb.ub"); 7927 CombUB = buildDeclRefExpr(SemaRef, CombUBDecl, VType, InitLoc); 7928 SemaRef.AddInitializerToDecl(CombUBDecl, LastIteration.get(), 7929 /*DirectInit*/ false); 7930 7931 ExprResult CombIsUBGreater = SemaRef.BuildBinOp( 7932 CurScope, InitLoc, BO_GT, CombUB.get(), LastIteration.get()); 7933 ExprResult CombCondOp = 7934 SemaRef.ActOnConditionalOp(InitLoc, InitLoc, CombIsUBGreater.get(), 7935 LastIteration.get(), CombUB.get()); 7936 CombEUB = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, CombUB.get(), 7937 CombCondOp.get()); 7938 CombEUB = 7939 SemaRef.ActOnFinishFullExpr(CombEUB.get(), /*DiscardedValue*/ false); 7940 7941 const CapturedDecl *CD = cast<CapturedStmt>(AStmt)->getCapturedDecl(); 7942 // We expect to have at least 2 more parameters than the 'parallel' 7943 // directive does - the lower and upper bounds of the previous schedule. 7944 assert(CD->getNumParams() >= 4 && 7945 "Unexpected number of parameters in loop combined directive"); 7946 7947 // Set the proper type for the bounds given what we learned from the 7948 // enclosed loops. 7949 ImplicitParamDecl *PrevLBDecl = CD->getParam(/*PrevLB=*/2); 7950 ImplicitParamDecl *PrevUBDecl = CD->getParam(/*PrevUB=*/3); 7951 7952 // Previous lower and upper bounds are obtained from the region 7953 // parameters. 7954 PrevLB = 7955 buildDeclRefExpr(SemaRef, PrevLBDecl, PrevLBDecl->getType(), InitLoc); 7956 PrevUB = 7957 buildDeclRefExpr(SemaRef, PrevUBDecl, PrevUBDecl->getType(), InitLoc); 7958 } 7959 } 7960 7961 // Build the iteration variable and its initialization before loop. 7962 ExprResult IV; 7963 ExprResult Init, CombInit; 7964 { 7965 VarDecl *IVDecl = buildVarDecl(SemaRef, InitLoc, RealVType, ".omp.iv"); 7966 IV = buildDeclRefExpr(SemaRef, IVDecl, RealVType, InitLoc); 7967 Expr *RHS = 7968 (isOpenMPWorksharingDirective(DKind) || 7969 isOpenMPTaskLoopDirective(DKind) || isOpenMPDistributeDirective(DKind)) 7970 ? LB.get() 7971 : SemaRef.ActOnIntegerConstant(SourceLocation(), 0).get(); 7972 Init = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, IV.get(), RHS); 7973 Init = SemaRef.ActOnFinishFullExpr(Init.get(), /*DiscardedValue*/ false); 7974 7975 if (isOpenMPLoopBoundSharingDirective(DKind)) { 7976 Expr *CombRHS = 7977 (isOpenMPWorksharingDirective(DKind) || 7978 isOpenMPTaskLoopDirective(DKind) || 7979 isOpenMPDistributeDirective(DKind)) 7980 ? CombLB.get() 7981 : SemaRef.ActOnIntegerConstant(SourceLocation(), 0).get(); 7982 CombInit = 7983 SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, IV.get(), CombRHS); 7984 CombInit = 7985 SemaRef.ActOnFinishFullExpr(CombInit.get(), /*DiscardedValue*/ false); 7986 } 7987 } 7988 7989 bool UseStrictCompare = 7990 RealVType->hasUnsignedIntegerRepresentation() && 7991 llvm::all_of(IterSpaces, [](const LoopIterationSpace &LIS) { 7992 return LIS.IsStrictCompare; 7993 }); 7994 // Loop condition (IV < NumIterations) or (IV <= UB or IV < UB + 1 (for 7995 // unsigned IV)) for worksharing loops. 7996 SourceLocation CondLoc = AStmt->getBeginLoc(); 7997 Expr *BoundUB = UB.get(); 7998 if (UseStrictCompare) { 7999 BoundUB = 8000 SemaRef 8001 .BuildBinOp(CurScope, CondLoc, BO_Add, BoundUB, 8002 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()) 8003 .get(); 8004 BoundUB = 8005 SemaRef.ActOnFinishFullExpr(BoundUB, /*DiscardedValue*/ false).get(); 8006 } 8007 ExprResult Cond = 8008 (isOpenMPWorksharingDirective(DKind) || 8009 isOpenMPTaskLoopDirective(DKind) || isOpenMPDistributeDirective(DKind)) 8010 ? SemaRef.BuildBinOp(CurScope, CondLoc, 8011 UseStrictCompare ? BO_LT : BO_LE, IV.get(), 8012 BoundUB) 8013 : SemaRef.BuildBinOp(CurScope, CondLoc, BO_LT, IV.get(), 8014 NumIterations.get()); 8015 ExprResult CombDistCond; 8016 if (isOpenMPLoopBoundSharingDirective(DKind)) { 8017 CombDistCond = SemaRef.BuildBinOp(CurScope, CondLoc, BO_LT, IV.get(), 8018 NumIterations.get()); 8019 } 8020 8021 ExprResult CombCond; 8022 if (isOpenMPLoopBoundSharingDirective(DKind)) { 8023 Expr *BoundCombUB = CombUB.get(); 8024 if (UseStrictCompare) { 8025 BoundCombUB = 8026 SemaRef 8027 .BuildBinOp( 8028 CurScope, CondLoc, BO_Add, BoundCombUB, 8029 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()) 8030 .get(); 8031 BoundCombUB = 8032 SemaRef.ActOnFinishFullExpr(BoundCombUB, /*DiscardedValue*/ false) 8033 .get(); 8034 } 8035 CombCond = 8036 SemaRef.BuildBinOp(CurScope, CondLoc, UseStrictCompare ? BO_LT : BO_LE, 8037 IV.get(), BoundCombUB); 8038 } 8039 // Loop increment (IV = IV + 1) 8040 SourceLocation IncLoc = AStmt->getBeginLoc(); 8041 ExprResult Inc = 8042 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, IV.get(), 8043 SemaRef.ActOnIntegerConstant(IncLoc, 1).get()); 8044 if (!Inc.isUsable()) 8045 return 0; 8046 Inc = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, IV.get(), Inc.get()); 8047 Inc = SemaRef.ActOnFinishFullExpr(Inc.get(), /*DiscardedValue*/ false); 8048 if (!Inc.isUsable()) 8049 return 0; 8050 8051 // Increments for worksharing loops (LB = LB + ST; UB = UB + ST). 8052 // Used for directives with static scheduling. 8053 // In combined construct, add combined version that use CombLB and CombUB 8054 // base variables for the update 8055 ExprResult NextLB, NextUB, CombNextLB, CombNextUB; 8056 if (isOpenMPWorksharingDirective(DKind) || isOpenMPTaskLoopDirective(DKind) || 8057 isOpenMPDistributeDirective(DKind)) { 8058 // LB + ST 8059 NextLB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, LB.get(), ST.get()); 8060 if (!NextLB.isUsable()) 8061 return 0; 8062 // LB = LB + ST 8063 NextLB = 8064 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, LB.get(), NextLB.get()); 8065 NextLB = 8066 SemaRef.ActOnFinishFullExpr(NextLB.get(), /*DiscardedValue*/ false); 8067 if (!NextLB.isUsable()) 8068 return 0; 8069 // UB + ST 8070 NextUB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, UB.get(), ST.get()); 8071 if (!NextUB.isUsable()) 8072 return 0; 8073 // UB = UB + ST 8074 NextUB = 8075 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, UB.get(), NextUB.get()); 8076 NextUB = 8077 SemaRef.ActOnFinishFullExpr(NextUB.get(), /*DiscardedValue*/ false); 8078 if (!NextUB.isUsable()) 8079 return 0; 8080 if (isOpenMPLoopBoundSharingDirective(DKind)) { 8081 CombNextLB = 8082 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, CombLB.get(), ST.get()); 8083 if (!NextLB.isUsable()) 8084 return 0; 8085 // LB = LB + ST 8086 CombNextLB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, CombLB.get(), 8087 CombNextLB.get()); 8088 CombNextLB = SemaRef.ActOnFinishFullExpr(CombNextLB.get(), 8089 /*DiscardedValue*/ false); 8090 if (!CombNextLB.isUsable()) 8091 return 0; 8092 // UB + ST 8093 CombNextUB = 8094 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, CombUB.get(), ST.get()); 8095 if (!CombNextUB.isUsable()) 8096 return 0; 8097 // UB = UB + ST 8098 CombNextUB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, CombUB.get(), 8099 CombNextUB.get()); 8100 CombNextUB = SemaRef.ActOnFinishFullExpr(CombNextUB.get(), 8101 /*DiscardedValue*/ false); 8102 if (!CombNextUB.isUsable()) 8103 return 0; 8104 } 8105 } 8106 8107 // Create increment expression for distribute loop when combined in a same 8108 // directive with for as IV = IV + ST; ensure upper bound expression based 8109 // on PrevUB instead of NumIterations - used to implement 'for' when found 8110 // in combination with 'distribute', like in 'distribute parallel for' 8111 SourceLocation DistIncLoc = AStmt->getBeginLoc(); 8112 ExprResult DistCond, DistInc, PrevEUB, ParForInDistCond; 8113 if (isOpenMPLoopBoundSharingDirective(DKind)) { 8114 DistCond = SemaRef.BuildBinOp( 8115 CurScope, CondLoc, UseStrictCompare ? BO_LT : BO_LE, IV.get(), BoundUB); 8116 assert(DistCond.isUsable() && "distribute cond expr was not built"); 8117 8118 DistInc = 8119 SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Add, IV.get(), ST.get()); 8120 assert(DistInc.isUsable() && "distribute inc expr was not built"); 8121 DistInc = SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Assign, IV.get(), 8122 DistInc.get()); 8123 DistInc = 8124 SemaRef.ActOnFinishFullExpr(DistInc.get(), /*DiscardedValue*/ false); 8125 assert(DistInc.isUsable() && "distribute inc expr was not built"); 8126 8127 // Build expression: UB = min(UB, prevUB) for #for in composite or combined 8128 // construct 8129 SourceLocation DistEUBLoc = AStmt->getBeginLoc(); 8130 ExprResult IsUBGreater = 8131 SemaRef.BuildBinOp(CurScope, DistEUBLoc, BO_GT, UB.get(), PrevUB.get()); 8132 ExprResult CondOp = SemaRef.ActOnConditionalOp( 8133 DistEUBLoc, DistEUBLoc, IsUBGreater.get(), PrevUB.get(), UB.get()); 8134 PrevEUB = SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Assign, UB.get(), 8135 CondOp.get()); 8136 PrevEUB = 8137 SemaRef.ActOnFinishFullExpr(PrevEUB.get(), /*DiscardedValue*/ false); 8138 8139 // Build IV <= PrevUB or IV < PrevUB + 1 for unsigned IV to be used in 8140 // parallel for is in combination with a distribute directive with 8141 // schedule(static, 1) 8142 Expr *BoundPrevUB = PrevUB.get(); 8143 if (UseStrictCompare) { 8144 BoundPrevUB = 8145 SemaRef 8146 .BuildBinOp( 8147 CurScope, CondLoc, BO_Add, BoundPrevUB, 8148 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()) 8149 .get(); 8150 BoundPrevUB = 8151 SemaRef.ActOnFinishFullExpr(BoundPrevUB, /*DiscardedValue*/ false) 8152 .get(); 8153 } 8154 ParForInDistCond = 8155 SemaRef.BuildBinOp(CurScope, CondLoc, UseStrictCompare ? BO_LT : BO_LE, 8156 IV.get(), BoundPrevUB); 8157 } 8158 8159 // Build updates and final values of the loop counters. 8160 bool HasErrors = false; 8161 Built.Counters.resize(NestedLoopCount); 8162 Built.Inits.resize(NestedLoopCount); 8163 Built.Updates.resize(NestedLoopCount); 8164 Built.Finals.resize(NestedLoopCount); 8165 Built.DependentCounters.resize(NestedLoopCount); 8166 Built.DependentInits.resize(NestedLoopCount); 8167 Built.FinalsConditions.resize(NestedLoopCount); 8168 { 8169 // We implement the following algorithm for obtaining the 8170 // original loop iteration variable values based on the 8171 // value of the collapsed loop iteration variable IV. 8172 // 8173 // Let n+1 be the number of collapsed loops in the nest. 8174 // Iteration variables (I0, I1, .... In) 8175 // Iteration counts (N0, N1, ... Nn) 8176 // 8177 // Acc = IV; 8178 // 8179 // To compute Ik for loop k, 0 <= k <= n, generate: 8180 // Prod = N(k+1) * N(k+2) * ... * Nn; 8181 // Ik = Acc / Prod; 8182 // Acc -= Ik * Prod; 8183 // 8184 ExprResult Acc = IV; 8185 for (unsigned int Cnt = 0; Cnt < NestedLoopCount; ++Cnt) { 8186 LoopIterationSpace &IS = IterSpaces[Cnt]; 8187 SourceLocation UpdLoc = IS.IncSrcRange.getBegin(); 8188 ExprResult Iter; 8189 8190 // Compute prod 8191 ExprResult Prod = 8192 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get(); 8193 for (unsigned int K = Cnt+1; K < NestedLoopCount; ++K) 8194 Prod = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Mul, Prod.get(), 8195 IterSpaces[K].NumIterations); 8196 8197 // Iter = Acc / Prod 8198 // If there is at least one more inner loop to avoid 8199 // multiplication by 1. 8200 if (Cnt + 1 < NestedLoopCount) 8201 Iter = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Div, 8202 Acc.get(), Prod.get()); 8203 else 8204 Iter = Acc; 8205 if (!Iter.isUsable()) { 8206 HasErrors = true; 8207 break; 8208 } 8209 8210 // Update Acc: 8211 // Acc -= Iter * Prod 8212 // Check if there is at least one more inner loop to avoid 8213 // multiplication by 1. 8214 if (Cnt + 1 < NestedLoopCount) 8215 Prod = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Mul, 8216 Iter.get(), Prod.get()); 8217 else 8218 Prod = Iter; 8219 Acc = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Sub, 8220 Acc.get(), Prod.get()); 8221 8222 // Build update: IS.CounterVar(Private) = IS.Start + Iter * IS.Step 8223 auto *VD = cast<VarDecl>(cast<DeclRefExpr>(IS.CounterVar)->getDecl()); 8224 DeclRefExpr *CounterVar = buildDeclRefExpr( 8225 SemaRef, VD, IS.CounterVar->getType(), IS.CounterVar->getExprLoc(), 8226 /*RefersToCapture=*/true); 8227 ExprResult Init = 8228 buildCounterInit(SemaRef, CurScope, UpdLoc, CounterVar, 8229 IS.CounterInit, IS.IsNonRectangularLB, Captures); 8230 if (!Init.isUsable()) { 8231 HasErrors = true; 8232 break; 8233 } 8234 ExprResult Update = buildCounterUpdate( 8235 SemaRef, CurScope, UpdLoc, CounterVar, IS.CounterInit, Iter, 8236 IS.CounterStep, IS.Subtract, IS.IsNonRectangularLB, &Captures); 8237 if (!Update.isUsable()) { 8238 HasErrors = true; 8239 break; 8240 } 8241 8242 // Build final: IS.CounterVar = IS.Start + IS.NumIters * IS.Step 8243 ExprResult Final = 8244 buildCounterUpdate(SemaRef, CurScope, UpdLoc, CounterVar, 8245 IS.CounterInit, IS.NumIterations, IS.CounterStep, 8246 IS.Subtract, IS.IsNonRectangularLB, &Captures); 8247 if (!Final.isUsable()) { 8248 HasErrors = true; 8249 break; 8250 } 8251 8252 if (!Update.isUsable() || !Final.isUsable()) { 8253 HasErrors = true; 8254 break; 8255 } 8256 // Save results 8257 Built.Counters[Cnt] = IS.CounterVar; 8258 Built.PrivateCounters[Cnt] = IS.PrivateCounterVar; 8259 Built.Inits[Cnt] = Init.get(); 8260 Built.Updates[Cnt] = Update.get(); 8261 Built.Finals[Cnt] = Final.get(); 8262 Built.DependentCounters[Cnt] = nullptr; 8263 Built.DependentInits[Cnt] = nullptr; 8264 Built.FinalsConditions[Cnt] = nullptr; 8265 if (IS.IsNonRectangularLB || IS.IsNonRectangularUB) { 8266 Built.DependentCounters[Cnt] = 8267 Built.Counters[NestedLoopCount - 1 - IS.LoopDependentIdx]; 8268 Built.DependentInits[Cnt] = 8269 Built.Inits[NestedLoopCount - 1 - IS.LoopDependentIdx]; 8270 Built.FinalsConditions[Cnt] = IS.FinalCondition; 8271 } 8272 } 8273 } 8274 8275 if (HasErrors) 8276 return 0; 8277 8278 // Save results 8279 Built.IterationVarRef = IV.get(); 8280 Built.LastIteration = LastIteration.get(); 8281 Built.NumIterations = NumIterations.get(); 8282 Built.CalcLastIteration = SemaRef 8283 .ActOnFinishFullExpr(CalcLastIteration.get(), 8284 /*DiscardedValue=*/false) 8285 .get(); 8286 Built.PreCond = PreCond.get(); 8287 Built.PreInits = buildPreInits(C, Captures); 8288 Built.Cond = Cond.get(); 8289 Built.Init = Init.get(); 8290 Built.Inc = Inc.get(); 8291 Built.LB = LB.get(); 8292 Built.UB = UB.get(); 8293 Built.IL = IL.get(); 8294 Built.ST = ST.get(); 8295 Built.EUB = EUB.get(); 8296 Built.NLB = NextLB.get(); 8297 Built.NUB = NextUB.get(); 8298 Built.PrevLB = PrevLB.get(); 8299 Built.PrevUB = PrevUB.get(); 8300 Built.DistInc = DistInc.get(); 8301 Built.PrevEUB = PrevEUB.get(); 8302 Built.DistCombinedFields.LB = CombLB.get(); 8303 Built.DistCombinedFields.UB = CombUB.get(); 8304 Built.DistCombinedFields.EUB = CombEUB.get(); 8305 Built.DistCombinedFields.Init = CombInit.get(); 8306 Built.DistCombinedFields.Cond = CombCond.get(); 8307 Built.DistCombinedFields.NLB = CombNextLB.get(); 8308 Built.DistCombinedFields.NUB = CombNextUB.get(); 8309 Built.DistCombinedFields.DistCond = CombDistCond.get(); 8310 Built.DistCombinedFields.ParForInDistCond = ParForInDistCond.get(); 8311 8312 return NestedLoopCount; 8313 } 8314 8315 static Expr *getCollapseNumberExpr(ArrayRef<OMPClause *> Clauses) { 8316 auto CollapseClauses = 8317 OMPExecutableDirective::getClausesOfKind<OMPCollapseClause>(Clauses); 8318 if (CollapseClauses.begin() != CollapseClauses.end()) 8319 return (*CollapseClauses.begin())->getNumForLoops(); 8320 return nullptr; 8321 } 8322 8323 static Expr *getOrderedNumberExpr(ArrayRef<OMPClause *> Clauses) { 8324 auto OrderedClauses = 8325 OMPExecutableDirective::getClausesOfKind<OMPOrderedClause>(Clauses); 8326 if (OrderedClauses.begin() != OrderedClauses.end()) 8327 return (*OrderedClauses.begin())->getNumForLoops(); 8328 return nullptr; 8329 } 8330 8331 static bool checkSimdlenSafelenSpecified(Sema &S, 8332 const ArrayRef<OMPClause *> Clauses) { 8333 const OMPSafelenClause *Safelen = nullptr; 8334 const OMPSimdlenClause *Simdlen = nullptr; 8335 8336 for (const OMPClause *Clause : Clauses) { 8337 if (Clause->getClauseKind() == OMPC_safelen) 8338 Safelen = cast<OMPSafelenClause>(Clause); 8339 else if (Clause->getClauseKind() == OMPC_simdlen) 8340 Simdlen = cast<OMPSimdlenClause>(Clause); 8341 if (Safelen && Simdlen) 8342 break; 8343 } 8344 8345 if (Simdlen && Safelen) { 8346 const Expr *SimdlenLength = Simdlen->getSimdlen(); 8347 const Expr *SafelenLength = Safelen->getSafelen(); 8348 if (SimdlenLength->isValueDependent() || SimdlenLength->isTypeDependent() || 8349 SimdlenLength->isInstantiationDependent() || 8350 SimdlenLength->containsUnexpandedParameterPack()) 8351 return false; 8352 if (SafelenLength->isValueDependent() || SafelenLength->isTypeDependent() || 8353 SafelenLength->isInstantiationDependent() || 8354 SafelenLength->containsUnexpandedParameterPack()) 8355 return false; 8356 Expr::EvalResult SimdlenResult, SafelenResult; 8357 SimdlenLength->EvaluateAsInt(SimdlenResult, S.Context); 8358 SafelenLength->EvaluateAsInt(SafelenResult, S.Context); 8359 llvm::APSInt SimdlenRes = SimdlenResult.Val.getInt(); 8360 llvm::APSInt SafelenRes = SafelenResult.Val.getInt(); 8361 // OpenMP 4.5 [2.8.1, simd Construct, Restrictions] 8362 // If both simdlen and safelen clauses are specified, the value of the 8363 // simdlen parameter must be less than or equal to the value of the safelen 8364 // parameter. 8365 if (SimdlenRes > SafelenRes) { 8366 S.Diag(SimdlenLength->getExprLoc(), 8367 diag::err_omp_wrong_simdlen_safelen_values) 8368 << SimdlenLength->getSourceRange() << SafelenLength->getSourceRange(); 8369 return true; 8370 } 8371 } 8372 return false; 8373 } 8374 8375 StmtResult 8376 Sema::ActOnOpenMPSimdDirective(ArrayRef<OMPClause *> Clauses, Stmt *AStmt, 8377 SourceLocation StartLoc, SourceLocation EndLoc, 8378 VarsWithInheritedDSAType &VarsWithImplicitDSA) { 8379 if (!AStmt) 8380 return StmtError(); 8381 8382 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 8383 OMPLoopDirective::HelperExprs B; 8384 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 8385 // define the nested loops number. 8386 unsigned NestedLoopCount = checkOpenMPLoop( 8387 OMPD_simd, getCollapseNumberExpr(Clauses), getOrderedNumberExpr(Clauses), 8388 AStmt, *this, *DSAStack, VarsWithImplicitDSA, B); 8389 if (NestedLoopCount == 0) 8390 return StmtError(); 8391 8392 assert((CurContext->isDependentContext() || B.builtAll()) && 8393 "omp simd loop exprs were not built"); 8394 8395 if (!CurContext->isDependentContext()) { 8396 // Finalize the clauses that need pre-built expressions for CodeGen. 8397 for (OMPClause *C : Clauses) { 8398 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 8399 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 8400 B.NumIterations, *this, CurScope, 8401 DSAStack)) 8402 return StmtError(); 8403 } 8404 } 8405 8406 if (checkSimdlenSafelenSpecified(*this, Clauses)) 8407 return StmtError(); 8408 8409 setFunctionHasBranchProtectedScope(); 8410 return OMPSimdDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount, 8411 Clauses, AStmt, B); 8412 } 8413 8414 StmtResult 8415 Sema::ActOnOpenMPForDirective(ArrayRef<OMPClause *> Clauses, Stmt *AStmt, 8416 SourceLocation StartLoc, SourceLocation EndLoc, 8417 VarsWithInheritedDSAType &VarsWithImplicitDSA) { 8418 if (!AStmt) 8419 return StmtError(); 8420 8421 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 8422 OMPLoopDirective::HelperExprs B; 8423 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 8424 // define the nested loops number. 8425 unsigned NestedLoopCount = checkOpenMPLoop( 8426 OMPD_for, getCollapseNumberExpr(Clauses), getOrderedNumberExpr(Clauses), 8427 AStmt, *this, *DSAStack, VarsWithImplicitDSA, B); 8428 if (NestedLoopCount == 0) 8429 return StmtError(); 8430 8431 assert((CurContext->isDependentContext() || B.builtAll()) && 8432 "omp for loop exprs were not built"); 8433 8434 if (!CurContext->isDependentContext()) { 8435 // Finalize the clauses that need pre-built expressions for CodeGen. 8436 for (OMPClause *C : Clauses) { 8437 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 8438 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 8439 B.NumIterations, *this, CurScope, 8440 DSAStack)) 8441 return StmtError(); 8442 } 8443 } 8444 8445 setFunctionHasBranchProtectedScope(); 8446 return OMPForDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount, 8447 Clauses, AStmt, B, DSAStack->isCancelRegion()); 8448 } 8449 8450 StmtResult Sema::ActOnOpenMPForSimdDirective( 8451 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 8452 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 8453 if (!AStmt) 8454 return StmtError(); 8455 8456 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 8457 OMPLoopDirective::HelperExprs B; 8458 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 8459 // define the nested loops number. 8460 unsigned NestedLoopCount = 8461 checkOpenMPLoop(OMPD_for_simd, getCollapseNumberExpr(Clauses), 8462 getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack, 8463 VarsWithImplicitDSA, B); 8464 if (NestedLoopCount == 0) 8465 return StmtError(); 8466 8467 assert((CurContext->isDependentContext() || B.builtAll()) && 8468 "omp for simd loop exprs were not built"); 8469 8470 if (!CurContext->isDependentContext()) { 8471 // Finalize the clauses that need pre-built expressions for CodeGen. 8472 for (OMPClause *C : Clauses) { 8473 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 8474 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 8475 B.NumIterations, *this, CurScope, 8476 DSAStack)) 8477 return StmtError(); 8478 } 8479 } 8480 8481 if (checkSimdlenSafelenSpecified(*this, Clauses)) 8482 return StmtError(); 8483 8484 setFunctionHasBranchProtectedScope(); 8485 return OMPForSimdDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount, 8486 Clauses, AStmt, B); 8487 } 8488 8489 StmtResult Sema::ActOnOpenMPSectionsDirective(ArrayRef<OMPClause *> Clauses, 8490 Stmt *AStmt, 8491 SourceLocation StartLoc, 8492 SourceLocation EndLoc) { 8493 if (!AStmt) 8494 return StmtError(); 8495 8496 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 8497 auto BaseStmt = AStmt; 8498 while (auto *CS = dyn_cast_or_null<CapturedStmt>(BaseStmt)) 8499 BaseStmt = CS->getCapturedStmt(); 8500 if (auto *C = dyn_cast_or_null<CompoundStmt>(BaseStmt)) { 8501 auto S = C->children(); 8502 if (S.begin() == S.end()) 8503 return StmtError(); 8504 // All associated statements must be '#pragma omp section' except for 8505 // the first one. 8506 for (Stmt *SectionStmt : llvm::make_range(std::next(S.begin()), S.end())) { 8507 if (!SectionStmt || !isa<OMPSectionDirective>(SectionStmt)) { 8508 if (SectionStmt) 8509 Diag(SectionStmt->getBeginLoc(), 8510 diag::err_omp_sections_substmt_not_section); 8511 return StmtError(); 8512 } 8513 cast<OMPSectionDirective>(SectionStmt) 8514 ->setHasCancel(DSAStack->isCancelRegion()); 8515 } 8516 } else { 8517 Diag(AStmt->getBeginLoc(), diag::err_omp_sections_not_compound_stmt); 8518 return StmtError(); 8519 } 8520 8521 setFunctionHasBranchProtectedScope(); 8522 8523 return OMPSectionsDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt, 8524 DSAStack->isCancelRegion()); 8525 } 8526 8527 StmtResult Sema::ActOnOpenMPSectionDirective(Stmt *AStmt, 8528 SourceLocation StartLoc, 8529 SourceLocation EndLoc) { 8530 if (!AStmt) 8531 return StmtError(); 8532 8533 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 8534 8535 setFunctionHasBranchProtectedScope(); 8536 DSAStack->setParentCancelRegion(DSAStack->isCancelRegion()); 8537 8538 return OMPSectionDirective::Create(Context, StartLoc, EndLoc, AStmt, 8539 DSAStack->isCancelRegion()); 8540 } 8541 8542 StmtResult Sema::ActOnOpenMPSingleDirective(ArrayRef<OMPClause *> Clauses, 8543 Stmt *AStmt, 8544 SourceLocation StartLoc, 8545 SourceLocation EndLoc) { 8546 if (!AStmt) 8547 return StmtError(); 8548 8549 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 8550 8551 setFunctionHasBranchProtectedScope(); 8552 8553 // OpenMP [2.7.3, single Construct, Restrictions] 8554 // The copyprivate clause must not be used with the nowait clause. 8555 const OMPClause *Nowait = nullptr; 8556 const OMPClause *Copyprivate = nullptr; 8557 for (const OMPClause *Clause : Clauses) { 8558 if (Clause->getClauseKind() == OMPC_nowait) 8559 Nowait = Clause; 8560 else if (Clause->getClauseKind() == OMPC_copyprivate) 8561 Copyprivate = Clause; 8562 if (Copyprivate && Nowait) { 8563 Diag(Copyprivate->getBeginLoc(), 8564 diag::err_omp_single_copyprivate_with_nowait); 8565 Diag(Nowait->getBeginLoc(), diag::note_omp_nowait_clause_here); 8566 return StmtError(); 8567 } 8568 } 8569 8570 return OMPSingleDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt); 8571 } 8572 8573 StmtResult Sema::ActOnOpenMPMasterDirective(Stmt *AStmt, 8574 SourceLocation StartLoc, 8575 SourceLocation EndLoc) { 8576 if (!AStmt) 8577 return StmtError(); 8578 8579 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 8580 8581 setFunctionHasBranchProtectedScope(); 8582 8583 return OMPMasterDirective::Create(Context, StartLoc, EndLoc, AStmt); 8584 } 8585 8586 StmtResult Sema::ActOnOpenMPCriticalDirective( 8587 const DeclarationNameInfo &DirName, ArrayRef<OMPClause *> Clauses, 8588 Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc) { 8589 if (!AStmt) 8590 return StmtError(); 8591 8592 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 8593 8594 bool ErrorFound = false; 8595 llvm::APSInt Hint; 8596 SourceLocation HintLoc; 8597 bool DependentHint = false; 8598 for (const OMPClause *C : Clauses) { 8599 if (C->getClauseKind() == OMPC_hint) { 8600 if (!DirName.getName()) { 8601 Diag(C->getBeginLoc(), diag::err_omp_hint_clause_no_name); 8602 ErrorFound = true; 8603 } 8604 Expr *E = cast<OMPHintClause>(C)->getHint(); 8605 if (E->isTypeDependent() || E->isValueDependent() || 8606 E->isInstantiationDependent()) { 8607 DependentHint = true; 8608 } else { 8609 Hint = E->EvaluateKnownConstInt(Context); 8610 HintLoc = C->getBeginLoc(); 8611 } 8612 } 8613 } 8614 if (ErrorFound) 8615 return StmtError(); 8616 const auto Pair = DSAStack->getCriticalWithHint(DirName); 8617 if (Pair.first && DirName.getName() && !DependentHint) { 8618 if (llvm::APSInt::compareValues(Hint, Pair.second) != 0) { 8619 Diag(StartLoc, diag::err_omp_critical_with_hint); 8620 if (HintLoc.isValid()) 8621 Diag(HintLoc, diag::note_omp_critical_hint_here) 8622 << 0 << Hint.toString(/*Radix=*/10, /*Signed=*/false); 8623 else 8624 Diag(StartLoc, diag::note_omp_critical_no_hint) << 0; 8625 if (const auto *C = Pair.first->getSingleClause<OMPHintClause>()) { 8626 Diag(C->getBeginLoc(), diag::note_omp_critical_hint_here) 8627 << 1 8628 << C->getHint()->EvaluateKnownConstInt(Context).toString( 8629 /*Radix=*/10, /*Signed=*/false); 8630 } else { 8631 Diag(Pair.first->getBeginLoc(), diag::note_omp_critical_no_hint) << 1; 8632 } 8633 } 8634 } 8635 8636 setFunctionHasBranchProtectedScope(); 8637 8638 auto *Dir = OMPCriticalDirective::Create(Context, DirName, StartLoc, EndLoc, 8639 Clauses, AStmt); 8640 if (!Pair.first && DirName.getName() && !DependentHint) 8641 DSAStack->addCriticalWithHint(Dir, Hint); 8642 return Dir; 8643 } 8644 8645 StmtResult Sema::ActOnOpenMPParallelForDirective( 8646 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 8647 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 8648 if (!AStmt) 8649 return StmtError(); 8650 8651 auto *CS = cast<CapturedStmt>(AStmt); 8652 // 1.2.2 OpenMP Language Terminology 8653 // Structured block - An executable statement with a single entry at the 8654 // top and a single exit at the bottom. 8655 // The point of exit cannot be a branch out of the structured block. 8656 // longjmp() and throw() must not violate the entry/exit criteria. 8657 CS->getCapturedDecl()->setNothrow(); 8658 8659 OMPLoopDirective::HelperExprs B; 8660 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 8661 // define the nested loops number. 8662 unsigned NestedLoopCount = 8663 checkOpenMPLoop(OMPD_parallel_for, getCollapseNumberExpr(Clauses), 8664 getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack, 8665 VarsWithImplicitDSA, B); 8666 if (NestedLoopCount == 0) 8667 return StmtError(); 8668 8669 assert((CurContext->isDependentContext() || B.builtAll()) && 8670 "omp parallel for loop exprs were not built"); 8671 8672 if (!CurContext->isDependentContext()) { 8673 // Finalize the clauses that need pre-built expressions for CodeGen. 8674 for (OMPClause *C : Clauses) { 8675 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 8676 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 8677 B.NumIterations, *this, CurScope, 8678 DSAStack)) 8679 return StmtError(); 8680 } 8681 } 8682 8683 setFunctionHasBranchProtectedScope(); 8684 return OMPParallelForDirective::Create(Context, StartLoc, EndLoc, 8685 NestedLoopCount, Clauses, AStmt, B, 8686 DSAStack->isCancelRegion()); 8687 } 8688 8689 StmtResult Sema::ActOnOpenMPParallelForSimdDirective( 8690 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 8691 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 8692 if (!AStmt) 8693 return StmtError(); 8694 8695 auto *CS = cast<CapturedStmt>(AStmt); 8696 // 1.2.2 OpenMP Language Terminology 8697 // Structured block - An executable statement with a single entry at the 8698 // top and a single exit at the bottom. 8699 // The point of exit cannot be a branch out of the structured block. 8700 // longjmp() and throw() must not violate the entry/exit criteria. 8701 CS->getCapturedDecl()->setNothrow(); 8702 8703 OMPLoopDirective::HelperExprs B; 8704 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 8705 // define the nested loops number. 8706 unsigned NestedLoopCount = 8707 checkOpenMPLoop(OMPD_parallel_for_simd, getCollapseNumberExpr(Clauses), 8708 getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack, 8709 VarsWithImplicitDSA, B); 8710 if (NestedLoopCount == 0) 8711 return StmtError(); 8712 8713 if (!CurContext->isDependentContext()) { 8714 // Finalize the clauses that need pre-built expressions for CodeGen. 8715 for (OMPClause *C : Clauses) { 8716 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 8717 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 8718 B.NumIterations, *this, CurScope, 8719 DSAStack)) 8720 return StmtError(); 8721 } 8722 } 8723 8724 if (checkSimdlenSafelenSpecified(*this, Clauses)) 8725 return StmtError(); 8726 8727 setFunctionHasBranchProtectedScope(); 8728 return OMPParallelForSimdDirective::Create( 8729 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 8730 } 8731 8732 StmtResult 8733 Sema::ActOnOpenMPParallelMasterDirective(ArrayRef<OMPClause *> Clauses, 8734 Stmt *AStmt, SourceLocation StartLoc, 8735 SourceLocation EndLoc) { 8736 if (!AStmt) 8737 return StmtError(); 8738 8739 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 8740 auto *CS = cast<CapturedStmt>(AStmt); 8741 // 1.2.2 OpenMP Language Terminology 8742 // Structured block - An executable statement with a single entry at the 8743 // top and a single exit at the bottom. 8744 // The point of exit cannot be a branch out of the structured block. 8745 // longjmp() and throw() must not violate the entry/exit criteria. 8746 CS->getCapturedDecl()->setNothrow(); 8747 8748 setFunctionHasBranchProtectedScope(); 8749 8750 return OMPParallelMasterDirective::Create(Context, StartLoc, EndLoc, Clauses, 8751 AStmt); 8752 } 8753 8754 StmtResult 8755 Sema::ActOnOpenMPParallelSectionsDirective(ArrayRef<OMPClause *> Clauses, 8756 Stmt *AStmt, SourceLocation StartLoc, 8757 SourceLocation EndLoc) { 8758 if (!AStmt) 8759 return StmtError(); 8760 8761 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 8762 auto BaseStmt = AStmt; 8763 while (auto *CS = dyn_cast_or_null<CapturedStmt>(BaseStmt)) 8764 BaseStmt = CS->getCapturedStmt(); 8765 if (auto *C = dyn_cast_or_null<CompoundStmt>(BaseStmt)) { 8766 auto S = C->children(); 8767 if (S.begin() == S.end()) 8768 return StmtError(); 8769 // All associated statements must be '#pragma omp section' except for 8770 // the first one. 8771 for (Stmt *SectionStmt : llvm::make_range(std::next(S.begin()), S.end())) { 8772 if (!SectionStmt || !isa<OMPSectionDirective>(SectionStmt)) { 8773 if (SectionStmt) 8774 Diag(SectionStmt->getBeginLoc(), 8775 diag::err_omp_parallel_sections_substmt_not_section); 8776 return StmtError(); 8777 } 8778 cast<OMPSectionDirective>(SectionStmt) 8779 ->setHasCancel(DSAStack->isCancelRegion()); 8780 } 8781 } else { 8782 Diag(AStmt->getBeginLoc(), 8783 diag::err_omp_parallel_sections_not_compound_stmt); 8784 return StmtError(); 8785 } 8786 8787 setFunctionHasBranchProtectedScope(); 8788 8789 return OMPParallelSectionsDirective::Create( 8790 Context, StartLoc, EndLoc, Clauses, AStmt, DSAStack->isCancelRegion()); 8791 } 8792 8793 /// detach and mergeable clauses are mutially exclusive, check for it. 8794 static bool checkDetachMergeableClauses(Sema &S, 8795 ArrayRef<OMPClause *> Clauses) { 8796 const OMPClause *PrevClause = nullptr; 8797 bool ErrorFound = false; 8798 for (const OMPClause *C : Clauses) { 8799 if (C->getClauseKind() == OMPC_detach || 8800 C->getClauseKind() == OMPC_mergeable) { 8801 if (!PrevClause) { 8802 PrevClause = C; 8803 } else if (PrevClause->getClauseKind() != C->getClauseKind()) { 8804 S.Diag(C->getBeginLoc(), diag::err_omp_clauses_mutually_exclusive) 8805 << getOpenMPClauseName(C->getClauseKind()) 8806 << getOpenMPClauseName(PrevClause->getClauseKind()); 8807 S.Diag(PrevClause->getBeginLoc(), diag::note_omp_previous_clause) 8808 << getOpenMPClauseName(PrevClause->getClauseKind()); 8809 ErrorFound = true; 8810 } 8811 } 8812 } 8813 return ErrorFound; 8814 } 8815 8816 StmtResult Sema::ActOnOpenMPTaskDirective(ArrayRef<OMPClause *> Clauses, 8817 Stmt *AStmt, SourceLocation StartLoc, 8818 SourceLocation EndLoc) { 8819 if (!AStmt) 8820 return StmtError(); 8821 8822 // OpenMP 5.0, 2.10.1 task Construct 8823 // If a detach clause appears on the directive, then a mergeable clause cannot 8824 // appear on the same directive. 8825 if (checkDetachMergeableClauses(*this, Clauses)) 8826 return StmtError(); 8827 8828 auto *CS = cast<CapturedStmt>(AStmt); 8829 // 1.2.2 OpenMP Language Terminology 8830 // Structured block - An executable statement with a single entry at the 8831 // top and a single exit at the bottom. 8832 // The point of exit cannot be a branch out of the structured block. 8833 // longjmp() and throw() must not violate the entry/exit criteria. 8834 CS->getCapturedDecl()->setNothrow(); 8835 8836 setFunctionHasBranchProtectedScope(); 8837 8838 return OMPTaskDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt, 8839 DSAStack->isCancelRegion()); 8840 } 8841 8842 StmtResult Sema::ActOnOpenMPTaskyieldDirective(SourceLocation StartLoc, 8843 SourceLocation EndLoc) { 8844 return OMPTaskyieldDirective::Create(Context, StartLoc, EndLoc); 8845 } 8846 8847 StmtResult Sema::ActOnOpenMPBarrierDirective(SourceLocation StartLoc, 8848 SourceLocation EndLoc) { 8849 return OMPBarrierDirective::Create(Context, StartLoc, EndLoc); 8850 } 8851 8852 StmtResult Sema::ActOnOpenMPTaskwaitDirective(SourceLocation StartLoc, 8853 SourceLocation EndLoc) { 8854 return OMPTaskwaitDirective::Create(Context, StartLoc, EndLoc); 8855 } 8856 8857 StmtResult Sema::ActOnOpenMPTaskgroupDirective(ArrayRef<OMPClause *> Clauses, 8858 Stmt *AStmt, 8859 SourceLocation StartLoc, 8860 SourceLocation EndLoc) { 8861 if (!AStmt) 8862 return StmtError(); 8863 8864 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 8865 8866 setFunctionHasBranchProtectedScope(); 8867 8868 return OMPTaskgroupDirective::Create(Context, StartLoc, EndLoc, Clauses, 8869 AStmt, 8870 DSAStack->getTaskgroupReductionRef()); 8871 } 8872 8873 StmtResult Sema::ActOnOpenMPFlushDirective(ArrayRef<OMPClause *> Clauses, 8874 SourceLocation StartLoc, 8875 SourceLocation EndLoc) { 8876 OMPFlushClause *FC = nullptr; 8877 OMPClause *OrderClause = nullptr; 8878 for (OMPClause *C : Clauses) { 8879 if (C->getClauseKind() == OMPC_flush) 8880 FC = cast<OMPFlushClause>(C); 8881 else 8882 OrderClause = C; 8883 } 8884 OpenMPClauseKind MemOrderKind = OMPC_unknown; 8885 SourceLocation MemOrderLoc; 8886 for (const OMPClause *C : Clauses) { 8887 if (C->getClauseKind() == OMPC_acq_rel || 8888 C->getClauseKind() == OMPC_acquire || 8889 C->getClauseKind() == OMPC_release) { 8890 if (MemOrderKind != OMPC_unknown) { 8891 Diag(C->getBeginLoc(), diag::err_omp_several_mem_order_clauses) 8892 << getOpenMPDirectiveName(OMPD_flush) << 1 8893 << SourceRange(C->getBeginLoc(), C->getEndLoc()); 8894 Diag(MemOrderLoc, diag::note_omp_previous_mem_order_clause) 8895 << getOpenMPClauseName(MemOrderKind); 8896 } else { 8897 MemOrderKind = C->getClauseKind(); 8898 MemOrderLoc = C->getBeginLoc(); 8899 } 8900 } 8901 } 8902 if (FC && OrderClause) { 8903 Diag(FC->getLParenLoc(), diag::err_omp_flush_order_clause_and_list) 8904 << getOpenMPClauseName(OrderClause->getClauseKind()); 8905 Diag(OrderClause->getBeginLoc(), diag::note_omp_flush_order_clause_here) 8906 << getOpenMPClauseName(OrderClause->getClauseKind()); 8907 return StmtError(); 8908 } 8909 return OMPFlushDirective::Create(Context, StartLoc, EndLoc, Clauses); 8910 } 8911 8912 StmtResult Sema::ActOnOpenMPDepobjDirective(ArrayRef<OMPClause *> Clauses, 8913 SourceLocation StartLoc, 8914 SourceLocation EndLoc) { 8915 if (Clauses.empty()) { 8916 Diag(StartLoc, diag::err_omp_depobj_expected); 8917 return StmtError(); 8918 } else if (Clauses[0]->getClauseKind() != OMPC_depobj) { 8919 Diag(Clauses[0]->getBeginLoc(), diag::err_omp_depobj_expected); 8920 return StmtError(); 8921 } 8922 // Only depobj expression and another single clause is allowed. 8923 if (Clauses.size() > 2) { 8924 Diag(Clauses[2]->getBeginLoc(), 8925 diag::err_omp_depobj_single_clause_expected); 8926 return StmtError(); 8927 } else if (Clauses.size() < 1) { 8928 Diag(Clauses[0]->getEndLoc(), diag::err_omp_depobj_single_clause_expected); 8929 return StmtError(); 8930 } 8931 return OMPDepobjDirective::Create(Context, StartLoc, EndLoc, Clauses); 8932 } 8933 8934 StmtResult Sema::ActOnOpenMPScanDirective(ArrayRef<OMPClause *> Clauses, 8935 SourceLocation StartLoc, 8936 SourceLocation EndLoc) { 8937 // Check that exactly one clause is specified. 8938 if (Clauses.size() != 1) { 8939 Diag(Clauses.empty() ? EndLoc : Clauses[1]->getBeginLoc(), 8940 diag::err_omp_scan_single_clause_expected); 8941 return StmtError(); 8942 } 8943 // Check that only one instance of scan directives is used in the same outer 8944 // region. 8945 if (DSAStack->doesParentHasScanDirective()) { 8946 Diag(StartLoc, diag::err_omp_several_scan_directives_in_region); 8947 Diag(DSAStack->getParentScanDirectiveLoc(), 8948 diag::note_omp_previous_scan_directive); 8949 return StmtError(); 8950 } 8951 DSAStack->setParentHasScanDirective(StartLoc); 8952 return OMPScanDirective::Create(Context, StartLoc, EndLoc, Clauses); 8953 } 8954 8955 StmtResult Sema::ActOnOpenMPOrderedDirective(ArrayRef<OMPClause *> Clauses, 8956 Stmt *AStmt, 8957 SourceLocation StartLoc, 8958 SourceLocation EndLoc) { 8959 const OMPClause *DependFound = nullptr; 8960 const OMPClause *DependSourceClause = nullptr; 8961 const OMPClause *DependSinkClause = nullptr; 8962 bool ErrorFound = false; 8963 const OMPThreadsClause *TC = nullptr; 8964 const OMPSIMDClause *SC = nullptr; 8965 for (const OMPClause *C : Clauses) { 8966 if (auto *DC = dyn_cast<OMPDependClause>(C)) { 8967 DependFound = C; 8968 if (DC->getDependencyKind() == OMPC_DEPEND_source) { 8969 if (DependSourceClause) { 8970 Diag(C->getBeginLoc(), diag::err_omp_more_one_clause) 8971 << getOpenMPDirectiveName(OMPD_ordered) 8972 << getOpenMPClauseName(OMPC_depend) << 2; 8973 ErrorFound = true; 8974 } else { 8975 DependSourceClause = C; 8976 } 8977 if (DependSinkClause) { 8978 Diag(C->getBeginLoc(), diag::err_omp_depend_sink_source_not_allowed) 8979 << 0; 8980 ErrorFound = true; 8981 } 8982 } else if (DC->getDependencyKind() == OMPC_DEPEND_sink) { 8983 if (DependSourceClause) { 8984 Diag(C->getBeginLoc(), diag::err_omp_depend_sink_source_not_allowed) 8985 << 1; 8986 ErrorFound = true; 8987 } 8988 DependSinkClause = C; 8989 } 8990 } else if (C->getClauseKind() == OMPC_threads) { 8991 TC = cast<OMPThreadsClause>(C); 8992 } else if (C->getClauseKind() == OMPC_simd) { 8993 SC = cast<OMPSIMDClause>(C); 8994 } 8995 } 8996 if (!ErrorFound && !SC && 8997 isOpenMPSimdDirective(DSAStack->getParentDirective())) { 8998 // OpenMP [2.8.1,simd Construct, Restrictions] 8999 // An ordered construct with the simd clause is the only OpenMP construct 9000 // that can appear in the simd region. 9001 Diag(StartLoc, diag::err_omp_prohibited_region_simd) 9002 << (LangOpts.OpenMP >= 50 ? 1 : 0); 9003 ErrorFound = true; 9004 } else if (DependFound && (TC || SC)) { 9005 Diag(DependFound->getBeginLoc(), diag::err_omp_depend_clause_thread_simd) 9006 << getOpenMPClauseName(TC ? TC->getClauseKind() : SC->getClauseKind()); 9007 ErrorFound = true; 9008 } else if (DependFound && !DSAStack->getParentOrderedRegionParam().first) { 9009 Diag(DependFound->getBeginLoc(), 9010 diag::err_omp_ordered_directive_without_param); 9011 ErrorFound = true; 9012 } else if (TC || Clauses.empty()) { 9013 if (const Expr *Param = DSAStack->getParentOrderedRegionParam().first) { 9014 SourceLocation ErrLoc = TC ? TC->getBeginLoc() : StartLoc; 9015 Diag(ErrLoc, diag::err_omp_ordered_directive_with_param) 9016 << (TC != nullptr); 9017 Diag(Param->getBeginLoc(), diag::note_omp_ordered_param) << 1; 9018 ErrorFound = true; 9019 } 9020 } 9021 if ((!AStmt && !DependFound) || ErrorFound) 9022 return StmtError(); 9023 9024 if (AStmt) { 9025 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 9026 9027 setFunctionHasBranchProtectedScope(); 9028 } 9029 9030 return OMPOrderedDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt); 9031 } 9032 9033 namespace { 9034 /// Helper class for checking expression in 'omp atomic [update]' 9035 /// construct. 9036 class OpenMPAtomicUpdateChecker { 9037 /// Error results for atomic update expressions. 9038 enum ExprAnalysisErrorCode { 9039 /// A statement is not an expression statement. 9040 NotAnExpression, 9041 /// Expression is not builtin binary or unary operation. 9042 NotABinaryOrUnaryExpression, 9043 /// Unary operation is not post-/pre- increment/decrement operation. 9044 NotAnUnaryIncDecExpression, 9045 /// An expression is not of scalar type. 9046 NotAScalarType, 9047 /// A binary operation is not an assignment operation. 9048 NotAnAssignmentOp, 9049 /// RHS part of the binary operation is not a binary expression. 9050 NotABinaryExpression, 9051 /// RHS part is not additive/multiplicative/shift/biwise binary 9052 /// expression. 9053 NotABinaryOperator, 9054 /// RHS binary operation does not have reference to the updated LHS 9055 /// part. 9056 NotAnUpdateExpression, 9057 /// No errors is found. 9058 NoError 9059 }; 9060 /// Reference to Sema. 9061 Sema &SemaRef; 9062 /// A location for note diagnostics (when error is found). 9063 SourceLocation NoteLoc; 9064 /// 'x' lvalue part of the source atomic expression. 9065 Expr *X; 9066 /// 'expr' rvalue part of the source atomic expression. 9067 Expr *E; 9068 /// Helper expression of the form 9069 /// 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or 9070 /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'. 9071 Expr *UpdateExpr; 9072 /// Is 'x' a LHS in a RHS part of full update expression. It is 9073 /// important for non-associative operations. 9074 bool IsXLHSInRHSPart; 9075 BinaryOperatorKind Op; 9076 SourceLocation OpLoc; 9077 /// true if the source expression is a postfix unary operation, false 9078 /// if it is a prefix unary operation. 9079 bool IsPostfixUpdate; 9080 9081 public: 9082 OpenMPAtomicUpdateChecker(Sema &SemaRef) 9083 : SemaRef(SemaRef), X(nullptr), E(nullptr), UpdateExpr(nullptr), 9084 IsXLHSInRHSPart(false), Op(BO_PtrMemD), IsPostfixUpdate(false) {} 9085 /// Check specified statement that it is suitable for 'atomic update' 9086 /// constructs and extract 'x', 'expr' and Operation from the original 9087 /// expression. If DiagId and NoteId == 0, then only check is performed 9088 /// without error notification. 9089 /// \param DiagId Diagnostic which should be emitted if error is found. 9090 /// \param NoteId Diagnostic note for the main error message. 9091 /// \return true if statement is not an update expression, false otherwise. 9092 bool checkStatement(Stmt *S, unsigned DiagId = 0, unsigned NoteId = 0); 9093 /// Return the 'x' lvalue part of the source atomic expression. 9094 Expr *getX() const { return X; } 9095 /// Return the 'expr' rvalue part of the source atomic expression. 9096 Expr *getExpr() const { return E; } 9097 /// Return the update expression used in calculation of the updated 9098 /// value. Always has form 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or 9099 /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'. 9100 Expr *getUpdateExpr() const { return UpdateExpr; } 9101 /// Return true if 'x' is LHS in RHS part of full update expression, 9102 /// false otherwise. 9103 bool isXLHSInRHSPart() const { return IsXLHSInRHSPart; } 9104 9105 /// true if the source expression is a postfix unary operation, false 9106 /// if it is a prefix unary operation. 9107 bool isPostfixUpdate() const { return IsPostfixUpdate; } 9108 9109 private: 9110 bool checkBinaryOperation(BinaryOperator *AtomicBinOp, unsigned DiagId = 0, 9111 unsigned NoteId = 0); 9112 }; 9113 } // namespace 9114 9115 bool OpenMPAtomicUpdateChecker::checkBinaryOperation( 9116 BinaryOperator *AtomicBinOp, unsigned DiagId, unsigned NoteId) { 9117 ExprAnalysisErrorCode ErrorFound = NoError; 9118 SourceLocation ErrorLoc, NoteLoc; 9119 SourceRange ErrorRange, NoteRange; 9120 // Allowed constructs are: 9121 // x = x binop expr; 9122 // x = expr binop x; 9123 if (AtomicBinOp->getOpcode() == BO_Assign) { 9124 X = AtomicBinOp->getLHS(); 9125 if (const auto *AtomicInnerBinOp = dyn_cast<BinaryOperator>( 9126 AtomicBinOp->getRHS()->IgnoreParenImpCasts())) { 9127 if (AtomicInnerBinOp->isMultiplicativeOp() || 9128 AtomicInnerBinOp->isAdditiveOp() || AtomicInnerBinOp->isShiftOp() || 9129 AtomicInnerBinOp->isBitwiseOp()) { 9130 Op = AtomicInnerBinOp->getOpcode(); 9131 OpLoc = AtomicInnerBinOp->getOperatorLoc(); 9132 Expr *LHS = AtomicInnerBinOp->getLHS(); 9133 Expr *RHS = AtomicInnerBinOp->getRHS(); 9134 llvm::FoldingSetNodeID XId, LHSId, RHSId; 9135 X->IgnoreParenImpCasts()->Profile(XId, SemaRef.getASTContext(), 9136 /*Canonical=*/true); 9137 LHS->IgnoreParenImpCasts()->Profile(LHSId, SemaRef.getASTContext(), 9138 /*Canonical=*/true); 9139 RHS->IgnoreParenImpCasts()->Profile(RHSId, SemaRef.getASTContext(), 9140 /*Canonical=*/true); 9141 if (XId == LHSId) { 9142 E = RHS; 9143 IsXLHSInRHSPart = true; 9144 } else if (XId == RHSId) { 9145 E = LHS; 9146 IsXLHSInRHSPart = false; 9147 } else { 9148 ErrorLoc = AtomicInnerBinOp->getExprLoc(); 9149 ErrorRange = AtomicInnerBinOp->getSourceRange(); 9150 NoteLoc = X->getExprLoc(); 9151 NoteRange = X->getSourceRange(); 9152 ErrorFound = NotAnUpdateExpression; 9153 } 9154 } else { 9155 ErrorLoc = AtomicInnerBinOp->getExprLoc(); 9156 ErrorRange = AtomicInnerBinOp->getSourceRange(); 9157 NoteLoc = AtomicInnerBinOp->getOperatorLoc(); 9158 NoteRange = SourceRange(NoteLoc, NoteLoc); 9159 ErrorFound = NotABinaryOperator; 9160 } 9161 } else { 9162 NoteLoc = ErrorLoc = AtomicBinOp->getRHS()->getExprLoc(); 9163 NoteRange = ErrorRange = AtomicBinOp->getRHS()->getSourceRange(); 9164 ErrorFound = NotABinaryExpression; 9165 } 9166 } else { 9167 ErrorLoc = AtomicBinOp->getExprLoc(); 9168 ErrorRange = AtomicBinOp->getSourceRange(); 9169 NoteLoc = AtomicBinOp->getOperatorLoc(); 9170 NoteRange = SourceRange(NoteLoc, NoteLoc); 9171 ErrorFound = NotAnAssignmentOp; 9172 } 9173 if (ErrorFound != NoError && DiagId != 0 && NoteId != 0) { 9174 SemaRef.Diag(ErrorLoc, DiagId) << ErrorRange; 9175 SemaRef.Diag(NoteLoc, NoteId) << ErrorFound << NoteRange; 9176 return true; 9177 } 9178 if (SemaRef.CurContext->isDependentContext()) 9179 E = X = UpdateExpr = nullptr; 9180 return ErrorFound != NoError; 9181 } 9182 9183 bool OpenMPAtomicUpdateChecker::checkStatement(Stmt *S, unsigned DiagId, 9184 unsigned NoteId) { 9185 ExprAnalysisErrorCode ErrorFound = NoError; 9186 SourceLocation ErrorLoc, NoteLoc; 9187 SourceRange ErrorRange, NoteRange; 9188 // Allowed constructs are: 9189 // x++; 9190 // x--; 9191 // ++x; 9192 // --x; 9193 // x binop= expr; 9194 // x = x binop expr; 9195 // x = expr binop x; 9196 if (auto *AtomicBody = dyn_cast<Expr>(S)) { 9197 AtomicBody = AtomicBody->IgnoreParenImpCasts(); 9198 if (AtomicBody->getType()->isScalarType() || 9199 AtomicBody->isInstantiationDependent()) { 9200 if (const auto *AtomicCompAssignOp = dyn_cast<CompoundAssignOperator>( 9201 AtomicBody->IgnoreParenImpCasts())) { 9202 // Check for Compound Assignment Operation 9203 Op = BinaryOperator::getOpForCompoundAssignment( 9204 AtomicCompAssignOp->getOpcode()); 9205 OpLoc = AtomicCompAssignOp->getOperatorLoc(); 9206 E = AtomicCompAssignOp->getRHS(); 9207 X = AtomicCompAssignOp->getLHS()->IgnoreParens(); 9208 IsXLHSInRHSPart = true; 9209 } else if (auto *AtomicBinOp = dyn_cast<BinaryOperator>( 9210 AtomicBody->IgnoreParenImpCasts())) { 9211 // Check for Binary Operation 9212 if (checkBinaryOperation(AtomicBinOp, DiagId, NoteId)) 9213 return true; 9214 } else if (const auto *AtomicUnaryOp = dyn_cast<UnaryOperator>( 9215 AtomicBody->IgnoreParenImpCasts())) { 9216 // Check for Unary Operation 9217 if (AtomicUnaryOp->isIncrementDecrementOp()) { 9218 IsPostfixUpdate = AtomicUnaryOp->isPostfix(); 9219 Op = AtomicUnaryOp->isIncrementOp() ? BO_Add : BO_Sub; 9220 OpLoc = AtomicUnaryOp->getOperatorLoc(); 9221 X = AtomicUnaryOp->getSubExpr()->IgnoreParens(); 9222 E = SemaRef.ActOnIntegerConstant(OpLoc, /*uint64_t Val=*/1).get(); 9223 IsXLHSInRHSPart = true; 9224 } else { 9225 ErrorFound = NotAnUnaryIncDecExpression; 9226 ErrorLoc = AtomicUnaryOp->getExprLoc(); 9227 ErrorRange = AtomicUnaryOp->getSourceRange(); 9228 NoteLoc = AtomicUnaryOp->getOperatorLoc(); 9229 NoteRange = SourceRange(NoteLoc, NoteLoc); 9230 } 9231 } else if (!AtomicBody->isInstantiationDependent()) { 9232 ErrorFound = NotABinaryOrUnaryExpression; 9233 NoteLoc = ErrorLoc = AtomicBody->getExprLoc(); 9234 NoteRange = ErrorRange = AtomicBody->getSourceRange(); 9235 } 9236 } else { 9237 ErrorFound = NotAScalarType; 9238 NoteLoc = ErrorLoc = AtomicBody->getBeginLoc(); 9239 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc); 9240 } 9241 } else { 9242 ErrorFound = NotAnExpression; 9243 NoteLoc = ErrorLoc = S->getBeginLoc(); 9244 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc); 9245 } 9246 if (ErrorFound != NoError && DiagId != 0 && NoteId != 0) { 9247 SemaRef.Diag(ErrorLoc, DiagId) << ErrorRange; 9248 SemaRef.Diag(NoteLoc, NoteId) << ErrorFound << NoteRange; 9249 return true; 9250 } 9251 if (SemaRef.CurContext->isDependentContext()) 9252 E = X = UpdateExpr = nullptr; 9253 if (ErrorFound == NoError && E && X) { 9254 // Build an update expression of form 'OpaqueValueExpr(x) binop 9255 // OpaqueValueExpr(expr)' or 'OpaqueValueExpr(expr) binop 9256 // OpaqueValueExpr(x)' and then cast it to the type of the 'x' expression. 9257 auto *OVEX = new (SemaRef.getASTContext()) 9258 OpaqueValueExpr(X->getExprLoc(), X->getType(), VK_RValue); 9259 auto *OVEExpr = new (SemaRef.getASTContext()) 9260 OpaqueValueExpr(E->getExprLoc(), E->getType(), VK_RValue); 9261 ExprResult Update = 9262 SemaRef.CreateBuiltinBinOp(OpLoc, Op, IsXLHSInRHSPart ? OVEX : OVEExpr, 9263 IsXLHSInRHSPart ? OVEExpr : OVEX); 9264 if (Update.isInvalid()) 9265 return true; 9266 Update = SemaRef.PerformImplicitConversion(Update.get(), X->getType(), 9267 Sema::AA_Casting); 9268 if (Update.isInvalid()) 9269 return true; 9270 UpdateExpr = Update.get(); 9271 } 9272 return ErrorFound != NoError; 9273 } 9274 9275 StmtResult Sema::ActOnOpenMPAtomicDirective(ArrayRef<OMPClause *> Clauses, 9276 Stmt *AStmt, 9277 SourceLocation StartLoc, 9278 SourceLocation EndLoc) { 9279 // Register location of the first atomic directive. 9280 DSAStack->addAtomicDirectiveLoc(StartLoc); 9281 if (!AStmt) 9282 return StmtError(); 9283 9284 auto *CS = cast<CapturedStmt>(AStmt); 9285 // 1.2.2 OpenMP Language Terminology 9286 // Structured block - An executable statement with a single entry at the 9287 // top and a single exit at the bottom. 9288 // The point of exit cannot be a branch out of the structured block. 9289 // longjmp() and throw() must not violate the entry/exit criteria. 9290 OpenMPClauseKind AtomicKind = OMPC_unknown; 9291 SourceLocation AtomicKindLoc; 9292 OpenMPClauseKind MemOrderKind = OMPC_unknown; 9293 SourceLocation MemOrderLoc; 9294 for (const OMPClause *C : Clauses) { 9295 if (C->getClauseKind() == OMPC_read || C->getClauseKind() == OMPC_write || 9296 C->getClauseKind() == OMPC_update || 9297 C->getClauseKind() == OMPC_capture) { 9298 if (AtomicKind != OMPC_unknown) { 9299 Diag(C->getBeginLoc(), diag::err_omp_atomic_several_clauses) 9300 << SourceRange(C->getBeginLoc(), C->getEndLoc()); 9301 Diag(AtomicKindLoc, diag::note_omp_previous_mem_order_clause) 9302 << getOpenMPClauseName(AtomicKind); 9303 } else { 9304 AtomicKind = C->getClauseKind(); 9305 AtomicKindLoc = C->getBeginLoc(); 9306 } 9307 } 9308 if (C->getClauseKind() == OMPC_seq_cst || 9309 C->getClauseKind() == OMPC_acq_rel || 9310 C->getClauseKind() == OMPC_acquire || 9311 C->getClauseKind() == OMPC_release || 9312 C->getClauseKind() == OMPC_relaxed) { 9313 if (MemOrderKind != OMPC_unknown) { 9314 Diag(C->getBeginLoc(), diag::err_omp_several_mem_order_clauses) 9315 << getOpenMPDirectiveName(OMPD_atomic) << 0 9316 << SourceRange(C->getBeginLoc(), C->getEndLoc()); 9317 Diag(MemOrderLoc, diag::note_omp_previous_mem_order_clause) 9318 << getOpenMPClauseName(MemOrderKind); 9319 } else { 9320 MemOrderKind = C->getClauseKind(); 9321 MemOrderLoc = C->getBeginLoc(); 9322 } 9323 } 9324 } 9325 // OpenMP 5.0, 2.17.7 atomic Construct, Restrictions 9326 // If atomic-clause is read then memory-order-clause must not be acq_rel or 9327 // release. 9328 // If atomic-clause is write then memory-order-clause must not be acq_rel or 9329 // acquire. 9330 // If atomic-clause is update or not present then memory-order-clause must not 9331 // be acq_rel or acquire. 9332 if ((AtomicKind == OMPC_read && 9333 (MemOrderKind == OMPC_acq_rel || MemOrderKind == OMPC_release)) || 9334 ((AtomicKind == OMPC_write || AtomicKind == OMPC_update || 9335 AtomicKind == OMPC_unknown) && 9336 (MemOrderKind == OMPC_acq_rel || MemOrderKind == OMPC_acquire))) { 9337 SourceLocation Loc = AtomicKindLoc; 9338 if (AtomicKind == OMPC_unknown) 9339 Loc = StartLoc; 9340 Diag(Loc, diag::err_omp_atomic_incompatible_mem_order_clause) 9341 << getOpenMPClauseName(AtomicKind) 9342 << (AtomicKind == OMPC_unknown ? 1 : 0) 9343 << getOpenMPClauseName(MemOrderKind); 9344 Diag(MemOrderLoc, diag::note_omp_previous_mem_order_clause) 9345 << getOpenMPClauseName(MemOrderKind); 9346 } 9347 9348 Stmt *Body = CS->getCapturedStmt(); 9349 if (auto *EWC = dyn_cast<ExprWithCleanups>(Body)) 9350 Body = EWC->getSubExpr(); 9351 9352 Expr *X = nullptr; 9353 Expr *V = nullptr; 9354 Expr *E = nullptr; 9355 Expr *UE = nullptr; 9356 bool IsXLHSInRHSPart = false; 9357 bool IsPostfixUpdate = false; 9358 // OpenMP [2.12.6, atomic Construct] 9359 // In the next expressions: 9360 // * x and v (as applicable) are both l-value expressions with scalar type. 9361 // * During the execution of an atomic region, multiple syntactic 9362 // occurrences of x must designate the same storage location. 9363 // * Neither of v and expr (as applicable) may access the storage location 9364 // designated by x. 9365 // * Neither of x and expr (as applicable) may access the storage location 9366 // designated by v. 9367 // * expr is an expression with scalar type. 9368 // * binop is one of +, *, -, /, &, ^, |, <<, or >>. 9369 // * binop, binop=, ++, and -- are not overloaded operators. 9370 // * The expression x binop expr must be numerically equivalent to x binop 9371 // (expr). This requirement is satisfied if the operators in expr have 9372 // precedence greater than binop, or by using parentheses around expr or 9373 // subexpressions of expr. 9374 // * The expression expr binop x must be numerically equivalent to (expr) 9375 // binop x. This requirement is satisfied if the operators in expr have 9376 // precedence equal to or greater than binop, or by using parentheses around 9377 // expr or subexpressions of expr. 9378 // * For forms that allow multiple occurrences of x, the number of times 9379 // that x is evaluated is unspecified. 9380 if (AtomicKind == OMPC_read) { 9381 enum { 9382 NotAnExpression, 9383 NotAnAssignmentOp, 9384 NotAScalarType, 9385 NotAnLValue, 9386 NoError 9387 } ErrorFound = NoError; 9388 SourceLocation ErrorLoc, NoteLoc; 9389 SourceRange ErrorRange, NoteRange; 9390 // If clause is read: 9391 // v = x; 9392 if (const auto *AtomicBody = dyn_cast<Expr>(Body)) { 9393 const auto *AtomicBinOp = 9394 dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts()); 9395 if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) { 9396 X = AtomicBinOp->getRHS()->IgnoreParenImpCasts(); 9397 V = AtomicBinOp->getLHS()->IgnoreParenImpCasts(); 9398 if ((X->isInstantiationDependent() || X->getType()->isScalarType()) && 9399 (V->isInstantiationDependent() || V->getType()->isScalarType())) { 9400 if (!X->isLValue() || !V->isLValue()) { 9401 const Expr *NotLValueExpr = X->isLValue() ? V : X; 9402 ErrorFound = NotAnLValue; 9403 ErrorLoc = AtomicBinOp->getExprLoc(); 9404 ErrorRange = AtomicBinOp->getSourceRange(); 9405 NoteLoc = NotLValueExpr->getExprLoc(); 9406 NoteRange = NotLValueExpr->getSourceRange(); 9407 } 9408 } else if (!X->isInstantiationDependent() || 9409 !V->isInstantiationDependent()) { 9410 const Expr *NotScalarExpr = 9411 (X->isInstantiationDependent() || X->getType()->isScalarType()) 9412 ? V 9413 : X; 9414 ErrorFound = NotAScalarType; 9415 ErrorLoc = AtomicBinOp->getExprLoc(); 9416 ErrorRange = AtomicBinOp->getSourceRange(); 9417 NoteLoc = NotScalarExpr->getExprLoc(); 9418 NoteRange = NotScalarExpr->getSourceRange(); 9419 } 9420 } else if (!AtomicBody->isInstantiationDependent()) { 9421 ErrorFound = NotAnAssignmentOp; 9422 ErrorLoc = AtomicBody->getExprLoc(); 9423 ErrorRange = AtomicBody->getSourceRange(); 9424 NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc() 9425 : AtomicBody->getExprLoc(); 9426 NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange() 9427 : AtomicBody->getSourceRange(); 9428 } 9429 } else { 9430 ErrorFound = NotAnExpression; 9431 NoteLoc = ErrorLoc = Body->getBeginLoc(); 9432 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc); 9433 } 9434 if (ErrorFound != NoError) { 9435 Diag(ErrorLoc, diag::err_omp_atomic_read_not_expression_statement) 9436 << ErrorRange; 9437 Diag(NoteLoc, diag::note_omp_atomic_read_write) << ErrorFound 9438 << NoteRange; 9439 return StmtError(); 9440 } 9441 if (CurContext->isDependentContext()) 9442 V = X = nullptr; 9443 } else if (AtomicKind == OMPC_write) { 9444 enum { 9445 NotAnExpression, 9446 NotAnAssignmentOp, 9447 NotAScalarType, 9448 NotAnLValue, 9449 NoError 9450 } ErrorFound = NoError; 9451 SourceLocation ErrorLoc, NoteLoc; 9452 SourceRange ErrorRange, NoteRange; 9453 // If clause is write: 9454 // x = expr; 9455 if (const auto *AtomicBody = dyn_cast<Expr>(Body)) { 9456 const auto *AtomicBinOp = 9457 dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts()); 9458 if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) { 9459 X = AtomicBinOp->getLHS(); 9460 E = AtomicBinOp->getRHS(); 9461 if ((X->isInstantiationDependent() || X->getType()->isScalarType()) && 9462 (E->isInstantiationDependent() || E->getType()->isScalarType())) { 9463 if (!X->isLValue()) { 9464 ErrorFound = NotAnLValue; 9465 ErrorLoc = AtomicBinOp->getExprLoc(); 9466 ErrorRange = AtomicBinOp->getSourceRange(); 9467 NoteLoc = X->getExprLoc(); 9468 NoteRange = X->getSourceRange(); 9469 } 9470 } else if (!X->isInstantiationDependent() || 9471 !E->isInstantiationDependent()) { 9472 const Expr *NotScalarExpr = 9473 (X->isInstantiationDependent() || X->getType()->isScalarType()) 9474 ? E 9475 : X; 9476 ErrorFound = NotAScalarType; 9477 ErrorLoc = AtomicBinOp->getExprLoc(); 9478 ErrorRange = AtomicBinOp->getSourceRange(); 9479 NoteLoc = NotScalarExpr->getExprLoc(); 9480 NoteRange = NotScalarExpr->getSourceRange(); 9481 } 9482 } else if (!AtomicBody->isInstantiationDependent()) { 9483 ErrorFound = NotAnAssignmentOp; 9484 ErrorLoc = AtomicBody->getExprLoc(); 9485 ErrorRange = AtomicBody->getSourceRange(); 9486 NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc() 9487 : AtomicBody->getExprLoc(); 9488 NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange() 9489 : AtomicBody->getSourceRange(); 9490 } 9491 } else { 9492 ErrorFound = NotAnExpression; 9493 NoteLoc = ErrorLoc = Body->getBeginLoc(); 9494 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc); 9495 } 9496 if (ErrorFound != NoError) { 9497 Diag(ErrorLoc, diag::err_omp_atomic_write_not_expression_statement) 9498 << ErrorRange; 9499 Diag(NoteLoc, diag::note_omp_atomic_read_write) << ErrorFound 9500 << NoteRange; 9501 return StmtError(); 9502 } 9503 if (CurContext->isDependentContext()) 9504 E = X = nullptr; 9505 } else if (AtomicKind == OMPC_update || AtomicKind == OMPC_unknown) { 9506 // If clause is update: 9507 // x++; 9508 // x--; 9509 // ++x; 9510 // --x; 9511 // x binop= expr; 9512 // x = x binop expr; 9513 // x = expr binop x; 9514 OpenMPAtomicUpdateChecker Checker(*this); 9515 if (Checker.checkStatement( 9516 Body, (AtomicKind == OMPC_update) 9517 ? diag::err_omp_atomic_update_not_expression_statement 9518 : diag::err_omp_atomic_not_expression_statement, 9519 diag::note_omp_atomic_update)) 9520 return StmtError(); 9521 if (!CurContext->isDependentContext()) { 9522 E = Checker.getExpr(); 9523 X = Checker.getX(); 9524 UE = Checker.getUpdateExpr(); 9525 IsXLHSInRHSPart = Checker.isXLHSInRHSPart(); 9526 } 9527 } else if (AtomicKind == OMPC_capture) { 9528 enum { 9529 NotAnAssignmentOp, 9530 NotACompoundStatement, 9531 NotTwoSubstatements, 9532 NotASpecificExpression, 9533 NoError 9534 } ErrorFound = NoError; 9535 SourceLocation ErrorLoc, NoteLoc; 9536 SourceRange ErrorRange, NoteRange; 9537 if (const auto *AtomicBody = dyn_cast<Expr>(Body)) { 9538 // If clause is a capture: 9539 // v = x++; 9540 // v = x--; 9541 // v = ++x; 9542 // v = --x; 9543 // v = x binop= expr; 9544 // v = x = x binop expr; 9545 // v = x = expr binop x; 9546 const auto *AtomicBinOp = 9547 dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts()); 9548 if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) { 9549 V = AtomicBinOp->getLHS(); 9550 Body = AtomicBinOp->getRHS()->IgnoreParenImpCasts(); 9551 OpenMPAtomicUpdateChecker Checker(*this); 9552 if (Checker.checkStatement( 9553 Body, diag::err_omp_atomic_capture_not_expression_statement, 9554 diag::note_omp_atomic_update)) 9555 return StmtError(); 9556 E = Checker.getExpr(); 9557 X = Checker.getX(); 9558 UE = Checker.getUpdateExpr(); 9559 IsXLHSInRHSPart = Checker.isXLHSInRHSPart(); 9560 IsPostfixUpdate = Checker.isPostfixUpdate(); 9561 } else if (!AtomicBody->isInstantiationDependent()) { 9562 ErrorLoc = AtomicBody->getExprLoc(); 9563 ErrorRange = AtomicBody->getSourceRange(); 9564 NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc() 9565 : AtomicBody->getExprLoc(); 9566 NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange() 9567 : AtomicBody->getSourceRange(); 9568 ErrorFound = NotAnAssignmentOp; 9569 } 9570 if (ErrorFound != NoError) { 9571 Diag(ErrorLoc, diag::err_omp_atomic_capture_not_expression_statement) 9572 << ErrorRange; 9573 Diag(NoteLoc, diag::note_omp_atomic_capture) << ErrorFound << NoteRange; 9574 return StmtError(); 9575 } 9576 if (CurContext->isDependentContext()) 9577 UE = V = E = X = nullptr; 9578 } else { 9579 // If clause is a capture: 9580 // { v = x; x = expr; } 9581 // { v = x; x++; } 9582 // { v = x; x--; } 9583 // { v = x; ++x; } 9584 // { v = x; --x; } 9585 // { v = x; x binop= expr; } 9586 // { v = x; x = x binop expr; } 9587 // { v = x; x = expr binop x; } 9588 // { x++; v = x; } 9589 // { x--; v = x; } 9590 // { ++x; v = x; } 9591 // { --x; v = x; } 9592 // { x binop= expr; v = x; } 9593 // { x = x binop expr; v = x; } 9594 // { x = expr binop x; v = x; } 9595 if (auto *CS = dyn_cast<CompoundStmt>(Body)) { 9596 // Check that this is { expr1; expr2; } 9597 if (CS->size() == 2) { 9598 Stmt *First = CS->body_front(); 9599 Stmt *Second = CS->body_back(); 9600 if (auto *EWC = dyn_cast<ExprWithCleanups>(First)) 9601 First = EWC->getSubExpr()->IgnoreParenImpCasts(); 9602 if (auto *EWC = dyn_cast<ExprWithCleanups>(Second)) 9603 Second = EWC->getSubExpr()->IgnoreParenImpCasts(); 9604 // Need to find what subexpression is 'v' and what is 'x'. 9605 OpenMPAtomicUpdateChecker Checker(*this); 9606 bool IsUpdateExprFound = !Checker.checkStatement(Second); 9607 BinaryOperator *BinOp = nullptr; 9608 if (IsUpdateExprFound) { 9609 BinOp = dyn_cast<BinaryOperator>(First); 9610 IsUpdateExprFound = BinOp && BinOp->getOpcode() == BO_Assign; 9611 } 9612 if (IsUpdateExprFound && !CurContext->isDependentContext()) { 9613 // { v = x; x++; } 9614 // { v = x; x--; } 9615 // { v = x; ++x; } 9616 // { v = x; --x; } 9617 // { v = x; x binop= expr; } 9618 // { v = x; x = x binop expr; } 9619 // { v = x; x = expr binop x; } 9620 // Check that the first expression has form v = x. 9621 Expr *PossibleX = BinOp->getRHS()->IgnoreParenImpCasts(); 9622 llvm::FoldingSetNodeID XId, PossibleXId; 9623 Checker.getX()->Profile(XId, Context, /*Canonical=*/true); 9624 PossibleX->Profile(PossibleXId, Context, /*Canonical=*/true); 9625 IsUpdateExprFound = XId == PossibleXId; 9626 if (IsUpdateExprFound) { 9627 V = BinOp->getLHS(); 9628 X = Checker.getX(); 9629 E = Checker.getExpr(); 9630 UE = Checker.getUpdateExpr(); 9631 IsXLHSInRHSPart = Checker.isXLHSInRHSPart(); 9632 IsPostfixUpdate = true; 9633 } 9634 } 9635 if (!IsUpdateExprFound) { 9636 IsUpdateExprFound = !Checker.checkStatement(First); 9637 BinOp = nullptr; 9638 if (IsUpdateExprFound) { 9639 BinOp = dyn_cast<BinaryOperator>(Second); 9640 IsUpdateExprFound = BinOp && BinOp->getOpcode() == BO_Assign; 9641 } 9642 if (IsUpdateExprFound && !CurContext->isDependentContext()) { 9643 // { x++; v = x; } 9644 // { x--; v = x; } 9645 // { ++x; v = x; } 9646 // { --x; v = x; } 9647 // { x binop= expr; v = x; } 9648 // { x = x binop expr; v = x; } 9649 // { x = expr binop x; v = x; } 9650 // Check that the second expression has form v = x. 9651 Expr *PossibleX = BinOp->getRHS()->IgnoreParenImpCasts(); 9652 llvm::FoldingSetNodeID XId, PossibleXId; 9653 Checker.getX()->Profile(XId, Context, /*Canonical=*/true); 9654 PossibleX->Profile(PossibleXId, Context, /*Canonical=*/true); 9655 IsUpdateExprFound = XId == PossibleXId; 9656 if (IsUpdateExprFound) { 9657 V = BinOp->getLHS(); 9658 X = Checker.getX(); 9659 E = Checker.getExpr(); 9660 UE = Checker.getUpdateExpr(); 9661 IsXLHSInRHSPart = Checker.isXLHSInRHSPart(); 9662 IsPostfixUpdate = false; 9663 } 9664 } 9665 } 9666 if (!IsUpdateExprFound) { 9667 // { v = x; x = expr; } 9668 auto *FirstExpr = dyn_cast<Expr>(First); 9669 auto *SecondExpr = dyn_cast<Expr>(Second); 9670 if (!FirstExpr || !SecondExpr || 9671 !(FirstExpr->isInstantiationDependent() || 9672 SecondExpr->isInstantiationDependent())) { 9673 auto *FirstBinOp = dyn_cast<BinaryOperator>(First); 9674 if (!FirstBinOp || FirstBinOp->getOpcode() != BO_Assign) { 9675 ErrorFound = NotAnAssignmentOp; 9676 NoteLoc = ErrorLoc = FirstBinOp ? FirstBinOp->getOperatorLoc() 9677 : First->getBeginLoc(); 9678 NoteRange = ErrorRange = FirstBinOp 9679 ? FirstBinOp->getSourceRange() 9680 : SourceRange(ErrorLoc, ErrorLoc); 9681 } else { 9682 auto *SecondBinOp = dyn_cast<BinaryOperator>(Second); 9683 if (!SecondBinOp || SecondBinOp->getOpcode() != BO_Assign) { 9684 ErrorFound = NotAnAssignmentOp; 9685 NoteLoc = ErrorLoc = SecondBinOp 9686 ? SecondBinOp->getOperatorLoc() 9687 : Second->getBeginLoc(); 9688 NoteRange = ErrorRange = 9689 SecondBinOp ? SecondBinOp->getSourceRange() 9690 : SourceRange(ErrorLoc, ErrorLoc); 9691 } else { 9692 Expr *PossibleXRHSInFirst = 9693 FirstBinOp->getRHS()->IgnoreParenImpCasts(); 9694 Expr *PossibleXLHSInSecond = 9695 SecondBinOp->getLHS()->IgnoreParenImpCasts(); 9696 llvm::FoldingSetNodeID X1Id, X2Id; 9697 PossibleXRHSInFirst->Profile(X1Id, Context, 9698 /*Canonical=*/true); 9699 PossibleXLHSInSecond->Profile(X2Id, Context, 9700 /*Canonical=*/true); 9701 IsUpdateExprFound = X1Id == X2Id; 9702 if (IsUpdateExprFound) { 9703 V = FirstBinOp->getLHS(); 9704 X = SecondBinOp->getLHS(); 9705 E = SecondBinOp->getRHS(); 9706 UE = nullptr; 9707 IsXLHSInRHSPart = false; 9708 IsPostfixUpdate = true; 9709 } else { 9710 ErrorFound = NotASpecificExpression; 9711 ErrorLoc = FirstBinOp->getExprLoc(); 9712 ErrorRange = FirstBinOp->getSourceRange(); 9713 NoteLoc = SecondBinOp->getLHS()->getExprLoc(); 9714 NoteRange = SecondBinOp->getRHS()->getSourceRange(); 9715 } 9716 } 9717 } 9718 } 9719 } 9720 } else { 9721 NoteLoc = ErrorLoc = Body->getBeginLoc(); 9722 NoteRange = ErrorRange = 9723 SourceRange(Body->getBeginLoc(), Body->getBeginLoc()); 9724 ErrorFound = NotTwoSubstatements; 9725 } 9726 } else { 9727 NoteLoc = ErrorLoc = Body->getBeginLoc(); 9728 NoteRange = ErrorRange = 9729 SourceRange(Body->getBeginLoc(), Body->getBeginLoc()); 9730 ErrorFound = NotACompoundStatement; 9731 } 9732 if (ErrorFound != NoError) { 9733 Diag(ErrorLoc, diag::err_omp_atomic_capture_not_compound_statement) 9734 << ErrorRange; 9735 Diag(NoteLoc, diag::note_omp_atomic_capture) << ErrorFound << NoteRange; 9736 return StmtError(); 9737 } 9738 if (CurContext->isDependentContext()) 9739 UE = V = E = X = nullptr; 9740 } 9741 } 9742 9743 setFunctionHasBranchProtectedScope(); 9744 9745 return OMPAtomicDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt, 9746 X, V, E, UE, IsXLHSInRHSPart, 9747 IsPostfixUpdate); 9748 } 9749 9750 StmtResult Sema::ActOnOpenMPTargetDirective(ArrayRef<OMPClause *> Clauses, 9751 Stmt *AStmt, 9752 SourceLocation StartLoc, 9753 SourceLocation EndLoc) { 9754 if (!AStmt) 9755 return StmtError(); 9756 9757 auto *CS = cast<CapturedStmt>(AStmt); 9758 // 1.2.2 OpenMP Language Terminology 9759 // Structured block - An executable statement with a single entry at the 9760 // top and a single exit at the bottom. 9761 // The point of exit cannot be a branch out of the structured block. 9762 // longjmp() and throw() must not violate the entry/exit criteria. 9763 CS->getCapturedDecl()->setNothrow(); 9764 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target); 9765 ThisCaptureLevel > 1; --ThisCaptureLevel) { 9766 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 9767 // 1.2.2 OpenMP Language Terminology 9768 // Structured block - An executable statement with a single entry at the 9769 // top and a single exit at the bottom. 9770 // The point of exit cannot be a branch out of the structured block. 9771 // longjmp() and throw() must not violate the entry/exit criteria. 9772 CS->getCapturedDecl()->setNothrow(); 9773 } 9774 9775 // OpenMP [2.16, Nesting of Regions] 9776 // If specified, a teams construct must be contained within a target 9777 // construct. That target construct must contain no statements or directives 9778 // outside of the teams construct. 9779 if (DSAStack->hasInnerTeamsRegion()) { 9780 const Stmt *S = CS->IgnoreContainers(/*IgnoreCaptured=*/true); 9781 bool OMPTeamsFound = true; 9782 if (const auto *CS = dyn_cast<CompoundStmt>(S)) { 9783 auto I = CS->body_begin(); 9784 while (I != CS->body_end()) { 9785 const auto *OED = dyn_cast<OMPExecutableDirective>(*I); 9786 if (!OED || !isOpenMPTeamsDirective(OED->getDirectiveKind()) || 9787 OMPTeamsFound) { 9788 9789 OMPTeamsFound = false; 9790 break; 9791 } 9792 ++I; 9793 } 9794 assert(I != CS->body_end() && "Not found statement"); 9795 S = *I; 9796 } else { 9797 const auto *OED = dyn_cast<OMPExecutableDirective>(S); 9798 OMPTeamsFound = OED && isOpenMPTeamsDirective(OED->getDirectiveKind()); 9799 } 9800 if (!OMPTeamsFound) { 9801 Diag(StartLoc, diag::err_omp_target_contains_not_only_teams); 9802 Diag(DSAStack->getInnerTeamsRegionLoc(), 9803 diag::note_omp_nested_teams_construct_here); 9804 Diag(S->getBeginLoc(), diag::note_omp_nested_statement_here) 9805 << isa<OMPExecutableDirective>(S); 9806 return StmtError(); 9807 } 9808 } 9809 9810 setFunctionHasBranchProtectedScope(); 9811 9812 return OMPTargetDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt); 9813 } 9814 9815 StmtResult 9816 Sema::ActOnOpenMPTargetParallelDirective(ArrayRef<OMPClause *> Clauses, 9817 Stmt *AStmt, SourceLocation StartLoc, 9818 SourceLocation EndLoc) { 9819 if (!AStmt) 9820 return StmtError(); 9821 9822 auto *CS = cast<CapturedStmt>(AStmt); 9823 // 1.2.2 OpenMP Language Terminology 9824 // Structured block - An executable statement with a single entry at the 9825 // top and a single exit at the bottom. 9826 // The point of exit cannot be a branch out of the structured block. 9827 // longjmp() and throw() must not violate the entry/exit criteria. 9828 CS->getCapturedDecl()->setNothrow(); 9829 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel); 9830 ThisCaptureLevel > 1; --ThisCaptureLevel) { 9831 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 9832 // 1.2.2 OpenMP Language Terminology 9833 // Structured block - An executable statement with a single entry at the 9834 // top and a single exit at the bottom. 9835 // The point of exit cannot be a branch out of the structured block. 9836 // longjmp() and throw() must not violate the entry/exit criteria. 9837 CS->getCapturedDecl()->setNothrow(); 9838 } 9839 9840 setFunctionHasBranchProtectedScope(); 9841 9842 return OMPTargetParallelDirective::Create(Context, StartLoc, EndLoc, Clauses, 9843 AStmt); 9844 } 9845 9846 StmtResult Sema::ActOnOpenMPTargetParallelForDirective( 9847 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 9848 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 9849 if (!AStmt) 9850 return StmtError(); 9851 9852 auto *CS = cast<CapturedStmt>(AStmt); 9853 // 1.2.2 OpenMP Language Terminology 9854 // Structured block - An executable statement with a single entry at the 9855 // top and a single exit at the bottom. 9856 // The point of exit cannot be a branch out of the structured block. 9857 // longjmp() and throw() must not violate the entry/exit criteria. 9858 CS->getCapturedDecl()->setNothrow(); 9859 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel_for); 9860 ThisCaptureLevel > 1; --ThisCaptureLevel) { 9861 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 9862 // 1.2.2 OpenMP Language Terminology 9863 // Structured block - An executable statement with a single entry at the 9864 // top and a single exit at the bottom. 9865 // The point of exit cannot be a branch out of the structured block. 9866 // longjmp() and throw() must not violate the entry/exit criteria. 9867 CS->getCapturedDecl()->setNothrow(); 9868 } 9869 9870 OMPLoopDirective::HelperExprs B; 9871 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 9872 // define the nested loops number. 9873 unsigned NestedLoopCount = 9874 checkOpenMPLoop(OMPD_target_parallel_for, getCollapseNumberExpr(Clauses), 9875 getOrderedNumberExpr(Clauses), CS, *this, *DSAStack, 9876 VarsWithImplicitDSA, B); 9877 if (NestedLoopCount == 0) 9878 return StmtError(); 9879 9880 assert((CurContext->isDependentContext() || B.builtAll()) && 9881 "omp target parallel for loop exprs were not built"); 9882 9883 if (!CurContext->isDependentContext()) { 9884 // Finalize the clauses that need pre-built expressions for CodeGen. 9885 for (OMPClause *C : Clauses) { 9886 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 9887 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 9888 B.NumIterations, *this, CurScope, 9889 DSAStack)) 9890 return StmtError(); 9891 } 9892 } 9893 9894 setFunctionHasBranchProtectedScope(); 9895 return OMPTargetParallelForDirective::Create(Context, StartLoc, EndLoc, 9896 NestedLoopCount, Clauses, AStmt, 9897 B, DSAStack->isCancelRegion()); 9898 } 9899 9900 /// Check for existence of a map clause in the list of clauses. 9901 static bool hasClauses(ArrayRef<OMPClause *> Clauses, 9902 const OpenMPClauseKind K) { 9903 return llvm::any_of( 9904 Clauses, [K](const OMPClause *C) { return C->getClauseKind() == K; }); 9905 } 9906 9907 template <typename... Params> 9908 static bool hasClauses(ArrayRef<OMPClause *> Clauses, const OpenMPClauseKind K, 9909 const Params... ClauseTypes) { 9910 return hasClauses(Clauses, K) || hasClauses(Clauses, ClauseTypes...); 9911 } 9912 9913 StmtResult Sema::ActOnOpenMPTargetDataDirective(ArrayRef<OMPClause *> Clauses, 9914 Stmt *AStmt, 9915 SourceLocation StartLoc, 9916 SourceLocation EndLoc) { 9917 if (!AStmt) 9918 return StmtError(); 9919 9920 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 9921 9922 // OpenMP [2.10.1, Restrictions, p. 97] 9923 // At least one map clause must appear on the directive. 9924 if (!hasClauses(Clauses, OMPC_map, OMPC_use_device_ptr)) { 9925 Diag(StartLoc, diag::err_omp_no_clause_for_directive) 9926 << "'map' or 'use_device_ptr'" 9927 << getOpenMPDirectiveName(OMPD_target_data); 9928 return StmtError(); 9929 } 9930 9931 setFunctionHasBranchProtectedScope(); 9932 9933 return OMPTargetDataDirective::Create(Context, StartLoc, EndLoc, Clauses, 9934 AStmt); 9935 } 9936 9937 StmtResult 9938 Sema::ActOnOpenMPTargetEnterDataDirective(ArrayRef<OMPClause *> Clauses, 9939 SourceLocation StartLoc, 9940 SourceLocation EndLoc, Stmt *AStmt) { 9941 if (!AStmt) 9942 return StmtError(); 9943 9944 auto *CS = cast<CapturedStmt>(AStmt); 9945 // 1.2.2 OpenMP Language Terminology 9946 // Structured block - An executable statement with a single entry at the 9947 // top and a single exit at the bottom. 9948 // The point of exit cannot be a branch out of the structured block. 9949 // longjmp() and throw() must not violate the entry/exit criteria. 9950 CS->getCapturedDecl()->setNothrow(); 9951 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_enter_data); 9952 ThisCaptureLevel > 1; --ThisCaptureLevel) { 9953 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 9954 // 1.2.2 OpenMP Language Terminology 9955 // Structured block - An executable statement with a single entry at the 9956 // top and a single exit at the bottom. 9957 // The point of exit cannot be a branch out of the structured block. 9958 // longjmp() and throw() must not violate the entry/exit criteria. 9959 CS->getCapturedDecl()->setNothrow(); 9960 } 9961 9962 // OpenMP [2.10.2, Restrictions, p. 99] 9963 // At least one map clause must appear on the directive. 9964 if (!hasClauses(Clauses, OMPC_map)) { 9965 Diag(StartLoc, diag::err_omp_no_clause_for_directive) 9966 << "'map'" << getOpenMPDirectiveName(OMPD_target_enter_data); 9967 return StmtError(); 9968 } 9969 9970 return OMPTargetEnterDataDirective::Create(Context, StartLoc, EndLoc, Clauses, 9971 AStmt); 9972 } 9973 9974 StmtResult 9975 Sema::ActOnOpenMPTargetExitDataDirective(ArrayRef<OMPClause *> Clauses, 9976 SourceLocation StartLoc, 9977 SourceLocation EndLoc, Stmt *AStmt) { 9978 if (!AStmt) 9979 return StmtError(); 9980 9981 auto *CS = cast<CapturedStmt>(AStmt); 9982 // 1.2.2 OpenMP Language Terminology 9983 // Structured block - An executable statement with a single entry at the 9984 // top and a single exit at the bottom. 9985 // The point of exit cannot be a branch out of the structured block. 9986 // longjmp() and throw() must not violate the entry/exit criteria. 9987 CS->getCapturedDecl()->setNothrow(); 9988 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_exit_data); 9989 ThisCaptureLevel > 1; --ThisCaptureLevel) { 9990 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 9991 // 1.2.2 OpenMP Language Terminology 9992 // Structured block - An executable statement with a single entry at the 9993 // top and a single exit at the bottom. 9994 // The point of exit cannot be a branch out of the structured block. 9995 // longjmp() and throw() must not violate the entry/exit criteria. 9996 CS->getCapturedDecl()->setNothrow(); 9997 } 9998 9999 // OpenMP [2.10.3, Restrictions, p. 102] 10000 // At least one map clause must appear on the directive. 10001 if (!hasClauses(Clauses, OMPC_map)) { 10002 Diag(StartLoc, diag::err_omp_no_clause_for_directive) 10003 << "'map'" << getOpenMPDirectiveName(OMPD_target_exit_data); 10004 return StmtError(); 10005 } 10006 10007 return OMPTargetExitDataDirective::Create(Context, StartLoc, EndLoc, Clauses, 10008 AStmt); 10009 } 10010 10011 StmtResult Sema::ActOnOpenMPTargetUpdateDirective(ArrayRef<OMPClause *> Clauses, 10012 SourceLocation StartLoc, 10013 SourceLocation EndLoc, 10014 Stmt *AStmt) { 10015 if (!AStmt) 10016 return StmtError(); 10017 10018 auto *CS = cast<CapturedStmt>(AStmt); 10019 // 1.2.2 OpenMP Language Terminology 10020 // Structured block - An executable statement with a single entry at the 10021 // top and a single exit at the bottom. 10022 // The point of exit cannot be a branch out of the structured block. 10023 // longjmp() and throw() must not violate the entry/exit criteria. 10024 CS->getCapturedDecl()->setNothrow(); 10025 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_update); 10026 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10027 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10028 // 1.2.2 OpenMP Language Terminology 10029 // Structured block - An executable statement with a single entry at the 10030 // top and a single exit at the bottom. 10031 // The point of exit cannot be a branch out of the structured block. 10032 // longjmp() and throw() must not violate the entry/exit criteria. 10033 CS->getCapturedDecl()->setNothrow(); 10034 } 10035 10036 if (!hasClauses(Clauses, OMPC_to, OMPC_from)) { 10037 Diag(StartLoc, diag::err_omp_at_least_one_motion_clause_required); 10038 return StmtError(); 10039 } 10040 return OMPTargetUpdateDirective::Create(Context, StartLoc, EndLoc, Clauses, 10041 AStmt); 10042 } 10043 10044 StmtResult Sema::ActOnOpenMPTeamsDirective(ArrayRef<OMPClause *> Clauses, 10045 Stmt *AStmt, SourceLocation StartLoc, 10046 SourceLocation EndLoc) { 10047 if (!AStmt) 10048 return StmtError(); 10049 10050 auto *CS = cast<CapturedStmt>(AStmt); 10051 // 1.2.2 OpenMP Language Terminology 10052 // Structured block - An executable statement with a single entry at the 10053 // top and a single exit at the bottom. 10054 // The point of exit cannot be a branch out of the structured block. 10055 // longjmp() and throw() must not violate the entry/exit criteria. 10056 CS->getCapturedDecl()->setNothrow(); 10057 10058 setFunctionHasBranchProtectedScope(); 10059 10060 DSAStack->setParentTeamsRegionLoc(StartLoc); 10061 10062 return OMPTeamsDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt); 10063 } 10064 10065 StmtResult 10066 Sema::ActOnOpenMPCancellationPointDirective(SourceLocation StartLoc, 10067 SourceLocation EndLoc, 10068 OpenMPDirectiveKind CancelRegion) { 10069 if (DSAStack->isParentNowaitRegion()) { 10070 Diag(StartLoc, diag::err_omp_parent_cancel_region_nowait) << 0; 10071 return StmtError(); 10072 } 10073 if (DSAStack->isParentOrderedRegion()) { 10074 Diag(StartLoc, diag::err_omp_parent_cancel_region_ordered) << 0; 10075 return StmtError(); 10076 } 10077 return OMPCancellationPointDirective::Create(Context, StartLoc, EndLoc, 10078 CancelRegion); 10079 } 10080 10081 StmtResult Sema::ActOnOpenMPCancelDirective(ArrayRef<OMPClause *> Clauses, 10082 SourceLocation StartLoc, 10083 SourceLocation EndLoc, 10084 OpenMPDirectiveKind CancelRegion) { 10085 if (DSAStack->isParentNowaitRegion()) { 10086 Diag(StartLoc, diag::err_omp_parent_cancel_region_nowait) << 1; 10087 return StmtError(); 10088 } 10089 if (DSAStack->isParentOrderedRegion()) { 10090 Diag(StartLoc, diag::err_omp_parent_cancel_region_ordered) << 1; 10091 return StmtError(); 10092 } 10093 DSAStack->setParentCancelRegion(/*Cancel=*/true); 10094 return OMPCancelDirective::Create(Context, StartLoc, EndLoc, Clauses, 10095 CancelRegion); 10096 } 10097 10098 static bool checkGrainsizeNumTasksClauses(Sema &S, 10099 ArrayRef<OMPClause *> Clauses) { 10100 const OMPClause *PrevClause = nullptr; 10101 bool ErrorFound = false; 10102 for (const OMPClause *C : Clauses) { 10103 if (C->getClauseKind() == OMPC_grainsize || 10104 C->getClauseKind() == OMPC_num_tasks) { 10105 if (!PrevClause) 10106 PrevClause = C; 10107 else if (PrevClause->getClauseKind() != C->getClauseKind()) { 10108 S.Diag(C->getBeginLoc(), diag::err_omp_clauses_mutually_exclusive) 10109 << getOpenMPClauseName(C->getClauseKind()) 10110 << getOpenMPClauseName(PrevClause->getClauseKind()); 10111 S.Diag(PrevClause->getBeginLoc(), diag::note_omp_previous_clause) 10112 << getOpenMPClauseName(PrevClause->getClauseKind()); 10113 ErrorFound = true; 10114 } 10115 } 10116 } 10117 return ErrorFound; 10118 } 10119 10120 static bool checkReductionClauseWithNogroup(Sema &S, 10121 ArrayRef<OMPClause *> Clauses) { 10122 const OMPClause *ReductionClause = nullptr; 10123 const OMPClause *NogroupClause = nullptr; 10124 for (const OMPClause *C : Clauses) { 10125 if (C->getClauseKind() == OMPC_reduction) { 10126 ReductionClause = C; 10127 if (NogroupClause) 10128 break; 10129 continue; 10130 } 10131 if (C->getClauseKind() == OMPC_nogroup) { 10132 NogroupClause = C; 10133 if (ReductionClause) 10134 break; 10135 continue; 10136 } 10137 } 10138 if (ReductionClause && NogroupClause) { 10139 S.Diag(ReductionClause->getBeginLoc(), diag::err_omp_reduction_with_nogroup) 10140 << SourceRange(NogroupClause->getBeginLoc(), 10141 NogroupClause->getEndLoc()); 10142 return true; 10143 } 10144 return false; 10145 } 10146 10147 StmtResult Sema::ActOnOpenMPTaskLoopDirective( 10148 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10149 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10150 if (!AStmt) 10151 return StmtError(); 10152 10153 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 10154 OMPLoopDirective::HelperExprs B; 10155 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 10156 // define the nested loops number. 10157 unsigned NestedLoopCount = 10158 checkOpenMPLoop(OMPD_taskloop, getCollapseNumberExpr(Clauses), 10159 /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack, 10160 VarsWithImplicitDSA, B); 10161 if (NestedLoopCount == 0) 10162 return StmtError(); 10163 10164 assert((CurContext->isDependentContext() || B.builtAll()) && 10165 "omp for loop exprs were not built"); 10166 10167 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 10168 // The grainsize clause and num_tasks clause are mutually exclusive and may 10169 // not appear on the same taskloop directive. 10170 if (checkGrainsizeNumTasksClauses(*this, Clauses)) 10171 return StmtError(); 10172 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 10173 // If a reduction clause is present on the taskloop directive, the nogroup 10174 // clause must not be specified. 10175 if (checkReductionClauseWithNogroup(*this, Clauses)) 10176 return StmtError(); 10177 10178 setFunctionHasBranchProtectedScope(); 10179 return OMPTaskLoopDirective::Create(Context, StartLoc, EndLoc, 10180 NestedLoopCount, Clauses, AStmt, B, 10181 DSAStack->isCancelRegion()); 10182 } 10183 10184 StmtResult Sema::ActOnOpenMPTaskLoopSimdDirective( 10185 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10186 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10187 if (!AStmt) 10188 return StmtError(); 10189 10190 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 10191 OMPLoopDirective::HelperExprs B; 10192 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 10193 // define the nested loops number. 10194 unsigned NestedLoopCount = 10195 checkOpenMPLoop(OMPD_taskloop_simd, getCollapseNumberExpr(Clauses), 10196 /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack, 10197 VarsWithImplicitDSA, B); 10198 if (NestedLoopCount == 0) 10199 return StmtError(); 10200 10201 assert((CurContext->isDependentContext() || B.builtAll()) && 10202 "omp for loop exprs were not built"); 10203 10204 if (!CurContext->isDependentContext()) { 10205 // Finalize the clauses that need pre-built expressions for CodeGen. 10206 for (OMPClause *C : Clauses) { 10207 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 10208 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 10209 B.NumIterations, *this, CurScope, 10210 DSAStack)) 10211 return StmtError(); 10212 } 10213 } 10214 10215 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 10216 // The grainsize clause and num_tasks clause are mutually exclusive and may 10217 // not appear on the same taskloop directive. 10218 if (checkGrainsizeNumTasksClauses(*this, Clauses)) 10219 return StmtError(); 10220 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 10221 // If a reduction clause is present on the taskloop directive, the nogroup 10222 // clause must not be specified. 10223 if (checkReductionClauseWithNogroup(*this, Clauses)) 10224 return StmtError(); 10225 if (checkSimdlenSafelenSpecified(*this, Clauses)) 10226 return StmtError(); 10227 10228 setFunctionHasBranchProtectedScope(); 10229 return OMPTaskLoopSimdDirective::Create(Context, StartLoc, EndLoc, 10230 NestedLoopCount, Clauses, AStmt, B); 10231 } 10232 10233 StmtResult Sema::ActOnOpenMPMasterTaskLoopDirective( 10234 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10235 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10236 if (!AStmt) 10237 return StmtError(); 10238 10239 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 10240 OMPLoopDirective::HelperExprs B; 10241 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 10242 // define the nested loops number. 10243 unsigned NestedLoopCount = 10244 checkOpenMPLoop(OMPD_master_taskloop, getCollapseNumberExpr(Clauses), 10245 /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack, 10246 VarsWithImplicitDSA, B); 10247 if (NestedLoopCount == 0) 10248 return StmtError(); 10249 10250 assert((CurContext->isDependentContext() || B.builtAll()) && 10251 "omp for loop exprs were not built"); 10252 10253 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 10254 // The grainsize clause and num_tasks clause are mutually exclusive and may 10255 // not appear on the same taskloop directive. 10256 if (checkGrainsizeNumTasksClauses(*this, Clauses)) 10257 return StmtError(); 10258 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 10259 // If a reduction clause is present on the taskloop directive, the nogroup 10260 // clause must not be specified. 10261 if (checkReductionClauseWithNogroup(*this, Clauses)) 10262 return StmtError(); 10263 10264 setFunctionHasBranchProtectedScope(); 10265 return OMPMasterTaskLoopDirective::Create(Context, StartLoc, EndLoc, 10266 NestedLoopCount, Clauses, AStmt, B, 10267 DSAStack->isCancelRegion()); 10268 } 10269 10270 StmtResult Sema::ActOnOpenMPMasterTaskLoopSimdDirective( 10271 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10272 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10273 if (!AStmt) 10274 return StmtError(); 10275 10276 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 10277 OMPLoopDirective::HelperExprs B; 10278 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 10279 // define the nested loops number. 10280 unsigned NestedLoopCount = 10281 checkOpenMPLoop(OMPD_master_taskloop_simd, getCollapseNumberExpr(Clauses), 10282 /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack, 10283 VarsWithImplicitDSA, B); 10284 if (NestedLoopCount == 0) 10285 return StmtError(); 10286 10287 assert((CurContext->isDependentContext() || B.builtAll()) && 10288 "omp for loop exprs were not built"); 10289 10290 if (!CurContext->isDependentContext()) { 10291 // Finalize the clauses that need pre-built expressions for CodeGen. 10292 for (OMPClause *C : Clauses) { 10293 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 10294 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 10295 B.NumIterations, *this, CurScope, 10296 DSAStack)) 10297 return StmtError(); 10298 } 10299 } 10300 10301 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 10302 // The grainsize clause and num_tasks clause are mutually exclusive and may 10303 // not appear on the same taskloop directive. 10304 if (checkGrainsizeNumTasksClauses(*this, Clauses)) 10305 return StmtError(); 10306 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 10307 // If a reduction clause is present on the taskloop directive, the nogroup 10308 // clause must not be specified. 10309 if (checkReductionClauseWithNogroup(*this, Clauses)) 10310 return StmtError(); 10311 if (checkSimdlenSafelenSpecified(*this, Clauses)) 10312 return StmtError(); 10313 10314 setFunctionHasBranchProtectedScope(); 10315 return OMPMasterTaskLoopSimdDirective::Create( 10316 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 10317 } 10318 10319 StmtResult Sema::ActOnOpenMPParallelMasterTaskLoopDirective( 10320 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10321 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10322 if (!AStmt) 10323 return StmtError(); 10324 10325 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 10326 auto *CS = cast<CapturedStmt>(AStmt); 10327 // 1.2.2 OpenMP Language Terminology 10328 // Structured block - An executable statement with a single entry at the 10329 // top and a single exit at the bottom. 10330 // The point of exit cannot be a branch out of the structured block. 10331 // longjmp() and throw() must not violate the entry/exit criteria. 10332 CS->getCapturedDecl()->setNothrow(); 10333 for (int ThisCaptureLevel = 10334 getOpenMPCaptureLevels(OMPD_parallel_master_taskloop); 10335 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10336 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10337 // 1.2.2 OpenMP Language Terminology 10338 // Structured block - An executable statement with a single entry at the 10339 // top and a single exit at the bottom. 10340 // The point of exit cannot be a branch out of the structured block. 10341 // longjmp() and throw() must not violate the entry/exit criteria. 10342 CS->getCapturedDecl()->setNothrow(); 10343 } 10344 10345 OMPLoopDirective::HelperExprs B; 10346 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 10347 // define the nested loops number. 10348 unsigned NestedLoopCount = checkOpenMPLoop( 10349 OMPD_parallel_master_taskloop, getCollapseNumberExpr(Clauses), 10350 /*OrderedLoopCountExpr=*/nullptr, CS, *this, *DSAStack, 10351 VarsWithImplicitDSA, B); 10352 if (NestedLoopCount == 0) 10353 return StmtError(); 10354 10355 assert((CurContext->isDependentContext() || B.builtAll()) && 10356 "omp for loop exprs were not built"); 10357 10358 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 10359 // The grainsize clause and num_tasks clause are mutually exclusive and may 10360 // not appear on the same taskloop directive. 10361 if (checkGrainsizeNumTasksClauses(*this, Clauses)) 10362 return StmtError(); 10363 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 10364 // If a reduction clause is present on the taskloop directive, the nogroup 10365 // clause must not be specified. 10366 if (checkReductionClauseWithNogroup(*this, Clauses)) 10367 return StmtError(); 10368 10369 setFunctionHasBranchProtectedScope(); 10370 return OMPParallelMasterTaskLoopDirective::Create( 10371 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B, 10372 DSAStack->isCancelRegion()); 10373 } 10374 10375 StmtResult Sema::ActOnOpenMPParallelMasterTaskLoopSimdDirective( 10376 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10377 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10378 if (!AStmt) 10379 return StmtError(); 10380 10381 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 10382 auto *CS = cast<CapturedStmt>(AStmt); 10383 // 1.2.2 OpenMP Language Terminology 10384 // Structured block - An executable statement with a single entry at the 10385 // top and a single exit at the bottom. 10386 // The point of exit cannot be a branch out of the structured block. 10387 // longjmp() and throw() must not violate the entry/exit criteria. 10388 CS->getCapturedDecl()->setNothrow(); 10389 for (int ThisCaptureLevel = 10390 getOpenMPCaptureLevels(OMPD_parallel_master_taskloop_simd); 10391 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10392 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10393 // 1.2.2 OpenMP Language Terminology 10394 // Structured block - An executable statement with a single entry at the 10395 // top and a single exit at the bottom. 10396 // The point of exit cannot be a branch out of the structured block. 10397 // longjmp() and throw() must not violate the entry/exit criteria. 10398 CS->getCapturedDecl()->setNothrow(); 10399 } 10400 10401 OMPLoopDirective::HelperExprs B; 10402 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 10403 // define the nested loops number. 10404 unsigned NestedLoopCount = checkOpenMPLoop( 10405 OMPD_parallel_master_taskloop_simd, getCollapseNumberExpr(Clauses), 10406 /*OrderedLoopCountExpr=*/nullptr, CS, *this, *DSAStack, 10407 VarsWithImplicitDSA, B); 10408 if (NestedLoopCount == 0) 10409 return StmtError(); 10410 10411 assert((CurContext->isDependentContext() || B.builtAll()) && 10412 "omp for loop exprs were not built"); 10413 10414 if (!CurContext->isDependentContext()) { 10415 // Finalize the clauses that need pre-built expressions for CodeGen. 10416 for (OMPClause *C : Clauses) { 10417 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 10418 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 10419 B.NumIterations, *this, CurScope, 10420 DSAStack)) 10421 return StmtError(); 10422 } 10423 } 10424 10425 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 10426 // The grainsize clause and num_tasks clause are mutually exclusive and may 10427 // not appear on the same taskloop directive. 10428 if (checkGrainsizeNumTasksClauses(*this, Clauses)) 10429 return StmtError(); 10430 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 10431 // If a reduction clause is present on the taskloop directive, the nogroup 10432 // clause must not be specified. 10433 if (checkReductionClauseWithNogroup(*this, Clauses)) 10434 return StmtError(); 10435 if (checkSimdlenSafelenSpecified(*this, Clauses)) 10436 return StmtError(); 10437 10438 setFunctionHasBranchProtectedScope(); 10439 return OMPParallelMasterTaskLoopSimdDirective::Create( 10440 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 10441 } 10442 10443 StmtResult Sema::ActOnOpenMPDistributeDirective( 10444 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10445 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10446 if (!AStmt) 10447 return StmtError(); 10448 10449 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 10450 OMPLoopDirective::HelperExprs B; 10451 // In presence of clause 'collapse' with number of loops, it will 10452 // define the nested loops number. 10453 unsigned NestedLoopCount = 10454 checkOpenMPLoop(OMPD_distribute, getCollapseNumberExpr(Clauses), 10455 nullptr /*ordered not a clause on distribute*/, AStmt, 10456 *this, *DSAStack, VarsWithImplicitDSA, B); 10457 if (NestedLoopCount == 0) 10458 return StmtError(); 10459 10460 assert((CurContext->isDependentContext() || B.builtAll()) && 10461 "omp for loop exprs were not built"); 10462 10463 setFunctionHasBranchProtectedScope(); 10464 return OMPDistributeDirective::Create(Context, StartLoc, EndLoc, 10465 NestedLoopCount, Clauses, AStmt, B); 10466 } 10467 10468 StmtResult Sema::ActOnOpenMPDistributeParallelForDirective( 10469 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10470 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10471 if (!AStmt) 10472 return StmtError(); 10473 10474 auto *CS = cast<CapturedStmt>(AStmt); 10475 // 1.2.2 OpenMP Language Terminology 10476 // Structured block - An executable statement with a single entry at the 10477 // top and a single exit at the bottom. 10478 // The point of exit cannot be a branch out of the structured block. 10479 // longjmp() and throw() must not violate the entry/exit criteria. 10480 CS->getCapturedDecl()->setNothrow(); 10481 for (int ThisCaptureLevel = 10482 getOpenMPCaptureLevels(OMPD_distribute_parallel_for); 10483 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10484 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10485 // 1.2.2 OpenMP Language Terminology 10486 // Structured block - An executable statement with a single entry at the 10487 // top and a single exit at the bottom. 10488 // The point of exit cannot be a branch out of the structured block. 10489 // longjmp() and throw() must not violate the entry/exit criteria. 10490 CS->getCapturedDecl()->setNothrow(); 10491 } 10492 10493 OMPLoopDirective::HelperExprs B; 10494 // In presence of clause 'collapse' with number of loops, it will 10495 // define the nested loops number. 10496 unsigned NestedLoopCount = checkOpenMPLoop( 10497 OMPD_distribute_parallel_for, getCollapseNumberExpr(Clauses), 10498 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 10499 VarsWithImplicitDSA, B); 10500 if (NestedLoopCount == 0) 10501 return StmtError(); 10502 10503 assert((CurContext->isDependentContext() || B.builtAll()) && 10504 "omp for loop exprs were not built"); 10505 10506 setFunctionHasBranchProtectedScope(); 10507 return OMPDistributeParallelForDirective::Create( 10508 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B, 10509 DSAStack->isCancelRegion()); 10510 } 10511 10512 StmtResult Sema::ActOnOpenMPDistributeParallelForSimdDirective( 10513 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10514 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10515 if (!AStmt) 10516 return StmtError(); 10517 10518 auto *CS = cast<CapturedStmt>(AStmt); 10519 // 1.2.2 OpenMP Language Terminology 10520 // Structured block - An executable statement with a single entry at the 10521 // top and a single exit at the bottom. 10522 // The point of exit cannot be a branch out of the structured block. 10523 // longjmp() and throw() must not violate the entry/exit criteria. 10524 CS->getCapturedDecl()->setNothrow(); 10525 for (int ThisCaptureLevel = 10526 getOpenMPCaptureLevels(OMPD_distribute_parallel_for_simd); 10527 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10528 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10529 // 1.2.2 OpenMP Language Terminology 10530 // Structured block - An executable statement with a single entry at the 10531 // top and a single exit at the bottom. 10532 // The point of exit cannot be a branch out of the structured block. 10533 // longjmp() and throw() must not violate the entry/exit criteria. 10534 CS->getCapturedDecl()->setNothrow(); 10535 } 10536 10537 OMPLoopDirective::HelperExprs B; 10538 // In presence of clause 'collapse' with number of loops, it will 10539 // define the nested loops number. 10540 unsigned NestedLoopCount = checkOpenMPLoop( 10541 OMPD_distribute_parallel_for_simd, getCollapseNumberExpr(Clauses), 10542 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 10543 VarsWithImplicitDSA, B); 10544 if (NestedLoopCount == 0) 10545 return StmtError(); 10546 10547 assert((CurContext->isDependentContext() || B.builtAll()) && 10548 "omp for loop exprs were not built"); 10549 10550 if (!CurContext->isDependentContext()) { 10551 // Finalize the clauses that need pre-built expressions for CodeGen. 10552 for (OMPClause *C : Clauses) { 10553 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 10554 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 10555 B.NumIterations, *this, CurScope, 10556 DSAStack)) 10557 return StmtError(); 10558 } 10559 } 10560 10561 if (checkSimdlenSafelenSpecified(*this, Clauses)) 10562 return StmtError(); 10563 10564 setFunctionHasBranchProtectedScope(); 10565 return OMPDistributeParallelForSimdDirective::Create( 10566 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 10567 } 10568 10569 StmtResult Sema::ActOnOpenMPDistributeSimdDirective( 10570 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10571 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10572 if (!AStmt) 10573 return StmtError(); 10574 10575 auto *CS = cast<CapturedStmt>(AStmt); 10576 // 1.2.2 OpenMP Language Terminology 10577 // Structured block - An executable statement with a single entry at the 10578 // top and a single exit at the bottom. 10579 // The point of exit cannot be a branch out of the structured block. 10580 // longjmp() and throw() must not violate the entry/exit criteria. 10581 CS->getCapturedDecl()->setNothrow(); 10582 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_distribute_simd); 10583 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10584 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10585 // 1.2.2 OpenMP Language Terminology 10586 // Structured block - An executable statement with a single entry at the 10587 // top and a single exit at the bottom. 10588 // The point of exit cannot be a branch out of the structured block. 10589 // longjmp() and throw() must not violate the entry/exit criteria. 10590 CS->getCapturedDecl()->setNothrow(); 10591 } 10592 10593 OMPLoopDirective::HelperExprs B; 10594 // In presence of clause 'collapse' with number of loops, it will 10595 // define the nested loops number. 10596 unsigned NestedLoopCount = 10597 checkOpenMPLoop(OMPD_distribute_simd, getCollapseNumberExpr(Clauses), 10598 nullptr /*ordered not a clause on distribute*/, CS, *this, 10599 *DSAStack, VarsWithImplicitDSA, B); 10600 if (NestedLoopCount == 0) 10601 return StmtError(); 10602 10603 assert((CurContext->isDependentContext() || B.builtAll()) && 10604 "omp for loop exprs were not built"); 10605 10606 if (!CurContext->isDependentContext()) { 10607 // Finalize the clauses that need pre-built expressions for CodeGen. 10608 for (OMPClause *C : Clauses) { 10609 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 10610 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 10611 B.NumIterations, *this, CurScope, 10612 DSAStack)) 10613 return StmtError(); 10614 } 10615 } 10616 10617 if (checkSimdlenSafelenSpecified(*this, Clauses)) 10618 return StmtError(); 10619 10620 setFunctionHasBranchProtectedScope(); 10621 return OMPDistributeSimdDirective::Create(Context, StartLoc, EndLoc, 10622 NestedLoopCount, Clauses, AStmt, B); 10623 } 10624 10625 StmtResult Sema::ActOnOpenMPTargetParallelForSimdDirective( 10626 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10627 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10628 if (!AStmt) 10629 return StmtError(); 10630 10631 auto *CS = cast<CapturedStmt>(AStmt); 10632 // 1.2.2 OpenMP Language Terminology 10633 // Structured block - An executable statement with a single entry at the 10634 // top and a single exit at the bottom. 10635 // The point of exit cannot be a branch out of the structured block. 10636 // longjmp() and throw() must not violate the entry/exit criteria. 10637 CS->getCapturedDecl()->setNothrow(); 10638 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel_for); 10639 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10640 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10641 // 1.2.2 OpenMP Language Terminology 10642 // Structured block - An executable statement with a single entry at the 10643 // top and a single exit at the bottom. 10644 // The point of exit cannot be a branch out of the structured block. 10645 // longjmp() and throw() must not violate the entry/exit criteria. 10646 CS->getCapturedDecl()->setNothrow(); 10647 } 10648 10649 OMPLoopDirective::HelperExprs B; 10650 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 10651 // define the nested loops number. 10652 unsigned NestedLoopCount = checkOpenMPLoop( 10653 OMPD_target_parallel_for_simd, getCollapseNumberExpr(Clauses), 10654 getOrderedNumberExpr(Clauses), CS, *this, *DSAStack, 10655 VarsWithImplicitDSA, B); 10656 if (NestedLoopCount == 0) 10657 return StmtError(); 10658 10659 assert((CurContext->isDependentContext() || B.builtAll()) && 10660 "omp target parallel for simd loop exprs were not built"); 10661 10662 if (!CurContext->isDependentContext()) { 10663 // Finalize the clauses that need pre-built expressions for CodeGen. 10664 for (OMPClause *C : Clauses) { 10665 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 10666 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 10667 B.NumIterations, *this, CurScope, 10668 DSAStack)) 10669 return StmtError(); 10670 } 10671 } 10672 if (checkSimdlenSafelenSpecified(*this, Clauses)) 10673 return StmtError(); 10674 10675 setFunctionHasBranchProtectedScope(); 10676 return OMPTargetParallelForSimdDirective::Create( 10677 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 10678 } 10679 10680 StmtResult Sema::ActOnOpenMPTargetSimdDirective( 10681 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10682 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10683 if (!AStmt) 10684 return StmtError(); 10685 10686 auto *CS = cast<CapturedStmt>(AStmt); 10687 // 1.2.2 OpenMP Language Terminology 10688 // Structured block - An executable statement with a single entry at the 10689 // top and a single exit at the bottom. 10690 // The point of exit cannot be a branch out of the structured block. 10691 // longjmp() and throw() must not violate the entry/exit criteria. 10692 CS->getCapturedDecl()->setNothrow(); 10693 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_simd); 10694 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10695 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10696 // 1.2.2 OpenMP Language Terminology 10697 // Structured block - An executable statement with a single entry at the 10698 // top and a single exit at the bottom. 10699 // The point of exit cannot be a branch out of the structured block. 10700 // longjmp() and throw() must not violate the entry/exit criteria. 10701 CS->getCapturedDecl()->setNothrow(); 10702 } 10703 10704 OMPLoopDirective::HelperExprs B; 10705 // In presence of clause 'collapse' with number of loops, it will define the 10706 // nested loops number. 10707 unsigned NestedLoopCount = 10708 checkOpenMPLoop(OMPD_target_simd, getCollapseNumberExpr(Clauses), 10709 getOrderedNumberExpr(Clauses), CS, *this, *DSAStack, 10710 VarsWithImplicitDSA, B); 10711 if (NestedLoopCount == 0) 10712 return StmtError(); 10713 10714 assert((CurContext->isDependentContext() || B.builtAll()) && 10715 "omp target simd loop exprs were not built"); 10716 10717 if (!CurContext->isDependentContext()) { 10718 // Finalize the clauses that need pre-built expressions for CodeGen. 10719 for (OMPClause *C : Clauses) { 10720 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 10721 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 10722 B.NumIterations, *this, CurScope, 10723 DSAStack)) 10724 return StmtError(); 10725 } 10726 } 10727 10728 if (checkSimdlenSafelenSpecified(*this, Clauses)) 10729 return StmtError(); 10730 10731 setFunctionHasBranchProtectedScope(); 10732 return OMPTargetSimdDirective::Create(Context, StartLoc, EndLoc, 10733 NestedLoopCount, Clauses, AStmt, B); 10734 } 10735 10736 StmtResult Sema::ActOnOpenMPTeamsDistributeDirective( 10737 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10738 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10739 if (!AStmt) 10740 return StmtError(); 10741 10742 auto *CS = cast<CapturedStmt>(AStmt); 10743 // 1.2.2 OpenMP Language Terminology 10744 // Structured block - An executable statement with a single entry at the 10745 // top and a single exit at the bottom. 10746 // The point of exit cannot be a branch out of the structured block. 10747 // longjmp() and throw() must not violate the entry/exit criteria. 10748 CS->getCapturedDecl()->setNothrow(); 10749 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_teams_distribute); 10750 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10751 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10752 // 1.2.2 OpenMP Language Terminology 10753 // Structured block - An executable statement with a single entry at the 10754 // top and a single exit at the bottom. 10755 // The point of exit cannot be a branch out of the structured block. 10756 // longjmp() and throw() must not violate the entry/exit criteria. 10757 CS->getCapturedDecl()->setNothrow(); 10758 } 10759 10760 OMPLoopDirective::HelperExprs B; 10761 // In presence of clause 'collapse' with number of loops, it will 10762 // define the nested loops number. 10763 unsigned NestedLoopCount = 10764 checkOpenMPLoop(OMPD_teams_distribute, getCollapseNumberExpr(Clauses), 10765 nullptr /*ordered not a clause on distribute*/, CS, *this, 10766 *DSAStack, VarsWithImplicitDSA, B); 10767 if (NestedLoopCount == 0) 10768 return StmtError(); 10769 10770 assert((CurContext->isDependentContext() || B.builtAll()) && 10771 "omp teams distribute loop exprs were not built"); 10772 10773 setFunctionHasBranchProtectedScope(); 10774 10775 DSAStack->setParentTeamsRegionLoc(StartLoc); 10776 10777 return OMPTeamsDistributeDirective::Create( 10778 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 10779 } 10780 10781 StmtResult Sema::ActOnOpenMPTeamsDistributeSimdDirective( 10782 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10783 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10784 if (!AStmt) 10785 return StmtError(); 10786 10787 auto *CS = cast<CapturedStmt>(AStmt); 10788 // 1.2.2 OpenMP Language Terminology 10789 // Structured block - An executable statement with a single entry at the 10790 // top and a single exit at the bottom. 10791 // The point of exit cannot be a branch out of the structured block. 10792 // longjmp() and throw() must not violate the entry/exit criteria. 10793 CS->getCapturedDecl()->setNothrow(); 10794 for (int ThisCaptureLevel = 10795 getOpenMPCaptureLevels(OMPD_teams_distribute_simd); 10796 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10797 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10798 // 1.2.2 OpenMP Language Terminology 10799 // Structured block - An executable statement with a single entry at the 10800 // top and a single exit at the bottom. 10801 // The point of exit cannot be a branch out of the structured block. 10802 // longjmp() and throw() must not violate the entry/exit criteria. 10803 CS->getCapturedDecl()->setNothrow(); 10804 } 10805 10806 OMPLoopDirective::HelperExprs B; 10807 // In presence of clause 'collapse' with number of loops, it will 10808 // define the nested loops number. 10809 unsigned NestedLoopCount = checkOpenMPLoop( 10810 OMPD_teams_distribute_simd, getCollapseNumberExpr(Clauses), 10811 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 10812 VarsWithImplicitDSA, B); 10813 10814 if (NestedLoopCount == 0) 10815 return StmtError(); 10816 10817 assert((CurContext->isDependentContext() || B.builtAll()) && 10818 "omp teams distribute simd loop exprs were not built"); 10819 10820 if (!CurContext->isDependentContext()) { 10821 // Finalize the clauses that need pre-built expressions for CodeGen. 10822 for (OMPClause *C : Clauses) { 10823 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 10824 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 10825 B.NumIterations, *this, CurScope, 10826 DSAStack)) 10827 return StmtError(); 10828 } 10829 } 10830 10831 if (checkSimdlenSafelenSpecified(*this, Clauses)) 10832 return StmtError(); 10833 10834 setFunctionHasBranchProtectedScope(); 10835 10836 DSAStack->setParentTeamsRegionLoc(StartLoc); 10837 10838 return OMPTeamsDistributeSimdDirective::Create( 10839 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 10840 } 10841 10842 StmtResult Sema::ActOnOpenMPTeamsDistributeParallelForSimdDirective( 10843 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10844 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10845 if (!AStmt) 10846 return StmtError(); 10847 10848 auto *CS = cast<CapturedStmt>(AStmt); 10849 // 1.2.2 OpenMP Language Terminology 10850 // Structured block - An executable statement with a single entry at the 10851 // top and a single exit at the bottom. 10852 // The point of exit cannot be a branch out of the structured block. 10853 // longjmp() and throw() must not violate the entry/exit criteria. 10854 CS->getCapturedDecl()->setNothrow(); 10855 10856 for (int ThisCaptureLevel = 10857 getOpenMPCaptureLevels(OMPD_teams_distribute_parallel_for_simd); 10858 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10859 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10860 // 1.2.2 OpenMP Language Terminology 10861 // Structured block - An executable statement with a single entry at the 10862 // top and a single exit at the bottom. 10863 // The point of exit cannot be a branch out of the structured block. 10864 // longjmp() and throw() must not violate the entry/exit criteria. 10865 CS->getCapturedDecl()->setNothrow(); 10866 } 10867 10868 OMPLoopDirective::HelperExprs B; 10869 // In presence of clause 'collapse' with number of loops, it will 10870 // define the nested loops number. 10871 unsigned NestedLoopCount = checkOpenMPLoop( 10872 OMPD_teams_distribute_parallel_for_simd, getCollapseNumberExpr(Clauses), 10873 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 10874 VarsWithImplicitDSA, B); 10875 10876 if (NestedLoopCount == 0) 10877 return StmtError(); 10878 10879 assert((CurContext->isDependentContext() || B.builtAll()) && 10880 "omp for loop exprs were not built"); 10881 10882 if (!CurContext->isDependentContext()) { 10883 // Finalize the clauses that need pre-built expressions for CodeGen. 10884 for (OMPClause *C : Clauses) { 10885 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 10886 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 10887 B.NumIterations, *this, CurScope, 10888 DSAStack)) 10889 return StmtError(); 10890 } 10891 } 10892 10893 if (checkSimdlenSafelenSpecified(*this, Clauses)) 10894 return StmtError(); 10895 10896 setFunctionHasBranchProtectedScope(); 10897 10898 DSAStack->setParentTeamsRegionLoc(StartLoc); 10899 10900 return OMPTeamsDistributeParallelForSimdDirective::Create( 10901 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 10902 } 10903 10904 StmtResult Sema::ActOnOpenMPTeamsDistributeParallelForDirective( 10905 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10906 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10907 if (!AStmt) 10908 return StmtError(); 10909 10910 auto *CS = cast<CapturedStmt>(AStmt); 10911 // 1.2.2 OpenMP Language Terminology 10912 // Structured block - An executable statement with a single entry at the 10913 // top and a single exit at the bottom. 10914 // The point of exit cannot be a branch out of the structured block. 10915 // longjmp() and throw() must not violate the entry/exit criteria. 10916 CS->getCapturedDecl()->setNothrow(); 10917 10918 for (int ThisCaptureLevel = 10919 getOpenMPCaptureLevels(OMPD_teams_distribute_parallel_for); 10920 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10921 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10922 // 1.2.2 OpenMP Language Terminology 10923 // Structured block - An executable statement with a single entry at the 10924 // top and a single exit at the bottom. 10925 // The point of exit cannot be a branch out of the structured block. 10926 // longjmp() and throw() must not violate the entry/exit criteria. 10927 CS->getCapturedDecl()->setNothrow(); 10928 } 10929 10930 OMPLoopDirective::HelperExprs B; 10931 // In presence of clause 'collapse' with number of loops, it will 10932 // define the nested loops number. 10933 unsigned NestedLoopCount = checkOpenMPLoop( 10934 OMPD_teams_distribute_parallel_for, getCollapseNumberExpr(Clauses), 10935 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 10936 VarsWithImplicitDSA, B); 10937 10938 if (NestedLoopCount == 0) 10939 return StmtError(); 10940 10941 assert((CurContext->isDependentContext() || B.builtAll()) && 10942 "omp for loop exprs were not built"); 10943 10944 setFunctionHasBranchProtectedScope(); 10945 10946 DSAStack->setParentTeamsRegionLoc(StartLoc); 10947 10948 return OMPTeamsDistributeParallelForDirective::Create( 10949 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B, 10950 DSAStack->isCancelRegion()); 10951 } 10952 10953 StmtResult Sema::ActOnOpenMPTargetTeamsDirective(ArrayRef<OMPClause *> Clauses, 10954 Stmt *AStmt, 10955 SourceLocation StartLoc, 10956 SourceLocation EndLoc) { 10957 if (!AStmt) 10958 return StmtError(); 10959 10960 auto *CS = cast<CapturedStmt>(AStmt); 10961 // 1.2.2 OpenMP Language Terminology 10962 // Structured block - An executable statement with a single entry at the 10963 // top and a single exit at the bottom. 10964 // The point of exit cannot be a branch out of the structured block. 10965 // longjmp() and throw() must not violate the entry/exit criteria. 10966 CS->getCapturedDecl()->setNothrow(); 10967 10968 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_teams); 10969 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10970 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10971 // 1.2.2 OpenMP Language Terminology 10972 // Structured block - An executable statement with a single entry at the 10973 // top and a single exit at the bottom. 10974 // The point of exit cannot be a branch out of the structured block. 10975 // longjmp() and throw() must not violate the entry/exit criteria. 10976 CS->getCapturedDecl()->setNothrow(); 10977 } 10978 setFunctionHasBranchProtectedScope(); 10979 10980 return OMPTargetTeamsDirective::Create(Context, StartLoc, EndLoc, Clauses, 10981 AStmt); 10982 } 10983 10984 StmtResult Sema::ActOnOpenMPTargetTeamsDistributeDirective( 10985 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10986 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10987 if (!AStmt) 10988 return StmtError(); 10989 10990 auto *CS = cast<CapturedStmt>(AStmt); 10991 // 1.2.2 OpenMP Language Terminology 10992 // Structured block - An executable statement with a single entry at the 10993 // top and a single exit at the bottom. 10994 // The point of exit cannot be a branch out of the structured block. 10995 // longjmp() and throw() must not violate the entry/exit criteria. 10996 CS->getCapturedDecl()->setNothrow(); 10997 for (int ThisCaptureLevel = 10998 getOpenMPCaptureLevels(OMPD_target_teams_distribute); 10999 ThisCaptureLevel > 1; --ThisCaptureLevel) { 11000 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 11001 // 1.2.2 OpenMP Language Terminology 11002 // Structured block - An executable statement with a single entry at the 11003 // top and a single exit at the bottom. 11004 // The point of exit cannot be a branch out of the structured block. 11005 // longjmp() and throw() must not violate the entry/exit criteria. 11006 CS->getCapturedDecl()->setNothrow(); 11007 } 11008 11009 OMPLoopDirective::HelperExprs B; 11010 // In presence of clause 'collapse' with number of loops, it will 11011 // define the nested loops number. 11012 unsigned NestedLoopCount = checkOpenMPLoop( 11013 OMPD_target_teams_distribute, getCollapseNumberExpr(Clauses), 11014 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 11015 VarsWithImplicitDSA, B); 11016 if (NestedLoopCount == 0) 11017 return StmtError(); 11018 11019 assert((CurContext->isDependentContext() || B.builtAll()) && 11020 "omp target teams distribute loop exprs were not built"); 11021 11022 setFunctionHasBranchProtectedScope(); 11023 return OMPTargetTeamsDistributeDirective::Create( 11024 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 11025 } 11026 11027 StmtResult Sema::ActOnOpenMPTargetTeamsDistributeParallelForDirective( 11028 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 11029 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 11030 if (!AStmt) 11031 return StmtError(); 11032 11033 auto *CS = cast<CapturedStmt>(AStmt); 11034 // 1.2.2 OpenMP Language Terminology 11035 // Structured block - An executable statement with a single entry at the 11036 // top and a single exit at the bottom. 11037 // The point of exit cannot be a branch out of the structured block. 11038 // longjmp() and throw() must not violate the entry/exit criteria. 11039 CS->getCapturedDecl()->setNothrow(); 11040 for (int ThisCaptureLevel = 11041 getOpenMPCaptureLevels(OMPD_target_teams_distribute_parallel_for); 11042 ThisCaptureLevel > 1; --ThisCaptureLevel) { 11043 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 11044 // 1.2.2 OpenMP Language Terminology 11045 // Structured block - An executable statement with a single entry at the 11046 // top and a single exit at the bottom. 11047 // The point of exit cannot be a branch out of the structured block. 11048 // longjmp() and throw() must not violate the entry/exit criteria. 11049 CS->getCapturedDecl()->setNothrow(); 11050 } 11051 11052 OMPLoopDirective::HelperExprs B; 11053 // In presence of clause 'collapse' with number of loops, it will 11054 // define the nested loops number. 11055 unsigned NestedLoopCount = checkOpenMPLoop( 11056 OMPD_target_teams_distribute_parallel_for, getCollapseNumberExpr(Clauses), 11057 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 11058 VarsWithImplicitDSA, B); 11059 if (NestedLoopCount == 0) 11060 return StmtError(); 11061 11062 assert((CurContext->isDependentContext() || B.builtAll()) && 11063 "omp target teams distribute parallel for loop exprs were not built"); 11064 11065 if (!CurContext->isDependentContext()) { 11066 // Finalize the clauses that need pre-built expressions for CodeGen. 11067 for (OMPClause *C : Clauses) { 11068 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 11069 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 11070 B.NumIterations, *this, CurScope, 11071 DSAStack)) 11072 return StmtError(); 11073 } 11074 } 11075 11076 setFunctionHasBranchProtectedScope(); 11077 return OMPTargetTeamsDistributeParallelForDirective::Create( 11078 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B, 11079 DSAStack->isCancelRegion()); 11080 } 11081 11082 StmtResult Sema::ActOnOpenMPTargetTeamsDistributeParallelForSimdDirective( 11083 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 11084 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 11085 if (!AStmt) 11086 return StmtError(); 11087 11088 auto *CS = cast<CapturedStmt>(AStmt); 11089 // 1.2.2 OpenMP Language Terminology 11090 // Structured block - An executable statement with a single entry at the 11091 // top and a single exit at the bottom. 11092 // The point of exit cannot be a branch out of the structured block. 11093 // longjmp() and throw() must not violate the entry/exit criteria. 11094 CS->getCapturedDecl()->setNothrow(); 11095 for (int ThisCaptureLevel = getOpenMPCaptureLevels( 11096 OMPD_target_teams_distribute_parallel_for_simd); 11097 ThisCaptureLevel > 1; --ThisCaptureLevel) { 11098 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 11099 // 1.2.2 OpenMP Language Terminology 11100 // Structured block - An executable statement with a single entry at the 11101 // top and a single exit at the bottom. 11102 // The point of exit cannot be a branch out of the structured block. 11103 // longjmp() and throw() must not violate the entry/exit criteria. 11104 CS->getCapturedDecl()->setNothrow(); 11105 } 11106 11107 OMPLoopDirective::HelperExprs B; 11108 // In presence of clause 'collapse' with number of loops, it will 11109 // define the nested loops number. 11110 unsigned NestedLoopCount = 11111 checkOpenMPLoop(OMPD_target_teams_distribute_parallel_for_simd, 11112 getCollapseNumberExpr(Clauses), 11113 nullptr /*ordered not a clause on distribute*/, CS, *this, 11114 *DSAStack, VarsWithImplicitDSA, B); 11115 if (NestedLoopCount == 0) 11116 return StmtError(); 11117 11118 assert((CurContext->isDependentContext() || B.builtAll()) && 11119 "omp target teams distribute parallel for simd loop exprs were not " 11120 "built"); 11121 11122 if (!CurContext->isDependentContext()) { 11123 // Finalize the clauses that need pre-built expressions for CodeGen. 11124 for (OMPClause *C : Clauses) { 11125 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 11126 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 11127 B.NumIterations, *this, CurScope, 11128 DSAStack)) 11129 return StmtError(); 11130 } 11131 } 11132 11133 if (checkSimdlenSafelenSpecified(*this, Clauses)) 11134 return StmtError(); 11135 11136 setFunctionHasBranchProtectedScope(); 11137 return OMPTargetTeamsDistributeParallelForSimdDirective::Create( 11138 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 11139 } 11140 11141 StmtResult Sema::ActOnOpenMPTargetTeamsDistributeSimdDirective( 11142 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 11143 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 11144 if (!AStmt) 11145 return StmtError(); 11146 11147 auto *CS = cast<CapturedStmt>(AStmt); 11148 // 1.2.2 OpenMP Language Terminology 11149 // Structured block - An executable statement with a single entry at the 11150 // top and a single exit at the bottom. 11151 // The point of exit cannot be a branch out of the structured block. 11152 // longjmp() and throw() must not violate the entry/exit criteria. 11153 CS->getCapturedDecl()->setNothrow(); 11154 for (int ThisCaptureLevel = 11155 getOpenMPCaptureLevels(OMPD_target_teams_distribute_simd); 11156 ThisCaptureLevel > 1; --ThisCaptureLevel) { 11157 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 11158 // 1.2.2 OpenMP Language Terminology 11159 // Structured block - An executable statement with a single entry at the 11160 // top and a single exit at the bottom. 11161 // The point of exit cannot be a branch out of the structured block. 11162 // longjmp() and throw() must not violate the entry/exit criteria. 11163 CS->getCapturedDecl()->setNothrow(); 11164 } 11165 11166 OMPLoopDirective::HelperExprs B; 11167 // In presence of clause 'collapse' with number of loops, it will 11168 // define the nested loops number. 11169 unsigned NestedLoopCount = checkOpenMPLoop( 11170 OMPD_target_teams_distribute_simd, getCollapseNumberExpr(Clauses), 11171 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 11172 VarsWithImplicitDSA, B); 11173 if (NestedLoopCount == 0) 11174 return StmtError(); 11175 11176 assert((CurContext->isDependentContext() || B.builtAll()) && 11177 "omp target teams distribute simd loop exprs were not built"); 11178 11179 if (!CurContext->isDependentContext()) { 11180 // Finalize the clauses that need pre-built expressions for CodeGen. 11181 for (OMPClause *C : Clauses) { 11182 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 11183 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 11184 B.NumIterations, *this, CurScope, 11185 DSAStack)) 11186 return StmtError(); 11187 } 11188 } 11189 11190 if (checkSimdlenSafelenSpecified(*this, Clauses)) 11191 return StmtError(); 11192 11193 setFunctionHasBranchProtectedScope(); 11194 return OMPTargetTeamsDistributeSimdDirective::Create( 11195 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 11196 } 11197 11198 OMPClause *Sema::ActOnOpenMPSingleExprClause(OpenMPClauseKind Kind, Expr *Expr, 11199 SourceLocation StartLoc, 11200 SourceLocation LParenLoc, 11201 SourceLocation EndLoc) { 11202 OMPClause *Res = nullptr; 11203 switch (Kind) { 11204 case OMPC_final: 11205 Res = ActOnOpenMPFinalClause(Expr, StartLoc, LParenLoc, EndLoc); 11206 break; 11207 case OMPC_num_threads: 11208 Res = ActOnOpenMPNumThreadsClause(Expr, StartLoc, LParenLoc, EndLoc); 11209 break; 11210 case OMPC_safelen: 11211 Res = ActOnOpenMPSafelenClause(Expr, StartLoc, LParenLoc, EndLoc); 11212 break; 11213 case OMPC_simdlen: 11214 Res = ActOnOpenMPSimdlenClause(Expr, StartLoc, LParenLoc, EndLoc); 11215 break; 11216 case OMPC_allocator: 11217 Res = ActOnOpenMPAllocatorClause(Expr, StartLoc, LParenLoc, EndLoc); 11218 break; 11219 case OMPC_collapse: 11220 Res = ActOnOpenMPCollapseClause(Expr, StartLoc, LParenLoc, EndLoc); 11221 break; 11222 case OMPC_ordered: 11223 Res = ActOnOpenMPOrderedClause(StartLoc, EndLoc, LParenLoc, Expr); 11224 break; 11225 case OMPC_num_teams: 11226 Res = ActOnOpenMPNumTeamsClause(Expr, StartLoc, LParenLoc, EndLoc); 11227 break; 11228 case OMPC_thread_limit: 11229 Res = ActOnOpenMPThreadLimitClause(Expr, StartLoc, LParenLoc, EndLoc); 11230 break; 11231 case OMPC_priority: 11232 Res = ActOnOpenMPPriorityClause(Expr, StartLoc, LParenLoc, EndLoc); 11233 break; 11234 case OMPC_grainsize: 11235 Res = ActOnOpenMPGrainsizeClause(Expr, StartLoc, LParenLoc, EndLoc); 11236 break; 11237 case OMPC_num_tasks: 11238 Res = ActOnOpenMPNumTasksClause(Expr, StartLoc, LParenLoc, EndLoc); 11239 break; 11240 case OMPC_hint: 11241 Res = ActOnOpenMPHintClause(Expr, StartLoc, LParenLoc, EndLoc); 11242 break; 11243 case OMPC_depobj: 11244 Res = ActOnOpenMPDepobjClause(Expr, StartLoc, LParenLoc, EndLoc); 11245 break; 11246 case OMPC_detach: 11247 Res = ActOnOpenMPDetachClause(Expr, StartLoc, LParenLoc, EndLoc); 11248 break; 11249 case OMPC_device: 11250 case OMPC_if: 11251 case OMPC_default: 11252 case OMPC_proc_bind: 11253 case OMPC_schedule: 11254 case OMPC_private: 11255 case OMPC_firstprivate: 11256 case OMPC_lastprivate: 11257 case OMPC_shared: 11258 case OMPC_reduction: 11259 case OMPC_task_reduction: 11260 case OMPC_in_reduction: 11261 case OMPC_linear: 11262 case OMPC_aligned: 11263 case OMPC_copyin: 11264 case OMPC_copyprivate: 11265 case OMPC_nowait: 11266 case OMPC_untied: 11267 case OMPC_mergeable: 11268 case OMPC_threadprivate: 11269 case OMPC_allocate: 11270 case OMPC_flush: 11271 case OMPC_read: 11272 case OMPC_write: 11273 case OMPC_update: 11274 case OMPC_capture: 11275 case OMPC_seq_cst: 11276 case OMPC_acq_rel: 11277 case OMPC_acquire: 11278 case OMPC_release: 11279 case OMPC_relaxed: 11280 case OMPC_depend: 11281 case OMPC_threads: 11282 case OMPC_simd: 11283 case OMPC_map: 11284 case OMPC_nogroup: 11285 case OMPC_dist_schedule: 11286 case OMPC_defaultmap: 11287 case OMPC_unknown: 11288 case OMPC_uniform: 11289 case OMPC_to: 11290 case OMPC_from: 11291 case OMPC_use_device_ptr: 11292 case OMPC_is_device_ptr: 11293 case OMPC_unified_address: 11294 case OMPC_unified_shared_memory: 11295 case OMPC_reverse_offload: 11296 case OMPC_dynamic_allocators: 11297 case OMPC_atomic_default_mem_order: 11298 case OMPC_device_type: 11299 case OMPC_match: 11300 case OMPC_nontemporal: 11301 case OMPC_order: 11302 case OMPC_destroy: 11303 case OMPC_inclusive: 11304 case OMPC_exclusive: 11305 llvm_unreachable("Clause is not allowed."); 11306 } 11307 return Res; 11308 } 11309 11310 // An OpenMP directive such as 'target parallel' has two captured regions: 11311 // for the 'target' and 'parallel' respectively. This function returns 11312 // the region in which to capture expressions associated with a clause. 11313 // A return value of OMPD_unknown signifies that the expression should not 11314 // be captured. 11315 static OpenMPDirectiveKind getOpenMPCaptureRegionForClause( 11316 OpenMPDirectiveKind DKind, OpenMPClauseKind CKind, unsigned OpenMPVersion, 11317 OpenMPDirectiveKind NameModifier = OMPD_unknown) { 11318 OpenMPDirectiveKind CaptureRegion = OMPD_unknown; 11319 switch (CKind) { 11320 case OMPC_if: 11321 switch (DKind) { 11322 case OMPD_target_parallel_for_simd: 11323 if (OpenMPVersion >= 50 && 11324 (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)) { 11325 CaptureRegion = OMPD_parallel; 11326 break; 11327 } 11328 LLVM_FALLTHROUGH; 11329 case OMPD_target_parallel: 11330 case OMPD_target_parallel_for: 11331 // If this clause applies to the nested 'parallel' region, capture within 11332 // the 'target' region, otherwise do not capture. 11333 if (NameModifier == OMPD_unknown || NameModifier == OMPD_parallel) 11334 CaptureRegion = OMPD_target; 11335 break; 11336 case OMPD_target_teams_distribute_parallel_for_simd: 11337 if (OpenMPVersion >= 50 && 11338 (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)) { 11339 CaptureRegion = OMPD_parallel; 11340 break; 11341 } 11342 LLVM_FALLTHROUGH; 11343 case OMPD_target_teams_distribute_parallel_for: 11344 // If this clause applies to the nested 'parallel' region, capture within 11345 // the 'teams' region, otherwise do not capture. 11346 if (NameModifier == OMPD_unknown || NameModifier == OMPD_parallel) 11347 CaptureRegion = OMPD_teams; 11348 break; 11349 case OMPD_teams_distribute_parallel_for_simd: 11350 if (OpenMPVersion >= 50 && 11351 (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)) { 11352 CaptureRegion = OMPD_parallel; 11353 break; 11354 } 11355 LLVM_FALLTHROUGH; 11356 case OMPD_teams_distribute_parallel_for: 11357 CaptureRegion = OMPD_teams; 11358 break; 11359 case OMPD_target_update: 11360 case OMPD_target_enter_data: 11361 case OMPD_target_exit_data: 11362 CaptureRegion = OMPD_task; 11363 break; 11364 case OMPD_parallel_master_taskloop: 11365 if (NameModifier == OMPD_unknown || NameModifier == OMPD_taskloop) 11366 CaptureRegion = OMPD_parallel; 11367 break; 11368 case OMPD_parallel_master_taskloop_simd: 11369 if ((OpenMPVersion <= 45 && NameModifier == OMPD_unknown) || 11370 NameModifier == OMPD_taskloop) { 11371 CaptureRegion = OMPD_parallel; 11372 break; 11373 } 11374 if (OpenMPVersion <= 45) 11375 break; 11376 if (NameModifier == OMPD_unknown || NameModifier == OMPD_simd) 11377 CaptureRegion = OMPD_taskloop; 11378 break; 11379 case OMPD_parallel_for_simd: 11380 if (OpenMPVersion <= 45) 11381 break; 11382 if (NameModifier == OMPD_unknown || NameModifier == OMPD_simd) 11383 CaptureRegion = OMPD_parallel; 11384 break; 11385 case OMPD_taskloop_simd: 11386 case OMPD_master_taskloop_simd: 11387 if (OpenMPVersion <= 45) 11388 break; 11389 if (NameModifier == OMPD_unknown || NameModifier == OMPD_simd) 11390 CaptureRegion = OMPD_taskloop; 11391 break; 11392 case OMPD_distribute_parallel_for_simd: 11393 if (OpenMPVersion <= 45) 11394 break; 11395 if (NameModifier == OMPD_unknown || NameModifier == OMPD_simd) 11396 CaptureRegion = OMPD_parallel; 11397 break; 11398 case OMPD_target_simd: 11399 if (OpenMPVersion >= 50 && 11400 (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)) 11401 CaptureRegion = OMPD_target; 11402 break; 11403 case OMPD_teams_distribute_simd: 11404 case OMPD_target_teams_distribute_simd: 11405 if (OpenMPVersion >= 50 && 11406 (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)) 11407 CaptureRegion = OMPD_teams; 11408 break; 11409 case OMPD_cancel: 11410 case OMPD_parallel: 11411 case OMPD_parallel_master: 11412 case OMPD_parallel_sections: 11413 case OMPD_parallel_for: 11414 case OMPD_target: 11415 case OMPD_target_teams: 11416 case OMPD_target_teams_distribute: 11417 case OMPD_distribute_parallel_for: 11418 case OMPD_task: 11419 case OMPD_taskloop: 11420 case OMPD_master_taskloop: 11421 case OMPD_target_data: 11422 case OMPD_simd: 11423 case OMPD_for_simd: 11424 case OMPD_distribute_simd: 11425 // Do not capture if-clause expressions. 11426 break; 11427 case OMPD_threadprivate: 11428 case OMPD_allocate: 11429 case OMPD_taskyield: 11430 case OMPD_barrier: 11431 case OMPD_taskwait: 11432 case OMPD_cancellation_point: 11433 case OMPD_flush: 11434 case OMPD_depobj: 11435 case OMPD_scan: 11436 case OMPD_declare_reduction: 11437 case OMPD_declare_mapper: 11438 case OMPD_declare_simd: 11439 case OMPD_declare_variant: 11440 case OMPD_begin_declare_variant: 11441 case OMPD_end_declare_variant: 11442 case OMPD_declare_target: 11443 case OMPD_end_declare_target: 11444 case OMPD_teams: 11445 case OMPD_for: 11446 case OMPD_sections: 11447 case OMPD_section: 11448 case OMPD_single: 11449 case OMPD_master: 11450 case OMPD_critical: 11451 case OMPD_taskgroup: 11452 case OMPD_distribute: 11453 case OMPD_ordered: 11454 case OMPD_atomic: 11455 case OMPD_teams_distribute: 11456 case OMPD_requires: 11457 llvm_unreachable("Unexpected OpenMP directive with if-clause"); 11458 case OMPD_unknown: 11459 llvm_unreachable("Unknown OpenMP directive"); 11460 } 11461 break; 11462 case OMPC_num_threads: 11463 switch (DKind) { 11464 case OMPD_target_parallel: 11465 case OMPD_target_parallel_for: 11466 case OMPD_target_parallel_for_simd: 11467 CaptureRegion = OMPD_target; 11468 break; 11469 case OMPD_teams_distribute_parallel_for: 11470 case OMPD_teams_distribute_parallel_for_simd: 11471 case OMPD_target_teams_distribute_parallel_for: 11472 case OMPD_target_teams_distribute_parallel_for_simd: 11473 CaptureRegion = OMPD_teams; 11474 break; 11475 case OMPD_parallel: 11476 case OMPD_parallel_master: 11477 case OMPD_parallel_sections: 11478 case OMPD_parallel_for: 11479 case OMPD_parallel_for_simd: 11480 case OMPD_distribute_parallel_for: 11481 case OMPD_distribute_parallel_for_simd: 11482 case OMPD_parallel_master_taskloop: 11483 case OMPD_parallel_master_taskloop_simd: 11484 // Do not capture num_threads-clause expressions. 11485 break; 11486 case OMPD_target_data: 11487 case OMPD_target_enter_data: 11488 case OMPD_target_exit_data: 11489 case OMPD_target_update: 11490 case OMPD_target: 11491 case OMPD_target_simd: 11492 case OMPD_target_teams: 11493 case OMPD_target_teams_distribute: 11494 case OMPD_target_teams_distribute_simd: 11495 case OMPD_cancel: 11496 case OMPD_task: 11497 case OMPD_taskloop: 11498 case OMPD_taskloop_simd: 11499 case OMPD_master_taskloop: 11500 case OMPD_master_taskloop_simd: 11501 case OMPD_threadprivate: 11502 case OMPD_allocate: 11503 case OMPD_taskyield: 11504 case OMPD_barrier: 11505 case OMPD_taskwait: 11506 case OMPD_cancellation_point: 11507 case OMPD_flush: 11508 case OMPD_depobj: 11509 case OMPD_scan: 11510 case OMPD_declare_reduction: 11511 case OMPD_declare_mapper: 11512 case OMPD_declare_simd: 11513 case OMPD_declare_variant: 11514 case OMPD_begin_declare_variant: 11515 case OMPD_end_declare_variant: 11516 case OMPD_declare_target: 11517 case OMPD_end_declare_target: 11518 case OMPD_teams: 11519 case OMPD_simd: 11520 case OMPD_for: 11521 case OMPD_for_simd: 11522 case OMPD_sections: 11523 case OMPD_section: 11524 case OMPD_single: 11525 case OMPD_master: 11526 case OMPD_critical: 11527 case OMPD_taskgroup: 11528 case OMPD_distribute: 11529 case OMPD_ordered: 11530 case OMPD_atomic: 11531 case OMPD_distribute_simd: 11532 case OMPD_teams_distribute: 11533 case OMPD_teams_distribute_simd: 11534 case OMPD_requires: 11535 llvm_unreachable("Unexpected OpenMP directive with num_threads-clause"); 11536 case OMPD_unknown: 11537 llvm_unreachable("Unknown OpenMP directive"); 11538 } 11539 break; 11540 case OMPC_num_teams: 11541 switch (DKind) { 11542 case OMPD_target_teams: 11543 case OMPD_target_teams_distribute: 11544 case OMPD_target_teams_distribute_simd: 11545 case OMPD_target_teams_distribute_parallel_for: 11546 case OMPD_target_teams_distribute_parallel_for_simd: 11547 CaptureRegion = OMPD_target; 11548 break; 11549 case OMPD_teams_distribute_parallel_for: 11550 case OMPD_teams_distribute_parallel_for_simd: 11551 case OMPD_teams: 11552 case OMPD_teams_distribute: 11553 case OMPD_teams_distribute_simd: 11554 // Do not capture num_teams-clause expressions. 11555 break; 11556 case OMPD_distribute_parallel_for: 11557 case OMPD_distribute_parallel_for_simd: 11558 case OMPD_task: 11559 case OMPD_taskloop: 11560 case OMPD_taskloop_simd: 11561 case OMPD_master_taskloop: 11562 case OMPD_master_taskloop_simd: 11563 case OMPD_parallel_master_taskloop: 11564 case OMPD_parallel_master_taskloop_simd: 11565 case OMPD_target_data: 11566 case OMPD_target_enter_data: 11567 case OMPD_target_exit_data: 11568 case OMPD_target_update: 11569 case OMPD_cancel: 11570 case OMPD_parallel: 11571 case OMPD_parallel_master: 11572 case OMPD_parallel_sections: 11573 case OMPD_parallel_for: 11574 case OMPD_parallel_for_simd: 11575 case OMPD_target: 11576 case OMPD_target_simd: 11577 case OMPD_target_parallel: 11578 case OMPD_target_parallel_for: 11579 case OMPD_target_parallel_for_simd: 11580 case OMPD_threadprivate: 11581 case OMPD_allocate: 11582 case OMPD_taskyield: 11583 case OMPD_barrier: 11584 case OMPD_taskwait: 11585 case OMPD_cancellation_point: 11586 case OMPD_flush: 11587 case OMPD_depobj: 11588 case OMPD_scan: 11589 case OMPD_declare_reduction: 11590 case OMPD_declare_mapper: 11591 case OMPD_declare_simd: 11592 case OMPD_declare_variant: 11593 case OMPD_begin_declare_variant: 11594 case OMPD_end_declare_variant: 11595 case OMPD_declare_target: 11596 case OMPD_end_declare_target: 11597 case OMPD_simd: 11598 case OMPD_for: 11599 case OMPD_for_simd: 11600 case OMPD_sections: 11601 case OMPD_section: 11602 case OMPD_single: 11603 case OMPD_master: 11604 case OMPD_critical: 11605 case OMPD_taskgroup: 11606 case OMPD_distribute: 11607 case OMPD_ordered: 11608 case OMPD_atomic: 11609 case OMPD_distribute_simd: 11610 case OMPD_requires: 11611 llvm_unreachable("Unexpected OpenMP directive with num_teams-clause"); 11612 case OMPD_unknown: 11613 llvm_unreachable("Unknown OpenMP directive"); 11614 } 11615 break; 11616 case OMPC_thread_limit: 11617 switch (DKind) { 11618 case OMPD_target_teams: 11619 case OMPD_target_teams_distribute: 11620 case OMPD_target_teams_distribute_simd: 11621 case OMPD_target_teams_distribute_parallel_for: 11622 case OMPD_target_teams_distribute_parallel_for_simd: 11623 CaptureRegion = OMPD_target; 11624 break; 11625 case OMPD_teams_distribute_parallel_for: 11626 case OMPD_teams_distribute_parallel_for_simd: 11627 case OMPD_teams: 11628 case OMPD_teams_distribute: 11629 case OMPD_teams_distribute_simd: 11630 // Do not capture thread_limit-clause expressions. 11631 break; 11632 case OMPD_distribute_parallel_for: 11633 case OMPD_distribute_parallel_for_simd: 11634 case OMPD_task: 11635 case OMPD_taskloop: 11636 case OMPD_taskloop_simd: 11637 case OMPD_master_taskloop: 11638 case OMPD_master_taskloop_simd: 11639 case OMPD_parallel_master_taskloop: 11640 case OMPD_parallel_master_taskloop_simd: 11641 case OMPD_target_data: 11642 case OMPD_target_enter_data: 11643 case OMPD_target_exit_data: 11644 case OMPD_target_update: 11645 case OMPD_cancel: 11646 case OMPD_parallel: 11647 case OMPD_parallel_master: 11648 case OMPD_parallel_sections: 11649 case OMPD_parallel_for: 11650 case OMPD_parallel_for_simd: 11651 case OMPD_target: 11652 case OMPD_target_simd: 11653 case OMPD_target_parallel: 11654 case OMPD_target_parallel_for: 11655 case OMPD_target_parallel_for_simd: 11656 case OMPD_threadprivate: 11657 case OMPD_allocate: 11658 case OMPD_taskyield: 11659 case OMPD_barrier: 11660 case OMPD_taskwait: 11661 case OMPD_cancellation_point: 11662 case OMPD_flush: 11663 case OMPD_depobj: 11664 case OMPD_scan: 11665 case OMPD_declare_reduction: 11666 case OMPD_declare_mapper: 11667 case OMPD_declare_simd: 11668 case OMPD_declare_variant: 11669 case OMPD_begin_declare_variant: 11670 case OMPD_end_declare_variant: 11671 case OMPD_declare_target: 11672 case OMPD_end_declare_target: 11673 case OMPD_simd: 11674 case OMPD_for: 11675 case OMPD_for_simd: 11676 case OMPD_sections: 11677 case OMPD_section: 11678 case OMPD_single: 11679 case OMPD_master: 11680 case OMPD_critical: 11681 case OMPD_taskgroup: 11682 case OMPD_distribute: 11683 case OMPD_ordered: 11684 case OMPD_atomic: 11685 case OMPD_distribute_simd: 11686 case OMPD_requires: 11687 llvm_unreachable("Unexpected OpenMP directive with thread_limit-clause"); 11688 case OMPD_unknown: 11689 llvm_unreachable("Unknown OpenMP directive"); 11690 } 11691 break; 11692 case OMPC_schedule: 11693 switch (DKind) { 11694 case OMPD_parallel_for: 11695 case OMPD_parallel_for_simd: 11696 case OMPD_distribute_parallel_for: 11697 case OMPD_distribute_parallel_for_simd: 11698 case OMPD_teams_distribute_parallel_for: 11699 case OMPD_teams_distribute_parallel_for_simd: 11700 case OMPD_target_parallel_for: 11701 case OMPD_target_parallel_for_simd: 11702 case OMPD_target_teams_distribute_parallel_for: 11703 case OMPD_target_teams_distribute_parallel_for_simd: 11704 CaptureRegion = OMPD_parallel; 11705 break; 11706 case OMPD_for: 11707 case OMPD_for_simd: 11708 // Do not capture schedule-clause expressions. 11709 break; 11710 case OMPD_task: 11711 case OMPD_taskloop: 11712 case OMPD_taskloop_simd: 11713 case OMPD_master_taskloop: 11714 case OMPD_master_taskloop_simd: 11715 case OMPD_parallel_master_taskloop: 11716 case OMPD_parallel_master_taskloop_simd: 11717 case OMPD_target_data: 11718 case OMPD_target_enter_data: 11719 case OMPD_target_exit_data: 11720 case OMPD_target_update: 11721 case OMPD_teams: 11722 case OMPD_teams_distribute: 11723 case OMPD_teams_distribute_simd: 11724 case OMPD_target_teams_distribute: 11725 case OMPD_target_teams_distribute_simd: 11726 case OMPD_target: 11727 case OMPD_target_simd: 11728 case OMPD_target_parallel: 11729 case OMPD_cancel: 11730 case OMPD_parallel: 11731 case OMPD_parallel_master: 11732 case OMPD_parallel_sections: 11733 case OMPD_threadprivate: 11734 case OMPD_allocate: 11735 case OMPD_taskyield: 11736 case OMPD_barrier: 11737 case OMPD_taskwait: 11738 case OMPD_cancellation_point: 11739 case OMPD_flush: 11740 case OMPD_depobj: 11741 case OMPD_scan: 11742 case OMPD_declare_reduction: 11743 case OMPD_declare_mapper: 11744 case OMPD_declare_simd: 11745 case OMPD_declare_variant: 11746 case OMPD_begin_declare_variant: 11747 case OMPD_end_declare_variant: 11748 case OMPD_declare_target: 11749 case OMPD_end_declare_target: 11750 case OMPD_simd: 11751 case OMPD_sections: 11752 case OMPD_section: 11753 case OMPD_single: 11754 case OMPD_master: 11755 case OMPD_critical: 11756 case OMPD_taskgroup: 11757 case OMPD_distribute: 11758 case OMPD_ordered: 11759 case OMPD_atomic: 11760 case OMPD_distribute_simd: 11761 case OMPD_target_teams: 11762 case OMPD_requires: 11763 llvm_unreachable("Unexpected OpenMP directive with schedule clause"); 11764 case OMPD_unknown: 11765 llvm_unreachable("Unknown OpenMP directive"); 11766 } 11767 break; 11768 case OMPC_dist_schedule: 11769 switch (DKind) { 11770 case OMPD_teams_distribute_parallel_for: 11771 case OMPD_teams_distribute_parallel_for_simd: 11772 case OMPD_teams_distribute: 11773 case OMPD_teams_distribute_simd: 11774 case OMPD_target_teams_distribute_parallel_for: 11775 case OMPD_target_teams_distribute_parallel_for_simd: 11776 case OMPD_target_teams_distribute: 11777 case OMPD_target_teams_distribute_simd: 11778 CaptureRegion = OMPD_teams; 11779 break; 11780 case OMPD_distribute_parallel_for: 11781 case OMPD_distribute_parallel_for_simd: 11782 case OMPD_distribute: 11783 case OMPD_distribute_simd: 11784 // Do not capture thread_limit-clause expressions. 11785 break; 11786 case OMPD_parallel_for: 11787 case OMPD_parallel_for_simd: 11788 case OMPD_target_parallel_for_simd: 11789 case OMPD_target_parallel_for: 11790 case OMPD_task: 11791 case OMPD_taskloop: 11792 case OMPD_taskloop_simd: 11793 case OMPD_master_taskloop: 11794 case OMPD_master_taskloop_simd: 11795 case OMPD_parallel_master_taskloop: 11796 case OMPD_parallel_master_taskloop_simd: 11797 case OMPD_target_data: 11798 case OMPD_target_enter_data: 11799 case OMPD_target_exit_data: 11800 case OMPD_target_update: 11801 case OMPD_teams: 11802 case OMPD_target: 11803 case OMPD_target_simd: 11804 case OMPD_target_parallel: 11805 case OMPD_cancel: 11806 case OMPD_parallel: 11807 case OMPD_parallel_master: 11808 case OMPD_parallel_sections: 11809 case OMPD_threadprivate: 11810 case OMPD_allocate: 11811 case OMPD_taskyield: 11812 case OMPD_barrier: 11813 case OMPD_taskwait: 11814 case OMPD_cancellation_point: 11815 case OMPD_flush: 11816 case OMPD_depobj: 11817 case OMPD_scan: 11818 case OMPD_declare_reduction: 11819 case OMPD_declare_mapper: 11820 case OMPD_declare_simd: 11821 case OMPD_declare_variant: 11822 case OMPD_begin_declare_variant: 11823 case OMPD_end_declare_variant: 11824 case OMPD_declare_target: 11825 case OMPD_end_declare_target: 11826 case OMPD_simd: 11827 case OMPD_for: 11828 case OMPD_for_simd: 11829 case OMPD_sections: 11830 case OMPD_section: 11831 case OMPD_single: 11832 case OMPD_master: 11833 case OMPD_critical: 11834 case OMPD_taskgroup: 11835 case OMPD_ordered: 11836 case OMPD_atomic: 11837 case OMPD_target_teams: 11838 case OMPD_requires: 11839 llvm_unreachable("Unexpected OpenMP directive with schedule clause"); 11840 case OMPD_unknown: 11841 llvm_unreachable("Unknown OpenMP directive"); 11842 } 11843 break; 11844 case OMPC_device: 11845 switch (DKind) { 11846 case OMPD_target_update: 11847 case OMPD_target_enter_data: 11848 case OMPD_target_exit_data: 11849 case OMPD_target: 11850 case OMPD_target_simd: 11851 case OMPD_target_teams: 11852 case OMPD_target_parallel: 11853 case OMPD_target_teams_distribute: 11854 case OMPD_target_teams_distribute_simd: 11855 case OMPD_target_parallel_for: 11856 case OMPD_target_parallel_for_simd: 11857 case OMPD_target_teams_distribute_parallel_for: 11858 case OMPD_target_teams_distribute_parallel_for_simd: 11859 CaptureRegion = OMPD_task; 11860 break; 11861 case OMPD_target_data: 11862 // Do not capture device-clause expressions. 11863 break; 11864 case OMPD_teams_distribute_parallel_for: 11865 case OMPD_teams_distribute_parallel_for_simd: 11866 case OMPD_teams: 11867 case OMPD_teams_distribute: 11868 case OMPD_teams_distribute_simd: 11869 case OMPD_distribute_parallel_for: 11870 case OMPD_distribute_parallel_for_simd: 11871 case OMPD_task: 11872 case OMPD_taskloop: 11873 case OMPD_taskloop_simd: 11874 case OMPD_master_taskloop: 11875 case OMPD_master_taskloop_simd: 11876 case OMPD_parallel_master_taskloop: 11877 case OMPD_parallel_master_taskloop_simd: 11878 case OMPD_cancel: 11879 case OMPD_parallel: 11880 case OMPD_parallel_master: 11881 case OMPD_parallel_sections: 11882 case OMPD_parallel_for: 11883 case OMPD_parallel_for_simd: 11884 case OMPD_threadprivate: 11885 case OMPD_allocate: 11886 case OMPD_taskyield: 11887 case OMPD_barrier: 11888 case OMPD_taskwait: 11889 case OMPD_cancellation_point: 11890 case OMPD_flush: 11891 case OMPD_depobj: 11892 case OMPD_scan: 11893 case OMPD_declare_reduction: 11894 case OMPD_declare_mapper: 11895 case OMPD_declare_simd: 11896 case OMPD_declare_variant: 11897 case OMPD_begin_declare_variant: 11898 case OMPD_end_declare_variant: 11899 case OMPD_declare_target: 11900 case OMPD_end_declare_target: 11901 case OMPD_simd: 11902 case OMPD_for: 11903 case OMPD_for_simd: 11904 case OMPD_sections: 11905 case OMPD_section: 11906 case OMPD_single: 11907 case OMPD_master: 11908 case OMPD_critical: 11909 case OMPD_taskgroup: 11910 case OMPD_distribute: 11911 case OMPD_ordered: 11912 case OMPD_atomic: 11913 case OMPD_distribute_simd: 11914 case OMPD_requires: 11915 llvm_unreachable("Unexpected OpenMP directive with num_teams-clause"); 11916 case OMPD_unknown: 11917 llvm_unreachable("Unknown OpenMP directive"); 11918 } 11919 break; 11920 case OMPC_grainsize: 11921 case OMPC_num_tasks: 11922 case OMPC_final: 11923 case OMPC_priority: 11924 switch (DKind) { 11925 case OMPD_task: 11926 case OMPD_taskloop: 11927 case OMPD_taskloop_simd: 11928 case OMPD_master_taskloop: 11929 case OMPD_master_taskloop_simd: 11930 break; 11931 case OMPD_parallel_master_taskloop: 11932 case OMPD_parallel_master_taskloop_simd: 11933 CaptureRegion = OMPD_parallel; 11934 break; 11935 case OMPD_target_update: 11936 case OMPD_target_enter_data: 11937 case OMPD_target_exit_data: 11938 case OMPD_target: 11939 case OMPD_target_simd: 11940 case OMPD_target_teams: 11941 case OMPD_target_parallel: 11942 case OMPD_target_teams_distribute: 11943 case OMPD_target_teams_distribute_simd: 11944 case OMPD_target_parallel_for: 11945 case OMPD_target_parallel_for_simd: 11946 case OMPD_target_teams_distribute_parallel_for: 11947 case OMPD_target_teams_distribute_parallel_for_simd: 11948 case OMPD_target_data: 11949 case OMPD_teams_distribute_parallel_for: 11950 case OMPD_teams_distribute_parallel_for_simd: 11951 case OMPD_teams: 11952 case OMPD_teams_distribute: 11953 case OMPD_teams_distribute_simd: 11954 case OMPD_distribute_parallel_for: 11955 case OMPD_distribute_parallel_for_simd: 11956 case OMPD_cancel: 11957 case OMPD_parallel: 11958 case OMPD_parallel_master: 11959 case OMPD_parallel_sections: 11960 case OMPD_parallel_for: 11961 case OMPD_parallel_for_simd: 11962 case OMPD_threadprivate: 11963 case OMPD_allocate: 11964 case OMPD_taskyield: 11965 case OMPD_barrier: 11966 case OMPD_taskwait: 11967 case OMPD_cancellation_point: 11968 case OMPD_flush: 11969 case OMPD_depobj: 11970 case OMPD_scan: 11971 case OMPD_declare_reduction: 11972 case OMPD_declare_mapper: 11973 case OMPD_declare_simd: 11974 case OMPD_declare_variant: 11975 case OMPD_begin_declare_variant: 11976 case OMPD_end_declare_variant: 11977 case OMPD_declare_target: 11978 case OMPD_end_declare_target: 11979 case OMPD_simd: 11980 case OMPD_for: 11981 case OMPD_for_simd: 11982 case OMPD_sections: 11983 case OMPD_section: 11984 case OMPD_single: 11985 case OMPD_master: 11986 case OMPD_critical: 11987 case OMPD_taskgroup: 11988 case OMPD_distribute: 11989 case OMPD_ordered: 11990 case OMPD_atomic: 11991 case OMPD_distribute_simd: 11992 case OMPD_requires: 11993 llvm_unreachable("Unexpected OpenMP directive with grainsize-clause"); 11994 case OMPD_unknown: 11995 llvm_unreachable("Unknown OpenMP directive"); 11996 } 11997 break; 11998 case OMPC_firstprivate: 11999 case OMPC_lastprivate: 12000 case OMPC_reduction: 12001 case OMPC_task_reduction: 12002 case OMPC_in_reduction: 12003 case OMPC_linear: 12004 case OMPC_default: 12005 case OMPC_proc_bind: 12006 case OMPC_safelen: 12007 case OMPC_simdlen: 12008 case OMPC_allocator: 12009 case OMPC_collapse: 12010 case OMPC_private: 12011 case OMPC_shared: 12012 case OMPC_aligned: 12013 case OMPC_copyin: 12014 case OMPC_copyprivate: 12015 case OMPC_ordered: 12016 case OMPC_nowait: 12017 case OMPC_untied: 12018 case OMPC_mergeable: 12019 case OMPC_threadprivate: 12020 case OMPC_allocate: 12021 case OMPC_flush: 12022 case OMPC_depobj: 12023 case OMPC_read: 12024 case OMPC_write: 12025 case OMPC_update: 12026 case OMPC_capture: 12027 case OMPC_seq_cst: 12028 case OMPC_acq_rel: 12029 case OMPC_acquire: 12030 case OMPC_release: 12031 case OMPC_relaxed: 12032 case OMPC_depend: 12033 case OMPC_threads: 12034 case OMPC_simd: 12035 case OMPC_map: 12036 case OMPC_nogroup: 12037 case OMPC_hint: 12038 case OMPC_defaultmap: 12039 case OMPC_unknown: 12040 case OMPC_uniform: 12041 case OMPC_to: 12042 case OMPC_from: 12043 case OMPC_use_device_ptr: 12044 case OMPC_is_device_ptr: 12045 case OMPC_unified_address: 12046 case OMPC_unified_shared_memory: 12047 case OMPC_reverse_offload: 12048 case OMPC_dynamic_allocators: 12049 case OMPC_atomic_default_mem_order: 12050 case OMPC_device_type: 12051 case OMPC_match: 12052 case OMPC_nontemporal: 12053 case OMPC_order: 12054 case OMPC_destroy: 12055 case OMPC_detach: 12056 case OMPC_inclusive: 12057 case OMPC_exclusive: 12058 llvm_unreachable("Unexpected OpenMP clause."); 12059 } 12060 return CaptureRegion; 12061 } 12062 12063 OMPClause *Sema::ActOnOpenMPIfClause(OpenMPDirectiveKind NameModifier, 12064 Expr *Condition, SourceLocation StartLoc, 12065 SourceLocation LParenLoc, 12066 SourceLocation NameModifierLoc, 12067 SourceLocation ColonLoc, 12068 SourceLocation EndLoc) { 12069 Expr *ValExpr = Condition; 12070 Stmt *HelperValStmt = nullptr; 12071 OpenMPDirectiveKind CaptureRegion = OMPD_unknown; 12072 if (!Condition->isValueDependent() && !Condition->isTypeDependent() && 12073 !Condition->isInstantiationDependent() && 12074 !Condition->containsUnexpandedParameterPack()) { 12075 ExprResult Val = CheckBooleanCondition(StartLoc, Condition); 12076 if (Val.isInvalid()) 12077 return nullptr; 12078 12079 ValExpr = Val.get(); 12080 12081 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 12082 CaptureRegion = getOpenMPCaptureRegionForClause( 12083 DKind, OMPC_if, LangOpts.OpenMP, NameModifier); 12084 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 12085 ValExpr = MakeFullExpr(ValExpr).get(); 12086 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 12087 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 12088 HelperValStmt = buildPreInits(Context, Captures); 12089 } 12090 } 12091 12092 return new (Context) 12093 OMPIfClause(NameModifier, ValExpr, HelperValStmt, CaptureRegion, StartLoc, 12094 LParenLoc, NameModifierLoc, ColonLoc, EndLoc); 12095 } 12096 12097 OMPClause *Sema::ActOnOpenMPFinalClause(Expr *Condition, 12098 SourceLocation StartLoc, 12099 SourceLocation LParenLoc, 12100 SourceLocation EndLoc) { 12101 Expr *ValExpr = Condition; 12102 Stmt *HelperValStmt = nullptr; 12103 OpenMPDirectiveKind CaptureRegion = OMPD_unknown; 12104 if (!Condition->isValueDependent() && !Condition->isTypeDependent() && 12105 !Condition->isInstantiationDependent() && 12106 !Condition->containsUnexpandedParameterPack()) { 12107 ExprResult Val = CheckBooleanCondition(StartLoc, Condition); 12108 if (Val.isInvalid()) 12109 return nullptr; 12110 12111 ValExpr = MakeFullExpr(Val.get()).get(); 12112 12113 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 12114 CaptureRegion = 12115 getOpenMPCaptureRegionForClause(DKind, OMPC_final, LangOpts.OpenMP); 12116 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 12117 ValExpr = MakeFullExpr(ValExpr).get(); 12118 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 12119 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 12120 HelperValStmt = buildPreInits(Context, Captures); 12121 } 12122 } 12123 12124 return new (Context) OMPFinalClause(ValExpr, HelperValStmt, CaptureRegion, 12125 StartLoc, LParenLoc, EndLoc); 12126 } 12127 12128 ExprResult Sema::PerformOpenMPImplicitIntegerConversion(SourceLocation Loc, 12129 Expr *Op) { 12130 if (!Op) 12131 return ExprError(); 12132 12133 class IntConvertDiagnoser : public ICEConvertDiagnoser { 12134 public: 12135 IntConvertDiagnoser() 12136 : ICEConvertDiagnoser(/*AllowScopedEnumerations*/ false, false, true) {} 12137 SemaDiagnosticBuilder diagnoseNotInt(Sema &S, SourceLocation Loc, 12138 QualType T) override { 12139 return S.Diag(Loc, diag::err_omp_not_integral) << T; 12140 } 12141 SemaDiagnosticBuilder diagnoseIncomplete(Sema &S, SourceLocation Loc, 12142 QualType T) override { 12143 return S.Diag(Loc, diag::err_omp_incomplete_type) << T; 12144 } 12145 SemaDiagnosticBuilder diagnoseExplicitConv(Sema &S, SourceLocation Loc, 12146 QualType T, 12147 QualType ConvTy) override { 12148 return S.Diag(Loc, diag::err_omp_explicit_conversion) << T << ConvTy; 12149 } 12150 SemaDiagnosticBuilder noteExplicitConv(Sema &S, CXXConversionDecl *Conv, 12151 QualType ConvTy) override { 12152 return S.Diag(Conv->getLocation(), diag::note_omp_conversion_here) 12153 << ConvTy->isEnumeralType() << ConvTy; 12154 } 12155 SemaDiagnosticBuilder diagnoseAmbiguous(Sema &S, SourceLocation Loc, 12156 QualType T) override { 12157 return S.Diag(Loc, diag::err_omp_ambiguous_conversion) << T; 12158 } 12159 SemaDiagnosticBuilder noteAmbiguous(Sema &S, CXXConversionDecl *Conv, 12160 QualType ConvTy) override { 12161 return S.Diag(Conv->getLocation(), diag::note_omp_conversion_here) 12162 << ConvTy->isEnumeralType() << ConvTy; 12163 } 12164 SemaDiagnosticBuilder diagnoseConversion(Sema &, SourceLocation, QualType, 12165 QualType) override { 12166 llvm_unreachable("conversion functions are permitted"); 12167 } 12168 } ConvertDiagnoser; 12169 return PerformContextualImplicitConversion(Loc, Op, ConvertDiagnoser); 12170 } 12171 12172 static bool 12173 isNonNegativeIntegerValue(Expr *&ValExpr, Sema &SemaRef, OpenMPClauseKind CKind, 12174 bool StrictlyPositive, bool BuildCapture = false, 12175 OpenMPDirectiveKind DKind = OMPD_unknown, 12176 OpenMPDirectiveKind *CaptureRegion = nullptr, 12177 Stmt **HelperValStmt = nullptr) { 12178 if (!ValExpr->isTypeDependent() && !ValExpr->isValueDependent() && 12179 !ValExpr->isInstantiationDependent()) { 12180 SourceLocation Loc = ValExpr->getExprLoc(); 12181 ExprResult Value = 12182 SemaRef.PerformOpenMPImplicitIntegerConversion(Loc, ValExpr); 12183 if (Value.isInvalid()) 12184 return false; 12185 12186 ValExpr = Value.get(); 12187 // The expression must evaluate to a non-negative integer value. 12188 llvm::APSInt Result; 12189 if (ValExpr->isIntegerConstantExpr(Result, SemaRef.Context) && 12190 Result.isSigned() && 12191 !((!StrictlyPositive && Result.isNonNegative()) || 12192 (StrictlyPositive && Result.isStrictlyPositive()))) { 12193 SemaRef.Diag(Loc, diag::err_omp_negative_expression_in_clause) 12194 << getOpenMPClauseName(CKind) << (StrictlyPositive ? 1 : 0) 12195 << ValExpr->getSourceRange(); 12196 return false; 12197 } 12198 if (!BuildCapture) 12199 return true; 12200 *CaptureRegion = 12201 getOpenMPCaptureRegionForClause(DKind, CKind, SemaRef.LangOpts.OpenMP); 12202 if (*CaptureRegion != OMPD_unknown && 12203 !SemaRef.CurContext->isDependentContext()) { 12204 ValExpr = SemaRef.MakeFullExpr(ValExpr).get(); 12205 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 12206 ValExpr = tryBuildCapture(SemaRef, ValExpr, Captures).get(); 12207 *HelperValStmt = buildPreInits(SemaRef.Context, Captures); 12208 } 12209 } 12210 return true; 12211 } 12212 12213 OMPClause *Sema::ActOnOpenMPNumThreadsClause(Expr *NumThreads, 12214 SourceLocation StartLoc, 12215 SourceLocation LParenLoc, 12216 SourceLocation EndLoc) { 12217 Expr *ValExpr = NumThreads; 12218 Stmt *HelperValStmt = nullptr; 12219 12220 // OpenMP [2.5, Restrictions] 12221 // The num_threads expression must evaluate to a positive integer value. 12222 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_num_threads, 12223 /*StrictlyPositive=*/true)) 12224 return nullptr; 12225 12226 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 12227 OpenMPDirectiveKind CaptureRegion = 12228 getOpenMPCaptureRegionForClause(DKind, OMPC_num_threads, LangOpts.OpenMP); 12229 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 12230 ValExpr = MakeFullExpr(ValExpr).get(); 12231 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 12232 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 12233 HelperValStmt = buildPreInits(Context, Captures); 12234 } 12235 12236 return new (Context) OMPNumThreadsClause( 12237 ValExpr, HelperValStmt, CaptureRegion, StartLoc, LParenLoc, EndLoc); 12238 } 12239 12240 ExprResult Sema::VerifyPositiveIntegerConstantInClause(Expr *E, 12241 OpenMPClauseKind CKind, 12242 bool StrictlyPositive) { 12243 if (!E) 12244 return ExprError(); 12245 if (E->isValueDependent() || E->isTypeDependent() || 12246 E->isInstantiationDependent() || E->containsUnexpandedParameterPack()) 12247 return E; 12248 llvm::APSInt Result; 12249 ExprResult ICE = VerifyIntegerConstantExpression(E, &Result); 12250 if (ICE.isInvalid()) 12251 return ExprError(); 12252 if ((StrictlyPositive && !Result.isStrictlyPositive()) || 12253 (!StrictlyPositive && !Result.isNonNegative())) { 12254 Diag(E->getExprLoc(), diag::err_omp_negative_expression_in_clause) 12255 << getOpenMPClauseName(CKind) << (StrictlyPositive ? 1 : 0) 12256 << E->getSourceRange(); 12257 return ExprError(); 12258 } 12259 if (CKind == OMPC_aligned && !Result.isPowerOf2()) { 12260 Diag(E->getExprLoc(), diag::warn_omp_alignment_not_power_of_two) 12261 << E->getSourceRange(); 12262 return ExprError(); 12263 } 12264 if (CKind == OMPC_collapse && DSAStack->getAssociatedLoops() == 1) 12265 DSAStack->setAssociatedLoops(Result.getExtValue()); 12266 else if (CKind == OMPC_ordered) 12267 DSAStack->setAssociatedLoops(Result.getExtValue()); 12268 return ICE; 12269 } 12270 12271 OMPClause *Sema::ActOnOpenMPSafelenClause(Expr *Len, SourceLocation StartLoc, 12272 SourceLocation LParenLoc, 12273 SourceLocation EndLoc) { 12274 // OpenMP [2.8.1, simd construct, Description] 12275 // The parameter of the safelen clause must be a constant 12276 // positive integer expression. 12277 ExprResult Safelen = VerifyPositiveIntegerConstantInClause(Len, OMPC_safelen); 12278 if (Safelen.isInvalid()) 12279 return nullptr; 12280 return new (Context) 12281 OMPSafelenClause(Safelen.get(), StartLoc, LParenLoc, EndLoc); 12282 } 12283 12284 OMPClause *Sema::ActOnOpenMPSimdlenClause(Expr *Len, SourceLocation StartLoc, 12285 SourceLocation LParenLoc, 12286 SourceLocation EndLoc) { 12287 // OpenMP [2.8.1, simd construct, Description] 12288 // The parameter of the simdlen clause must be a constant 12289 // positive integer expression. 12290 ExprResult Simdlen = VerifyPositiveIntegerConstantInClause(Len, OMPC_simdlen); 12291 if (Simdlen.isInvalid()) 12292 return nullptr; 12293 return new (Context) 12294 OMPSimdlenClause(Simdlen.get(), StartLoc, LParenLoc, EndLoc); 12295 } 12296 12297 /// Tries to find omp_allocator_handle_t type. 12298 static bool findOMPAllocatorHandleT(Sema &S, SourceLocation Loc, 12299 DSAStackTy *Stack) { 12300 QualType OMPAllocatorHandleT = Stack->getOMPAllocatorHandleT(); 12301 if (!OMPAllocatorHandleT.isNull()) 12302 return true; 12303 // Build the predefined allocator expressions. 12304 bool ErrorFound = false; 12305 for (int I = OMPAllocateDeclAttr::OMPDefaultMemAlloc; 12306 I < OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; ++I) { 12307 auto AllocatorKind = static_cast<OMPAllocateDeclAttr::AllocatorTypeTy>(I); 12308 StringRef Allocator = 12309 OMPAllocateDeclAttr::ConvertAllocatorTypeTyToStr(AllocatorKind); 12310 DeclarationName AllocatorName = &S.getASTContext().Idents.get(Allocator); 12311 auto *VD = dyn_cast_or_null<ValueDecl>( 12312 S.LookupSingleName(S.TUScope, AllocatorName, Loc, Sema::LookupAnyName)); 12313 if (!VD) { 12314 ErrorFound = true; 12315 break; 12316 } 12317 QualType AllocatorType = 12318 VD->getType().getNonLValueExprType(S.getASTContext()); 12319 ExprResult Res = S.BuildDeclRefExpr(VD, AllocatorType, VK_LValue, Loc); 12320 if (!Res.isUsable()) { 12321 ErrorFound = true; 12322 break; 12323 } 12324 if (OMPAllocatorHandleT.isNull()) 12325 OMPAllocatorHandleT = AllocatorType; 12326 if (!S.getASTContext().hasSameType(OMPAllocatorHandleT, AllocatorType)) { 12327 ErrorFound = true; 12328 break; 12329 } 12330 Stack->setAllocator(AllocatorKind, Res.get()); 12331 } 12332 if (ErrorFound) { 12333 S.Diag(Loc, diag::err_omp_implied_type_not_found) 12334 << "omp_allocator_handle_t"; 12335 return false; 12336 } 12337 OMPAllocatorHandleT.addConst(); 12338 Stack->setOMPAllocatorHandleT(OMPAllocatorHandleT); 12339 return true; 12340 } 12341 12342 OMPClause *Sema::ActOnOpenMPAllocatorClause(Expr *A, SourceLocation StartLoc, 12343 SourceLocation LParenLoc, 12344 SourceLocation EndLoc) { 12345 // OpenMP [2.11.3, allocate Directive, Description] 12346 // allocator is an expression of omp_allocator_handle_t type. 12347 if (!findOMPAllocatorHandleT(*this, A->getExprLoc(), DSAStack)) 12348 return nullptr; 12349 12350 ExprResult Allocator = DefaultLvalueConversion(A); 12351 if (Allocator.isInvalid()) 12352 return nullptr; 12353 Allocator = PerformImplicitConversion(Allocator.get(), 12354 DSAStack->getOMPAllocatorHandleT(), 12355 Sema::AA_Initializing, 12356 /*AllowExplicit=*/true); 12357 if (Allocator.isInvalid()) 12358 return nullptr; 12359 return new (Context) 12360 OMPAllocatorClause(Allocator.get(), StartLoc, LParenLoc, EndLoc); 12361 } 12362 12363 OMPClause *Sema::ActOnOpenMPCollapseClause(Expr *NumForLoops, 12364 SourceLocation StartLoc, 12365 SourceLocation LParenLoc, 12366 SourceLocation EndLoc) { 12367 // OpenMP [2.7.1, loop construct, Description] 12368 // OpenMP [2.8.1, simd construct, Description] 12369 // OpenMP [2.9.6, distribute construct, Description] 12370 // The parameter of the collapse clause must be a constant 12371 // positive integer expression. 12372 ExprResult NumForLoopsResult = 12373 VerifyPositiveIntegerConstantInClause(NumForLoops, OMPC_collapse); 12374 if (NumForLoopsResult.isInvalid()) 12375 return nullptr; 12376 return new (Context) 12377 OMPCollapseClause(NumForLoopsResult.get(), StartLoc, LParenLoc, EndLoc); 12378 } 12379 12380 OMPClause *Sema::ActOnOpenMPOrderedClause(SourceLocation StartLoc, 12381 SourceLocation EndLoc, 12382 SourceLocation LParenLoc, 12383 Expr *NumForLoops) { 12384 // OpenMP [2.7.1, loop construct, Description] 12385 // OpenMP [2.8.1, simd construct, Description] 12386 // OpenMP [2.9.6, distribute construct, Description] 12387 // The parameter of the ordered clause must be a constant 12388 // positive integer expression if any. 12389 if (NumForLoops && LParenLoc.isValid()) { 12390 ExprResult NumForLoopsResult = 12391 VerifyPositiveIntegerConstantInClause(NumForLoops, OMPC_ordered); 12392 if (NumForLoopsResult.isInvalid()) 12393 return nullptr; 12394 NumForLoops = NumForLoopsResult.get(); 12395 } else { 12396 NumForLoops = nullptr; 12397 } 12398 auto *Clause = OMPOrderedClause::Create( 12399 Context, NumForLoops, NumForLoops ? DSAStack->getAssociatedLoops() : 0, 12400 StartLoc, LParenLoc, EndLoc); 12401 DSAStack->setOrderedRegion(/*IsOrdered=*/true, NumForLoops, Clause); 12402 return Clause; 12403 } 12404 12405 OMPClause *Sema::ActOnOpenMPSimpleClause( 12406 OpenMPClauseKind Kind, unsigned Argument, SourceLocation ArgumentLoc, 12407 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) { 12408 OMPClause *Res = nullptr; 12409 switch (Kind) { 12410 case OMPC_default: 12411 Res = ActOnOpenMPDefaultClause(static_cast<DefaultKind>(Argument), 12412 ArgumentLoc, StartLoc, LParenLoc, EndLoc); 12413 break; 12414 case OMPC_proc_bind: 12415 Res = ActOnOpenMPProcBindClause(static_cast<ProcBindKind>(Argument), 12416 ArgumentLoc, StartLoc, LParenLoc, EndLoc); 12417 break; 12418 case OMPC_atomic_default_mem_order: 12419 Res = ActOnOpenMPAtomicDefaultMemOrderClause( 12420 static_cast<OpenMPAtomicDefaultMemOrderClauseKind>(Argument), 12421 ArgumentLoc, StartLoc, LParenLoc, EndLoc); 12422 break; 12423 case OMPC_order: 12424 Res = ActOnOpenMPOrderClause(static_cast<OpenMPOrderClauseKind>(Argument), 12425 ArgumentLoc, StartLoc, LParenLoc, EndLoc); 12426 break; 12427 case OMPC_update: 12428 Res = ActOnOpenMPUpdateClause(static_cast<OpenMPDependClauseKind>(Argument), 12429 ArgumentLoc, StartLoc, LParenLoc, EndLoc); 12430 break; 12431 case OMPC_if: 12432 case OMPC_final: 12433 case OMPC_num_threads: 12434 case OMPC_safelen: 12435 case OMPC_simdlen: 12436 case OMPC_allocator: 12437 case OMPC_collapse: 12438 case OMPC_schedule: 12439 case OMPC_private: 12440 case OMPC_firstprivate: 12441 case OMPC_lastprivate: 12442 case OMPC_shared: 12443 case OMPC_reduction: 12444 case OMPC_task_reduction: 12445 case OMPC_in_reduction: 12446 case OMPC_linear: 12447 case OMPC_aligned: 12448 case OMPC_copyin: 12449 case OMPC_copyprivate: 12450 case OMPC_ordered: 12451 case OMPC_nowait: 12452 case OMPC_untied: 12453 case OMPC_mergeable: 12454 case OMPC_threadprivate: 12455 case OMPC_allocate: 12456 case OMPC_flush: 12457 case OMPC_depobj: 12458 case OMPC_read: 12459 case OMPC_write: 12460 case OMPC_capture: 12461 case OMPC_seq_cst: 12462 case OMPC_acq_rel: 12463 case OMPC_acquire: 12464 case OMPC_release: 12465 case OMPC_relaxed: 12466 case OMPC_depend: 12467 case OMPC_device: 12468 case OMPC_threads: 12469 case OMPC_simd: 12470 case OMPC_map: 12471 case OMPC_num_teams: 12472 case OMPC_thread_limit: 12473 case OMPC_priority: 12474 case OMPC_grainsize: 12475 case OMPC_nogroup: 12476 case OMPC_num_tasks: 12477 case OMPC_hint: 12478 case OMPC_dist_schedule: 12479 case OMPC_defaultmap: 12480 case OMPC_unknown: 12481 case OMPC_uniform: 12482 case OMPC_to: 12483 case OMPC_from: 12484 case OMPC_use_device_ptr: 12485 case OMPC_is_device_ptr: 12486 case OMPC_unified_address: 12487 case OMPC_unified_shared_memory: 12488 case OMPC_reverse_offload: 12489 case OMPC_dynamic_allocators: 12490 case OMPC_device_type: 12491 case OMPC_match: 12492 case OMPC_nontemporal: 12493 case OMPC_destroy: 12494 case OMPC_detach: 12495 case OMPC_inclusive: 12496 case OMPC_exclusive: 12497 llvm_unreachable("Clause is not allowed."); 12498 } 12499 return Res; 12500 } 12501 12502 static std::string 12503 getListOfPossibleValues(OpenMPClauseKind K, unsigned First, unsigned Last, 12504 ArrayRef<unsigned> Exclude = llvm::None) { 12505 SmallString<256> Buffer; 12506 llvm::raw_svector_ostream Out(Buffer); 12507 unsigned Skipped = Exclude.size(); 12508 auto S = Exclude.begin(), E = Exclude.end(); 12509 for (unsigned I = First; I < Last; ++I) { 12510 if (std::find(S, E, I) != E) { 12511 --Skipped; 12512 continue; 12513 } 12514 Out << "'" << getOpenMPSimpleClauseTypeName(K, I) << "'"; 12515 if (I + Skipped + 2 == Last) 12516 Out << " or "; 12517 else if (I + Skipped + 1 != Last) 12518 Out << ", "; 12519 } 12520 return std::string(Out.str()); 12521 } 12522 12523 OMPClause *Sema::ActOnOpenMPDefaultClause(DefaultKind Kind, 12524 SourceLocation KindKwLoc, 12525 SourceLocation StartLoc, 12526 SourceLocation LParenLoc, 12527 SourceLocation EndLoc) { 12528 if (Kind == OMP_DEFAULT_unknown) { 12529 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value) 12530 << getListOfPossibleValues(OMPC_default, /*First=*/0, 12531 /*Last=*/unsigned(OMP_DEFAULT_unknown)) 12532 << getOpenMPClauseName(OMPC_default); 12533 return nullptr; 12534 } 12535 if (Kind == OMP_DEFAULT_none) 12536 DSAStack->setDefaultDSANone(KindKwLoc); 12537 else if (Kind == OMP_DEFAULT_shared) 12538 DSAStack->setDefaultDSAShared(KindKwLoc); 12539 12540 return new (Context) 12541 OMPDefaultClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc); 12542 } 12543 12544 OMPClause *Sema::ActOnOpenMPProcBindClause(ProcBindKind Kind, 12545 SourceLocation KindKwLoc, 12546 SourceLocation StartLoc, 12547 SourceLocation LParenLoc, 12548 SourceLocation EndLoc) { 12549 if (Kind == OMP_PROC_BIND_unknown) { 12550 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value) 12551 << getListOfPossibleValues(OMPC_proc_bind, 12552 /*First=*/unsigned(OMP_PROC_BIND_master), 12553 /*Last=*/5) 12554 << getOpenMPClauseName(OMPC_proc_bind); 12555 return nullptr; 12556 } 12557 return new (Context) 12558 OMPProcBindClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc); 12559 } 12560 12561 OMPClause *Sema::ActOnOpenMPAtomicDefaultMemOrderClause( 12562 OpenMPAtomicDefaultMemOrderClauseKind Kind, SourceLocation KindKwLoc, 12563 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) { 12564 if (Kind == OMPC_ATOMIC_DEFAULT_MEM_ORDER_unknown) { 12565 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value) 12566 << getListOfPossibleValues( 12567 OMPC_atomic_default_mem_order, /*First=*/0, 12568 /*Last=*/OMPC_ATOMIC_DEFAULT_MEM_ORDER_unknown) 12569 << getOpenMPClauseName(OMPC_atomic_default_mem_order); 12570 return nullptr; 12571 } 12572 return new (Context) OMPAtomicDefaultMemOrderClause(Kind, KindKwLoc, StartLoc, 12573 LParenLoc, EndLoc); 12574 } 12575 12576 OMPClause *Sema::ActOnOpenMPOrderClause(OpenMPOrderClauseKind Kind, 12577 SourceLocation KindKwLoc, 12578 SourceLocation StartLoc, 12579 SourceLocation LParenLoc, 12580 SourceLocation EndLoc) { 12581 if (Kind == OMPC_ORDER_unknown) { 12582 static_assert(OMPC_ORDER_unknown > 0, 12583 "OMPC_ORDER_unknown not greater than 0"); 12584 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value) 12585 << getListOfPossibleValues(OMPC_order, /*First=*/0, 12586 /*Last=*/OMPC_ORDER_unknown) 12587 << getOpenMPClauseName(OMPC_order); 12588 return nullptr; 12589 } 12590 return new (Context) 12591 OMPOrderClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc); 12592 } 12593 12594 OMPClause *Sema::ActOnOpenMPUpdateClause(OpenMPDependClauseKind Kind, 12595 SourceLocation KindKwLoc, 12596 SourceLocation StartLoc, 12597 SourceLocation LParenLoc, 12598 SourceLocation EndLoc) { 12599 if (Kind == OMPC_DEPEND_unknown || Kind == OMPC_DEPEND_source || 12600 Kind == OMPC_DEPEND_sink || Kind == OMPC_DEPEND_depobj) { 12601 unsigned Except[] = {OMPC_DEPEND_source, OMPC_DEPEND_sink, 12602 OMPC_DEPEND_depobj}; 12603 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value) 12604 << getListOfPossibleValues(OMPC_depend, /*First=*/0, 12605 /*Last=*/OMPC_DEPEND_unknown, Except) 12606 << getOpenMPClauseName(OMPC_update); 12607 return nullptr; 12608 } 12609 return OMPUpdateClause::Create(Context, StartLoc, LParenLoc, KindKwLoc, Kind, 12610 EndLoc); 12611 } 12612 12613 OMPClause *Sema::ActOnOpenMPSingleExprWithArgClause( 12614 OpenMPClauseKind Kind, ArrayRef<unsigned> Argument, Expr *Expr, 12615 SourceLocation StartLoc, SourceLocation LParenLoc, 12616 ArrayRef<SourceLocation> ArgumentLoc, SourceLocation DelimLoc, 12617 SourceLocation EndLoc) { 12618 OMPClause *Res = nullptr; 12619 switch (Kind) { 12620 case OMPC_schedule: 12621 enum { Modifier1, Modifier2, ScheduleKind, NumberOfElements }; 12622 assert(Argument.size() == NumberOfElements && 12623 ArgumentLoc.size() == NumberOfElements); 12624 Res = ActOnOpenMPScheduleClause( 12625 static_cast<OpenMPScheduleClauseModifier>(Argument[Modifier1]), 12626 static_cast<OpenMPScheduleClauseModifier>(Argument[Modifier2]), 12627 static_cast<OpenMPScheduleClauseKind>(Argument[ScheduleKind]), Expr, 12628 StartLoc, LParenLoc, ArgumentLoc[Modifier1], ArgumentLoc[Modifier2], 12629 ArgumentLoc[ScheduleKind], DelimLoc, EndLoc); 12630 break; 12631 case OMPC_if: 12632 assert(Argument.size() == 1 && ArgumentLoc.size() == 1); 12633 Res = ActOnOpenMPIfClause(static_cast<OpenMPDirectiveKind>(Argument.back()), 12634 Expr, StartLoc, LParenLoc, ArgumentLoc.back(), 12635 DelimLoc, EndLoc); 12636 break; 12637 case OMPC_dist_schedule: 12638 Res = ActOnOpenMPDistScheduleClause( 12639 static_cast<OpenMPDistScheduleClauseKind>(Argument.back()), Expr, 12640 StartLoc, LParenLoc, ArgumentLoc.back(), DelimLoc, EndLoc); 12641 break; 12642 case OMPC_defaultmap: 12643 enum { Modifier, DefaultmapKind }; 12644 Res = ActOnOpenMPDefaultmapClause( 12645 static_cast<OpenMPDefaultmapClauseModifier>(Argument[Modifier]), 12646 static_cast<OpenMPDefaultmapClauseKind>(Argument[DefaultmapKind]), 12647 StartLoc, LParenLoc, ArgumentLoc[Modifier], ArgumentLoc[DefaultmapKind], 12648 EndLoc); 12649 break; 12650 case OMPC_device: 12651 assert(Argument.size() == 1 && ArgumentLoc.size() == 1); 12652 Res = ActOnOpenMPDeviceClause( 12653 static_cast<OpenMPDeviceClauseModifier>(Argument.back()), Expr, 12654 StartLoc, LParenLoc, ArgumentLoc.back(), EndLoc); 12655 break; 12656 case OMPC_final: 12657 case OMPC_num_threads: 12658 case OMPC_safelen: 12659 case OMPC_simdlen: 12660 case OMPC_allocator: 12661 case OMPC_collapse: 12662 case OMPC_default: 12663 case OMPC_proc_bind: 12664 case OMPC_private: 12665 case OMPC_firstprivate: 12666 case OMPC_lastprivate: 12667 case OMPC_shared: 12668 case OMPC_reduction: 12669 case OMPC_task_reduction: 12670 case OMPC_in_reduction: 12671 case OMPC_linear: 12672 case OMPC_aligned: 12673 case OMPC_copyin: 12674 case OMPC_copyprivate: 12675 case OMPC_ordered: 12676 case OMPC_nowait: 12677 case OMPC_untied: 12678 case OMPC_mergeable: 12679 case OMPC_threadprivate: 12680 case OMPC_allocate: 12681 case OMPC_flush: 12682 case OMPC_depobj: 12683 case OMPC_read: 12684 case OMPC_write: 12685 case OMPC_update: 12686 case OMPC_capture: 12687 case OMPC_seq_cst: 12688 case OMPC_acq_rel: 12689 case OMPC_acquire: 12690 case OMPC_release: 12691 case OMPC_relaxed: 12692 case OMPC_depend: 12693 case OMPC_threads: 12694 case OMPC_simd: 12695 case OMPC_map: 12696 case OMPC_num_teams: 12697 case OMPC_thread_limit: 12698 case OMPC_priority: 12699 case OMPC_grainsize: 12700 case OMPC_nogroup: 12701 case OMPC_num_tasks: 12702 case OMPC_hint: 12703 case OMPC_unknown: 12704 case OMPC_uniform: 12705 case OMPC_to: 12706 case OMPC_from: 12707 case OMPC_use_device_ptr: 12708 case OMPC_is_device_ptr: 12709 case OMPC_unified_address: 12710 case OMPC_unified_shared_memory: 12711 case OMPC_reverse_offload: 12712 case OMPC_dynamic_allocators: 12713 case OMPC_atomic_default_mem_order: 12714 case OMPC_device_type: 12715 case OMPC_match: 12716 case OMPC_nontemporal: 12717 case OMPC_order: 12718 case OMPC_destroy: 12719 case OMPC_detach: 12720 case OMPC_inclusive: 12721 case OMPC_exclusive: 12722 llvm_unreachable("Clause is not allowed."); 12723 } 12724 return Res; 12725 } 12726 12727 static bool checkScheduleModifiers(Sema &S, OpenMPScheduleClauseModifier M1, 12728 OpenMPScheduleClauseModifier M2, 12729 SourceLocation M1Loc, SourceLocation M2Loc) { 12730 if (M1 == OMPC_SCHEDULE_MODIFIER_unknown && M1Loc.isValid()) { 12731 SmallVector<unsigned, 2> Excluded; 12732 if (M2 != OMPC_SCHEDULE_MODIFIER_unknown) 12733 Excluded.push_back(M2); 12734 if (M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) 12735 Excluded.push_back(OMPC_SCHEDULE_MODIFIER_monotonic); 12736 if (M2 == OMPC_SCHEDULE_MODIFIER_monotonic) 12737 Excluded.push_back(OMPC_SCHEDULE_MODIFIER_nonmonotonic); 12738 S.Diag(M1Loc, diag::err_omp_unexpected_clause_value) 12739 << getListOfPossibleValues(OMPC_schedule, 12740 /*First=*/OMPC_SCHEDULE_MODIFIER_unknown + 1, 12741 /*Last=*/OMPC_SCHEDULE_MODIFIER_last, 12742 Excluded) 12743 << getOpenMPClauseName(OMPC_schedule); 12744 return true; 12745 } 12746 return false; 12747 } 12748 12749 OMPClause *Sema::ActOnOpenMPScheduleClause( 12750 OpenMPScheduleClauseModifier M1, OpenMPScheduleClauseModifier M2, 12751 OpenMPScheduleClauseKind Kind, Expr *ChunkSize, SourceLocation StartLoc, 12752 SourceLocation LParenLoc, SourceLocation M1Loc, SourceLocation M2Loc, 12753 SourceLocation KindLoc, SourceLocation CommaLoc, SourceLocation EndLoc) { 12754 if (checkScheduleModifiers(*this, M1, M2, M1Loc, M2Loc) || 12755 checkScheduleModifiers(*this, M2, M1, M2Loc, M1Loc)) 12756 return nullptr; 12757 // OpenMP, 2.7.1, Loop Construct, Restrictions 12758 // Either the monotonic modifier or the nonmonotonic modifier can be specified 12759 // but not both. 12760 if ((M1 == M2 && M1 != OMPC_SCHEDULE_MODIFIER_unknown) || 12761 (M1 == OMPC_SCHEDULE_MODIFIER_monotonic && 12762 M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) || 12763 (M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic && 12764 M2 == OMPC_SCHEDULE_MODIFIER_monotonic)) { 12765 Diag(M2Loc, diag::err_omp_unexpected_schedule_modifier) 12766 << getOpenMPSimpleClauseTypeName(OMPC_schedule, M2) 12767 << getOpenMPSimpleClauseTypeName(OMPC_schedule, M1); 12768 return nullptr; 12769 } 12770 if (Kind == OMPC_SCHEDULE_unknown) { 12771 std::string Values; 12772 if (M1Loc.isInvalid() && M2Loc.isInvalid()) { 12773 unsigned Exclude[] = {OMPC_SCHEDULE_unknown}; 12774 Values = getListOfPossibleValues(OMPC_schedule, /*First=*/0, 12775 /*Last=*/OMPC_SCHEDULE_MODIFIER_last, 12776 Exclude); 12777 } else { 12778 Values = getListOfPossibleValues(OMPC_schedule, /*First=*/0, 12779 /*Last=*/OMPC_SCHEDULE_unknown); 12780 } 12781 Diag(KindLoc, diag::err_omp_unexpected_clause_value) 12782 << Values << getOpenMPClauseName(OMPC_schedule); 12783 return nullptr; 12784 } 12785 // OpenMP, 2.7.1, Loop Construct, Restrictions 12786 // The nonmonotonic modifier can only be specified with schedule(dynamic) or 12787 // schedule(guided). 12788 if ((M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic || 12789 M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) && 12790 Kind != OMPC_SCHEDULE_dynamic && Kind != OMPC_SCHEDULE_guided) { 12791 Diag(M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic ? M1Loc : M2Loc, 12792 diag::err_omp_schedule_nonmonotonic_static); 12793 return nullptr; 12794 } 12795 Expr *ValExpr = ChunkSize; 12796 Stmt *HelperValStmt = nullptr; 12797 if (ChunkSize) { 12798 if (!ChunkSize->isValueDependent() && !ChunkSize->isTypeDependent() && 12799 !ChunkSize->isInstantiationDependent() && 12800 !ChunkSize->containsUnexpandedParameterPack()) { 12801 SourceLocation ChunkSizeLoc = ChunkSize->getBeginLoc(); 12802 ExprResult Val = 12803 PerformOpenMPImplicitIntegerConversion(ChunkSizeLoc, ChunkSize); 12804 if (Val.isInvalid()) 12805 return nullptr; 12806 12807 ValExpr = Val.get(); 12808 12809 // OpenMP [2.7.1, Restrictions] 12810 // chunk_size must be a loop invariant integer expression with a positive 12811 // value. 12812 llvm::APSInt Result; 12813 if (ValExpr->isIntegerConstantExpr(Result, Context)) { 12814 if (Result.isSigned() && !Result.isStrictlyPositive()) { 12815 Diag(ChunkSizeLoc, diag::err_omp_negative_expression_in_clause) 12816 << "schedule" << 1 << ChunkSize->getSourceRange(); 12817 return nullptr; 12818 } 12819 } else if (getOpenMPCaptureRegionForClause( 12820 DSAStack->getCurrentDirective(), OMPC_schedule, 12821 LangOpts.OpenMP) != OMPD_unknown && 12822 !CurContext->isDependentContext()) { 12823 ValExpr = MakeFullExpr(ValExpr).get(); 12824 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 12825 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 12826 HelperValStmt = buildPreInits(Context, Captures); 12827 } 12828 } 12829 } 12830 12831 return new (Context) 12832 OMPScheduleClause(StartLoc, LParenLoc, KindLoc, CommaLoc, EndLoc, Kind, 12833 ValExpr, HelperValStmt, M1, M1Loc, M2, M2Loc); 12834 } 12835 12836 OMPClause *Sema::ActOnOpenMPClause(OpenMPClauseKind Kind, 12837 SourceLocation StartLoc, 12838 SourceLocation EndLoc) { 12839 OMPClause *Res = nullptr; 12840 switch (Kind) { 12841 case OMPC_ordered: 12842 Res = ActOnOpenMPOrderedClause(StartLoc, EndLoc); 12843 break; 12844 case OMPC_nowait: 12845 Res = ActOnOpenMPNowaitClause(StartLoc, EndLoc); 12846 break; 12847 case OMPC_untied: 12848 Res = ActOnOpenMPUntiedClause(StartLoc, EndLoc); 12849 break; 12850 case OMPC_mergeable: 12851 Res = ActOnOpenMPMergeableClause(StartLoc, EndLoc); 12852 break; 12853 case OMPC_read: 12854 Res = ActOnOpenMPReadClause(StartLoc, EndLoc); 12855 break; 12856 case OMPC_write: 12857 Res = ActOnOpenMPWriteClause(StartLoc, EndLoc); 12858 break; 12859 case OMPC_update: 12860 Res = ActOnOpenMPUpdateClause(StartLoc, EndLoc); 12861 break; 12862 case OMPC_capture: 12863 Res = ActOnOpenMPCaptureClause(StartLoc, EndLoc); 12864 break; 12865 case OMPC_seq_cst: 12866 Res = ActOnOpenMPSeqCstClause(StartLoc, EndLoc); 12867 break; 12868 case OMPC_acq_rel: 12869 Res = ActOnOpenMPAcqRelClause(StartLoc, EndLoc); 12870 break; 12871 case OMPC_acquire: 12872 Res = ActOnOpenMPAcquireClause(StartLoc, EndLoc); 12873 break; 12874 case OMPC_release: 12875 Res = ActOnOpenMPReleaseClause(StartLoc, EndLoc); 12876 break; 12877 case OMPC_relaxed: 12878 Res = ActOnOpenMPRelaxedClause(StartLoc, EndLoc); 12879 break; 12880 case OMPC_threads: 12881 Res = ActOnOpenMPThreadsClause(StartLoc, EndLoc); 12882 break; 12883 case OMPC_simd: 12884 Res = ActOnOpenMPSIMDClause(StartLoc, EndLoc); 12885 break; 12886 case OMPC_nogroup: 12887 Res = ActOnOpenMPNogroupClause(StartLoc, EndLoc); 12888 break; 12889 case OMPC_unified_address: 12890 Res = ActOnOpenMPUnifiedAddressClause(StartLoc, EndLoc); 12891 break; 12892 case OMPC_unified_shared_memory: 12893 Res = ActOnOpenMPUnifiedSharedMemoryClause(StartLoc, EndLoc); 12894 break; 12895 case OMPC_reverse_offload: 12896 Res = ActOnOpenMPReverseOffloadClause(StartLoc, EndLoc); 12897 break; 12898 case OMPC_dynamic_allocators: 12899 Res = ActOnOpenMPDynamicAllocatorsClause(StartLoc, EndLoc); 12900 break; 12901 case OMPC_destroy: 12902 Res = ActOnOpenMPDestroyClause(StartLoc, EndLoc); 12903 break; 12904 case OMPC_if: 12905 case OMPC_final: 12906 case OMPC_num_threads: 12907 case OMPC_safelen: 12908 case OMPC_simdlen: 12909 case OMPC_allocator: 12910 case OMPC_collapse: 12911 case OMPC_schedule: 12912 case OMPC_private: 12913 case OMPC_firstprivate: 12914 case OMPC_lastprivate: 12915 case OMPC_shared: 12916 case OMPC_reduction: 12917 case OMPC_task_reduction: 12918 case OMPC_in_reduction: 12919 case OMPC_linear: 12920 case OMPC_aligned: 12921 case OMPC_copyin: 12922 case OMPC_copyprivate: 12923 case OMPC_default: 12924 case OMPC_proc_bind: 12925 case OMPC_threadprivate: 12926 case OMPC_allocate: 12927 case OMPC_flush: 12928 case OMPC_depobj: 12929 case OMPC_depend: 12930 case OMPC_device: 12931 case OMPC_map: 12932 case OMPC_num_teams: 12933 case OMPC_thread_limit: 12934 case OMPC_priority: 12935 case OMPC_grainsize: 12936 case OMPC_num_tasks: 12937 case OMPC_hint: 12938 case OMPC_dist_schedule: 12939 case OMPC_defaultmap: 12940 case OMPC_unknown: 12941 case OMPC_uniform: 12942 case OMPC_to: 12943 case OMPC_from: 12944 case OMPC_use_device_ptr: 12945 case OMPC_is_device_ptr: 12946 case OMPC_atomic_default_mem_order: 12947 case OMPC_device_type: 12948 case OMPC_match: 12949 case OMPC_nontemporal: 12950 case OMPC_order: 12951 case OMPC_detach: 12952 case OMPC_inclusive: 12953 case OMPC_exclusive: 12954 llvm_unreachable("Clause is not allowed."); 12955 } 12956 return Res; 12957 } 12958 12959 OMPClause *Sema::ActOnOpenMPNowaitClause(SourceLocation StartLoc, 12960 SourceLocation EndLoc) { 12961 DSAStack->setNowaitRegion(); 12962 return new (Context) OMPNowaitClause(StartLoc, EndLoc); 12963 } 12964 12965 OMPClause *Sema::ActOnOpenMPUntiedClause(SourceLocation StartLoc, 12966 SourceLocation EndLoc) { 12967 return new (Context) OMPUntiedClause(StartLoc, EndLoc); 12968 } 12969 12970 OMPClause *Sema::ActOnOpenMPMergeableClause(SourceLocation StartLoc, 12971 SourceLocation EndLoc) { 12972 return new (Context) OMPMergeableClause(StartLoc, EndLoc); 12973 } 12974 12975 OMPClause *Sema::ActOnOpenMPReadClause(SourceLocation StartLoc, 12976 SourceLocation EndLoc) { 12977 return new (Context) OMPReadClause(StartLoc, EndLoc); 12978 } 12979 12980 OMPClause *Sema::ActOnOpenMPWriteClause(SourceLocation StartLoc, 12981 SourceLocation EndLoc) { 12982 return new (Context) OMPWriteClause(StartLoc, EndLoc); 12983 } 12984 12985 OMPClause *Sema::ActOnOpenMPUpdateClause(SourceLocation StartLoc, 12986 SourceLocation EndLoc) { 12987 return OMPUpdateClause::Create(Context, StartLoc, EndLoc); 12988 } 12989 12990 OMPClause *Sema::ActOnOpenMPCaptureClause(SourceLocation StartLoc, 12991 SourceLocation EndLoc) { 12992 return new (Context) OMPCaptureClause(StartLoc, EndLoc); 12993 } 12994 12995 OMPClause *Sema::ActOnOpenMPSeqCstClause(SourceLocation StartLoc, 12996 SourceLocation EndLoc) { 12997 return new (Context) OMPSeqCstClause(StartLoc, EndLoc); 12998 } 12999 13000 OMPClause *Sema::ActOnOpenMPAcqRelClause(SourceLocation StartLoc, 13001 SourceLocation EndLoc) { 13002 return new (Context) OMPAcqRelClause(StartLoc, EndLoc); 13003 } 13004 13005 OMPClause *Sema::ActOnOpenMPAcquireClause(SourceLocation StartLoc, 13006 SourceLocation EndLoc) { 13007 return new (Context) OMPAcquireClause(StartLoc, EndLoc); 13008 } 13009 13010 OMPClause *Sema::ActOnOpenMPReleaseClause(SourceLocation StartLoc, 13011 SourceLocation EndLoc) { 13012 return new (Context) OMPReleaseClause(StartLoc, EndLoc); 13013 } 13014 13015 OMPClause *Sema::ActOnOpenMPRelaxedClause(SourceLocation StartLoc, 13016 SourceLocation EndLoc) { 13017 return new (Context) OMPRelaxedClause(StartLoc, EndLoc); 13018 } 13019 13020 OMPClause *Sema::ActOnOpenMPThreadsClause(SourceLocation StartLoc, 13021 SourceLocation EndLoc) { 13022 return new (Context) OMPThreadsClause(StartLoc, EndLoc); 13023 } 13024 13025 OMPClause *Sema::ActOnOpenMPSIMDClause(SourceLocation StartLoc, 13026 SourceLocation EndLoc) { 13027 return new (Context) OMPSIMDClause(StartLoc, EndLoc); 13028 } 13029 13030 OMPClause *Sema::ActOnOpenMPNogroupClause(SourceLocation StartLoc, 13031 SourceLocation EndLoc) { 13032 return new (Context) OMPNogroupClause(StartLoc, EndLoc); 13033 } 13034 13035 OMPClause *Sema::ActOnOpenMPUnifiedAddressClause(SourceLocation StartLoc, 13036 SourceLocation EndLoc) { 13037 return new (Context) OMPUnifiedAddressClause(StartLoc, EndLoc); 13038 } 13039 13040 OMPClause *Sema::ActOnOpenMPUnifiedSharedMemoryClause(SourceLocation StartLoc, 13041 SourceLocation EndLoc) { 13042 return new (Context) OMPUnifiedSharedMemoryClause(StartLoc, EndLoc); 13043 } 13044 13045 OMPClause *Sema::ActOnOpenMPReverseOffloadClause(SourceLocation StartLoc, 13046 SourceLocation EndLoc) { 13047 return new (Context) OMPReverseOffloadClause(StartLoc, EndLoc); 13048 } 13049 13050 OMPClause *Sema::ActOnOpenMPDynamicAllocatorsClause(SourceLocation StartLoc, 13051 SourceLocation EndLoc) { 13052 return new (Context) OMPDynamicAllocatorsClause(StartLoc, EndLoc); 13053 } 13054 13055 OMPClause *Sema::ActOnOpenMPDestroyClause(SourceLocation StartLoc, 13056 SourceLocation EndLoc) { 13057 return new (Context) OMPDestroyClause(StartLoc, EndLoc); 13058 } 13059 13060 OMPClause *Sema::ActOnOpenMPVarListClause( 13061 OpenMPClauseKind Kind, ArrayRef<Expr *> VarList, Expr *DepModOrTailExpr, 13062 const OMPVarListLocTy &Locs, SourceLocation ColonLoc, 13063 CXXScopeSpec &ReductionOrMapperIdScopeSpec, 13064 DeclarationNameInfo &ReductionOrMapperId, int ExtraModifier, 13065 ArrayRef<OpenMPMapModifierKind> MapTypeModifiers, 13066 ArrayRef<SourceLocation> MapTypeModifiersLoc, bool IsMapTypeImplicit, 13067 SourceLocation ExtraModifierLoc) { 13068 SourceLocation StartLoc = Locs.StartLoc; 13069 SourceLocation LParenLoc = Locs.LParenLoc; 13070 SourceLocation EndLoc = Locs.EndLoc; 13071 OMPClause *Res = nullptr; 13072 switch (Kind) { 13073 case OMPC_private: 13074 Res = ActOnOpenMPPrivateClause(VarList, StartLoc, LParenLoc, EndLoc); 13075 break; 13076 case OMPC_firstprivate: 13077 Res = ActOnOpenMPFirstprivateClause(VarList, StartLoc, LParenLoc, EndLoc); 13078 break; 13079 case OMPC_lastprivate: 13080 assert(0 <= ExtraModifier && ExtraModifier <= OMPC_LASTPRIVATE_unknown && 13081 "Unexpected lastprivate modifier."); 13082 Res = ActOnOpenMPLastprivateClause( 13083 VarList, static_cast<OpenMPLastprivateModifier>(ExtraModifier), 13084 ExtraModifierLoc, ColonLoc, StartLoc, LParenLoc, EndLoc); 13085 break; 13086 case OMPC_shared: 13087 Res = ActOnOpenMPSharedClause(VarList, StartLoc, LParenLoc, EndLoc); 13088 break; 13089 case OMPC_reduction: 13090 assert(0 <= ExtraModifier && ExtraModifier <= OMPC_REDUCTION_unknown && 13091 "Unexpected lastprivate modifier."); 13092 Res = ActOnOpenMPReductionClause( 13093 VarList, static_cast<OpenMPReductionClauseModifier>(ExtraModifier), 13094 StartLoc, LParenLoc, ExtraModifierLoc, ColonLoc, EndLoc, 13095 ReductionOrMapperIdScopeSpec, ReductionOrMapperId); 13096 break; 13097 case OMPC_task_reduction: 13098 Res = ActOnOpenMPTaskReductionClause(VarList, StartLoc, LParenLoc, ColonLoc, 13099 EndLoc, ReductionOrMapperIdScopeSpec, 13100 ReductionOrMapperId); 13101 break; 13102 case OMPC_in_reduction: 13103 Res = ActOnOpenMPInReductionClause(VarList, StartLoc, LParenLoc, ColonLoc, 13104 EndLoc, ReductionOrMapperIdScopeSpec, 13105 ReductionOrMapperId); 13106 break; 13107 case OMPC_linear: 13108 assert(0 <= ExtraModifier && ExtraModifier <= OMPC_LINEAR_unknown && 13109 "Unexpected linear modifier."); 13110 Res = ActOnOpenMPLinearClause( 13111 VarList, DepModOrTailExpr, StartLoc, LParenLoc, 13112 static_cast<OpenMPLinearClauseKind>(ExtraModifier), ExtraModifierLoc, 13113 ColonLoc, EndLoc); 13114 break; 13115 case OMPC_aligned: 13116 Res = ActOnOpenMPAlignedClause(VarList, DepModOrTailExpr, StartLoc, 13117 LParenLoc, ColonLoc, EndLoc); 13118 break; 13119 case OMPC_copyin: 13120 Res = ActOnOpenMPCopyinClause(VarList, StartLoc, LParenLoc, EndLoc); 13121 break; 13122 case OMPC_copyprivate: 13123 Res = ActOnOpenMPCopyprivateClause(VarList, StartLoc, LParenLoc, EndLoc); 13124 break; 13125 case OMPC_flush: 13126 Res = ActOnOpenMPFlushClause(VarList, StartLoc, LParenLoc, EndLoc); 13127 break; 13128 case OMPC_depend: 13129 assert(0 <= ExtraModifier && ExtraModifier <= OMPC_DEPEND_unknown && 13130 "Unexpected depend modifier."); 13131 Res = ActOnOpenMPDependClause( 13132 DepModOrTailExpr, static_cast<OpenMPDependClauseKind>(ExtraModifier), 13133 ExtraModifierLoc, ColonLoc, VarList, StartLoc, LParenLoc, EndLoc); 13134 break; 13135 case OMPC_map: 13136 assert(0 <= ExtraModifier && ExtraModifier <= OMPC_MAP_unknown && 13137 "Unexpected map modifier."); 13138 Res = ActOnOpenMPMapClause( 13139 MapTypeModifiers, MapTypeModifiersLoc, ReductionOrMapperIdScopeSpec, 13140 ReductionOrMapperId, static_cast<OpenMPMapClauseKind>(ExtraModifier), 13141 IsMapTypeImplicit, ExtraModifierLoc, ColonLoc, VarList, Locs); 13142 break; 13143 case OMPC_to: 13144 Res = ActOnOpenMPToClause(VarList, ReductionOrMapperIdScopeSpec, 13145 ReductionOrMapperId, Locs); 13146 break; 13147 case OMPC_from: 13148 Res = ActOnOpenMPFromClause(VarList, ReductionOrMapperIdScopeSpec, 13149 ReductionOrMapperId, Locs); 13150 break; 13151 case OMPC_use_device_ptr: 13152 Res = ActOnOpenMPUseDevicePtrClause(VarList, Locs); 13153 break; 13154 case OMPC_is_device_ptr: 13155 Res = ActOnOpenMPIsDevicePtrClause(VarList, Locs); 13156 break; 13157 case OMPC_allocate: 13158 Res = ActOnOpenMPAllocateClause(DepModOrTailExpr, VarList, StartLoc, 13159 LParenLoc, ColonLoc, EndLoc); 13160 break; 13161 case OMPC_nontemporal: 13162 Res = ActOnOpenMPNontemporalClause(VarList, StartLoc, LParenLoc, EndLoc); 13163 break; 13164 case OMPC_inclusive: 13165 Res = ActOnOpenMPInclusiveClause(VarList, StartLoc, LParenLoc, EndLoc); 13166 break; 13167 case OMPC_exclusive: 13168 Res = ActOnOpenMPExclusiveClause(VarList, StartLoc, LParenLoc, EndLoc); 13169 break; 13170 case OMPC_if: 13171 case OMPC_depobj: 13172 case OMPC_final: 13173 case OMPC_num_threads: 13174 case OMPC_safelen: 13175 case OMPC_simdlen: 13176 case OMPC_allocator: 13177 case OMPC_collapse: 13178 case OMPC_default: 13179 case OMPC_proc_bind: 13180 case OMPC_schedule: 13181 case OMPC_ordered: 13182 case OMPC_nowait: 13183 case OMPC_untied: 13184 case OMPC_mergeable: 13185 case OMPC_threadprivate: 13186 case OMPC_read: 13187 case OMPC_write: 13188 case OMPC_update: 13189 case OMPC_capture: 13190 case OMPC_seq_cst: 13191 case OMPC_acq_rel: 13192 case OMPC_acquire: 13193 case OMPC_release: 13194 case OMPC_relaxed: 13195 case OMPC_device: 13196 case OMPC_threads: 13197 case OMPC_simd: 13198 case OMPC_num_teams: 13199 case OMPC_thread_limit: 13200 case OMPC_priority: 13201 case OMPC_grainsize: 13202 case OMPC_nogroup: 13203 case OMPC_num_tasks: 13204 case OMPC_hint: 13205 case OMPC_dist_schedule: 13206 case OMPC_defaultmap: 13207 case OMPC_unknown: 13208 case OMPC_uniform: 13209 case OMPC_unified_address: 13210 case OMPC_unified_shared_memory: 13211 case OMPC_reverse_offload: 13212 case OMPC_dynamic_allocators: 13213 case OMPC_atomic_default_mem_order: 13214 case OMPC_device_type: 13215 case OMPC_match: 13216 case OMPC_order: 13217 case OMPC_destroy: 13218 case OMPC_detach: 13219 llvm_unreachable("Clause is not allowed."); 13220 } 13221 return Res; 13222 } 13223 13224 ExprResult Sema::getOpenMPCapturedExpr(VarDecl *Capture, ExprValueKind VK, 13225 ExprObjectKind OK, SourceLocation Loc) { 13226 ExprResult Res = BuildDeclRefExpr( 13227 Capture, Capture->getType().getNonReferenceType(), VK_LValue, Loc); 13228 if (!Res.isUsable()) 13229 return ExprError(); 13230 if (OK == OK_Ordinary && !getLangOpts().CPlusPlus) { 13231 Res = CreateBuiltinUnaryOp(Loc, UO_Deref, Res.get()); 13232 if (!Res.isUsable()) 13233 return ExprError(); 13234 } 13235 if (VK != VK_LValue && Res.get()->isGLValue()) { 13236 Res = DefaultLvalueConversion(Res.get()); 13237 if (!Res.isUsable()) 13238 return ExprError(); 13239 } 13240 return Res; 13241 } 13242 13243 OMPClause *Sema::ActOnOpenMPPrivateClause(ArrayRef<Expr *> VarList, 13244 SourceLocation StartLoc, 13245 SourceLocation LParenLoc, 13246 SourceLocation EndLoc) { 13247 SmallVector<Expr *, 8> Vars; 13248 SmallVector<Expr *, 8> PrivateCopies; 13249 for (Expr *RefExpr : VarList) { 13250 assert(RefExpr && "NULL expr in OpenMP private clause."); 13251 SourceLocation ELoc; 13252 SourceRange ERange; 13253 Expr *SimpleRefExpr = RefExpr; 13254 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 13255 if (Res.second) { 13256 // It will be analyzed later. 13257 Vars.push_back(RefExpr); 13258 PrivateCopies.push_back(nullptr); 13259 } 13260 ValueDecl *D = Res.first; 13261 if (!D) 13262 continue; 13263 13264 QualType Type = D->getType(); 13265 auto *VD = dyn_cast<VarDecl>(D); 13266 13267 // OpenMP [2.9.3.3, Restrictions, C/C++, p.3] 13268 // A variable that appears in a private clause must not have an incomplete 13269 // type or a reference type. 13270 if (RequireCompleteType(ELoc, Type, diag::err_omp_private_incomplete_type)) 13271 continue; 13272 Type = Type.getNonReferenceType(); 13273 13274 // OpenMP 5.0 [2.19.3, List Item Privatization, Restrictions] 13275 // A variable that is privatized must not have a const-qualified type 13276 // unless it is of class type with a mutable member. This restriction does 13277 // not apply to the firstprivate clause. 13278 // 13279 // OpenMP 3.1 [2.9.3.3, private clause, Restrictions] 13280 // A variable that appears in a private clause must not have a 13281 // const-qualified type unless it is of class type with a mutable member. 13282 if (rejectConstNotMutableType(*this, D, Type, OMPC_private, ELoc)) 13283 continue; 13284 13285 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 13286 // in a Construct] 13287 // Variables with the predetermined data-sharing attributes may not be 13288 // listed in data-sharing attributes clauses, except for the cases 13289 // listed below. For these exceptions only, listing a predetermined 13290 // variable in a data-sharing attribute clause is allowed and overrides 13291 // the variable's predetermined data-sharing attributes. 13292 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false); 13293 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_private) { 13294 Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind) 13295 << getOpenMPClauseName(OMPC_private); 13296 reportOriginalDsa(*this, DSAStack, D, DVar); 13297 continue; 13298 } 13299 13300 OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective(); 13301 // Variably modified types are not supported for tasks. 13302 if (!Type->isAnyPointerType() && Type->isVariablyModifiedType() && 13303 isOpenMPTaskingDirective(CurrDir)) { 13304 Diag(ELoc, diag::err_omp_variably_modified_type_not_supported) 13305 << getOpenMPClauseName(OMPC_private) << Type 13306 << getOpenMPDirectiveName(CurrDir); 13307 bool IsDecl = 13308 !VD || 13309 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 13310 Diag(D->getLocation(), 13311 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 13312 << D; 13313 continue; 13314 } 13315 13316 // OpenMP 4.5 [2.15.5.1, Restrictions, p.3] 13317 // A list item cannot appear in both a map clause and a data-sharing 13318 // attribute clause on the same construct 13319 // 13320 // OpenMP 5.0 [2.19.7.1, Restrictions, p.7] 13321 // A list item cannot appear in both a map clause and a data-sharing 13322 // attribute clause on the same construct unless the construct is a 13323 // combined construct. 13324 if ((LangOpts.OpenMP <= 45 && isOpenMPTargetExecutionDirective(CurrDir)) || 13325 CurrDir == OMPD_target) { 13326 OpenMPClauseKind ConflictKind; 13327 if (DSAStack->checkMappableExprComponentListsForDecl( 13328 VD, /*CurrentRegionOnly=*/true, 13329 [&](OMPClauseMappableExprCommon::MappableExprComponentListRef, 13330 OpenMPClauseKind WhereFoundClauseKind) -> bool { 13331 ConflictKind = WhereFoundClauseKind; 13332 return true; 13333 })) { 13334 Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa) 13335 << getOpenMPClauseName(OMPC_private) 13336 << getOpenMPClauseName(ConflictKind) 13337 << getOpenMPDirectiveName(CurrDir); 13338 reportOriginalDsa(*this, DSAStack, D, DVar); 13339 continue; 13340 } 13341 } 13342 13343 // OpenMP [2.9.3.3, Restrictions, C/C++, p.1] 13344 // A variable of class type (or array thereof) that appears in a private 13345 // clause requires an accessible, unambiguous default constructor for the 13346 // class type. 13347 // Generate helper private variable and initialize it with the default 13348 // value. The address of the original variable is replaced by the address of 13349 // the new private variable in CodeGen. This new variable is not added to 13350 // IdResolver, so the code in the OpenMP region uses original variable for 13351 // proper diagnostics. 13352 Type = Type.getUnqualifiedType(); 13353 VarDecl *VDPrivate = 13354 buildVarDecl(*this, ELoc, Type, D->getName(), 13355 D->hasAttrs() ? &D->getAttrs() : nullptr, 13356 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr); 13357 ActOnUninitializedDecl(VDPrivate); 13358 if (VDPrivate->isInvalidDecl()) 13359 continue; 13360 DeclRefExpr *VDPrivateRefExpr = buildDeclRefExpr( 13361 *this, VDPrivate, RefExpr->getType().getUnqualifiedType(), ELoc); 13362 13363 DeclRefExpr *Ref = nullptr; 13364 if (!VD && !CurContext->isDependentContext()) 13365 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false); 13366 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_private, Ref); 13367 Vars.push_back((VD || CurContext->isDependentContext()) 13368 ? RefExpr->IgnoreParens() 13369 : Ref); 13370 PrivateCopies.push_back(VDPrivateRefExpr); 13371 } 13372 13373 if (Vars.empty()) 13374 return nullptr; 13375 13376 return OMPPrivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars, 13377 PrivateCopies); 13378 } 13379 13380 namespace { 13381 class DiagsUninitializedSeveretyRAII { 13382 private: 13383 DiagnosticsEngine &Diags; 13384 SourceLocation SavedLoc; 13385 bool IsIgnored = false; 13386 13387 public: 13388 DiagsUninitializedSeveretyRAII(DiagnosticsEngine &Diags, SourceLocation Loc, 13389 bool IsIgnored) 13390 : Diags(Diags), SavedLoc(Loc), IsIgnored(IsIgnored) { 13391 if (!IsIgnored) { 13392 Diags.setSeverity(/*Diag*/ diag::warn_uninit_self_reference_in_init, 13393 /*Map*/ diag::Severity::Ignored, Loc); 13394 } 13395 } 13396 ~DiagsUninitializedSeveretyRAII() { 13397 if (!IsIgnored) 13398 Diags.popMappings(SavedLoc); 13399 } 13400 }; 13401 } 13402 13403 OMPClause *Sema::ActOnOpenMPFirstprivateClause(ArrayRef<Expr *> VarList, 13404 SourceLocation StartLoc, 13405 SourceLocation LParenLoc, 13406 SourceLocation EndLoc) { 13407 SmallVector<Expr *, 8> Vars; 13408 SmallVector<Expr *, 8> PrivateCopies; 13409 SmallVector<Expr *, 8> Inits; 13410 SmallVector<Decl *, 4> ExprCaptures; 13411 bool IsImplicitClause = 13412 StartLoc.isInvalid() && LParenLoc.isInvalid() && EndLoc.isInvalid(); 13413 SourceLocation ImplicitClauseLoc = DSAStack->getConstructLoc(); 13414 13415 for (Expr *RefExpr : VarList) { 13416 assert(RefExpr && "NULL expr in OpenMP firstprivate clause."); 13417 SourceLocation ELoc; 13418 SourceRange ERange; 13419 Expr *SimpleRefExpr = RefExpr; 13420 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 13421 if (Res.second) { 13422 // It will be analyzed later. 13423 Vars.push_back(RefExpr); 13424 PrivateCopies.push_back(nullptr); 13425 Inits.push_back(nullptr); 13426 } 13427 ValueDecl *D = Res.first; 13428 if (!D) 13429 continue; 13430 13431 ELoc = IsImplicitClause ? ImplicitClauseLoc : ELoc; 13432 QualType Type = D->getType(); 13433 auto *VD = dyn_cast<VarDecl>(D); 13434 13435 // OpenMP [2.9.3.3, Restrictions, C/C++, p.3] 13436 // A variable that appears in a private clause must not have an incomplete 13437 // type or a reference type. 13438 if (RequireCompleteType(ELoc, Type, 13439 diag::err_omp_firstprivate_incomplete_type)) 13440 continue; 13441 Type = Type.getNonReferenceType(); 13442 13443 // OpenMP [2.9.3.4, Restrictions, C/C++, p.1] 13444 // A variable of class type (or array thereof) that appears in a private 13445 // clause requires an accessible, unambiguous copy constructor for the 13446 // class type. 13447 QualType ElemType = Context.getBaseElementType(Type).getNonReferenceType(); 13448 13449 // If an implicit firstprivate variable found it was checked already. 13450 DSAStackTy::DSAVarData TopDVar; 13451 if (!IsImplicitClause) { 13452 DSAStackTy::DSAVarData DVar = 13453 DSAStack->getTopDSA(D, /*FromParent=*/false); 13454 TopDVar = DVar; 13455 OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective(); 13456 bool IsConstant = ElemType.isConstant(Context); 13457 // OpenMP [2.4.13, Data-sharing Attribute Clauses] 13458 // A list item that specifies a given variable may not appear in more 13459 // than one clause on the same directive, except that a variable may be 13460 // specified in both firstprivate and lastprivate clauses. 13461 // OpenMP 4.5 [2.10.8, Distribute Construct, p.3] 13462 // A list item may appear in a firstprivate or lastprivate clause but not 13463 // both. 13464 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_firstprivate && 13465 (isOpenMPDistributeDirective(CurrDir) || 13466 DVar.CKind != OMPC_lastprivate) && 13467 DVar.RefExpr) { 13468 Diag(ELoc, diag::err_omp_wrong_dsa) 13469 << getOpenMPClauseName(DVar.CKind) 13470 << getOpenMPClauseName(OMPC_firstprivate); 13471 reportOriginalDsa(*this, DSAStack, D, DVar); 13472 continue; 13473 } 13474 13475 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 13476 // in a Construct] 13477 // Variables with the predetermined data-sharing attributes may not be 13478 // listed in data-sharing attributes clauses, except for the cases 13479 // listed below. For these exceptions only, listing a predetermined 13480 // variable in a data-sharing attribute clause is allowed and overrides 13481 // the variable's predetermined data-sharing attributes. 13482 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 13483 // in a Construct, C/C++, p.2] 13484 // Variables with const-qualified type having no mutable member may be 13485 // listed in a firstprivate clause, even if they are static data members. 13486 if (!(IsConstant || (VD && VD->isStaticDataMember())) && !DVar.RefExpr && 13487 DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_shared) { 13488 Diag(ELoc, diag::err_omp_wrong_dsa) 13489 << getOpenMPClauseName(DVar.CKind) 13490 << getOpenMPClauseName(OMPC_firstprivate); 13491 reportOriginalDsa(*this, DSAStack, D, DVar); 13492 continue; 13493 } 13494 13495 // OpenMP [2.9.3.4, Restrictions, p.2] 13496 // A list item that is private within a parallel region must not appear 13497 // in a firstprivate clause on a worksharing construct if any of the 13498 // worksharing regions arising from the worksharing construct ever bind 13499 // to any of the parallel regions arising from the parallel construct. 13500 // OpenMP 4.5 [2.15.3.4, Restrictions, p.3] 13501 // A list item that is private within a teams region must not appear in a 13502 // firstprivate clause on a distribute construct if any of the distribute 13503 // regions arising from the distribute construct ever bind to any of the 13504 // teams regions arising from the teams construct. 13505 // OpenMP 4.5 [2.15.3.4, Restrictions, p.3] 13506 // A list item that appears in a reduction clause of a teams construct 13507 // must not appear in a firstprivate clause on a distribute construct if 13508 // any of the distribute regions arising from the distribute construct 13509 // ever bind to any of the teams regions arising from the teams construct. 13510 if ((isOpenMPWorksharingDirective(CurrDir) || 13511 isOpenMPDistributeDirective(CurrDir)) && 13512 !isOpenMPParallelDirective(CurrDir) && 13513 !isOpenMPTeamsDirective(CurrDir)) { 13514 DVar = DSAStack->getImplicitDSA(D, true); 13515 if (DVar.CKind != OMPC_shared && 13516 (isOpenMPParallelDirective(DVar.DKind) || 13517 isOpenMPTeamsDirective(DVar.DKind) || 13518 DVar.DKind == OMPD_unknown)) { 13519 Diag(ELoc, diag::err_omp_required_access) 13520 << getOpenMPClauseName(OMPC_firstprivate) 13521 << getOpenMPClauseName(OMPC_shared); 13522 reportOriginalDsa(*this, DSAStack, D, DVar); 13523 continue; 13524 } 13525 } 13526 // OpenMP [2.9.3.4, Restrictions, p.3] 13527 // A list item that appears in a reduction clause of a parallel construct 13528 // must not appear in a firstprivate clause on a worksharing or task 13529 // construct if any of the worksharing or task regions arising from the 13530 // worksharing or task construct ever bind to any of the parallel regions 13531 // arising from the parallel construct. 13532 // OpenMP [2.9.3.4, Restrictions, p.4] 13533 // A list item that appears in a reduction clause in worksharing 13534 // construct must not appear in a firstprivate clause in a task construct 13535 // encountered during execution of any of the worksharing regions arising 13536 // from the worksharing construct. 13537 if (isOpenMPTaskingDirective(CurrDir)) { 13538 DVar = DSAStack->hasInnermostDSA( 13539 D, [](OpenMPClauseKind C) { return C == OMPC_reduction; }, 13540 [](OpenMPDirectiveKind K) { 13541 return isOpenMPParallelDirective(K) || 13542 isOpenMPWorksharingDirective(K) || 13543 isOpenMPTeamsDirective(K); 13544 }, 13545 /*FromParent=*/true); 13546 if (DVar.CKind == OMPC_reduction && 13547 (isOpenMPParallelDirective(DVar.DKind) || 13548 isOpenMPWorksharingDirective(DVar.DKind) || 13549 isOpenMPTeamsDirective(DVar.DKind))) { 13550 Diag(ELoc, diag::err_omp_parallel_reduction_in_task_firstprivate) 13551 << getOpenMPDirectiveName(DVar.DKind); 13552 reportOriginalDsa(*this, DSAStack, D, DVar); 13553 continue; 13554 } 13555 } 13556 13557 // OpenMP 4.5 [2.15.5.1, Restrictions, p.3] 13558 // A list item cannot appear in both a map clause and a data-sharing 13559 // attribute clause on the same construct 13560 // 13561 // OpenMP 5.0 [2.19.7.1, Restrictions, p.7] 13562 // A list item cannot appear in both a map clause and a data-sharing 13563 // attribute clause on the same construct unless the construct is a 13564 // combined construct. 13565 if ((LangOpts.OpenMP <= 45 && 13566 isOpenMPTargetExecutionDirective(CurrDir)) || 13567 CurrDir == OMPD_target) { 13568 OpenMPClauseKind ConflictKind; 13569 if (DSAStack->checkMappableExprComponentListsForDecl( 13570 VD, /*CurrentRegionOnly=*/true, 13571 [&ConflictKind]( 13572 OMPClauseMappableExprCommon::MappableExprComponentListRef, 13573 OpenMPClauseKind WhereFoundClauseKind) { 13574 ConflictKind = WhereFoundClauseKind; 13575 return true; 13576 })) { 13577 Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa) 13578 << getOpenMPClauseName(OMPC_firstprivate) 13579 << getOpenMPClauseName(ConflictKind) 13580 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 13581 reportOriginalDsa(*this, DSAStack, D, DVar); 13582 continue; 13583 } 13584 } 13585 } 13586 13587 // Variably modified types are not supported for tasks. 13588 if (!Type->isAnyPointerType() && Type->isVariablyModifiedType() && 13589 isOpenMPTaskingDirective(DSAStack->getCurrentDirective())) { 13590 Diag(ELoc, diag::err_omp_variably_modified_type_not_supported) 13591 << getOpenMPClauseName(OMPC_firstprivate) << Type 13592 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 13593 bool IsDecl = 13594 !VD || 13595 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 13596 Diag(D->getLocation(), 13597 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 13598 << D; 13599 continue; 13600 } 13601 13602 Type = Type.getUnqualifiedType(); 13603 VarDecl *VDPrivate = 13604 buildVarDecl(*this, ELoc, Type, D->getName(), 13605 D->hasAttrs() ? &D->getAttrs() : nullptr, 13606 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr); 13607 // Generate helper private variable and initialize it with the value of the 13608 // original variable. The address of the original variable is replaced by 13609 // the address of the new private variable in the CodeGen. This new variable 13610 // is not added to IdResolver, so the code in the OpenMP region uses 13611 // original variable for proper diagnostics and variable capturing. 13612 Expr *VDInitRefExpr = nullptr; 13613 // For arrays generate initializer for single element and replace it by the 13614 // original array element in CodeGen. 13615 if (Type->isArrayType()) { 13616 VarDecl *VDInit = 13617 buildVarDecl(*this, RefExpr->getExprLoc(), ElemType, D->getName()); 13618 VDInitRefExpr = buildDeclRefExpr(*this, VDInit, ElemType, ELoc); 13619 Expr *Init = DefaultLvalueConversion(VDInitRefExpr).get(); 13620 ElemType = ElemType.getUnqualifiedType(); 13621 VarDecl *VDInitTemp = buildVarDecl(*this, RefExpr->getExprLoc(), ElemType, 13622 ".firstprivate.temp"); 13623 InitializedEntity Entity = 13624 InitializedEntity::InitializeVariable(VDInitTemp); 13625 InitializationKind Kind = InitializationKind::CreateCopy(ELoc, ELoc); 13626 13627 InitializationSequence InitSeq(*this, Entity, Kind, Init); 13628 ExprResult Result = InitSeq.Perform(*this, Entity, Kind, Init); 13629 if (Result.isInvalid()) 13630 VDPrivate->setInvalidDecl(); 13631 else 13632 VDPrivate->setInit(Result.getAs<Expr>()); 13633 // Remove temp variable declaration. 13634 Context.Deallocate(VDInitTemp); 13635 } else { 13636 VarDecl *VDInit = buildVarDecl(*this, RefExpr->getExprLoc(), Type, 13637 ".firstprivate.temp"); 13638 VDInitRefExpr = buildDeclRefExpr(*this, VDInit, RefExpr->getType(), 13639 RefExpr->getExprLoc()); 13640 AddInitializerToDecl(VDPrivate, 13641 DefaultLvalueConversion(VDInitRefExpr).get(), 13642 /*DirectInit=*/false); 13643 } 13644 if (VDPrivate->isInvalidDecl()) { 13645 if (IsImplicitClause) { 13646 Diag(RefExpr->getExprLoc(), 13647 diag::note_omp_task_predetermined_firstprivate_here); 13648 } 13649 continue; 13650 } 13651 CurContext->addDecl(VDPrivate); 13652 DeclRefExpr *VDPrivateRefExpr = buildDeclRefExpr( 13653 *this, VDPrivate, RefExpr->getType().getUnqualifiedType(), 13654 RefExpr->getExprLoc()); 13655 DeclRefExpr *Ref = nullptr; 13656 if (!VD && !CurContext->isDependentContext()) { 13657 if (TopDVar.CKind == OMPC_lastprivate) { 13658 Ref = TopDVar.PrivateCopy; 13659 } else { 13660 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true); 13661 if (!isOpenMPCapturedDecl(D)) 13662 ExprCaptures.push_back(Ref->getDecl()); 13663 } 13664 } 13665 if (!IsImplicitClause) 13666 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_firstprivate, Ref); 13667 Vars.push_back((VD || CurContext->isDependentContext()) 13668 ? RefExpr->IgnoreParens() 13669 : Ref); 13670 PrivateCopies.push_back(VDPrivateRefExpr); 13671 Inits.push_back(VDInitRefExpr); 13672 } 13673 13674 if (Vars.empty()) 13675 return nullptr; 13676 13677 return OMPFirstprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, 13678 Vars, PrivateCopies, Inits, 13679 buildPreInits(Context, ExprCaptures)); 13680 } 13681 13682 OMPClause *Sema::ActOnOpenMPLastprivateClause( 13683 ArrayRef<Expr *> VarList, OpenMPLastprivateModifier LPKind, 13684 SourceLocation LPKindLoc, SourceLocation ColonLoc, SourceLocation StartLoc, 13685 SourceLocation LParenLoc, SourceLocation EndLoc) { 13686 if (LPKind == OMPC_LASTPRIVATE_unknown && LPKindLoc.isValid()) { 13687 assert(ColonLoc.isValid() && "Colon location must be valid."); 13688 Diag(LPKindLoc, diag::err_omp_unexpected_clause_value) 13689 << getListOfPossibleValues(OMPC_lastprivate, /*First=*/0, 13690 /*Last=*/OMPC_LASTPRIVATE_unknown) 13691 << getOpenMPClauseName(OMPC_lastprivate); 13692 return nullptr; 13693 } 13694 13695 SmallVector<Expr *, 8> Vars; 13696 SmallVector<Expr *, 8> SrcExprs; 13697 SmallVector<Expr *, 8> DstExprs; 13698 SmallVector<Expr *, 8> AssignmentOps; 13699 SmallVector<Decl *, 4> ExprCaptures; 13700 SmallVector<Expr *, 4> ExprPostUpdates; 13701 for (Expr *RefExpr : VarList) { 13702 assert(RefExpr && "NULL expr in OpenMP lastprivate clause."); 13703 SourceLocation ELoc; 13704 SourceRange ERange; 13705 Expr *SimpleRefExpr = RefExpr; 13706 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 13707 if (Res.second) { 13708 // It will be analyzed later. 13709 Vars.push_back(RefExpr); 13710 SrcExprs.push_back(nullptr); 13711 DstExprs.push_back(nullptr); 13712 AssignmentOps.push_back(nullptr); 13713 } 13714 ValueDecl *D = Res.first; 13715 if (!D) 13716 continue; 13717 13718 QualType Type = D->getType(); 13719 auto *VD = dyn_cast<VarDecl>(D); 13720 13721 // OpenMP [2.14.3.5, Restrictions, C/C++, p.2] 13722 // A variable that appears in a lastprivate clause must not have an 13723 // incomplete type or a reference type. 13724 if (RequireCompleteType(ELoc, Type, 13725 diag::err_omp_lastprivate_incomplete_type)) 13726 continue; 13727 Type = Type.getNonReferenceType(); 13728 13729 // OpenMP 5.0 [2.19.3, List Item Privatization, Restrictions] 13730 // A variable that is privatized must not have a const-qualified type 13731 // unless it is of class type with a mutable member. This restriction does 13732 // not apply to the firstprivate clause. 13733 // 13734 // OpenMP 3.1 [2.9.3.5, lastprivate clause, Restrictions] 13735 // A variable that appears in a lastprivate clause must not have a 13736 // const-qualified type unless it is of class type with a mutable member. 13737 if (rejectConstNotMutableType(*this, D, Type, OMPC_lastprivate, ELoc)) 13738 continue; 13739 13740 // OpenMP 5.0 [2.19.4.5 lastprivate Clause, Restrictions] 13741 // A list item that appears in a lastprivate clause with the conditional 13742 // modifier must be a scalar variable. 13743 if (LPKind == OMPC_LASTPRIVATE_conditional && !Type->isScalarType()) { 13744 Diag(ELoc, diag::err_omp_lastprivate_conditional_non_scalar); 13745 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) == 13746 VarDecl::DeclarationOnly; 13747 Diag(D->getLocation(), 13748 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 13749 << D; 13750 continue; 13751 } 13752 13753 OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective(); 13754 // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables Referenced 13755 // in a Construct] 13756 // Variables with the predetermined data-sharing attributes may not be 13757 // listed in data-sharing attributes clauses, except for the cases 13758 // listed below. 13759 // OpenMP 4.5 [2.10.8, Distribute Construct, p.3] 13760 // A list item may appear in a firstprivate or lastprivate clause but not 13761 // both. 13762 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false); 13763 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_lastprivate && 13764 (isOpenMPDistributeDirective(CurrDir) || 13765 DVar.CKind != OMPC_firstprivate) && 13766 (DVar.CKind != OMPC_private || DVar.RefExpr != nullptr)) { 13767 Diag(ELoc, diag::err_omp_wrong_dsa) 13768 << getOpenMPClauseName(DVar.CKind) 13769 << getOpenMPClauseName(OMPC_lastprivate); 13770 reportOriginalDsa(*this, DSAStack, D, DVar); 13771 continue; 13772 } 13773 13774 // OpenMP [2.14.3.5, Restrictions, p.2] 13775 // A list item that is private within a parallel region, or that appears in 13776 // the reduction clause of a parallel construct, must not appear in a 13777 // lastprivate clause on a worksharing construct if any of the corresponding 13778 // worksharing regions ever binds to any of the corresponding parallel 13779 // regions. 13780 DSAStackTy::DSAVarData TopDVar = DVar; 13781 if (isOpenMPWorksharingDirective(CurrDir) && 13782 !isOpenMPParallelDirective(CurrDir) && 13783 !isOpenMPTeamsDirective(CurrDir)) { 13784 DVar = DSAStack->getImplicitDSA(D, true); 13785 if (DVar.CKind != OMPC_shared) { 13786 Diag(ELoc, diag::err_omp_required_access) 13787 << getOpenMPClauseName(OMPC_lastprivate) 13788 << getOpenMPClauseName(OMPC_shared); 13789 reportOriginalDsa(*this, DSAStack, D, DVar); 13790 continue; 13791 } 13792 } 13793 13794 // OpenMP [2.14.3.5, Restrictions, C++, p.1,2] 13795 // A variable of class type (or array thereof) that appears in a 13796 // lastprivate clause requires an accessible, unambiguous default 13797 // constructor for the class type, unless the list item is also specified 13798 // in a firstprivate clause. 13799 // A variable of class type (or array thereof) that appears in a 13800 // lastprivate clause requires an accessible, unambiguous copy assignment 13801 // operator for the class type. 13802 Type = Context.getBaseElementType(Type).getNonReferenceType(); 13803 VarDecl *SrcVD = buildVarDecl(*this, ERange.getBegin(), 13804 Type.getUnqualifiedType(), ".lastprivate.src", 13805 D->hasAttrs() ? &D->getAttrs() : nullptr); 13806 DeclRefExpr *PseudoSrcExpr = 13807 buildDeclRefExpr(*this, SrcVD, Type.getUnqualifiedType(), ELoc); 13808 VarDecl *DstVD = 13809 buildVarDecl(*this, ERange.getBegin(), Type, ".lastprivate.dst", 13810 D->hasAttrs() ? &D->getAttrs() : nullptr); 13811 DeclRefExpr *PseudoDstExpr = buildDeclRefExpr(*this, DstVD, Type, ELoc); 13812 // For arrays generate assignment operation for single element and replace 13813 // it by the original array element in CodeGen. 13814 ExprResult AssignmentOp = BuildBinOp(/*S=*/nullptr, ELoc, BO_Assign, 13815 PseudoDstExpr, PseudoSrcExpr); 13816 if (AssignmentOp.isInvalid()) 13817 continue; 13818 AssignmentOp = 13819 ActOnFinishFullExpr(AssignmentOp.get(), ELoc, /*DiscardedValue*/ false); 13820 if (AssignmentOp.isInvalid()) 13821 continue; 13822 13823 DeclRefExpr *Ref = nullptr; 13824 if (!VD && !CurContext->isDependentContext()) { 13825 if (TopDVar.CKind == OMPC_firstprivate) { 13826 Ref = TopDVar.PrivateCopy; 13827 } else { 13828 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false); 13829 if (!isOpenMPCapturedDecl(D)) 13830 ExprCaptures.push_back(Ref->getDecl()); 13831 } 13832 if (TopDVar.CKind == OMPC_firstprivate || 13833 (!isOpenMPCapturedDecl(D) && 13834 Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>())) { 13835 ExprResult RefRes = DefaultLvalueConversion(Ref); 13836 if (!RefRes.isUsable()) 13837 continue; 13838 ExprResult PostUpdateRes = 13839 BuildBinOp(DSAStack->getCurScope(), ELoc, BO_Assign, SimpleRefExpr, 13840 RefRes.get()); 13841 if (!PostUpdateRes.isUsable()) 13842 continue; 13843 ExprPostUpdates.push_back( 13844 IgnoredValueConversions(PostUpdateRes.get()).get()); 13845 } 13846 } 13847 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_lastprivate, Ref); 13848 Vars.push_back((VD || CurContext->isDependentContext()) 13849 ? RefExpr->IgnoreParens() 13850 : Ref); 13851 SrcExprs.push_back(PseudoSrcExpr); 13852 DstExprs.push_back(PseudoDstExpr); 13853 AssignmentOps.push_back(AssignmentOp.get()); 13854 } 13855 13856 if (Vars.empty()) 13857 return nullptr; 13858 13859 return OMPLastprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, 13860 Vars, SrcExprs, DstExprs, AssignmentOps, 13861 LPKind, LPKindLoc, ColonLoc, 13862 buildPreInits(Context, ExprCaptures), 13863 buildPostUpdate(*this, ExprPostUpdates)); 13864 } 13865 13866 OMPClause *Sema::ActOnOpenMPSharedClause(ArrayRef<Expr *> VarList, 13867 SourceLocation StartLoc, 13868 SourceLocation LParenLoc, 13869 SourceLocation EndLoc) { 13870 SmallVector<Expr *, 8> Vars; 13871 for (Expr *RefExpr : VarList) { 13872 assert(RefExpr && "NULL expr in OpenMP lastprivate clause."); 13873 SourceLocation ELoc; 13874 SourceRange ERange; 13875 Expr *SimpleRefExpr = RefExpr; 13876 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 13877 if (Res.second) { 13878 // It will be analyzed later. 13879 Vars.push_back(RefExpr); 13880 } 13881 ValueDecl *D = Res.first; 13882 if (!D) 13883 continue; 13884 13885 auto *VD = dyn_cast<VarDecl>(D); 13886 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 13887 // in a Construct] 13888 // Variables with the predetermined data-sharing attributes may not be 13889 // listed in data-sharing attributes clauses, except for the cases 13890 // listed below. For these exceptions only, listing a predetermined 13891 // variable in a data-sharing attribute clause is allowed and overrides 13892 // the variable's predetermined data-sharing attributes. 13893 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false); 13894 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_shared && 13895 DVar.RefExpr) { 13896 Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind) 13897 << getOpenMPClauseName(OMPC_shared); 13898 reportOriginalDsa(*this, DSAStack, D, DVar); 13899 continue; 13900 } 13901 13902 DeclRefExpr *Ref = nullptr; 13903 if (!VD && isOpenMPCapturedDecl(D) && !CurContext->isDependentContext()) 13904 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true); 13905 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_shared, Ref); 13906 Vars.push_back((VD || !Ref || CurContext->isDependentContext()) 13907 ? RefExpr->IgnoreParens() 13908 : Ref); 13909 } 13910 13911 if (Vars.empty()) 13912 return nullptr; 13913 13914 return OMPSharedClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars); 13915 } 13916 13917 namespace { 13918 class DSARefChecker : public StmtVisitor<DSARefChecker, bool> { 13919 DSAStackTy *Stack; 13920 13921 public: 13922 bool VisitDeclRefExpr(DeclRefExpr *E) { 13923 if (auto *VD = dyn_cast<VarDecl>(E->getDecl())) { 13924 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(VD, /*FromParent=*/false); 13925 if (DVar.CKind == OMPC_shared && !DVar.RefExpr) 13926 return false; 13927 if (DVar.CKind != OMPC_unknown) 13928 return true; 13929 DSAStackTy::DSAVarData DVarPrivate = Stack->hasDSA( 13930 VD, isOpenMPPrivate, [](OpenMPDirectiveKind) { return true; }, 13931 /*FromParent=*/true); 13932 return DVarPrivate.CKind != OMPC_unknown; 13933 } 13934 return false; 13935 } 13936 bool VisitStmt(Stmt *S) { 13937 for (Stmt *Child : S->children()) { 13938 if (Child && Visit(Child)) 13939 return true; 13940 } 13941 return false; 13942 } 13943 explicit DSARefChecker(DSAStackTy *S) : Stack(S) {} 13944 }; 13945 } // namespace 13946 13947 namespace { 13948 // Transform MemberExpression for specified FieldDecl of current class to 13949 // DeclRefExpr to specified OMPCapturedExprDecl. 13950 class TransformExprToCaptures : public TreeTransform<TransformExprToCaptures> { 13951 typedef TreeTransform<TransformExprToCaptures> BaseTransform; 13952 ValueDecl *Field = nullptr; 13953 DeclRefExpr *CapturedExpr = nullptr; 13954 13955 public: 13956 TransformExprToCaptures(Sema &SemaRef, ValueDecl *FieldDecl) 13957 : BaseTransform(SemaRef), Field(FieldDecl), CapturedExpr(nullptr) {} 13958 13959 ExprResult TransformMemberExpr(MemberExpr *E) { 13960 if (isa<CXXThisExpr>(E->getBase()->IgnoreParenImpCasts()) && 13961 E->getMemberDecl() == Field) { 13962 CapturedExpr = buildCapture(SemaRef, Field, E, /*WithInit=*/false); 13963 return CapturedExpr; 13964 } 13965 return BaseTransform::TransformMemberExpr(E); 13966 } 13967 DeclRefExpr *getCapturedExpr() { return CapturedExpr; } 13968 }; 13969 } // namespace 13970 13971 template <typename T, typename U> 13972 static T filterLookupForUDReductionAndMapper( 13973 SmallVectorImpl<U> &Lookups, const llvm::function_ref<T(ValueDecl *)> Gen) { 13974 for (U &Set : Lookups) { 13975 for (auto *D : Set) { 13976 if (T Res = Gen(cast<ValueDecl>(D))) 13977 return Res; 13978 } 13979 } 13980 return T(); 13981 } 13982 13983 static NamedDecl *findAcceptableDecl(Sema &SemaRef, NamedDecl *D) { 13984 assert(!LookupResult::isVisible(SemaRef, D) && "not in slow case"); 13985 13986 for (auto RD : D->redecls()) { 13987 // Don't bother with extra checks if we already know this one isn't visible. 13988 if (RD == D) 13989 continue; 13990 13991 auto ND = cast<NamedDecl>(RD); 13992 if (LookupResult::isVisible(SemaRef, ND)) 13993 return ND; 13994 } 13995 13996 return nullptr; 13997 } 13998 13999 static void 14000 argumentDependentLookup(Sema &SemaRef, const DeclarationNameInfo &Id, 14001 SourceLocation Loc, QualType Ty, 14002 SmallVectorImpl<UnresolvedSet<8>> &Lookups) { 14003 // Find all of the associated namespaces and classes based on the 14004 // arguments we have. 14005 Sema::AssociatedNamespaceSet AssociatedNamespaces; 14006 Sema::AssociatedClassSet AssociatedClasses; 14007 OpaqueValueExpr OVE(Loc, Ty, VK_LValue); 14008 SemaRef.FindAssociatedClassesAndNamespaces(Loc, &OVE, AssociatedNamespaces, 14009 AssociatedClasses); 14010 14011 // C++ [basic.lookup.argdep]p3: 14012 // Let X be the lookup set produced by unqualified lookup (3.4.1) 14013 // and let Y be the lookup set produced by argument dependent 14014 // lookup (defined as follows). If X contains [...] then Y is 14015 // empty. Otherwise Y is the set of declarations found in the 14016 // namespaces associated with the argument types as described 14017 // below. The set of declarations found by the lookup of the name 14018 // is the union of X and Y. 14019 // 14020 // Here, we compute Y and add its members to the overloaded 14021 // candidate set. 14022 for (auto *NS : AssociatedNamespaces) { 14023 // When considering an associated namespace, the lookup is the 14024 // same as the lookup performed when the associated namespace is 14025 // used as a qualifier (3.4.3.2) except that: 14026 // 14027 // -- Any using-directives in the associated namespace are 14028 // ignored. 14029 // 14030 // -- Any namespace-scope friend functions declared in 14031 // associated classes are visible within their respective 14032 // namespaces even if they are not visible during an ordinary 14033 // lookup (11.4). 14034 DeclContext::lookup_result R = NS->lookup(Id.getName()); 14035 for (auto *D : R) { 14036 auto *Underlying = D; 14037 if (auto *USD = dyn_cast<UsingShadowDecl>(D)) 14038 Underlying = USD->getTargetDecl(); 14039 14040 if (!isa<OMPDeclareReductionDecl>(Underlying) && 14041 !isa<OMPDeclareMapperDecl>(Underlying)) 14042 continue; 14043 14044 if (!SemaRef.isVisible(D)) { 14045 D = findAcceptableDecl(SemaRef, D); 14046 if (!D) 14047 continue; 14048 if (auto *USD = dyn_cast<UsingShadowDecl>(D)) 14049 Underlying = USD->getTargetDecl(); 14050 } 14051 Lookups.emplace_back(); 14052 Lookups.back().addDecl(Underlying); 14053 } 14054 } 14055 } 14056 14057 static ExprResult 14058 buildDeclareReductionRef(Sema &SemaRef, SourceLocation Loc, SourceRange Range, 14059 Scope *S, CXXScopeSpec &ReductionIdScopeSpec, 14060 const DeclarationNameInfo &ReductionId, QualType Ty, 14061 CXXCastPath &BasePath, Expr *UnresolvedReduction) { 14062 if (ReductionIdScopeSpec.isInvalid()) 14063 return ExprError(); 14064 SmallVector<UnresolvedSet<8>, 4> Lookups; 14065 if (S) { 14066 LookupResult Lookup(SemaRef, ReductionId, Sema::LookupOMPReductionName); 14067 Lookup.suppressDiagnostics(); 14068 while (S && SemaRef.LookupParsedName(Lookup, S, &ReductionIdScopeSpec)) { 14069 NamedDecl *D = Lookup.getRepresentativeDecl(); 14070 do { 14071 S = S->getParent(); 14072 } while (S && !S->isDeclScope(D)); 14073 if (S) 14074 S = S->getParent(); 14075 Lookups.emplace_back(); 14076 Lookups.back().append(Lookup.begin(), Lookup.end()); 14077 Lookup.clear(); 14078 } 14079 } else if (auto *ULE = 14080 cast_or_null<UnresolvedLookupExpr>(UnresolvedReduction)) { 14081 Lookups.push_back(UnresolvedSet<8>()); 14082 Decl *PrevD = nullptr; 14083 for (NamedDecl *D : ULE->decls()) { 14084 if (D == PrevD) 14085 Lookups.push_back(UnresolvedSet<8>()); 14086 else if (auto *DRD = dyn_cast<OMPDeclareReductionDecl>(D)) 14087 Lookups.back().addDecl(DRD); 14088 PrevD = D; 14089 } 14090 } 14091 if (SemaRef.CurContext->isDependentContext() || Ty->isDependentType() || 14092 Ty->isInstantiationDependentType() || 14093 Ty->containsUnexpandedParameterPack() || 14094 filterLookupForUDReductionAndMapper<bool>(Lookups, [](ValueDecl *D) { 14095 return !D->isInvalidDecl() && 14096 (D->getType()->isDependentType() || 14097 D->getType()->isInstantiationDependentType() || 14098 D->getType()->containsUnexpandedParameterPack()); 14099 })) { 14100 UnresolvedSet<8> ResSet; 14101 for (const UnresolvedSet<8> &Set : Lookups) { 14102 if (Set.empty()) 14103 continue; 14104 ResSet.append(Set.begin(), Set.end()); 14105 // The last item marks the end of all declarations at the specified scope. 14106 ResSet.addDecl(Set[Set.size() - 1]); 14107 } 14108 return UnresolvedLookupExpr::Create( 14109 SemaRef.Context, /*NamingClass=*/nullptr, 14110 ReductionIdScopeSpec.getWithLocInContext(SemaRef.Context), ReductionId, 14111 /*ADL=*/true, /*Overloaded=*/true, ResSet.begin(), ResSet.end()); 14112 } 14113 // Lookup inside the classes. 14114 // C++ [over.match.oper]p3: 14115 // For a unary operator @ with an operand of a type whose 14116 // cv-unqualified version is T1, and for a binary operator @ with 14117 // a left operand of a type whose cv-unqualified version is T1 and 14118 // a right operand of a type whose cv-unqualified version is T2, 14119 // three sets of candidate functions, designated member 14120 // candidates, non-member candidates and built-in candidates, are 14121 // constructed as follows: 14122 // -- If T1 is a complete class type or a class currently being 14123 // defined, the set of member candidates is the result of the 14124 // qualified lookup of T1::operator@ (13.3.1.1.1); otherwise, 14125 // the set of member candidates is empty. 14126 LookupResult Lookup(SemaRef, ReductionId, Sema::LookupOMPReductionName); 14127 Lookup.suppressDiagnostics(); 14128 if (const auto *TyRec = Ty->getAs<RecordType>()) { 14129 // Complete the type if it can be completed. 14130 // If the type is neither complete nor being defined, bail out now. 14131 if (SemaRef.isCompleteType(Loc, Ty) || TyRec->isBeingDefined() || 14132 TyRec->getDecl()->getDefinition()) { 14133 Lookup.clear(); 14134 SemaRef.LookupQualifiedName(Lookup, TyRec->getDecl()); 14135 if (Lookup.empty()) { 14136 Lookups.emplace_back(); 14137 Lookups.back().append(Lookup.begin(), Lookup.end()); 14138 } 14139 } 14140 } 14141 // Perform ADL. 14142 if (SemaRef.getLangOpts().CPlusPlus) 14143 argumentDependentLookup(SemaRef, ReductionId, Loc, Ty, Lookups); 14144 if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>( 14145 Lookups, [&SemaRef, Ty](ValueDecl *D) -> ValueDecl * { 14146 if (!D->isInvalidDecl() && 14147 SemaRef.Context.hasSameType(D->getType(), Ty)) 14148 return D; 14149 return nullptr; 14150 })) 14151 return SemaRef.BuildDeclRefExpr(VD, VD->getType().getNonReferenceType(), 14152 VK_LValue, Loc); 14153 if (SemaRef.getLangOpts().CPlusPlus) { 14154 if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>( 14155 Lookups, [&SemaRef, Ty, Loc](ValueDecl *D) -> ValueDecl * { 14156 if (!D->isInvalidDecl() && 14157 SemaRef.IsDerivedFrom(Loc, Ty, D->getType()) && 14158 !Ty.isMoreQualifiedThan(D->getType())) 14159 return D; 14160 return nullptr; 14161 })) { 14162 CXXBasePaths Paths(/*FindAmbiguities=*/true, /*RecordPaths=*/true, 14163 /*DetectVirtual=*/false); 14164 if (SemaRef.IsDerivedFrom(Loc, Ty, VD->getType(), Paths)) { 14165 if (!Paths.isAmbiguous(SemaRef.Context.getCanonicalType( 14166 VD->getType().getUnqualifiedType()))) { 14167 if (SemaRef.CheckBaseClassAccess( 14168 Loc, VD->getType(), Ty, Paths.front(), 14169 /*DiagID=*/0) != Sema::AR_inaccessible) { 14170 SemaRef.BuildBasePathArray(Paths, BasePath); 14171 return SemaRef.BuildDeclRefExpr( 14172 VD, VD->getType().getNonReferenceType(), VK_LValue, Loc); 14173 } 14174 } 14175 } 14176 } 14177 } 14178 if (ReductionIdScopeSpec.isSet()) { 14179 SemaRef.Diag(Loc, diag::err_omp_not_resolved_reduction_identifier) 14180 << Ty << Range; 14181 return ExprError(); 14182 } 14183 return ExprEmpty(); 14184 } 14185 14186 namespace { 14187 /// Data for the reduction-based clauses. 14188 struct ReductionData { 14189 /// List of original reduction items. 14190 SmallVector<Expr *, 8> Vars; 14191 /// List of private copies of the reduction items. 14192 SmallVector<Expr *, 8> Privates; 14193 /// LHS expressions for the reduction_op expressions. 14194 SmallVector<Expr *, 8> LHSs; 14195 /// RHS expressions for the reduction_op expressions. 14196 SmallVector<Expr *, 8> RHSs; 14197 /// Reduction operation expression. 14198 SmallVector<Expr *, 8> ReductionOps; 14199 /// Taskgroup descriptors for the corresponding reduction items in 14200 /// in_reduction clauses. 14201 SmallVector<Expr *, 8> TaskgroupDescriptors; 14202 /// List of captures for clause. 14203 SmallVector<Decl *, 4> ExprCaptures; 14204 /// List of postupdate expressions. 14205 SmallVector<Expr *, 4> ExprPostUpdates; 14206 /// Reduction modifier. 14207 unsigned RedModifier = 0; 14208 ReductionData() = delete; 14209 /// Reserves required memory for the reduction data. 14210 ReductionData(unsigned Size, unsigned Modifier = 0) : RedModifier(Modifier) { 14211 Vars.reserve(Size); 14212 Privates.reserve(Size); 14213 LHSs.reserve(Size); 14214 RHSs.reserve(Size); 14215 ReductionOps.reserve(Size); 14216 TaskgroupDescriptors.reserve(Size); 14217 ExprCaptures.reserve(Size); 14218 ExprPostUpdates.reserve(Size); 14219 } 14220 /// Stores reduction item and reduction operation only (required for dependent 14221 /// reduction item). 14222 void push(Expr *Item, Expr *ReductionOp) { 14223 Vars.emplace_back(Item); 14224 Privates.emplace_back(nullptr); 14225 LHSs.emplace_back(nullptr); 14226 RHSs.emplace_back(nullptr); 14227 ReductionOps.emplace_back(ReductionOp); 14228 TaskgroupDescriptors.emplace_back(nullptr); 14229 } 14230 /// Stores reduction data. 14231 void push(Expr *Item, Expr *Private, Expr *LHS, Expr *RHS, Expr *ReductionOp, 14232 Expr *TaskgroupDescriptor) { 14233 Vars.emplace_back(Item); 14234 Privates.emplace_back(Private); 14235 LHSs.emplace_back(LHS); 14236 RHSs.emplace_back(RHS); 14237 ReductionOps.emplace_back(ReductionOp); 14238 TaskgroupDescriptors.emplace_back(TaskgroupDescriptor); 14239 } 14240 }; 14241 } // namespace 14242 14243 static bool checkOMPArraySectionConstantForReduction( 14244 ASTContext &Context, const OMPArraySectionExpr *OASE, bool &SingleElement, 14245 SmallVectorImpl<llvm::APSInt> &ArraySizes) { 14246 const Expr *Length = OASE->getLength(); 14247 if (Length == nullptr) { 14248 // For array sections of the form [1:] or [:], we would need to analyze 14249 // the lower bound... 14250 if (OASE->getColonLoc().isValid()) 14251 return false; 14252 14253 // This is an array subscript which has implicit length 1! 14254 SingleElement = true; 14255 ArraySizes.push_back(llvm::APSInt::get(1)); 14256 } else { 14257 Expr::EvalResult Result; 14258 if (!Length->EvaluateAsInt(Result, Context)) 14259 return false; 14260 14261 llvm::APSInt ConstantLengthValue = Result.Val.getInt(); 14262 SingleElement = (ConstantLengthValue.getSExtValue() == 1); 14263 ArraySizes.push_back(ConstantLengthValue); 14264 } 14265 14266 // Get the base of this array section and walk up from there. 14267 const Expr *Base = OASE->getBase()->IgnoreParenImpCasts(); 14268 14269 // We require length = 1 for all array sections except the right-most to 14270 // guarantee that the memory region is contiguous and has no holes in it. 14271 while (const auto *TempOASE = dyn_cast<OMPArraySectionExpr>(Base)) { 14272 Length = TempOASE->getLength(); 14273 if (Length == nullptr) { 14274 // For array sections of the form [1:] or [:], we would need to analyze 14275 // the lower bound... 14276 if (OASE->getColonLoc().isValid()) 14277 return false; 14278 14279 // This is an array subscript which has implicit length 1! 14280 ArraySizes.push_back(llvm::APSInt::get(1)); 14281 } else { 14282 Expr::EvalResult Result; 14283 if (!Length->EvaluateAsInt(Result, Context)) 14284 return false; 14285 14286 llvm::APSInt ConstantLengthValue = Result.Val.getInt(); 14287 if (ConstantLengthValue.getSExtValue() != 1) 14288 return false; 14289 14290 ArraySizes.push_back(ConstantLengthValue); 14291 } 14292 Base = TempOASE->getBase()->IgnoreParenImpCasts(); 14293 } 14294 14295 // If we have a single element, we don't need to add the implicit lengths. 14296 if (!SingleElement) { 14297 while (const auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base)) { 14298 // Has implicit length 1! 14299 ArraySizes.push_back(llvm::APSInt::get(1)); 14300 Base = TempASE->getBase()->IgnoreParenImpCasts(); 14301 } 14302 } 14303 14304 // This array section can be privatized as a single value or as a constant 14305 // sized array. 14306 return true; 14307 } 14308 14309 static bool actOnOMPReductionKindClause( 14310 Sema &S, DSAStackTy *Stack, OpenMPClauseKind ClauseKind, 14311 ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, 14312 SourceLocation ColonLoc, SourceLocation EndLoc, 14313 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, 14314 ArrayRef<Expr *> UnresolvedReductions, ReductionData &RD) { 14315 DeclarationName DN = ReductionId.getName(); 14316 OverloadedOperatorKind OOK = DN.getCXXOverloadedOperator(); 14317 BinaryOperatorKind BOK = BO_Comma; 14318 14319 ASTContext &Context = S.Context; 14320 // OpenMP [2.14.3.6, reduction clause] 14321 // C 14322 // reduction-identifier is either an identifier or one of the following 14323 // operators: +, -, *, &, |, ^, && and || 14324 // C++ 14325 // reduction-identifier is either an id-expression or one of the following 14326 // operators: +, -, *, &, |, ^, && and || 14327 switch (OOK) { 14328 case OO_Plus: 14329 case OO_Minus: 14330 BOK = BO_Add; 14331 break; 14332 case OO_Star: 14333 BOK = BO_Mul; 14334 break; 14335 case OO_Amp: 14336 BOK = BO_And; 14337 break; 14338 case OO_Pipe: 14339 BOK = BO_Or; 14340 break; 14341 case OO_Caret: 14342 BOK = BO_Xor; 14343 break; 14344 case OO_AmpAmp: 14345 BOK = BO_LAnd; 14346 break; 14347 case OO_PipePipe: 14348 BOK = BO_LOr; 14349 break; 14350 case OO_New: 14351 case OO_Delete: 14352 case OO_Array_New: 14353 case OO_Array_Delete: 14354 case OO_Slash: 14355 case OO_Percent: 14356 case OO_Tilde: 14357 case OO_Exclaim: 14358 case OO_Equal: 14359 case OO_Less: 14360 case OO_Greater: 14361 case OO_LessEqual: 14362 case OO_GreaterEqual: 14363 case OO_PlusEqual: 14364 case OO_MinusEqual: 14365 case OO_StarEqual: 14366 case OO_SlashEqual: 14367 case OO_PercentEqual: 14368 case OO_CaretEqual: 14369 case OO_AmpEqual: 14370 case OO_PipeEqual: 14371 case OO_LessLess: 14372 case OO_GreaterGreater: 14373 case OO_LessLessEqual: 14374 case OO_GreaterGreaterEqual: 14375 case OO_EqualEqual: 14376 case OO_ExclaimEqual: 14377 case OO_Spaceship: 14378 case OO_PlusPlus: 14379 case OO_MinusMinus: 14380 case OO_Comma: 14381 case OO_ArrowStar: 14382 case OO_Arrow: 14383 case OO_Call: 14384 case OO_Subscript: 14385 case OO_Conditional: 14386 case OO_Coawait: 14387 case NUM_OVERLOADED_OPERATORS: 14388 llvm_unreachable("Unexpected reduction identifier"); 14389 case OO_None: 14390 if (IdentifierInfo *II = DN.getAsIdentifierInfo()) { 14391 if (II->isStr("max")) 14392 BOK = BO_GT; 14393 else if (II->isStr("min")) 14394 BOK = BO_LT; 14395 } 14396 break; 14397 } 14398 SourceRange ReductionIdRange; 14399 if (ReductionIdScopeSpec.isValid()) 14400 ReductionIdRange.setBegin(ReductionIdScopeSpec.getBeginLoc()); 14401 else 14402 ReductionIdRange.setBegin(ReductionId.getBeginLoc()); 14403 ReductionIdRange.setEnd(ReductionId.getEndLoc()); 14404 14405 auto IR = UnresolvedReductions.begin(), ER = UnresolvedReductions.end(); 14406 bool FirstIter = true; 14407 for (Expr *RefExpr : VarList) { 14408 assert(RefExpr && "nullptr expr in OpenMP reduction clause."); 14409 // OpenMP [2.1, C/C++] 14410 // A list item is a variable or array section, subject to the restrictions 14411 // specified in Section 2.4 on page 42 and in each of the sections 14412 // describing clauses and directives for which a list appears. 14413 // OpenMP [2.14.3.3, Restrictions, p.1] 14414 // A variable that is part of another variable (as an array or 14415 // structure element) cannot appear in a private clause. 14416 if (!FirstIter && IR != ER) 14417 ++IR; 14418 FirstIter = false; 14419 SourceLocation ELoc; 14420 SourceRange ERange; 14421 Expr *SimpleRefExpr = RefExpr; 14422 auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange, 14423 /*AllowArraySection=*/true); 14424 if (Res.second) { 14425 // Try to find 'declare reduction' corresponding construct before using 14426 // builtin/overloaded operators. 14427 QualType Type = Context.DependentTy; 14428 CXXCastPath BasePath; 14429 ExprResult DeclareReductionRef = buildDeclareReductionRef( 14430 S, ELoc, ERange, Stack->getCurScope(), ReductionIdScopeSpec, 14431 ReductionId, Type, BasePath, IR == ER ? nullptr : *IR); 14432 Expr *ReductionOp = nullptr; 14433 if (S.CurContext->isDependentContext() && 14434 (DeclareReductionRef.isUnset() || 14435 isa<UnresolvedLookupExpr>(DeclareReductionRef.get()))) 14436 ReductionOp = DeclareReductionRef.get(); 14437 // It will be analyzed later. 14438 RD.push(RefExpr, ReductionOp); 14439 } 14440 ValueDecl *D = Res.first; 14441 if (!D) 14442 continue; 14443 14444 Expr *TaskgroupDescriptor = nullptr; 14445 QualType Type; 14446 auto *ASE = dyn_cast<ArraySubscriptExpr>(RefExpr->IgnoreParens()); 14447 auto *OASE = dyn_cast<OMPArraySectionExpr>(RefExpr->IgnoreParens()); 14448 if (ASE) { 14449 Type = ASE->getType().getNonReferenceType(); 14450 } else if (OASE) { 14451 QualType BaseType = 14452 OMPArraySectionExpr::getBaseOriginalType(OASE->getBase()); 14453 if (const auto *ATy = BaseType->getAsArrayTypeUnsafe()) 14454 Type = ATy->getElementType(); 14455 else 14456 Type = BaseType->getPointeeType(); 14457 Type = Type.getNonReferenceType(); 14458 } else { 14459 Type = Context.getBaseElementType(D->getType().getNonReferenceType()); 14460 } 14461 auto *VD = dyn_cast<VarDecl>(D); 14462 14463 // OpenMP [2.9.3.3, Restrictions, C/C++, p.3] 14464 // A variable that appears in a private clause must not have an incomplete 14465 // type or a reference type. 14466 if (S.RequireCompleteType(ELoc, D->getType(), 14467 diag::err_omp_reduction_incomplete_type)) 14468 continue; 14469 // OpenMP [2.14.3.6, reduction clause, Restrictions] 14470 // A list item that appears in a reduction clause must not be 14471 // const-qualified. 14472 if (rejectConstNotMutableType(S, D, Type, ClauseKind, ELoc, 14473 /*AcceptIfMutable*/ false, ASE || OASE)) 14474 continue; 14475 14476 OpenMPDirectiveKind CurrDir = Stack->getCurrentDirective(); 14477 // OpenMP [2.9.3.6, Restrictions, C/C++, p.4] 14478 // If a list-item is a reference type then it must bind to the same object 14479 // for all threads of the team. 14480 if (!ASE && !OASE) { 14481 if (VD) { 14482 VarDecl *VDDef = VD->getDefinition(); 14483 if (VD->getType()->isReferenceType() && VDDef && VDDef->hasInit()) { 14484 DSARefChecker Check(Stack); 14485 if (Check.Visit(VDDef->getInit())) { 14486 S.Diag(ELoc, diag::err_omp_reduction_ref_type_arg) 14487 << getOpenMPClauseName(ClauseKind) << ERange; 14488 S.Diag(VDDef->getLocation(), diag::note_defined_here) << VDDef; 14489 continue; 14490 } 14491 } 14492 } 14493 14494 // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables Referenced 14495 // in a Construct] 14496 // Variables with the predetermined data-sharing attributes may not be 14497 // listed in data-sharing attributes clauses, except for the cases 14498 // listed below. For these exceptions only, listing a predetermined 14499 // variable in a data-sharing attribute clause is allowed and overrides 14500 // the variable's predetermined data-sharing attributes. 14501 // OpenMP [2.14.3.6, Restrictions, p.3] 14502 // Any number of reduction clauses can be specified on the directive, 14503 // but a list item can appear only once in the reduction clauses for that 14504 // directive. 14505 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(D, /*FromParent=*/false); 14506 if (DVar.CKind == OMPC_reduction) { 14507 S.Diag(ELoc, diag::err_omp_once_referenced) 14508 << getOpenMPClauseName(ClauseKind); 14509 if (DVar.RefExpr) 14510 S.Diag(DVar.RefExpr->getExprLoc(), diag::note_omp_referenced); 14511 continue; 14512 } 14513 if (DVar.CKind != OMPC_unknown) { 14514 S.Diag(ELoc, diag::err_omp_wrong_dsa) 14515 << getOpenMPClauseName(DVar.CKind) 14516 << getOpenMPClauseName(OMPC_reduction); 14517 reportOriginalDsa(S, Stack, D, DVar); 14518 continue; 14519 } 14520 14521 // OpenMP [2.14.3.6, Restrictions, p.1] 14522 // A list item that appears in a reduction clause of a worksharing 14523 // construct must be shared in the parallel regions to which any of the 14524 // worksharing regions arising from the worksharing construct bind. 14525 if (isOpenMPWorksharingDirective(CurrDir) && 14526 !isOpenMPParallelDirective(CurrDir) && 14527 !isOpenMPTeamsDirective(CurrDir)) { 14528 DVar = Stack->getImplicitDSA(D, true); 14529 if (DVar.CKind != OMPC_shared) { 14530 S.Diag(ELoc, diag::err_omp_required_access) 14531 << getOpenMPClauseName(OMPC_reduction) 14532 << getOpenMPClauseName(OMPC_shared); 14533 reportOriginalDsa(S, Stack, D, DVar); 14534 continue; 14535 } 14536 } 14537 } 14538 14539 // Try to find 'declare reduction' corresponding construct before using 14540 // builtin/overloaded operators. 14541 CXXCastPath BasePath; 14542 ExprResult DeclareReductionRef = buildDeclareReductionRef( 14543 S, ELoc, ERange, Stack->getCurScope(), ReductionIdScopeSpec, 14544 ReductionId, Type, BasePath, IR == ER ? nullptr : *IR); 14545 if (DeclareReductionRef.isInvalid()) 14546 continue; 14547 if (S.CurContext->isDependentContext() && 14548 (DeclareReductionRef.isUnset() || 14549 isa<UnresolvedLookupExpr>(DeclareReductionRef.get()))) { 14550 RD.push(RefExpr, DeclareReductionRef.get()); 14551 continue; 14552 } 14553 if (BOK == BO_Comma && DeclareReductionRef.isUnset()) { 14554 // Not allowed reduction identifier is found. 14555 S.Diag(ReductionId.getBeginLoc(), 14556 diag::err_omp_unknown_reduction_identifier) 14557 << Type << ReductionIdRange; 14558 continue; 14559 } 14560 14561 // OpenMP [2.14.3.6, reduction clause, Restrictions] 14562 // The type of a list item that appears in a reduction clause must be valid 14563 // for the reduction-identifier. For a max or min reduction in C, the type 14564 // of the list item must be an allowed arithmetic data type: char, int, 14565 // float, double, or _Bool, possibly modified with long, short, signed, or 14566 // unsigned. For a max or min reduction in C++, the type of the list item 14567 // must be an allowed arithmetic data type: char, wchar_t, int, float, 14568 // double, or bool, possibly modified with long, short, signed, or unsigned. 14569 if (DeclareReductionRef.isUnset()) { 14570 if ((BOK == BO_GT || BOK == BO_LT) && 14571 !(Type->isScalarType() || 14572 (S.getLangOpts().CPlusPlus && Type->isArithmeticType()))) { 14573 S.Diag(ELoc, diag::err_omp_clause_not_arithmetic_type_arg) 14574 << getOpenMPClauseName(ClauseKind) << S.getLangOpts().CPlusPlus; 14575 if (!ASE && !OASE) { 14576 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) == 14577 VarDecl::DeclarationOnly; 14578 S.Diag(D->getLocation(), 14579 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 14580 << D; 14581 } 14582 continue; 14583 } 14584 if ((BOK == BO_OrAssign || BOK == BO_AndAssign || BOK == BO_XorAssign) && 14585 !S.getLangOpts().CPlusPlus && Type->isFloatingType()) { 14586 S.Diag(ELoc, diag::err_omp_clause_floating_type_arg) 14587 << getOpenMPClauseName(ClauseKind); 14588 if (!ASE && !OASE) { 14589 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) == 14590 VarDecl::DeclarationOnly; 14591 S.Diag(D->getLocation(), 14592 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 14593 << D; 14594 } 14595 continue; 14596 } 14597 } 14598 14599 Type = Type.getNonLValueExprType(Context).getUnqualifiedType(); 14600 VarDecl *LHSVD = buildVarDecl(S, ELoc, Type, ".reduction.lhs", 14601 D->hasAttrs() ? &D->getAttrs() : nullptr); 14602 VarDecl *RHSVD = buildVarDecl(S, ELoc, Type, D->getName(), 14603 D->hasAttrs() ? &D->getAttrs() : nullptr); 14604 QualType PrivateTy = Type; 14605 14606 // Try if we can determine constant lengths for all array sections and avoid 14607 // the VLA. 14608 bool ConstantLengthOASE = false; 14609 if (OASE) { 14610 bool SingleElement; 14611 llvm::SmallVector<llvm::APSInt, 4> ArraySizes; 14612 ConstantLengthOASE = checkOMPArraySectionConstantForReduction( 14613 Context, OASE, SingleElement, ArraySizes); 14614 14615 // If we don't have a single element, we must emit a constant array type. 14616 if (ConstantLengthOASE && !SingleElement) { 14617 for (llvm::APSInt &Size : ArraySizes) 14618 PrivateTy = Context.getConstantArrayType(PrivateTy, Size, nullptr, 14619 ArrayType::Normal, 14620 /*IndexTypeQuals=*/0); 14621 } 14622 } 14623 14624 if ((OASE && !ConstantLengthOASE) || 14625 (!OASE && !ASE && 14626 D->getType().getNonReferenceType()->isVariablyModifiedType())) { 14627 if (!Context.getTargetInfo().isVLASupported()) { 14628 if (isOpenMPTargetExecutionDirective(Stack->getCurrentDirective())) { 14629 S.Diag(ELoc, diag::err_omp_reduction_vla_unsupported) << !!OASE; 14630 S.Diag(ELoc, diag::note_vla_unsupported); 14631 } else { 14632 S.targetDiag(ELoc, diag::err_omp_reduction_vla_unsupported) << !!OASE; 14633 S.targetDiag(ELoc, diag::note_vla_unsupported); 14634 } 14635 continue; 14636 } 14637 // For arrays/array sections only: 14638 // Create pseudo array type for private copy. The size for this array will 14639 // be generated during codegen. 14640 // For array subscripts or single variables Private Ty is the same as Type 14641 // (type of the variable or single array element). 14642 PrivateTy = Context.getVariableArrayType( 14643 Type, 14644 new (Context) OpaqueValueExpr(ELoc, Context.getSizeType(), VK_RValue), 14645 ArrayType::Normal, /*IndexTypeQuals=*/0, SourceRange()); 14646 } else if (!ASE && !OASE && 14647 Context.getAsArrayType(D->getType().getNonReferenceType())) { 14648 PrivateTy = D->getType().getNonReferenceType(); 14649 } 14650 // Private copy. 14651 VarDecl *PrivateVD = 14652 buildVarDecl(S, ELoc, PrivateTy, D->getName(), 14653 D->hasAttrs() ? &D->getAttrs() : nullptr, 14654 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr); 14655 // Add initializer for private variable. 14656 Expr *Init = nullptr; 14657 DeclRefExpr *LHSDRE = buildDeclRefExpr(S, LHSVD, Type, ELoc); 14658 DeclRefExpr *RHSDRE = buildDeclRefExpr(S, RHSVD, Type, ELoc); 14659 if (DeclareReductionRef.isUsable()) { 14660 auto *DRDRef = DeclareReductionRef.getAs<DeclRefExpr>(); 14661 auto *DRD = cast<OMPDeclareReductionDecl>(DRDRef->getDecl()); 14662 if (DRD->getInitializer()) { 14663 Init = DRDRef; 14664 RHSVD->setInit(DRDRef); 14665 RHSVD->setInitStyle(VarDecl::CallInit); 14666 } 14667 } else { 14668 switch (BOK) { 14669 case BO_Add: 14670 case BO_Xor: 14671 case BO_Or: 14672 case BO_LOr: 14673 // '+', '-', '^', '|', '||' reduction ops - initializer is '0'. 14674 if (Type->isScalarType() || Type->isAnyComplexType()) 14675 Init = S.ActOnIntegerConstant(ELoc, /*Val=*/0).get(); 14676 break; 14677 case BO_Mul: 14678 case BO_LAnd: 14679 if (Type->isScalarType() || Type->isAnyComplexType()) { 14680 // '*' and '&&' reduction ops - initializer is '1'. 14681 Init = S.ActOnIntegerConstant(ELoc, /*Val=*/1).get(); 14682 } 14683 break; 14684 case BO_And: { 14685 // '&' reduction op - initializer is '~0'. 14686 QualType OrigType = Type; 14687 if (auto *ComplexTy = OrigType->getAs<ComplexType>()) 14688 Type = ComplexTy->getElementType(); 14689 if (Type->isRealFloatingType()) { 14690 llvm::APFloat InitValue = 14691 llvm::APFloat::getAllOnesValue(Context.getTypeSize(Type), 14692 /*isIEEE=*/true); 14693 Init = FloatingLiteral::Create(Context, InitValue, /*isexact=*/true, 14694 Type, ELoc); 14695 } else if (Type->isScalarType()) { 14696 uint64_t Size = Context.getTypeSize(Type); 14697 QualType IntTy = Context.getIntTypeForBitwidth(Size, /*Signed=*/0); 14698 llvm::APInt InitValue = llvm::APInt::getAllOnesValue(Size); 14699 Init = IntegerLiteral::Create(Context, InitValue, IntTy, ELoc); 14700 } 14701 if (Init && OrigType->isAnyComplexType()) { 14702 // Init = 0xFFFF + 0xFFFFi; 14703 auto *Im = new (Context) ImaginaryLiteral(Init, OrigType); 14704 Init = S.CreateBuiltinBinOp(ELoc, BO_Add, Init, Im).get(); 14705 } 14706 Type = OrigType; 14707 break; 14708 } 14709 case BO_LT: 14710 case BO_GT: { 14711 // 'min' reduction op - initializer is 'Largest representable number in 14712 // the reduction list item type'. 14713 // 'max' reduction op - initializer is 'Least representable number in 14714 // the reduction list item type'. 14715 if (Type->isIntegerType() || Type->isPointerType()) { 14716 bool IsSigned = Type->hasSignedIntegerRepresentation(); 14717 uint64_t Size = Context.getTypeSize(Type); 14718 QualType IntTy = 14719 Context.getIntTypeForBitwidth(Size, /*Signed=*/IsSigned); 14720 llvm::APInt InitValue = 14721 (BOK != BO_LT) ? IsSigned ? llvm::APInt::getSignedMinValue(Size) 14722 : llvm::APInt::getMinValue(Size) 14723 : IsSigned ? llvm::APInt::getSignedMaxValue(Size) 14724 : llvm::APInt::getMaxValue(Size); 14725 Init = IntegerLiteral::Create(Context, InitValue, IntTy, ELoc); 14726 if (Type->isPointerType()) { 14727 // Cast to pointer type. 14728 ExprResult CastExpr = S.BuildCStyleCastExpr( 14729 ELoc, Context.getTrivialTypeSourceInfo(Type, ELoc), ELoc, Init); 14730 if (CastExpr.isInvalid()) 14731 continue; 14732 Init = CastExpr.get(); 14733 } 14734 } else if (Type->isRealFloatingType()) { 14735 llvm::APFloat InitValue = llvm::APFloat::getLargest( 14736 Context.getFloatTypeSemantics(Type), BOK != BO_LT); 14737 Init = FloatingLiteral::Create(Context, InitValue, /*isexact=*/true, 14738 Type, ELoc); 14739 } 14740 break; 14741 } 14742 case BO_PtrMemD: 14743 case BO_PtrMemI: 14744 case BO_MulAssign: 14745 case BO_Div: 14746 case BO_Rem: 14747 case BO_Sub: 14748 case BO_Shl: 14749 case BO_Shr: 14750 case BO_LE: 14751 case BO_GE: 14752 case BO_EQ: 14753 case BO_NE: 14754 case BO_Cmp: 14755 case BO_AndAssign: 14756 case BO_XorAssign: 14757 case BO_OrAssign: 14758 case BO_Assign: 14759 case BO_AddAssign: 14760 case BO_SubAssign: 14761 case BO_DivAssign: 14762 case BO_RemAssign: 14763 case BO_ShlAssign: 14764 case BO_ShrAssign: 14765 case BO_Comma: 14766 llvm_unreachable("Unexpected reduction operation"); 14767 } 14768 } 14769 if (Init && DeclareReductionRef.isUnset()) 14770 S.AddInitializerToDecl(RHSVD, Init, /*DirectInit=*/false); 14771 else if (!Init) 14772 S.ActOnUninitializedDecl(RHSVD); 14773 if (RHSVD->isInvalidDecl()) 14774 continue; 14775 if (!RHSVD->hasInit() && 14776 (DeclareReductionRef.isUnset() || !S.LangOpts.CPlusPlus)) { 14777 S.Diag(ELoc, diag::err_omp_reduction_id_not_compatible) 14778 << Type << ReductionIdRange; 14779 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) == 14780 VarDecl::DeclarationOnly; 14781 S.Diag(D->getLocation(), 14782 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 14783 << D; 14784 continue; 14785 } 14786 // Store initializer for single element in private copy. Will be used during 14787 // codegen. 14788 PrivateVD->setInit(RHSVD->getInit()); 14789 PrivateVD->setInitStyle(RHSVD->getInitStyle()); 14790 DeclRefExpr *PrivateDRE = buildDeclRefExpr(S, PrivateVD, PrivateTy, ELoc); 14791 ExprResult ReductionOp; 14792 if (DeclareReductionRef.isUsable()) { 14793 QualType RedTy = DeclareReductionRef.get()->getType(); 14794 QualType PtrRedTy = Context.getPointerType(RedTy); 14795 ExprResult LHS = S.CreateBuiltinUnaryOp(ELoc, UO_AddrOf, LHSDRE); 14796 ExprResult RHS = S.CreateBuiltinUnaryOp(ELoc, UO_AddrOf, RHSDRE); 14797 if (!BasePath.empty()) { 14798 LHS = S.DefaultLvalueConversion(LHS.get()); 14799 RHS = S.DefaultLvalueConversion(RHS.get()); 14800 LHS = ImplicitCastExpr::Create(Context, PtrRedTy, 14801 CK_UncheckedDerivedToBase, LHS.get(), 14802 &BasePath, LHS.get()->getValueKind()); 14803 RHS = ImplicitCastExpr::Create(Context, PtrRedTy, 14804 CK_UncheckedDerivedToBase, RHS.get(), 14805 &BasePath, RHS.get()->getValueKind()); 14806 } 14807 FunctionProtoType::ExtProtoInfo EPI; 14808 QualType Params[] = {PtrRedTy, PtrRedTy}; 14809 QualType FnTy = Context.getFunctionType(Context.VoidTy, Params, EPI); 14810 auto *OVE = new (Context) OpaqueValueExpr( 14811 ELoc, Context.getPointerType(FnTy), VK_RValue, OK_Ordinary, 14812 S.DefaultLvalueConversion(DeclareReductionRef.get()).get()); 14813 Expr *Args[] = {LHS.get(), RHS.get()}; 14814 ReductionOp = 14815 CallExpr::Create(Context, OVE, Args, Context.VoidTy, VK_RValue, ELoc); 14816 } else { 14817 ReductionOp = S.BuildBinOp( 14818 Stack->getCurScope(), ReductionId.getBeginLoc(), BOK, LHSDRE, RHSDRE); 14819 if (ReductionOp.isUsable()) { 14820 if (BOK != BO_LT && BOK != BO_GT) { 14821 ReductionOp = 14822 S.BuildBinOp(Stack->getCurScope(), ReductionId.getBeginLoc(), 14823 BO_Assign, LHSDRE, ReductionOp.get()); 14824 } else { 14825 auto *ConditionalOp = new (Context) 14826 ConditionalOperator(ReductionOp.get(), ELoc, LHSDRE, ELoc, RHSDRE, 14827 Type, VK_LValue, OK_Ordinary); 14828 ReductionOp = 14829 S.BuildBinOp(Stack->getCurScope(), ReductionId.getBeginLoc(), 14830 BO_Assign, LHSDRE, ConditionalOp); 14831 } 14832 if (ReductionOp.isUsable()) 14833 ReductionOp = S.ActOnFinishFullExpr(ReductionOp.get(), 14834 /*DiscardedValue*/ false); 14835 } 14836 if (!ReductionOp.isUsable()) 14837 continue; 14838 } 14839 14840 // OpenMP [2.15.4.6, Restrictions, p.2] 14841 // A list item that appears in an in_reduction clause of a task construct 14842 // must appear in a task_reduction clause of a construct associated with a 14843 // taskgroup region that includes the participating task in its taskgroup 14844 // set. The construct associated with the innermost region that meets this 14845 // condition must specify the same reduction-identifier as the in_reduction 14846 // clause. 14847 if (ClauseKind == OMPC_in_reduction) { 14848 SourceRange ParentSR; 14849 BinaryOperatorKind ParentBOK; 14850 const Expr *ParentReductionOp = nullptr; 14851 Expr *ParentBOKTD = nullptr, *ParentReductionOpTD = nullptr; 14852 DSAStackTy::DSAVarData ParentBOKDSA = 14853 Stack->getTopMostTaskgroupReductionData(D, ParentSR, ParentBOK, 14854 ParentBOKTD); 14855 DSAStackTy::DSAVarData ParentReductionOpDSA = 14856 Stack->getTopMostTaskgroupReductionData( 14857 D, ParentSR, ParentReductionOp, ParentReductionOpTD); 14858 bool IsParentBOK = ParentBOKDSA.DKind != OMPD_unknown; 14859 bool IsParentReductionOp = ParentReductionOpDSA.DKind != OMPD_unknown; 14860 if ((DeclareReductionRef.isUnset() && IsParentReductionOp) || 14861 (DeclareReductionRef.isUsable() && IsParentBOK) || 14862 (IsParentBOK && BOK != ParentBOK) || IsParentReductionOp) { 14863 bool EmitError = true; 14864 if (IsParentReductionOp && DeclareReductionRef.isUsable()) { 14865 llvm::FoldingSetNodeID RedId, ParentRedId; 14866 ParentReductionOp->Profile(ParentRedId, Context, /*Canonical=*/true); 14867 DeclareReductionRef.get()->Profile(RedId, Context, 14868 /*Canonical=*/true); 14869 EmitError = RedId != ParentRedId; 14870 } 14871 if (EmitError) { 14872 S.Diag(ReductionId.getBeginLoc(), 14873 diag::err_omp_reduction_identifier_mismatch) 14874 << ReductionIdRange << RefExpr->getSourceRange(); 14875 S.Diag(ParentSR.getBegin(), 14876 diag::note_omp_previous_reduction_identifier) 14877 << ParentSR 14878 << (IsParentBOK ? ParentBOKDSA.RefExpr 14879 : ParentReductionOpDSA.RefExpr) 14880 ->getSourceRange(); 14881 continue; 14882 } 14883 } 14884 TaskgroupDescriptor = IsParentBOK ? ParentBOKTD : ParentReductionOpTD; 14885 } 14886 14887 DeclRefExpr *Ref = nullptr; 14888 Expr *VarsExpr = RefExpr->IgnoreParens(); 14889 if (!VD && !S.CurContext->isDependentContext()) { 14890 if (ASE || OASE) { 14891 TransformExprToCaptures RebuildToCapture(S, D); 14892 VarsExpr = 14893 RebuildToCapture.TransformExpr(RefExpr->IgnoreParens()).get(); 14894 Ref = RebuildToCapture.getCapturedExpr(); 14895 } else { 14896 VarsExpr = Ref = buildCapture(S, D, SimpleRefExpr, /*WithInit=*/false); 14897 } 14898 if (!S.isOpenMPCapturedDecl(D)) { 14899 RD.ExprCaptures.emplace_back(Ref->getDecl()); 14900 if (Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>()) { 14901 ExprResult RefRes = S.DefaultLvalueConversion(Ref); 14902 if (!RefRes.isUsable()) 14903 continue; 14904 ExprResult PostUpdateRes = 14905 S.BuildBinOp(Stack->getCurScope(), ELoc, BO_Assign, SimpleRefExpr, 14906 RefRes.get()); 14907 if (!PostUpdateRes.isUsable()) 14908 continue; 14909 if (isOpenMPTaskingDirective(Stack->getCurrentDirective()) || 14910 Stack->getCurrentDirective() == OMPD_taskgroup) { 14911 S.Diag(RefExpr->getExprLoc(), 14912 diag::err_omp_reduction_non_addressable_expression) 14913 << RefExpr->getSourceRange(); 14914 continue; 14915 } 14916 RD.ExprPostUpdates.emplace_back( 14917 S.IgnoredValueConversions(PostUpdateRes.get()).get()); 14918 } 14919 } 14920 } 14921 // All reduction items are still marked as reduction (to do not increase 14922 // code base size). 14923 Stack->addDSA(D, RefExpr->IgnoreParens(), OMPC_reduction, Ref, 14924 RD.RedModifier); 14925 if (CurrDir == OMPD_taskgroup) { 14926 if (DeclareReductionRef.isUsable()) 14927 Stack->addTaskgroupReductionData(D, ReductionIdRange, 14928 DeclareReductionRef.get()); 14929 else 14930 Stack->addTaskgroupReductionData(D, ReductionIdRange, BOK); 14931 } 14932 RD.push(VarsExpr, PrivateDRE, LHSDRE, RHSDRE, ReductionOp.get(), 14933 TaskgroupDescriptor); 14934 } 14935 return RD.Vars.empty(); 14936 } 14937 14938 OMPClause *Sema::ActOnOpenMPReductionClause( 14939 ArrayRef<Expr *> VarList, OpenMPReductionClauseModifier Modifier, 14940 SourceLocation StartLoc, SourceLocation LParenLoc, 14941 SourceLocation ModifierLoc, SourceLocation ColonLoc, SourceLocation EndLoc, 14942 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, 14943 ArrayRef<Expr *> UnresolvedReductions) { 14944 if (ModifierLoc.isValid() && Modifier == OMPC_REDUCTION_unknown) { 14945 Diag(LParenLoc, diag::err_omp_unexpected_clause_value) 14946 << getListOfPossibleValues(OMPC_reduction, /*First=*/0, 14947 /*Last=*/OMPC_REDUCTION_unknown) 14948 << getOpenMPClauseName(OMPC_reduction); 14949 return nullptr; 14950 } 14951 // OpenMP 5.0, 2.19.5.4 reduction Clause, Restrictions 14952 // A reduction clause with the inscan reduction-modifier may only appear on a 14953 // worksharing-loop construct, a worksharing-loop SIMD construct, a simd 14954 // construct, a parallel worksharing-loop construct or a parallel 14955 // worksharing-loop SIMD construct. 14956 if (Modifier == OMPC_REDUCTION_inscan && 14957 (DSAStack->getCurrentDirective() != OMPD_for && 14958 DSAStack->getCurrentDirective() != OMPD_for_simd && 14959 DSAStack->getCurrentDirective() != OMPD_simd && 14960 DSAStack->getCurrentDirective() != OMPD_parallel_for && 14961 DSAStack->getCurrentDirective() != OMPD_parallel_for_simd)) { 14962 Diag(ModifierLoc, diag::err_omp_wrong_inscan_reduction); 14963 return nullptr; 14964 } 14965 14966 ReductionData RD(VarList.size(), Modifier); 14967 if (actOnOMPReductionKindClause(*this, DSAStack, OMPC_reduction, VarList, 14968 StartLoc, LParenLoc, ColonLoc, EndLoc, 14969 ReductionIdScopeSpec, ReductionId, 14970 UnresolvedReductions, RD)) 14971 return nullptr; 14972 14973 return OMPReductionClause::Create( 14974 Context, StartLoc, LParenLoc, ModifierLoc, ColonLoc, EndLoc, Modifier, 14975 RD.Vars, ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId, 14976 RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps, 14977 buildPreInits(Context, RD.ExprCaptures), 14978 buildPostUpdate(*this, RD.ExprPostUpdates)); 14979 } 14980 14981 OMPClause *Sema::ActOnOpenMPTaskReductionClause( 14982 ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, 14983 SourceLocation ColonLoc, SourceLocation EndLoc, 14984 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, 14985 ArrayRef<Expr *> UnresolvedReductions) { 14986 ReductionData RD(VarList.size()); 14987 if (actOnOMPReductionKindClause(*this, DSAStack, OMPC_task_reduction, VarList, 14988 StartLoc, LParenLoc, ColonLoc, EndLoc, 14989 ReductionIdScopeSpec, ReductionId, 14990 UnresolvedReductions, RD)) 14991 return nullptr; 14992 14993 return OMPTaskReductionClause::Create( 14994 Context, StartLoc, LParenLoc, ColonLoc, EndLoc, RD.Vars, 14995 ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId, 14996 RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps, 14997 buildPreInits(Context, RD.ExprCaptures), 14998 buildPostUpdate(*this, RD.ExprPostUpdates)); 14999 } 15000 15001 OMPClause *Sema::ActOnOpenMPInReductionClause( 15002 ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, 15003 SourceLocation ColonLoc, SourceLocation EndLoc, 15004 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, 15005 ArrayRef<Expr *> UnresolvedReductions) { 15006 ReductionData RD(VarList.size()); 15007 if (actOnOMPReductionKindClause(*this, DSAStack, OMPC_in_reduction, VarList, 15008 StartLoc, LParenLoc, ColonLoc, EndLoc, 15009 ReductionIdScopeSpec, ReductionId, 15010 UnresolvedReductions, RD)) 15011 return nullptr; 15012 15013 return OMPInReductionClause::Create( 15014 Context, StartLoc, LParenLoc, ColonLoc, EndLoc, RD.Vars, 15015 ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId, 15016 RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps, RD.TaskgroupDescriptors, 15017 buildPreInits(Context, RD.ExprCaptures), 15018 buildPostUpdate(*this, RD.ExprPostUpdates)); 15019 } 15020 15021 bool Sema::CheckOpenMPLinearModifier(OpenMPLinearClauseKind LinKind, 15022 SourceLocation LinLoc) { 15023 if ((!LangOpts.CPlusPlus && LinKind != OMPC_LINEAR_val) || 15024 LinKind == OMPC_LINEAR_unknown) { 15025 Diag(LinLoc, diag::err_omp_wrong_linear_modifier) << LangOpts.CPlusPlus; 15026 return true; 15027 } 15028 return false; 15029 } 15030 15031 bool Sema::CheckOpenMPLinearDecl(const ValueDecl *D, SourceLocation ELoc, 15032 OpenMPLinearClauseKind LinKind, QualType Type, 15033 bool IsDeclareSimd) { 15034 const auto *VD = dyn_cast_or_null<VarDecl>(D); 15035 // A variable must not have an incomplete type or a reference type. 15036 if (RequireCompleteType(ELoc, Type, diag::err_omp_linear_incomplete_type)) 15037 return true; 15038 if ((LinKind == OMPC_LINEAR_uval || LinKind == OMPC_LINEAR_ref) && 15039 !Type->isReferenceType()) { 15040 Diag(ELoc, diag::err_omp_wrong_linear_modifier_non_reference) 15041 << Type << getOpenMPSimpleClauseTypeName(OMPC_linear, LinKind); 15042 return true; 15043 } 15044 Type = Type.getNonReferenceType(); 15045 15046 // OpenMP 5.0 [2.19.3, List Item Privatization, Restrictions] 15047 // A variable that is privatized must not have a const-qualified type 15048 // unless it is of class type with a mutable member. This restriction does 15049 // not apply to the firstprivate clause, nor to the linear clause on 15050 // declarative directives (like declare simd). 15051 if (!IsDeclareSimd && 15052 rejectConstNotMutableType(*this, D, Type, OMPC_linear, ELoc)) 15053 return true; 15054 15055 // A list item must be of integral or pointer type. 15056 Type = Type.getUnqualifiedType().getCanonicalType(); 15057 const auto *Ty = Type.getTypePtrOrNull(); 15058 if (!Ty || (LinKind != OMPC_LINEAR_ref && !Ty->isDependentType() && 15059 !Ty->isIntegralType(Context) && !Ty->isPointerType())) { 15060 Diag(ELoc, diag::err_omp_linear_expected_int_or_ptr) << Type; 15061 if (D) { 15062 bool IsDecl = 15063 !VD || 15064 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 15065 Diag(D->getLocation(), 15066 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 15067 << D; 15068 } 15069 return true; 15070 } 15071 return false; 15072 } 15073 15074 OMPClause *Sema::ActOnOpenMPLinearClause( 15075 ArrayRef<Expr *> VarList, Expr *Step, SourceLocation StartLoc, 15076 SourceLocation LParenLoc, OpenMPLinearClauseKind LinKind, 15077 SourceLocation LinLoc, SourceLocation ColonLoc, SourceLocation EndLoc) { 15078 SmallVector<Expr *, 8> Vars; 15079 SmallVector<Expr *, 8> Privates; 15080 SmallVector<Expr *, 8> Inits; 15081 SmallVector<Decl *, 4> ExprCaptures; 15082 SmallVector<Expr *, 4> ExprPostUpdates; 15083 if (CheckOpenMPLinearModifier(LinKind, LinLoc)) 15084 LinKind = OMPC_LINEAR_val; 15085 for (Expr *RefExpr : VarList) { 15086 assert(RefExpr && "NULL expr in OpenMP linear clause."); 15087 SourceLocation ELoc; 15088 SourceRange ERange; 15089 Expr *SimpleRefExpr = RefExpr; 15090 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 15091 if (Res.second) { 15092 // It will be analyzed later. 15093 Vars.push_back(RefExpr); 15094 Privates.push_back(nullptr); 15095 Inits.push_back(nullptr); 15096 } 15097 ValueDecl *D = Res.first; 15098 if (!D) 15099 continue; 15100 15101 QualType Type = D->getType(); 15102 auto *VD = dyn_cast<VarDecl>(D); 15103 15104 // OpenMP [2.14.3.7, linear clause] 15105 // A list-item cannot appear in more than one linear clause. 15106 // A list-item that appears in a linear clause cannot appear in any 15107 // other data-sharing attribute clause. 15108 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false); 15109 if (DVar.RefExpr) { 15110 Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind) 15111 << getOpenMPClauseName(OMPC_linear); 15112 reportOriginalDsa(*this, DSAStack, D, DVar); 15113 continue; 15114 } 15115 15116 if (CheckOpenMPLinearDecl(D, ELoc, LinKind, Type)) 15117 continue; 15118 Type = Type.getNonReferenceType().getUnqualifiedType().getCanonicalType(); 15119 15120 // Build private copy of original var. 15121 VarDecl *Private = 15122 buildVarDecl(*this, ELoc, Type, D->getName(), 15123 D->hasAttrs() ? &D->getAttrs() : nullptr, 15124 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr); 15125 DeclRefExpr *PrivateRef = buildDeclRefExpr(*this, Private, Type, ELoc); 15126 // Build var to save initial value. 15127 VarDecl *Init = buildVarDecl(*this, ELoc, Type, ".linear.start"); 15128 Expr *InitExpr; 15129 DeclRefExpr *Ref = nullptr; 15130 if (!VD && !CurContext->isDependentContext()) { 15131 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false); 15132 if (!isOpenMPCapturedDecl(D)) { 15133 ExprCaptures.push_back(Ref->getDecl()); 15134 if (Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>()) { 15135 ExprResult RefRes = DefaultLvalueConversion(Ref); 15136 if (!RefRes.isUsable()) 15137 continue; 15138 ExprResult PostUpdateRes = 15139 BuildBinOp(DSAStack->getCurScope(), ELoc, BO_Assign, 15140 SimpleRefExpr, RefRes.get()); 15141 if (!PostUpdateRes.isUsable()) 15142 continue; 15143 ExprPostUpdates.push_back( 15144 IgnoredValueConversions(PostUpdateRes.get()).get()); 15145 } 15146 } 15147 } 15148 if (LinKind == OMPC_LINEAR_uval) 15149 InitExpr = VD ? VD->getInit() : SimpleRefExpr; 15150 else 15151 InitExpr = VD ? SimpleRefExpr : Ref; 15152 AddInitializerToDecl(Init, DefaultLvalueConversion(InitExpr).get(), 15153 /*DirectInit=*/false); 15154 DeclRefExpr *InitRef = buildDeclRefExpr(*this, Init, Type, ELoc); 15155 15156 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_linear, Ref); 15157 Vars.push_back((VD || CurContext->isDependentContext()) 15158 ? RefExpr->IgnoreParens() 15159 : Ref); 15160 Privates.push_back(PrivateRef); 15161 Inits.push_back(InitRef); 15162 } 15163 15164 if (Vars.empty()) 15165 return nullptr; 15166 15167 Expr *StepExpr = Step; 15168 Expr *CalcStepExpr = nullptr; 15169 if (Step && !Step->isValueDependent() && !Step->isTypeDependent() && 15170 !Step->isInstantiationDependent() && 15171 !Step->containsUnexpandedParameterPack()) { 15172 SourceLocation StepLoc = Step->getBeginLoc(); 15173 ExprResult Val = PerformOpenMPImplicitIntegerConversion(StepLoc, Step); 15174 if (Val.isInvalid()) 15175 return nullptr; 15176 StepExpr = Val.get(); 15177 15178 // Build var to save the step value. 15179 VarDecl *SaveVar = 15180 buildVarDecl(*this, StepLoc, StepExpr->getType(), ".linear.step"); 15181 ExprResult SaveRef = 15182 buildDeclRefExpr(*this, SaveVar, StepExpr->getType(), StepLoc); 15183 ExprResult CalcStep = 15184 BuildBinOp(CurScope, StepLoc, BO_Assign, SaveRef.get(), StepExpr); 15185 CalcStep = ActOnFinishFullExpr(CalcStep.get(), /*DiscardedValue*/ false); 15186 15187 // Warn about zero linear step (it would be probably better specified as 15188 // making corresponding variables 'const'). 15189 llvm::APSInt Result; 15190 bool IsConstant = StepExpr->isIntegerConstantExpr(Result, Context); 15191 if (IsConstant && !Result.isNegative() && !Result.isStrictlyPositive()) 15192 Diag(StepLoc, diag::warn_omp_linear_step_zero) << Vars[0] 15193 << (Vars.size() > 1); 15194 if (!IsConstant && CalcStep.isUsable()) { 15195 // Calculate the step beforehand instead of doing this on each iteration. 15196 // (This is not used if the number of iterations may be kfold-ed). 15197 CalcStepExpr = CalcStep.get(); 15198 } 15199 } 15200 15201 return OMPLinearClause::Create(Context, StartLoc, LParenLoc, LinKind, LinLoc, 15202 ColonLoc, EndLoc, Vars, Privates, Inits, 15203 StepExpr, CalcStepExpr, 15204 buildPreInits(Context, ExprCaptures), 15205 buildPostUpdate(*this, ExprPostUpdates)); 15206 } 15207 15208 static bool FinishOpenMPLinearClause(OMPLinearClause &Clause, DeclRefExpr *IV, 15209 Expr *NumIterations, Sema &SemaRef, 15210 Scope *S, DSAStackTy *Stack) { 15211 // Walk the vars and build update/final expressions for the CodeGen. 15212 SmallVector<Expr *, 8> Updates; 15213 SmallVector<Expr *, 8> Finals; 15214 SmallVector<Expr *, 8> UsedExprs; 15215 Expr *Step = Clause.getStep(); 15216 Expr *CalcStep = Clause.getCalcStep(); 15217 // OpenMP [2.14.3.7, linear clause] 15218 // If linear-step is not specified it is assumed to be 1. 15219 if (!Step) 15220 Step = SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get(); 15221 else if (CalcStep) 15222 Step = cast<BinaryOperator>(CalcStep)->getLHS(); 15223 bool HasErrors = false; 15224 auto CurInit = Clause.inits().begin(); 15225 auto CurPrivate = Clause.privates().begin(); 15226 OpenMPLinearClauseKind LinKind = Clause.getModifier(); 15227 for (Expr *RefExpr : Clause.varlists()) { 15228 SourceLocation ELoc; 15229 SourceRange ERange; 15230 Expr *SimpleRefExpr = RefExpr; 15231 auto Res = getPrivateItem(SemaRef, SimpleRefExpr, ELoc, ERange); 15232 ValueDecl *D = Res.first; 15233 if (Res.second || !D) { 15234 Updates.push_back(nullptr); 15235 Finals.push_back(nullptr); 15236 HasErrors = true; 15237 continue; 15238 } 15239 auto &&Info = Stack->isLoopControlVariable(D); 15240 // OpenMP [2.15.11, distribute simd Construct] 15241 // A list item may not appear in a linear clause, unless it is the loop 15242 // iteration variable. 15243 if (isOpenMPDistributeDirective(Stack->getCurrentDirective()) && 15244 isOpenMPSimdDirective(Stack->getCurrentDirective()) && !Info.first) { 15245 SemaRef.Diag(ELoc, 15246 diag::err_omp_linear_distribute_var_non_loop_iteration); 15247 Updates.push_back(nullptr); 15248 Finals.push_back(nullptr); 15249 HasErrors = true; 15250 continue; 15251 } 15252 Expr *InitExpr = *CurInit; 15253 15254 // Build privatized reference to the current linear var. 15255 auto *DE = cast<DeclRefExpr>(SimpleRefExpr); 15256 Expr *CapturedRef; 15257 if (LinKind == OMPC_LINEAR_uval) 15258 CapturedRef = cast<VarDecl>(DE->getDecl())->getInit(); 15259 else 15260 CapturedRef = 15261 buildDeclRefExpr(SemaRef, cast<VarDecl>(DE->getDecl()), 15262 DE->getType().getUnqualifiedType(), DE->getExprLoc(), 15263 /*RefersToCapture=*/true); 15264 15265 // Build update: Var = InitExpr + IV * Step 15266 ExprResult Update; 15267 if (!Info.first) 15268 Update = buildCounterUpdate( 15269 SemaRef, S, RefExpr->getExprLoc(), *CurPrivate, InitExpr, IV, Step, 15270 /*Subtract=*/false, /*IsNonRectangularLB=*/false); 15271 else 15272 Update = *CurPrivate; 15273 Update = SemaRef.ActOnFinishFullExpr(Update.get(), DE->getBeginLoc(), 15274 /*DiscardedValue*/ false); 15275 15276 // Build final: Var = InitExpr + NumIterations * Step 15277 ExprResult Final; 15278 if (!Info.first) 15279 Final = 15280 buildCounterUpdate(SemaRef, S, RefExpr->getExprLoc(), CapturedRef, 15281 InitExpr, NumIterations, Step, /*Subtract=*/false, 15282 /*IsNonRectangularLB=*/false); 15283 else 15284 Final = *CurPrivate; 15285 Final = SemaRef.ActOnFinishFullExpr(Final.get(), DE->getBeginLoc(), 15286 /*DiscardedValue*/ false); 15287 15288 if (!Update.isUsable() || !Final.isUsable()) { 15289 Updates.push_back(nullptr); 15290 Finals.push_back(nullptr); 15291 UsedExprs.push_back(nullptr); 15292 HasErrors = true; 15293 } else { 15294 Updates.push_back(Update.get()); 15295 Finals.push_back(Final.get()); 15296 if (!Info.first) 15297 UsedExprs.push_back(SimpleRefExpr); 15298 } 15299 ++CurInit; 15300 ++CurPrivate; 15301 } 15302 if (Expr *S = Clause.getStep()) 15303 UsedExprs.push_back(S); 15304 // Fill the remaining part with the nullptr. 15305 UsedExprs.append(Clause.varlist_size() + 1 - UsedExprs.size(), nullptr); 15306 Clause.setUpdates(Updates); 15307 Clause.setFinals(Finals); 15308 Clause.setUsedExprs(UsedExprs); 15309 return HasErrors; 15310 } 15311 15312 OMPClause *Sema::ActOnOpenMPAlignedClause( 15313 ArrayRef<Expr *> VarList, Expr *Alignment, SourceLocation StartLoc, 15314 SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc) { 15315 SmallVector<Expr *, 8> Vars; 15316 for (Expr *RefExpr : VarList) { 15317 assert(RefExpr && "NULL expr in OpenMP linear clause."); 15318 SourceLocation ELoc; 15319 SourceRange ERange; 15320 Expr *SimpleRefExpr = RefExpr; 15321 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 15322 if (Res.second) { 15323 // It will be analyzed later. 15324 Vars.push_back(RefExpr); 15325 } 15326 ValueDecl *D = Res.first; 15327 if (!D) 15328 continue; 15329 15330 QualType QType = D->getType(); 15331 auto *VD = dyn_cast<VarDecl>(D); 15332 15333 // OpenMP [2.8.1, simd construct, Restrictions] 15334 // The type of list items appearing in the aligned clause must be 15335 // array, pointer, reference to array, or reference to pointer. 15336 QType = QType.getNonReferenceType().getUnqualifiedType().getCanonicalType(); 15337 const Type *Ty = QType.getTypePtrOrNull(); 15338 if (!Ty || (!Ty->isArrayType() && !Ty->isPointerType())) { 15339 Diag(ELoc, diag::err_omp_aligned_expected_array_or_ptr) 15340 << QType << getLangOpts().CPlusPlus << ERange; 15341 bool IsDecl = 15342 !VD || 15343 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 15344 Diag(D->getLocation(), 15345 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 15346 << D; 15347 continue; 15348 } 15349 15350 // OpenMP [2.8.1, simd construct, Restrictions] 15351 // A list-item cannot appear in more than one aligned clause. 15352 if (const Expr *PrevRef = DSAStack->addUniqueAligned(D, SimpleRefExpr)) { 15353 Diag(ELoc, diag::err_omp_used_in_clause_twice) 15354 << 0 << getOpenMPClauseName(OMPC_aligned) << ERange; 15355 Diag(PrevRef->getExprLoc(), diag::note_omp_explicit_dsa) 15356 << getOpenMPClauseName(OMPC_aligned); 15357 continue; 15358 } 15359 15360 DeclRefExpr *Ref = nullptr; 15361 if (!VD && isOpenMPCapturedDecl(D)) 15362 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true); 15363 Vars.push_back(DefaultFunctionArrayConversion( 15364 (VD || !Ref) ? RefExpr->IgnoreParens() : Ref) 15365 .get()); 15366 } 15367 15368 // OpenMP [2.8.1, simd construct, Description] 15369 // The parameter of the aligned clause, alignment, must be a constant 15370 // positive integer expression. 15371 // If no optional parameter is specified, implementation-defined default 15372 // alignments for SIMD instructions on the target platforms are assumed. 15373 if (Alignment != nullptr) { 15374 ExprResult AlignResult = 15375 VerifyPositiveIntegerConstantInClause(Alignment, OMPC_aligned); 15376 if (AlignResult.isInvalid()) 15377 return nullptr; 15378 Alignment = AlignResult.get(); 15379 } 15380 if (Vars.empty()) 15381 return nullptr; 15382 15383 return OMPAlignedClause::Create(Context, StartLoc, LParenLoc, ColonLoc, 15384 EndLoc, Vars, Alignment); 15385 } 15386 15387 OMPClause *Sema::ActOnOpenMPCopyinClause(ArrayRef<Expr *> VarList, 15388 SourceLocation StartLoc, 15389 SourceLocation LParenLoc, 15390 SourceLocation EndLoc) { 15391 SmallVector<Expr *, 8> Vars; 15392 SmallVector<Expr *, 8> SrcExprs; 15393 SmallVector<Expr *, 8> DstExprs; 15394 SmallVector<Expr *, 8> AssignmentOps; 15395 for (Expr *RefExpr : VarList) { 15396 assert(RefExpr && "NULL expr in OpenMP copyin clause."); 15397 if (isa<DependentScopeDeclRefExpr>(RefExpr)) { 15398 // It will be analyzed later. 15399 Vars.push_back(RefExpr); 15400 SrcExprs.push_back(nullptr); 15401 DstExprs.push_back(nullptr); 15402 AssignmentOps.push_back(nullptr); 15403 continue; 15404 } 15405 15406 SourceLocation ELoc = RefExpr->getExprLoc(); 15407 // OpenMP [2.1, C/C++] 15408 // A list item is a variable name. 15409 // OpenMP [2.14.4.1, Restrictions, p.1] 15410 // A list item that appears in a copyin clause must be threadprivate. 15411 auto *DE = dyn_cast<DeclRefExpr>(RefExpr); 15412 if (!DE || !isa<VarDecl>(DE->getDecl())) { 15413 Diag(ELoc, diag::err_omp_expected_var_name_member_expr) 15414 << 0 << RefExpr->getSourceRange(); 15415 continue; 15416 } 15417 15418 Decl *D = DE->getDecl(); 15419 auto *VD = cast<VarDecl>(D); 15420 15421 QualType Type = VD->getType(); 15422 if (Type->isDependentType() || Type->isInstantiationDependentType()) { 15423 // It will be analyzed later. 15424 Vars.push_back(DE); 15425 SrcExprs.push_back(nullptr); 15426 DstExprs.push_back(nullptr); 15427 AssignmentOps.push_back(nullptr); 15428 continue; 15429 } 15430 15431 // OpenMP [2.14.4.1, Restrictions, C/C++, p.1] 15432 // A list item that appears in a copyin clause must be threadprivate. 15433 if (!DSAStack->isThreadPrivate(VD)) { 15434 Diag(ELoc, diag::err_omp_required_access) 15435 << getOpenMPClauseName(OMPC_copyin) 15436 << getOpenMPDirectiveName(OMPD_threadprivate); 15437 continue; 15438 } 15439 15440 // OpenMP [2.14.4.1, Restrictions, C/C++, p.2] 15441 // A variable of class type (or array thereof) that appears in a 15442 // copyin clause requires an accessible, unambiguous copy assignment 15443 // operator for the class type. 15444 QualType ElemType = Context.getBaseElementType(Type).getNonReferenceType(); 15445 VarDecl *SrcVD = 15446 buildVarDecl(*this, DE->getBeginLoc(), ElemType.getUnqualifiedType(), 15447 ".copyin.src", VD->hasAttrs() ? &VD->getAttrs() : nullptr); 15448 DeclRefExpr *PseudoSrcExpr = buildDeclRefExpr( 15449 *this, SrcVD, ElemType.getUnqualifiedType(), DE->getExprLoc()); 15450 VarDecl *DstVD = 15451 buildVarDecl(*this, DE->getBeginLoc(), ElemType, ".copyin.dst", 15452 VD->hasAttrs() ? &VD->getAttrs() : nullptr); 15453 DeclRefExpr *PseudoDstExpr = 15454 buildDeclRefExpr(*this, DstVD, ElemType, DE->getExprLoc()); 15455 // For arrays generate assignment operation for single element and replace 15456 // it by the original array element in CodeGen. 15457 ExprResult AssignmentOp = 15458 BuildBinOp(/*S=*/nullptr, DE->getExprLoc(), BO_Assign, PseudoDstExpr, 15459 PseudoSrcExpr); 15460 if (AssignmentOp.isInvalid()) 15461 continue; 15462 AssignmentOp = ActOnFinishFullExpr(AssignmentOp.get(), DE->getExprLoc(), 15463 /*DiscardedValue*/ false); 15464 if (AssignmentOp.isInvalid()) 15465 continue; 15466 15467 DSAStack->addDSA(VD, DE, OMPC_copyin); 15468 Vars.push_back(DE); 15469 SrcExprs.push_back(PseudoSrcExpr); 15470 DstExprs.push_back(PseudoDstExpr); 15471 AssignmentOps.push_back(AssignmentOp.get()); 15472 } 15473 15474 if (Vars.empty()) 15475 return nullptr; 15476 15477 return OMPCopyinClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars, 15478 SrcExprs, DstExprs, AssignmentOps); 15479 } 15480 15481 OMPClause *Sema::ActOnOpenMPCopyprivateClause(ArrayRef<Expr *> VarList, 15482 SourceLocation StartLoc, 15483 SourceLocation LParenLoc, 15484 SourceLocation EndLoc) { 15485 SmallVector<Expr *, 8> Vars; 15486 SmallVector<Expr *, 8> SrcExprs; 15487 SmallVector<Expr *, 8> DstExprs; 15488 SmallVector<Expr *, 8> AssignmentOps; 15489 for (Expr *RefExpr : VarList) { 15490 assert(RefExpr && "NULL expr in OpenMP linear clause."); 15491 SourceLocation ELoc; 15492 SourceRange ERange; 15493 Expr *SimpleRefExpr = RefExpr; 15494 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 15495 if (Res.second) { 15496 // It will be analyzed later. 15497 Vars.push_back(RefExpr); 15498 SrcExprs.push_back(nullptr); 15499 DstExprs.push_back(nullptr); 15500 AssignmentOps.push_back(nullptr); 15501 } 15502 ValueDecl *D = Res.first; 15503 if (!D) 15504 continue; 15505 15506 QualType Type = D->getType(); 15507 auto *VD = dyn_cast<VarDecl>(D); 15508 15509 // OpenMP [2.14.4.2, Restrictions, p.2] 15510 // A list item that appears in a copyprivate clause may not appear in a 15511 // private or firstprivate clause on the single construct. 15512 if (!VD || !DSAStack->isThreadPrivate(VD)) { 15513 DSAStackTy::DSAVarData DVar = 15514 DSAStack->getTopDSA(D, /*FromParent=*/false); 15515 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_copyprivate && 15516 DVar.RefExpr) { 15517 Diag(ELoc, diag::err_omp_wrong_dsa) 15518 << getOpenMPClauseName(DVar.CKind) 15519 << getOpenMPClauseName(OMPC_copyprivate); 15520 reportOriginalDsa(*this, DSAStack, D, DVar); 15521 continue; 15522 } 15523 15524 // OpenMP [2.11.4.2, Restrictions, p.1] 15525 // All list items that appear in a copyprivate clause must be either 15526 // threadprivate or private in the enclosing context. 15527 if (DVar.CKind == OMPC_unknown) { 15528 DVar = DSAStack->getImplicitDSA(D, false); 15529 if (DVar.CKind == OMPC_shared) { 15530 Diag(ELoc, diag::err_omp_required_access) 15531 << getOpenMPClauseName(OMPC_copyprivate) 15532 << "threadprivate or private in the enclosing context"; 15533 reportOriginalDsa(*this, DSAStack, D, DVar); 15534 continue; 15535 } 15536 } 15537 } 15538 15539 // Variably modified types are not supported. 15540 if (!Type->isAnyPointerType() && Type->isVariablyModifiedType()) { 15541 Diag(ELoc, diag::err_omp_variably_modified_type_not_supported) 15542 << getOpenMPClauseName(OMPC_copyprivate) << Type 15543 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 15544 bool IsDecl = 15545 !VD || 15546 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 15547 Diag(D->getLocation(), 15548 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 15549 << D; 15550 continue; 15551 } 15552 15553 // OpenMP [2.14.4.1, Restrictions, C/C++, p.2] 15554 // A variable of class type (or array thereof) that appears in a 15555 // copyin clause requires an accessible, unambiguous copy assignment 15556 // operator for the class type. 15557 Type = Context.getBaseElementType(Type.getNonReferenceType()) 15558 .getUnqualifiedType(); 15559 VarDecl *SrcVD = 15560 buildVarDecl(*this, RefExpr->getBeginLoc(), Type, ".copyprivate.src", 15561 D->hasAttrs() ? &D->getAttrs() : nullptr); 15562 DeclRefExpr *PseudoSrcExpr = buildDeclRefExpr(*this, SrcVD, Type, ELoc); 15563 VarDecl *DstVD = 15564 buildVarDecl(*this, RefExpr->getBeginLoc(), Type, ".copyprivate.dst", 15565 D->hasAttrs() ? &D->getAttrs() : nullptr); 15566 DeclRefExpr *PseudoDstExpr = buildDeclRefExpr(*this, DstVD, Type, ELoc); 15567 ExprResult AssignmentOp = BuildBinOp( 15568 DSAStack->getCurScope(), ELoc, BO_Assign, PseudoDstExpr, PseudoSrcExpr); 15569 if (AssignmentOp.isInvalid()) 15570 continue; 15571 AssignmentOp = 15572 ActOnFinishFullExpr(AssignmentOp.get(), ELoc, /*DiscardedValue*/ false); 15573 if (AssignmentOp.isInvalid()) 15574 continue; 15575 15576 // No need to mark vars as copyprivate, they are already threadprivate or 15577 // implicitly private. 15578 assert(VD || isOpenMPCapturedDecl(D)); 15579 Vars.push_back( 15580 VD ? RefExpr->IgnoreParens() 15581 : buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false)); 15582 SrcExprs.push_back(PseudoSrcExpr); 15583 DstExprs.push_back(PseudoDstExpr); 15584 AssignmentOps.push_back(AssignmentOp.get()); 15585 } 15586 15587 if (Vars.empty()) 15588 return nullptr; 15589 15590 return OMPCopyprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, 15591 Vars, SrcExprs, DstExprs, AssignmentOps); 15592 } 15593 15594 OMPClause *Sema::ActOnOpenMPFlushClause(ArrayRef<Expr *> VarList, 15595 SourceLocation StartLoc, 15596 SourceLocation LParenLoc, 15597 SourceLocation EndLoc) { 15598 if (VarList.empty()) 15599 return nullptr; 15600 15601 return OMPFlushClause::Create(Context, StartLoc, LParenLoc, EndLoc, VarList); 15602 } 15603 15604 /// Tries to find omp_depend_t. type. 15605 static bool findOMPDependT(Sema &S, SourceLocation Loc, DSAStackTy *Stack, 15606 bool Diagnose = true) { 15607 QualType OMPDependT = Stack->getOMPDependT(); 15608 if (!OMPDependT.isNull()) 15609 return true; 15610 IdentifierInfo *II = &S.PP.getIdentifierTable().get("omp_depend_t"); 15611 ParsedType PT = S.getTypeName(*II, Loc, S.getCurScope()); 15612 if (!PT.getAsOpaquePtr() || PT.get().isNull()) { 15613 if (Diagnose) 15614 S.Diag(Loc, diag::err_omp_implied_type_not_found) << "omp_depend_t"; 15615 return false; 15616 } 15617 Stack->setOMPDependT(PT.get()); 15618 return true; 15619 } 15620 15621 OMPClause *Sema::ActOnOpenMPDepobjClause(Expr *Depobj, SourceLocation StartLoc, 15622 SourceLocation LParenLoc, 15623 SourceLocation EndLoc) { 15624 if (!Depobj) 15625 return nullptr; 15626 15627 bool OMPDependTFound = findOMPDependT(*this, StartLoc, DSAStack); 15628 15629 // OpenMP 5.0, 2.17.10.1 depobj Construct 15630 // depobj is an lvalue expression of type omp_depend_t. 15631 if (!Depobj->isTypeDependent() && !Depobj->isValueDependent() && 15632 !Depobj->isInstantiationDependent() && 15633 !Depobj->containsUnexpandedParameterPack() && 15634 (OMPDependTFound && 15635 !Context.typesAreCompatible(DSAStack->getOMPDependT(), Depobj->getType(), 15636 /*CompareUnqualified=*/true))) { 15637 Diag(Depobj->getExprLoc(), diag::err_omp_expected_omp_depend_t_lvalue) 15638 << 0 << Depobj->getType() << Depobj->getSourceRange(); 15639 } 15640 15641 if (!Depobj->isLValue()) { 15642 Diag(Depobj->getExprLoc(), diag::err_omp_expected_omp_depend_t_lvalue) 15643 << 1 << Depobj->getSourceRange(); 15644 } 15645 15646 return OMPDepobjClause::Create(Context, StartLoc, LParenLoc, EndLoc, Depobj); 15647 } 15648 15649 OMPClause * 15650 Sema::ActOnOpenMPDependClause(Expr *DepModifier, OpenMPDependClauseKind DepKind, 15651 SourceLocation DepLoc, SourceLocation ColonLoc, 15652 ArrayRef<Expr *> VarList, SourceLocation StartLoc, 15653 SourceLocation LParenLoc, SourceLocation EndLoc) { 15654 if (DSAStack->getCurrentDirective() == OMPD_ordered && 15655 DepKind != OMPC_DEPEND_source && DepKind != OMPC_DEPEND_sink) { 15656 Diag(DepLoc, diag::err_omp_unexpected_clause_value) 15657 << "'source' or 'sink'" << getOpenMPClauseName(OMPC_depend); 15658 return nullptr; 15659 } 15660 if ((DSAStack->getCurrentDirective() != OMPD_ordered || 15661 DSAStack->getCurrentDirective() == OMPD_depobj) && 15662 (DepKind == OMPC_DEPEND_unknown || DepKind == OMPC_DEPEND_source || 15663 DepKind == OMPC_DEPEND_sink || 15664 ((LangOpts.OpenMP < 50 || 15665 DSAStack->getCurrentDirective() == OMPD_depobj) && 15666 DepKind == OMPC_DEPEND_depobj))) { 15667 SmallVector<unsigned, 3> Except; 15668 Except.push_back(OMPC_DEPEND_source); 15669 Except.push_back(OMPC_DEPEND_sink); 15670 if (LangOpts.OpenMP < 50 || DSAStack->getCurrentDirective() == OMPD_depobj) 15671 Except.push_back(OMPC_DEPEND_depobj); 15672 std::string Expected = (LangOpts.OpenMP >= 50 && !DepModifier) 15673 ? "depend modifier(iterator) or " 15674 : ""; 15675 Diag(DepLoc, diag::err_omp_unexpected_clause_value) 15676 << Expected + getListOfPossibleValues(OMPC_depend, /*First=*/0, 15677 /*Last=*/OMPC_DEPEND_unknown, 15678 Except) 15679 << getOpenMPClauseName(OMPC_depend); 15680 return nullptr; 15681 } 15682 if (DepModifier && 15683 (DepKind == OMPC_DEPEND_source || DepKind == OMPC_DEPEND_sink)) { 15684 Diag(DepModifier->getExprLoc(), 15685 diag::err_omp_depend_sink_source_with_modifier); 15686 return nullptr; 15687 } 15688 if (DepModifier && 15689 !DepModifier->getType()->isSpecificBuiltinType(BuiltinType::OMPIterator)) 15690 Diag(DepModifier->getExprLoc(), diag::err_omp_depend_modifier_not_iterator); 15691 15692 SmallVector<Expr *, 8> Vars; 15693 DSAStackTy::OperatorOffsetTy OpsOffs; 15694 llvm::APSInt DepCounter(/*BitWidth=*/32); 15695 llvm::APSInt TotalDepCount(/*BitWidth=*/32); 15696 if (DepKind == OMPC_DEPEND_sink || DepKind == OMPC_DEPEND_source) { 15697 if (const Expr *OrderedCountExpr = 15698 DSAStack->getParentOrderedRegionParam().first) { 15699 TotalDepCount = OrderedCountExpr->EvaluateKnownConstInt(Context); 15700 TotalDepCount.setIsUnsigned(/*Val=*/true); 15701 } 15702 } 15703 for (Expr *RefExpr : VarList) { 15704 assert(RefExpr && "NULL expr in OpenMP shared clause."); 15705 if (isa<DependentScopeDeclRefExpr>(RefExpr)) { 15706 // It will be analyzed later. 15707 Vars.push_back(RefExpr); 15708 continue; 15709 } 15710 15711 SourceLocation ELoc = RefExpr->getExprLoc(); 15712 Expr *SimpleExpr = RefExpr->IgnoreParenCasts(); 15713 if (DepKind == OMPC_DEPEND_sink) { 15714 if (DSAStack->getParentOrderedRegionParam().first && 15715 DepCounter >= TotalDepCount) { 15716 Diag(ELoc, diag::err_omp_depend_sink_unexpected_expr); 15717 continue; 15718 } 15719 ++DepCounter; 15720 // OpenMP [2.13.9, Summary] 15721 // depend(dependence-type : vec), where dependence-type is: 15722 // 'sink' and where vec is the iteration vector, which has the form: 15723 // x1 [+- d1], x2 [+- d2 ], . . . , xn [+- dn] 15724 // where n is the value specified by the ordered clause in the loop 15725 // directive, xi denotes the loop iteration variable of the i-th nested 15726 // loop associated with the loop directive, and di is a constant 15727 // non-negative integer. 15728 if (CurContext->isDependentContext()) { 15729 // It will be analyzed later. 15730 Vars.push_back(RefExpr); 15731 continue; 15732 } 15733 SimpleExpr = SimpleExpr->IgnoreImplicit(); 15734 OverloadedOperatorKind OOK = OO_None; 15735 SourceLocation OOLoc; 15736 Expr *LHS = SimpleExpr; 15737 Expr *RHS = nullptr; 15738 if (auto *BO = dyn_cast<BinaryOperator>(SimpleExpr)) { 15739 OOK = BinaryOperator::getOverloadedOperator(BO->getOpcode()); 15740 OOLoc = BO->getOperatorLoc(); 15741 LHS = BO->getLHS()->IgnoreParenImpCasts(); 15742 RHS = BO->getRHS()->IgnoreParenImpCasts(); 15743 } else if (auto *OCE = dyn_cast<CXXOperatorCallExpr>(SimpleExpr)) { 15744 OOK = OCE->getOperator(); 15745 OOLoc = OCE->getOperatorLoc(); 15746 LHS = OCE->getArg(/*Arg=*/0)->IgnoreParenImpCasts(); 15747 RHS = OCE->getArg(/*Arg=*/1)->IgnoreParenImpCasts(); 15748 } else if (auto *MCE = dyn_cast<CXXMemberCallExpr>(SimpleExpr)) { 15749 OOK = MCE->getMethodDecl() 15750 ->getNameInfo() 15751 .getName() 15752 .getCXXOverloadedOperator(); 15753 OOLoc = MCE->getCallee()->getExprLoc(); 15754 LHS = MCE->getImplicitObjectArgument()->IgnoreParenImpCasts(); 15755 RHS = MCE->getArg(/*Arg=*/0)->IgnoreParenImpCasts(); 15756 } 15757 SourceLocation ELoc; 15758 SourceRange ERange; 15759 auto Res = getPrivateItem(*this, LHS, ELoc, ERange); 15760 if (Res.second) { 15761 // It will be analyzed later. 15762 Vars.push_back(RefExpr); 15763 } 15764 ValueDecl *D = Res.first; 15765 if (!D) 15766 continue; 15767 15768 if (OOK != OO_Plus && OOK != OO_Minus && (RHS || OOK != OO_None)) { 15769 Diag(OOLoc, diag::err_omp_depend_sink_expected_plus_minus); 15770 continue; 15771 } 15772 if (RHS) { 15773 ExprResult RHSRes = VerifyPositiveIntegerConstantInClause( 15774 RHS, OMPC_depend, /*StrictlyPositive=*/false); 15775 if (RHSRes.isInvalid()) 15776 continue; 15777 } 15778 if (!CurContext->isDependentContext() && 15779 DSAStack->getParentOrderedRegionParam().first && 15780 DepCounter != DSAStack->isParentLoopControlVariable(D).first) { 15781 const ValueDecl *VD = 15782 DSAStack->getParentLoopControlVariable(DepCounter.getZExtValue()); 15783 if (VD) 15784 Diag(ELoc, diag::err_omp_depend_sink_expected_loop_iteration) 15785 << 1 << VD; 15786 else 15787 Diag(ELoc, diag::err_omp_depend_sink_expected_loop_iteration) << 0; 15788 continue; 15789 } 15790 OpsOffs.emplace_back(RHS, OOK); 15791 } else { 15792 bool OMPDependTFound = LangOpts.OpenMP >= 50; 15793 if (OMPDependTFound) 15794 OMPDependTFound = findOMPDependT(*this, StartLoc, DSAStack, 15795 DepKind == OMPC_DEPEND_depobj); 15796 if (DepKind == OMPC_DEPEND_depobj) { 15797 // OpenMP 5.0, 2.17.11 depend Clause, Restrictions, C/C++ 15798 // List items used in depend clauses with the depobj dependence type 15799 // must be expressions of the omp_depend_t type. 15800 if (!RefExpr->isValueDependent() && !RefExpr->isTypeDependent() && 15801 !RefExpr->isInstantiationDependent() && 15802 !RefExpr->containsUnexpandedParameterPack() && 15803 (OMPDependTFound && 15804 !Context.hasSameUnqualifiedType(DSAStack->getOMPDependT(), 15805 RefExpr->getType()))) { 15806 Diag(ELoc, diag::err_omp_expected_omp_depend_t_lvalue) 15807 << 0 << RefExpr->getType() << RefExpr->getSourceRange(); 15808 continue; 15809 } 15810 if (!RefExpr->isLValue()) { 15811 Diag(ELoc, diag::err_omp_expected_omp_depend_t_lvalue) 15812 << 1 << RefExpr->getType() << RefExpr->getSourceRange(); 15813 continue; 15814 } 15815 } else { 15816 // OpenMP 5.0 [2.17.11, Restrictions] 15817 // List items used in depend clauses cannot be zero-length array 15818 // sections. 15819 QualType ExprTy = RefExpr->getType().getNonReferenceType(); 15820 const auto *OASE = dyn_cast<OMPArraySectionExpr>(SimpleExpr); 15821 if (OASE) { 15822 QualType BaseType = 15823 OMPArraySectionExpr::getBaseOriginalType(OASE->getBase()); 15824 if (const auto *ATy = BaseType->getAsArrayTypeUnsafe()) 15825 ExprTy = ATy->getElementType(); 15826 else 15827 ExprTy = BaseType->getPointeeType(); 15828 ExprTy = ExprTy.getNonReferenceType(); 15829 const Expr *Length = OASE->getLength(); 15830 Expr::EvalResult Result; 15831 if (Length && !Length->isValueDependent() && 15832 Length->EvaluateAsInt(Result, Context) && 15833 Result.Val.getInt().isNullValue()) { 15834 Diag(ELoc, 15835 diag::err_omp_depend_zero_length_array_section_not_allowed) 15836 << SimpleExpr->getSourceRange(); 15837 continue; 15838 } 15839 } 15840 15841 // OpenMP 5.0, 2.17.11 depend Clause, Restrictions, C/C++ 15842 // List items used in depend clauses with the in, out, inout or 15843 // mutexinoutset dependence types cannot be expressions of the 15844 // omp_depend_t type. 15845 if (!RefExpr->isValueDependent() && !RefExpr->isTypeDependent() && 15846 !RefExpr->isInstantiationDependent() && 15847 !RefExpr->containsUnexpandedParameterPack() && 15848 (OMPDependTFound && 15849 DSAStack->getOMPDependT().getTypePtr() == ExprTy.getTypePtr())) { 15850 Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item) 15851 << (LangOpts.OpenMP >= 50 ? 1 : 0) << 1 15852 << RefExpr->getSourceRange(); 15853 continue; 15854 } 15855 15856 auto *ASE = dyn_cast<ArraySubscriptExpr>(SimpleExpr); 15857 if (!RefExpr->IgnoreParenImpCasts()->isLValue() || 15858 (ASE && 15859 !ASE->getBase() 15860 ->getType() 15861 .getNonReferenceType() 15862 ->isPointerType() && 15863 !ASE->getBase()->getType().getNonReferenceType()->isArrayType())) { 15864 Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item) 15865 << (LangOpts.OpenMP >= 50 ? 1 : 0) 15866 << (LangOpts.OpenMP >= 50 ? 1 : 0) << RefExpr->getSourceRange(); 15867 continue; 15868 } 15869 15870 ExprResult Res; 15871 { 15872 Sema::TentativeAnalysisScope Trap(*this); 15873 Res = CreateBuiltinUnaryOp(ELoc, UO_AddrOf, 15874 RefExpr->IgnoreParenImpCasts()); 15875 } 15876 if (!Res.isUsable() && !isa<OMPArraySectionExpr>(SimpleExpr) && 15877 !isa<OMPArrayShapingExpr>(SimpleExpr)) { 15878 Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item) 15879 << (LangOpts.OpenMP >= 50 ? 1 : 0) 15880 << (LangOpts.OpenMP >= 50 ? 1 : 0) << RefExpr->getSourceRange(); 15881 continue; 15882 } 15883 } 15884 } 15885 Vars.push_back(RefExpr->IgnoreParenImpCasts()); 15886 } 15887 15888 if (!CurContext->isDependentContext() && DepKind == OMPC_DEPEND_sink && 15889 TotalDepCount > VarList.size() && 15890 DSAStack->getParentOrderedRegionParam().first && 15891 DSAStack->getParentLoopControlVariable(VarList.size() + 1)) { 15892 Diag(EndLoc, diag::err_omp_depend_sink_expected_loop_iteration) 15893 << 1 << DSAStack->getParentLoopControlVariable(VarList.size() + 1); 15894 } 15895 if (DepKind != OMPC_DEPEND_source && DepKind != OMPC_DEPEND_sink && 15896 Vars.empty()) 15897 return nullptr; 15898 15899 auto *C = OMPDependClause::Create(Context, StartLoc, LParenLoc, EndLoc, 15900 DepModifier, DepKind, DepLoc, ColonLoc, 15901 Vars, TotalDepCount.getZExtValue()); 15902 if ((DepKind == OMPC_DEPEND_sink || DepKind == OMPC_DEPEND_source) && 15903 DSAStack->isParentOrderedRegion()) 15904 DSAStack->addDoacrossDependClause(C, OpsOffs); 15905 return C; 15906 } 15907 15908 OMPClause *Sema::ActOnOpenMPDeviceClause(OpenMPDeviceClauseModifier Modifier, 15909 Expr *Device, SourceLocation StartLoc, 15910 SourceLocation LParenLoc, 15911 SourceLocation ModifierLoc, 15912 SourceLocation EndLoc) { 15913 assert((ModifierLoc.isInvalid() || LangOpts.OpenMP >= 50) && 15914 "Unexpected device modifier in OpenMP < 50."); 15915 15916 bool ErrorFound = false; 15917 if (ModifierLoc.isValid() && Modifier == OMPC_DEVICE_unknown) { 15918 std::string Values = 15919 getListOfPossibleValues(OMPC_device, /*First=*/0, OMPC_DEVICE_unknown); 15920 Diag(ModifierLoc, diag::err_omp_unexpected_clause_value) 15921 << Values << getOpenMPClauseName(OMPC_device); 15922 ErrorFound = true; 15923 } 15924 15925 Expr *ValExpr = Device; 15926 Stmt *HelperValStmt = nullptr; 15927 15928 // OpenMP [2.9.1, Restrictions] 15929 // The device expression must evaluate to a non-negative integer value. 15930 ErrorFound = !isNonNegativeIntegerValue(ValExpr, *this, OMPC_device, 15931 /*StrictlyPositive=*/false) || 15932 ErrorFound; 15933 if (ErrorFound) 15934 return nullptr; 15935 15936 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 15937 OpenMPDirectiveKind CaptureRegion = 15938 getOpenMPCaptureRegionForClause(DKind, OMPC_device, LangOpts.OpenMP); 15939 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 15940 ValExpr = MakeFullExpr(ValExpr).get(); 15941 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 15942 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 15943 HelperValStmt = buildPreInits(Context, Captures); 15944 } 15945 15946 return new (Context) 15947 OMPDeviceClause(Modifier, ValExpr, HelperValStmt, CaptureRegion, StartLoc, 15948 LParenLoc, ModifierLoc, EndLoc); 15949 } 15950 15951 static bool checkTypeMappable(SourceLocation SL, SourceRange SR, Sema &SemaRef, 15952 DSAStackTy *Stack, QualType QTy, 15953 bool FullCheck = true) { 15954 NamedDecl *ND; 15955 if (QTy->isIncompleteType(&ND)) { 15956 SemaRef.Diag(SL, diag::err_incomplete_type) << QTy << SR; 15957 return false; 15958 } 15959 if (FullCheck && !SemaRef.CurContext->isDependentContext() && 15960 !QTy.isTriviallyCopyableType(SemaRef.Context)) 15961 SemaRef.Diag(SL, diag::warn_omp_non_trivial_type_mapped) << QTy << SR; 15962 return true; 15963 } 15964 15965 /// Return true if it can be proven that the provided array expression 15966 /// (array section or array subscript) does NOT specify the whole size of the 15967 /// array whose base type is \a BaseQTy. 15968 static bool checkArrayExpressionDoesNotReferToWholeSize(Sema &SemaRef, 15969 const Expr *E, 15970 QualType BaseQTy) { 15971 const auto *OASE = dyn_cast<OMPArraySectionExpr>(E); 15972 15973 // If this is an array subscript, it refers to the whole size if the size of 15974 // the dimension is constant and equals 1. Also, an array section assumes the 15975 // format of an array subscript if no colon is used. 15976 if (isa<ArraySubscriptExpr>(E) || (OASE && OASE->getColonLoc().isInvalid())) { 15977 if (const auto *ATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr())) 15978 return ATy->getSize().getSExtValue() != 1; 15979 // Size can't be evaluated statically. 15980 return false; 15981 } 15982 15983 assert(OASE && "Expecting array section if not an array subscript."); 15984 const Expr *LowerBound = OASE->getLowerBound(); 15985 const Expr *Length = OASE->getLength(); 15986 15987 // If there is a lower bound that does not evaluates to zero, we are not 15988 // covering the whole dimension. 15989 if (LowerBound) { 15990 Expr::EvalResult Result; 15991 if (!LowerBound->EvaluateAsInt(Result, SemaRef.getASTContext())) 15992 return false; // Can't get the integer value as a constant. 15993 15994 llvm::APSInt ConstLowerBound = Result.Val.getInt(); 15995 if (ConstLowerBound.getSExtValue()) 15996 return true; 15997 } 15998 15999 // If we don't have a length we covering the whole dimension. 16000 if (!Length) 16001 return false; 16002 16003 // If the base is a pointer, we don't have a way to get the size of the 16004 // pointee. 16005 if (BaseQTy->isPointerType()) 16006 return false; 16007 16008 // We can only check if the length is the same as the size of the dimension 16009 // if we have a constant array. 16010 const auto *CATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr()); 16011 if (!CATy) 16012 return false; 16013 16014 Expr::EvalResult Result; 16015 if (!Length->EvaluateAsInt(Result, SemaRef.getASTContext())) 16016 return false; // Can't get the integer value as a constant. 16017 16018 llvm::APSInt ConstLength = Result.Val.getInt(); 16019 return CATy->getSize().getSExtValue() != ConstLength.getSExtValue(); 16020 } 16021 16022 // Return true if it can be proven that the provided array expression (array 16023 // section or array subscript) does NOT specify a single element of the array 16024 // whose base type is \a BaseQTy. 16025 static bool checkArrayExpressionDoesNotReferToUnitySize(Sema &SemaRef, 16026 const Expr *E, 16027 QualType BaseQTy) { 16028 const auto *OASE = dyn_cast<OMPArraySectionExpr>(E); 16029 16030 // An array subscript always refer to a single element. Also, an array section 16031 // assumes the format of an array subscript if no colon is used. 16032 if (isa<ArraySubscriptExpr>(E) || (OASE && OASE->getColonLoc().isInvalid())) 16033 return false; 16034 16035 assert(OASE && "Expecting array section if not an array subscript."); 16036 const Expr *Length = OASE->getLength(); 16037 16038 // If we don't have a length we have to check if the array has unitary size 16039 // for this dimension. Also, we should always expect a length if the base type 16040 // is pointer. 16041 if (!Length) { 16042 if (const auto *ATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr())) 16043 return ATy->getSize().getSExtValue() != 1; 16044 // We cannot assume anything. 16045 return false; 16046 } 16047 16048 // Check if the length evaluates to 1. 16049 Expr::EvalResult Result; 16050 if (!Length->EvaluateAsInt(Result, SemaRef.getASTContext())) 16051 return false; // Can't get the integer value as a constant. 16052 16053 llvm::APSInt ConstLength = Result.Val.getInt(); 16054 return ConstLength.getSExtValue() != 1; 16055 } 16056 16057 // The base of elements of list in a map clause have to be either: 16058 // - a reference to variable or field. 16059 // - a member expression. 16060 // - an array expression. 16061 // 16062 // E.g. if we have the expression 'r.S.Arr[:12]', we want to retrieve the 16063 // reference to 'r'. 16064 // 16065 // If we have: 16066 // 16067 // struct SS { 16068 // Bla S; 16069 // foo() { 16070 // #pragma omp target map (S.Arr[:12]); 16071 // } 16072 // } 16073 // 16074 // We want to retrieve the member expression 'this->S'; 16075 16076 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.2] 16077 // If a list item is an array section, it must specify contiguous storage. 16078 // 16079 // For this restriction it is sufficient that we make sure only references 16080 // to variables or fields and array expressions, and that no array sections 16081 // exist except in the rightmost expression (unless they cover the whole 16082 // dimension of the array). E.g. these would be invalid: 16083 // 16084 // r.ArrS[3:5].Arr[6:7] 16085 // 16086 // r.ArrS[3:5].x 16087 // 16088 // but these would be valid: 16089 // r.ArrS[3].Arr[6:7] 16090 // 16091 // r.ArrS[3].x 16092 namespace { 16093 class MapBaseChecker final : public StmtVisitor<MapBaseChecker, bool> { 16094 Sema &SemaRef; 16095 OpenMPClauseKind CKind = OMPC_unknown; 16096 OMPClauseMappableExprCommon::MappableExprComponentList &Components; 16097 bool NoDiagnose = false; 16098 const Expr *RelevantExpr = nullptr; 16099 bool AllowUnitySizeArraySection = true; 16100 bool AllowWholeSizeArraySection = true; 16101 SourceLocation ELoc; 16102 SourceRange ERange; 16103 16104 void emitErrorMsg() { 16105 // If nothing else worked, this is not a valid map clause expression. 16106 if (SemaRef.getLangOpts().OpenMP < 50) { 16107 SemaRef.Diag(ELoc, 16108 diag::err_omp_expected_named_var_member_or_array_expression) 16109 << ERange; 16110 } else { 16111 SemaRef.Diag(ELoc, diag::err_omp_non_lvalue_in_map_or_motion_clauses) 16112 << getOpenMPClauseName(CKind) << ERange; 16113 } 16114 } 16115 16116 public: 16117 bool VisitDeclRefExpr(DeclRefExpr *DRE) { 16118 if (!isa<VarDecl>(DRE->getDecl())) { 16119 emitErrorMsg(); 16120 return false; 16121 } 16122 assert(!RelevantExpr && "RelevantExpr is expected to be nullptr"); 16123 RelevantExpr = DRE; 16124 // Record the component. 16125 Components.emplace_back(DRE, DRE->getDecl()); 16126 return true; 16127 } 16128 16129 bool VisitMemberExpr(MemberExpr *ME) { 16130 Expr *E = ME; 16131 Expr *BaseE = ME->getBase()->IgnoreParenCasts(); 16132 16133 if (isa<CXXThisExpr>(BaseE)) { 16134 assert(!RelevantExpr && "RelevantExpr is expected to be nullptr"); 16135 // We found a base expression: this->Val. 16136 RelevantExpr = ME; 16137 } else { 16138 E = BaseE; 16139 } 16140 16141 if (!isa<FieldDecl>(ME->getMemberDecl())) { 16142 if (!NoDiagnose) { 16143 SemaRef.Diag(ELoc, diag::err_omp_expected_access_to_data_field) 16144 << ME->getSourceRange(); 16145 return false; 16146 } 16147 if (RelevantExpr) 16148 return false; 16149 return Visit(E); 16150 } 16151 16152 auto *FD = cast<FieldDecl>(ME->getMemberDecl()); 16153 16154 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.3] 16155 // A bit-field cannot appear in a map clause. 16156 // 16157 if (FD->isBitField()) { 16158 if (!NoDiagnose) { 16159 SemaRef.Diag(ELoc, diag::err_omp_bit_fields_forbidden_in_clause) 16160 << ME->getSourceRange() << getOpenMPClauseName(CKind); 16161 return false; 16162 } 16163 if (RelevantExpr) 16164 return false; 16165 return Visit(E); 16166 } 16167 16168 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1] 16169 // If the type of a list item is a reference to a type T then the type 16170 // will be considered to be T for all purposes of this clause. 16171 QualType CurType = BaseE->getType().getNonReferenceType(); 16172 16173 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.2] 16174 // A list item cannot be a variable that is a member of a structure with 16175 // a union type. 16176 // 16177 if (CurType->isUnionType()) { 16178 if (!NoDiagnose) { 16179 SemaRef.Diag(ELoc, diag::err_omp_union_type_not_allowed) 16180 << ME->getSourceRange(); 16181 return false; 16182 } 16183 return RelevantExpr || Visit(E); 16184 } 16185 16186 // If we got a member expression, we should not expect any array section 16187 // before that: 16188 // 16189 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.7] 16190 // If a list item is an element of a structure, only the rightmost symbol 16191 // of the variable reference can be an array section. 16192 // 16193 AllowUnitySizeArraySection = false; 16194 AllowWholeSizeArraySection = false; 16195 16196 // Record the component. 16197 Components.emplace_back(ME, FD); 16198 return RelevantExpr || Visit(E); 16199 } 16200 16201 bool VisitArraySubscriptExpr(ArraySubscriptExpr *AE) { 16202 Expr *E = AE->getBase()->IgnoreParenImpCasts(); 16203 16204 if (!E->getType()->isAnyPointerType() && !E->getType()->isArrayType()) { 16205 if (!NoDiagnose) { 16206 SemaRef.Diag(ELoc, diag::err_omp_expected_base_var_name) 16207 << 0 << AE->getSourceRange(); 16208 return false; 16209 } 16210 return RelevantExpr || Visit(E); 16211 } 16212 16213 // If we got an array subscript that express the whole dimension we 16214 // can have any array expressions before. If it only expressing part of 16215 // the dimension, we can only have unitary-size array expressions. 16216 if (checkArrayExpressionDoesNotReferToWholeSize(SemaRef, AE, 16217 E->getType())) 16218 AllowWholeSizeArraySection = false; 16219 16220 if (const auto *TE = dyn_cast<CXXThisExpr>(E->IgnoreParenCasts())) { 16221 Expr::EvalResult Result; 16222 if (!AE->getIdx()->isValueDependent() && 16223 AE->getIdx()->EvaluateAsInt(Result, SemaRef.getASTContext()) && 16224 !Result.Val.getInt().isNullValue()) { 16225 SemaRef.Diag(AE->getIdx()->getExprLoc(), 16226 diag::err_omp_invalid_map_this_expr); 16227 SemaRef.Diag(AE->getIdx()->getExprLoc(), 16228 diag::note_omp_invalid_subscript_on_this_ptr_map); 16229 } 16230 assert(!RelevantExpr && "RelevantExpr is expected to be nullptr"); 16231 RelevantExpr = TE; 16232 } 16233 16234 // Record the component - we don't have any declaration associated. 16235 Components.emplace_back(AE, nullptr); 16236 16237 return RelevantExpr || Visit(E); 16238 } 16239 16240 bool VisitOMPArraySectionExpr(OMPArraySectionExpr *OASE) { 16241 assert(!NoDiagnose && "Array sections cannot be implicitly mapped."); 16242 Expr *E = OASE->getBase()->IgnoreParenImpCasts(); 16243 QualType CurType = 16244 OMPArraySectionExpr::getBaseOriginalType(E).getCanonicalType(); 16245 16246 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1] 16247 // If the type of a list item is a reference to a type T then the type 16248 // will be considered to be T for all purposes of this clause. 16249 if (CurType->isReferenceType()) 16250 CurType = CurType->getPointeeType(); 16251 16252 bool IsPointer = CurType->isAnyPointerType(); 16253 16254 if (!IsPointer && !CurType->isArrayType()) { 16255 SemaRef.Diag(ELoc, diag::err_omp_expected_base_var_name) 16256 << 0 << OASE->getSourceRange(); 16257 return false; 16258 } 16259 16260 bool NotWhole = 16261 checkArrayExpressionDoesNotReferToWholeSize(SemaRef, OASE, CurType); 16262 bool NotUnity = 16263 checkArrayExpressionDoesNotReferToUnitySize(SemaRef, OASE, CurType); 16264 16265 if (AllowWholeSizeArraySection) { 16266 // Any array section is currently allowed. Allowing a whole size array 16267 // section implies allowing a unity array section as well. 16268 // 16269 // If this array section refers to the whole dimension we can still 16270 // accept other array sections before this one, except if the base is a 16271 // pointer. Otherwise, only unitary sections are accepted. 16272 if (NotWhole || IsPointer) 16273 AllowWholeSizeArraySection = false; 16274 } else if (AllowUnitySizeArraySection && NotUnity) { 16275 // A unity or whole array section is not allowed and that is not 16276 // compatible with the properties of the current array section. 16277 SemaRef.Diag( 16278 ELoc, diag::err_array_section_does_not_specify_contiguous_storage) 16279 << OASE->getSourceRange(); 16280 return false; 16281 } 16282 16283 if (const auto *TE = dyn_cast<CXXThisExpr>(E)) { 16284 Expr::EvalResult ResultR; 16285 Expr::EvalResult ResultL; 16286 if (!OASE->getLength()->isValueDependent() && 16287 OASE->getLength()->EvaluateAsInt(ResultR, SemaRef.getASTContext()) && 16288 !ResultR.Val.getInt().isOneValue()) { 16289 SemaRef.Diag(OASE->getLength()->getExprLoc(), 16290 diag::err_omp_invalid_map_this_expr); 16291 SemaRef.Diag(OASE->getLength()->getExprLoc(), 16292 diag::note_omp_invalid_length_on_this_ptr_mapping); 16293 } 16294 if (OASE->getLowerBound() && !OASE->getLowerBound()->isValueDependent() && 16295 OASE->getLowerBound()->EvaluateAsInt(ResultL, 16296 SemaRef.getASTContext()) && 16297 !ResultL.Val.getInt().isNullValue()) { 16298 SemaRef.Diag(OASE->getLowerBound()->getExprLoc(), 16299 diag::err_omp_invalid_map_this_expr); 16300 SemaRef.Diag(OASE->getLowerBound()->getExprLoc(), 16301 diag::note_omp_invalid_lower_bound_on_this_ptr_mapping); 16302 } 16303 assert(!RelevantExpr && "RelevantExpr is expected to be nullptr"); 16304 RelevantExpr = TE; 16305 } 16306 16307 // Record the component - we don't have any declaration associated. 16308 Components.emplace_back(OASE, nullptr); 16309 return RelevantExpr || Visit(E); 16310 } 16311 bool VisitOMPArrayShapingExpr(OMPArrayShapingExpr *E) { 16312 Expr *Base = E->getBase(); 16313 16314 // Record the component - we don't have any declaration associated. 16315 Components.emplace_back(E, nullptr); 16316 16317 return Visit(Base->IgnoreParenImpCasts()); 16318 } 16319 16320 bool VisitUnaryOperator(UnaryOperator *UO) { 16321 if (SemaRef.getLangOpts().OpenMP < 50 || !UO->isLValue() || 16322 UO->getOpcode() != UO_Deref) { 16323 emitErrorMsg(); 16324 return false; 16325 } 16326 if (!RelevantExpr) { 16327 // Record the component if haven't found base decl. 16328 Components.emplace_back(UO, nullptr); 16329 } 16330 return RelevantExpr || Visit(UO->getSubExpr()->IgnoreParenImpCasts()); 16331 } 16332 bool VisitBinaryOperator(BinaryOperator *BO) { 16333 if (SemaRef.getLangOpts().OpenMP < 50 || !BO->getType()->isPointerType()) { 16334 emitErrorMsg(); 16335 return false; 16336 } 16337 16338 // Pointer arithmetic is the only thing we expect to happen here so after we 16339 // make sure the binary operator is a pointer type, the we only thing need 16340 // to to is to visit the subtree that has the same type as root (so that we 16341 // know the other subtree is just an offset) 16342 Expr *LE = BO->getLHS()->IgnoreParenImpCasts(); 16343 Expr *RE = BO->getRHS()->IgnoreParenImpCasts(); 16344 Components.emplace_back(BO, nullptr); 16345 assert((LE->getType().getTypePtr() == BO->getType().getTypePtr() || 16346 RE->getType().getTypePtr() == BO->getType().getTypePtr()) && 16347 "Either LHS or RHS have base decl inside"); 16348 if (BO->getType().getTypePtr() == LE->getType().getTypePtr()) 16349 return RelevantExpr || Visit(LE); 16350 return RelevantExpr || Visit(RE); 16351 } 16352 bool VisitCXXThisExpr(CXXThisExpr *CTE) { 16353 assert(!RelevantExpr && "RelevantExpr is expected to be nullptr"); 16354 RelevantExpr = CTE; 16355 Components.emplace_back(CTE, nullptr); 16356 return true; 16357 } 16358 bool VisitStmt(Stmt *) { 16359 emitErrorMsg(); 16360 return false; 16361 } 16362 const Expr *getFoundBase() const { 16363 return RelevantExpr; 16364 } 16365 explicit MapBaseChecker( 16366 Sema &SemaRef, OpenMPClauseKind CKind, 16367 OMPClauseMappableExprCommon::MappableExprComponentList &Components, 16368 bool NoDiagnose, SourceLocation &ELoc, SourceRange &ERange) 16369 : SemaRef(SemaRef), CKind(CKind), Components(Components), 16370 NoDiagnose(NoDiagnose), ELoc(ELoc), ERange(ERange) {} 16371 }; 16372 } // namespace 16373 16374 /// Return the expression of the base of the mappable expression or null if it 16375 /// cannot be determined and do all the necessary checks to see if the expression 16376 /// is valid as a standalone mappable expression. In the process, record all the 16377 /// components of the expression. 16378 static const Expr *checkMapClauseExpressionBase( 16379 Sema &SemaRef, Expr *E, 16380 OMPClauseMappableExprCommon::MappableExprComponentList &CurComponents, 16381 OpenMPClauseKind CKind, bool NoDiagnose) { 16382 SourceLocation ELoc = E->getExprLoc(); 16383 SourceRange ERange = E->getSourceRange(); 16384 MapBaseChecker Checker(SemaRef, CKind, CurComponents, NoDiagnose, ELoc, 16385 ERange); 16386 if (Checker.Visit(E->IgnoreParens())) 16387 return Checker.getFoundBase(); 16388 return nullptr; 16389 } 16390 16391 // Return true if expression E associated with value VD has conflicts with other 16392 // map information. 16393 static bool checkMapConflicts( 16394 Sema &SemaRef, DSAStackTy *DSAS, const ValueDecl *VD, const Expr *E, 16395 bool CurrentRegionOnly, 16396 OMPClauseMappableExprCommon::MappableExprComponentListRef CurComponents, 16397 OpenMPClauseKind CKind) { 16398 assert(VD && E); 16399 SourceLocation ELoc = E->getExprLoc(); 16400 SourceRange ERange = E->getSourceRange(); 16401 16402 // In order to easily check the conflicts we need to match each component of 16403 // the expression under test with the components of the expressions that are 16404 // already in the stack. 16405 16406 assert(!CurComponents.empty() && "Map clause expression with no components!"); 16407 assert(CurComponents.back().getAssociatedDeclaration() == VD && 16408 "Map clause expression with unexpected base!"); 16409 16410 // Variables to help detecting enclosing problems in data environment nests. 16411 bool IsEnclosedByDataEnvironmentExpr = false; 16412 const Expr *EnclosingExpr = nullptr; 16413 16414 bool FoundError = DSAS->checkMappableExprComponentListsForDecl( 16415 VD, CurrentRegionOnly, 16416 [&IsEnclosedByDataEnvironmentExpr, &SemaRef, VD, CurrentRegionOnly, ELoc, 16417 ERange, CKind, &EnclosingExpr, 16418 CurComponents](OMPClauseMappableExprCommon::MappableExprComponentListRef 16419 StackComponents, 16420 OpenMPClauseKind) { 16421 assert(!StackComponents.empty() && 16422 "Map clause expression with no components!"); 16423 assert(StackComponents.back().getAssociatedDeclaration() == VD && 16424 "Map clause expression with unexpected base!"); 16425 (void)VD; 16426 16427 // The whole expression in the stack. 16428 const Expr *RE = StackComponents.front().getAssociatedExpression(); 16429 16430 // Expressions must start from the same base. Here we detect at which 16431 // point both expressions diverge from each other and see if we can 16432 // detect if the memory referred to both expressions is contiguous and 16433 // do not overlap. 16434 auto CI = CurComponents.rbegin(); 16435 auto CE = CurComponents.rend(); 16436 auto SI = StackComponents.rbegin(); 16437 auto SE = StackComponents.rend(); 16438 for (; CI != CE && SI != SE; ++CI, ++SI) { 16439 16440 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.3] 16441 // At most one list item can be an array item derived from a given 16442 // variable in map clauses of the same construct. 16443 if (CurrentRegionOnly && 16444 (isa<ArraySubscriptExpr>(CI->getAssociatedExpression()) || 16445 isa<OMPArraySectionExpr>(CI->getAssociatedExpression()) || 16446 isa<OMPArrayShapingExpr>(CI->getAssociatedExpression())) && 16447 (isa<ArraySubscriptExpr>(SI->getAssociatedExpression()) || 16448 isa<OMPArraySectionExpr>(SI->getAssociatedExpression()) || 16449 isa<OMPArrayShapingExpr>(SI->getAssociatedExpression()))) { 16450 SemaRef.Diag(CI->getAssociatedExpression()->getExprLoc(), 16451 diag::err_omp_multiple_array_items_in_map_clause) 16452 << CI->getAssociatedExpression()->getSourceRange(); 16453 SemaRef.Diag(SI->getAssociatedExpression()->getExprLoc(), 16454 diag::note_used_here) 16455 << SI->getAssociatedExpression()->getSourceRange(); 16456 return true; 16457 } 16458 16459 // Do both expressions have the same kind? 16460 if (CI->getAssociatedExpression()->getStmtClass() != 16461 SI->getAssociatedExpression()->getStmtClass()) 16462 break; 16463 16464 // Are we dealing with different variables/fields? 16465 if (CI->getAssociatedDeclaration() != SI->getAssociatedDeclaration()) 16466 break; 16467 } 16468 // Check if the extra components of the expressions in the enclosing 16469 // data environment are redundant for the current base declaration. 16470 // If they are, the maps completely overlap, which is legal. 16471 for (; SI != SE; ++SI) { 16472 QualType Type; 16473 if (const auto *ASE = 16474 dyn_cast<ArraySubscriptExpr>(SI->getAssociatedExpression())) { 16475 Type = ASE->getBase()->IgnoreParenImpCasts()->getType(); 16476 } else if (const auto *OASE = dyn_cast<OMPArraySectionExpr>( 16477 SI->getAssociatedExpression())) { 16478 const Expr *E = OASE->getBase()->IgnoreParenImpCasts(); 16479 Type = 16480 OMPArraySectionExpr::getBaseOriginalType(E).getCanonicalType(); 16481 } else if (const auto *OASE = dyn_cast<OMPArrayShapingExpr>( 16482 SI->getAssociatedExpression())) { 16483 Type = OASE->getBase()->getType()->getPointeeType(); 16484 } 16485 if (Type.isNull() || Type->isAnyPointerType() || 16486 checkArrayExpressionDoesNotReferToWholeSize( 16487 SemaRef, SI->getAssociatedExpression(), Type)) 16488 break; 16489 } 16490 16491 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.4] 16492 // List items of map clauses in the same construct must not share 16493 // original storage. 16494 // 16495 // If the expressions are exactly the same or one is a subset of the 16496 // other, it means they are sharing storage. 16497 if (CI == CE && SI == SE) { 16498 if (CurrentRegionOnly) { 16499 if (CKind == OMPC_map) { 16500 SemaRef.Diag(ELoc, diag::err_omp_map_shared_storage) << ERange; 16501 } else { 16502 assert(CKind == OMPC_to || CKind == OMPC_from); 16503 SemaRef.Diag(ELoc, diag::err_omp_once_referenced_in_target_update) 16504 << ERange; 16505 } 16506 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here) 16507 << RE->getSourceRange(); 16508 return true; 16509 } 16510 // If we find the same expression in the enclosing data environment, 16511 // that is legal. 16512 IsEnclosedByDataEnvironmentExpr = true; 16513 return false; 16514 } 16515 16516 QualType DerivedType = 16517 std::prev(CI)->getAssociatedDeclaration()->getType(); 16518 SourceLocation DerivedLoc = 16519 std::prev(CI)->getAssociatedExpression()->getExprLoc(); 16520 16521 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1] 16522 // If the type of a list item is a reference to a type T then the type 16523 // will be considered to be T for all purposes of this clause. 16524 DerivedType = DerivedType.getNonReferenceType(); 16525 16526 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.1] 16527 // A variable for which the type is pointer and an array section 16528 // derived from that variable must not appear as list items of map 16529 // clauses of the same construct. 16530 // 16531 // Also, cover one of the cases in: 16532 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.5] 16533 // If any part of the original storage of a list item has corresponding 16534 // storage in the device data environment, all of the original storage 16535 // must have corresponding storage in the device data environment. 16536 // 16537 if (DerivedType->isAnyPointerType()) { 16538 if (CI == CE || SI == SE) { 16539 SemaRef.Diag( 16540 DerivedLoc, 16541 diag::err_omp_pointer_mapped_along_with_derived_section) 16542 << DerivedLoc; 16543 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here) 16544 << RE->getSourceRange(); 16545 return true; 16546 } 16547 if (CI->getAssociatedExpression()->getStmtClass() != 16548 SI->getAssociatedExpression()->getStmtClass() || 16549 CI->getAssociatedDeclaration()->getCanonicalDecl() == 16550 SI->getAssociatedDeclaration()->getCanonicalDecl()) { 16551 assert(CI != CE && SI != SE); 16552 SemaRef.Diag(DerivedLoc, diag::err_omp_same_pointer_dereferenced) 16553 << DerivedLoc; 16554 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here) 16555 << RE->getSourceRange(); 16556 return true; 16557 } 16558 } 16559 16560 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.4] 16561 // List items of map clauses in the same construct must not share 16562 // original storage. 16563 // 16564 // An expression is a subset of the other. 16565 if (CurrentRegionOnly && (CI == CE || SI == SE)) { 16566 if (CKind == OMPC_map) { 16567 if (CI != CE || SI != SE) { 16568 // Allow constructs like this: map(s, s.ptr[0:1]), where s.ptr is 16569 // a pointer. 16570 auto Begin = 16571 CI != CE ? CurComponents.begin() : StackComponents.begin(); 16572 auto End = CI != CE ? CurComponents.end() : StackComponents.end(); 16573 auto It = Begin; 16574 while (It != End && !It->getAssociatedDeclaration()) 16575 std::advance(It, 1); 16576 assert(It != End && 16577 "Expected at least one component with the declaration."); 16578 if (It != Begin && It->getAssociatedDeclaration() 16579 ->getType() 16580 .getCanonicalType() 16581 ->isAnyPointerType()) { 16582 IsEnclosedByDataEnvironmentExpr = false; 16583 EnclosingExpr = nullptr; 16584 return false; 16585 } 16586 } 16587 SemaRef.Diag(ELoc, diag::err_omp_map_shared_storage) << ERange; 16588 } else { 16589 assert(CKind == OMPC_to || CKind == OMPC_from); 16590 SemaRef.Diag(ELoc, diag::err_omp_once_referenced_in_target_update) 16591 << ERange; 16592 } 16593 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here) 16594 << RE->getSourceRange(); 16595 return true; 16596 } 16597 16598 // The current expression uses the same base as other expression in the 16599 // data environment but does not contain it completely. 16600 if (!CurrentRegionOnly && SI != SE) 16601 EnclosingExpr = RE; 16602 16603 // The current expression is a subset of the expression in the data 16604 // environment. 16605 IsEnclosedByDataEnvironmentExpr |= 16606 (!CurrentRegionOnly && CI != CE && SI == SE); 16607 16608 return false; 16609 }); 16610 16611 if (CurrentRegionOnly) 16612 return FoundError; 16613 16614 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.5] 16615 // If any part of the original storage of a list item has corresponding 16616 // storage in the device data environment, all of the original storage must 16617 // have corresponding storage in the device data environment. 16618 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.6] 16619 // If a list item is an element of a structure, and a different element of 16620 // the structure has a corresponding list item in the device data environment 16621 // prior to a task encountering the construct associated with the map clause, 16622 // then the list item must also have a corresponding list item in the device 16623 // data environment prior to the task encountering the construct. 16624 // 16625 if (EnclosingExpr && !IsEnclosedByDataEnvironmentExpr) { 16626 SemaRef.Diag(ELoc, 16627 diag::err_omp_original_storage_is_shared_and_does_not_contain) 16628 << ERange; 16629 SemaRef.Diag(EnclosingExpr->getExprLoc(), diag::note_used_here) 16630 << EnclosingExpr->getSourceRange(); 16631 return true; 16632 } 16633 16634 return FoundError; 16635 } 16636 16637 // Look up the user-defined mapper given the mapper name and mapped type, and 16638 // build a reference to it. 16639 static ExprResult buildUserDefinedMapperRef(Sema &SemaRef, Scope *S, 16640 CXXScopeSpec &MapperIdScopeSpec, 16641 const DeclarationNameInfo &MapperId, 16642 QualType Type, 16643 Expr *UnresolvedMapper) { 16644 if (MapperIdScopeSpec.isInvalid()) 16645 return ExprError(); 16646 // Get the actual type for the array type. 16647 if (Type->isArrayType()) { 16648 assert(Type->getAsArrayTypeUnsafe() && "Expect to get a valid array type"); 16649 Type = Type->getAsArrayTypeUnsafe()->getElementType().getCanonicalType(); 16650 } 16651 // Find all user-defined mappers with the given MapperId. 16652 SmallVector<UnresolvedSet<8>, 4> Lookups; 16653 LookupResult Lookup(SemaRef, MapperId, Sema::LookupOMPMapperName); 16654 Lookup.suppressDiagnostics(); 16655 if (S) { 16656 while (S && SemaRef.LookupParsedName(Lookup, S, &MapperIdScopeSpec)) { 16657 NamedDecl *D = Lookup.getRepresentativeDecl(); 16658 while (S && !S->isDeclScope(D)) 16659 S = S->getParent(); 16660 if (S) 16661 S = S->getParent(); 16662 Lookups.emplace_back(); 16663 Lookups.back().append(Lookup.begin(), Lookup.end()); 16664 Lookup.clear(); 16665 } 16666 } else if (auto *ULE = cast_or_null<UnresolvedLookupExpr>(UnresolvedMapper)) { 16667 // Extract the user-defined mappers with the given MapperId. 16668 Lookups.push_back(UnresolvedSet<8>()); 16669 for (NamedDecl *D : ULE->decls()) { 16670 auto *DMD = cast<OMPDeclareMapperDecl>(D); 16671 assert(DMD && "Expect valid OMPDeclareMapperDecl during instantiation."); 16672 Lookups.back().addDecl(DMD); 16673 } 16674 } 16675 // Defer the lookup for dependent types. The results will be passed through 16676 // UnresolvedMapper on instantiation. 16677 if (SemaRef.CurContext->isDependentContext() || Type->isDependentType() || 16678 Type->isInstantiationDependentType() || 16679 Type->containsUnexpandedParameterPack() || 16680 filterLookupForUDReductionAndMapper<bool>(Lookups, [](ValueDecl *D) { 16681 return !D->isInvalidDecl() && 16682 (D->getType()->isDependentType() || 16683 D->getType()->isInstantiationDependentType() || 16684 D->getType()->containsUnexpandedParameterPack()); 16685 })) { 16686 UnresolvedSet<8> URS; 16687 for (const UnresolvedSet<8> &Set : Lookups) { 16688 if (Set.empty()) 16689 continue; 16690 URS.append(Set.begin(), Set.end()); 16691 } 16692 return UnresolvedLookupExpr::Create( 16693 SemaRef.Context, /*NamingClass=*/nullptr, 16694 MapperIdScopeSpec.getWithLocInContext(SemaRef.Context), MapperId, 16695 /*ADL=*/false, /*Overloaded=*/true, URS.begin(), URS.end()); 16696 } 16697 SourceLocation Loc = MapperId.getLoc(); 16698 // [OpenMP 5.0], 2.19.7.3 declare mapper Directive, Restrictions 16699 // The type must be of struct, union or class type in C and C++ 16700 if (!Type->isStructureOrClassType() && !Type->isUnionType() && 16701 (MapperIdScopeSpec.isSet() || MapperId.getAsString() != "default")) { 16702 SemaRef.Diag(Loc, diag::err_omp_mapper_wrong_type); 16703 return ExprError(); 16704 } 16705 // Perform argument dependent lookup. 16706 if (SemaRef.getLangOpts().CPlusPlus && !MapperIdScopeSpec.isSet()) 16707 argumentDependentLookup(SemaRef, MapperId, Loc, Type, Lookups); 16708 // Return the first user-defined mapper with the desired type. 16709 if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>( 16710 Lookups, [&SemaRef, Type](ValueDecl *D) -> ValueDecl * { 16711 if (!D->isInvalidDecl() && 16712 SemaRef.Context.hasSameType(D->getType(), Type)) 16713 return D; 16714 return nullptr; 16715 })) 16716 return SemaRef.BuildDeclRefExpr(VD, Type, VK_LValue, Loc); 16717 // Find the first user-defined mapper with a type derived from the desired 16718 // type. 16719 if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>( 16720 Lookups, [&SemaRef, Type, Loc](ValueDecl *D) -> ValueDecl * { 16721 if (!D->isInvalidDecl() && 16722 SemaRef.IsDerivedFrom(Loc, Type, D->getType()) && 16723 !Type.isMoreQualifiedThan(D->getType())) 16724 return D; 16725 return nullptr; 16726 })) { 16727 CXXBasePaths Paths(/*FindAmbiguities=*/true, /*RecordPaths=*/true, 16728 /*DetectVirtual=*/false); 16729 if (SemaRef.IsDerivedFrom(Loc, Type, VD->getType(), Paths)) { 16730 if (!Paths.isAmbiguous(SemaRef.Context.getCanonicalType( 16731 VD->getType().getUnqualifiedType()))) { 16732 if (SemaRef.CheckBaseClassAccess( 16733 Loc, VD->getType(), Type, Paths.front(), 16734 /*DiagID=*/0) != Sema::AR_inaccessible) { 16735 return SemaRef.BuildDeclRefExpr(VD, Type, VK_LValue, Loc); 16736 } 16737 } 16738 } 16739 } 16740 // Report error if a mapper is specified, but cannot be found. 16741 if (MapperIdScopeSpec.isSet() || MapperId.getAsString() != "default") { 16742 SemaRef.Diag(Loc, diag::err_omp_invalid_mapper) 16743 << Type << MapperId.getName(); 16744 return ExprError(); 16745 } 16746 return ExprEmpty(); 16747 } 16748 16749 namespace { 16750 // Utility struct that gathers all the related lists associated with a mappable 16751 // expression. 16752 struct MappableVarListInfo { 16753 // The list of expressions. 16754 ArrayRef<Expr *> VarList; 16755 // The list of processed expressions. 16756 SmallVector<Expr *, 16> ProcessedVarList; 16757 // The mappble components for each expression. 16758 OMPClauseMappableExprCommon::MappableExprComponentLists VarComponents; 16759 // The base declaration of the variable. 16760 SmallVector<ValueDecl *, 16> VarBaseDeclarations; 16761 // The reference to the user-defined mapper associated with every expression. 16762 SmallVector<Expr *, 16> UDMapperList; 16763 16764 MappableVarListInfo(ArrayRef<Expr *> VarList) : VarList(VarList) { 16765 // We have a list of components and base declarations for each entry in the 16766 // variable list. 16767 VarComponents.reserve(VarList.size()); 16768 VarBaseDeclarations.reserve(VarList.size()); 16769 } 16770 }; 16771 } 16772 16773 // Check the validity of the provided variable list for the provided clause kind 16774 // \a CKind. In the check process the valid expressions, mappable expression 16775 // components, variables, and user-defined mappers are extracted and used to 16776 // fill \a ProcessedVarList, \a VarComponents, \a VarBaseDeclarations, and \a 16777 // UDMapperList in MVLI. \a MapType, \a IsMapTypeImplicit, \a MapperIdScopeSpec, 16778 // and \a MapperId are expected to be valid if the clause kind is 'map'. 16779 static void checkMappableExpressionList( 16780 Sema &SemaRef, DSAStackTy *DSAS, OpenMPClauseKind CKind, 16781 MappableVarListInfo &MVLI, SourceLocation StartLoc, 16782 CXXScopeSpec &MapperIdScopeSpec, DeclarationNameInfo MapperId, 16783 ArrayRef<Expr *> UnresolvedMappers, 16784 OpenMPMapClauseKind MapType = OMPC_MAP_unknown, 16785 bool IsMapTypeImplicit = false) { 16786 // We only expect mappable expressions in 'to', 'from', and 'map' clauses. 16787 assert((CKind == OMPC_map || CKind == OMPC_to || CKind == OMPC_from) && 16788 "Unexpected clause kind with mappable expressions!"); 16789 16790 // If the identifier of user-defined mapper is not specified, it is "default". 16791 // We do not change the actual name in this clause to distinguish whether a 16792 // mapper is specified explicitly, i.e., it is not explicitly specified when 16793 // MapperId.getName() is empty. 16794 if (!MapperId.getName() || MapperId.getName().isEmpty()) { 16795 auto &DeclNames = SemaRef.getASTContext().DeclarationNames; 16796 MapperId.setName(DeclNames.getIdentifier( 16797 &SemaRef.getASTContext().Idents.get("default"))); 16798 } 16799 16800 // Iterators to find the current unresolved mapper expression. 16801 auto UMIt = UnresolvedMappers.begin(), UMEnd = UnresolvedMappers.end(); 16802 bool UpdateUMIt = false; 16803 Expr *UnresolvedMapper = nullptr; 16804 16805 // Keep track of the mappable components and base declarations in this clause. 16806 // Each entry in the list is going to have a list of components associated. We 16807 // record each set of the components so that we can build the clause later on. 16808 // In the end we should have the same amount of declarations and component 16809 // lists. 16810 16811 for (Expr *RE : MVLI.VarList) { 16812 assert(RE && "Null expr in omp to/from/map clause"); 16813 SourceLocation ELoc = RE->getExprLoc(); 16814 16815 // Find the current unresolved mapper expression. 16816 if (UpdateUMIt && UMIt != UMEnd) { 16817 UMIt++; 16818 assert( 16819 UMIt != UMEnd && 16820 "Expect the size of UnresolvedMappers to match with that of VarList"); 16821 } 16822 UpdateUMIt = true; 16823 if (UMIt != UMEnd) 16824 UnresolvedMapper = *UMIt; 16825 16826 const Expr *VE = RE->IgnoreParenLValueCasts(); 16827 16828 if (VE->isValueDependent() || VE->isTypeDependent() || 16829 VE->isInstantiationDependent() || 16830 VE->containsUnexpandedParameterPack()) { 16831 // Try to find the associated user-defined mapper. 16832 ExprResult ER = buildUserDefinedMapperRef( 16833 SemaRef, DSAS->getCurScope(), MapperIdScopeSpec, MapperId, 16834 VE->getType().getCanonicalType(), UnresolvedMapper); 16835 if (ER.isInvalid()) 16836 continue; 16837 MVLI.UDMapperList.push_back(ER.get()); 16838 // We can only analyze this information once the missing information is 16839 // resolved. 16840 MVLI.ProcessedVarList.push_back(RE); 16841 continue; 16842 } 16843 16844 Expr *SimpleExpr = RE->IgnoreParenCasts(); 16845 16846 if (!RE->isLValue()) { 16847 if (SemaRef.getLangOpts().OpenMP < 50) { 16848 SemaRef.Diag( 16849 ELoc, diag::err_omp_expected_named_var_member_or_array_expression) 16850 << RE->getSourceRange(); 16851 } else { 16852 SemaRef.Diag(ELoc, diag::err_omp_non_lvalue_in_map_or_motion_clauses) 16853 << getOpenMPClauseName(CKind) << RE->getSourceRange(); 16854 } 16855 continue; 16856 } 16857 16858 OMPClauseMappableExprCommon::MappableExprComponentList CurComponents; 16859 ValueDecl *CurDeclaration = nullptr; 16860 16861 // Obtain the array or member expression bases if required. Also, fill the 16862 // components array with all the components identified in the process. 16863 const Expr *BE = checkMapClauseExpressionBase( 16864 SemaRef, SimpleExpr, CurComponents, CKind, /*NoDiagnose=*/false); 16865 if (!BE) 16866 continue; 16867 16868 assert(!CurComponents.empty() && 16869 "Invalid mappable expression information."); 16870 16871 if (const auto *TE = dyn_cast<CXXThisExpr>(BE)) { 16872 // Add store "this" pointer to class in DSAStackTy for future checking 16873 DSAS->addMappedClassesQualTypes(TE->getType()); 16874 // Try to find the associated user-defined mapper. 16875 ExprResult ER = buildUserDefinedMapperRef( 16876 SemaRef, DSAS->getCurScope(), MapperIdScopeSpec, MapperId, 16877 VE->getType().getCanonicalType(), UnresolvedMapper); 16878 if (ER.isInvalid()) 16879 continue; 16880 MVLI.UDMapperList.push_back(ER.get()); 16881 // Skip restriction checking for variable or field declarations 16882 MVLI.ProcessedVarList.push_back(RE); 16883 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1); 16884 MVLI.VarComponents.back().append(CurComponents.begin(), 16885 CurComponents.end()); 16886 MVLI.VarBaseDeclarations.push_back(nullptr); 16887 continue; 16888 } 16889 16890 // For the following checks, we rely on the base declaration which is 16891 // expected to be associated with the last component. The declaration is 16892 // expected to be a variable or a field (if 'this' is being mapped). 16893 CurDeclaration = CurComponents.back().getAssociatedDeclaration(); 16894 assert(CurDeclaration && "Null decl on map clause."); 16895 assert( 16896 CurDeclaration->isCanonicalDecl() && 16897 "Expecting components to have associated only canonical declarations."); 16898 16899 auto *VD = dyn_cast<VarDecl>(CurDeclaration); 16900 const auto *FD = dyn_cast<FieldDecl>(CurDeclaration); 16901 16902 assert((VD || FD) && "Only variables or fields are expected here!"); 16903 (void)FD; 16904 16905 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.10] 16906 // threadprivate variables cannot appear in a map clause. 16907 // OpenMP 4.5 [2.10.5, target update Construct] 16908 // threadprivate variables cannot appear in a from clause. 16909 if (VD && DSAS->isThreadPrivate(VD)) { 16910 DSAStackTy::DSAVarData DVar = DSAS->getTopDSA(VD, /*FromParent=*/false); 16911 SemaRef.Diag(ELoc, diag::err_omp_threadprivate_in_clause) 16912 << getOpenMPClauseName(CKind); 16913 reportOriginalDsa(SemaRef, DSAS, VD, DVar); 16914 continue; 16915 } 16916 16917 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.9] 16918 // A list item cannot appear in both a map clause and a data-sharing 16919 // attribute clause on the same construct. 16920 16921 // Check conflicts with other map clause expressions. We check the conflicts 16922 // with the current construct separately from the enclosing data 16923 // environment, because the restrictions are different. We only have to 16924 // check conflicts across regions for the map clauses. 16925 if (checkMapConflicts(SemaRef, DSAS, CurDeclaration, SimpleExpr, 16926 /*CurrentRegionOnly=*/true, CurComponents, CKind)) 16927 break; 16928 if (CKind == OMPC_map && 16929 checkMapConflicts(SemaRef, DSAS, CurDeclaration, SimpleExpr, 16930 /*CurrentRegionOnly=*/false, CurComponents, CKind)) 16931 break; 16932 16933 // OpenMP 4.5 [2.10.5, target update Construct] 16934 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1] 16935 // If the type of a list item is a reference to a type T then the type will 16936 // be considered to be T for all purposes of this clause. 16937 auto I = llvm::find_if( 16938 CurComponents, 16939 [](const OMPClauseMappableExprCommon::MappableComponent &MC) { 16940 return MC.getAssociatedDeclaration(); 16941 }); 16942 assert(I != CurComponents.end() && "Null decl on map clause."); 16943 QualType Type; 16944 auto *ASE = dyn_cast<ArraySubscriptExpr>(VE->IgnoreParens()); 16945 auto *OASE = dyn_cast<OMPArraySectionExpr>(VE->IgnoreParens()); 16946 auto *OAShE = dyn_cast<OMPArrayShapingExpr>(VE->IgnoreParens()); 16947 if (ASE) { 16948 Type = ASE->getType().getNonReferenceType(); 16949 } else if (OASE) { 16950 QualType BaseType = 16951 OMPArraySectionExpr::getBaseOriginalType(OASE->getBase()); 16952 if (const auto *ATy = BaseType->getAsArrayTypeUnsafe()) 16953 Type = ATy->getElementType(); 16954 else 16955 Type = BaseType->getPointeeType(); 16956 Type = Type.getNonReferenceType(); 16957 } else if (OAShE) { 16958 Type = OAShE->getBase()->getType()->getPointeeType(); 16959 } else { 16960 Type = VE->getType(); 16961 } 16962 16963 // OpenMP 4.5 [2.10.5, target update Construct, Restrictions, p.4] 16964 // A list item in a to or from clause must have a mappable type. 16965 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.9] 16966 // A list item must have a mappable type. 16967 if (!checkTypeMappable(VE->getExprLoc(), VE->getSourceRange(), SemaRef, 16968 DSAS, Type)) 16969 continue; 16970 16971 Type = I->getAssociatedDeclaration()->getType().getNonReferenceType(); 16972 16973 if (CKind == OMPC_map) { 16974 // target enter data 16975 // OpenMP [2.10.2, Restrictions, p. 99] 16976 // A map-type must be specified in all map clauses and must be either 16977 // to or alloc. 16978 OpenMPDirectiveKind DKind = DSAS->getCurrentDirective(); 16979 if (DKind == OMPD_target_enter_data && 16980 !(MapType == OMPC_MAP_to || MapType == OMPC_MAP_alloc)) { 16981 SemaRef.Diag(StartLoc, diag::err_omp_invalid_map_type_for_directive) 16982 << (IsMapTypeImplicit ? 1 : 0) 16983 << getOpenMPSimpleClauseTypeName(OMPC_map, MapType) 16984 << getOpenMPDirectiveName(DKind); 16985 continue; 16986 } 16987 16988 // target exit_data 16989 // OpenMP [2.10.3, Restrictions, p. 102] 16990 // A map-type must be specified in all map clauses and must be either 16991 // from, release, or delete. 16992 if (DKind == OMPD_target_exit_data && 16993 !(MapType == OMPC_MAP_from || MapType == OMPC_MAP_release || 16994 MapType == OMPC_MAP_delete)) { 16995 SemaRef.Diag(StartLoc, diag::err_omp_invalid_map_type_for_directive) 16996 << (IsMapTypeImplicit ? 1 : 0) 16997 << getOpenMPSimpleClauseTypeName(OMPC_map, MapType) 16998 << getOpenMPDirectiveName(DKind); 16999 continue; 17000 } 17001 17002 // OpenMP 4.5 [2.15.5.1, Restrictions, p.3] 17003 // A list item cannot appear in both a map clause and a data-sharing 17004 // attribute clause on the same construct 17005 // 17006 // OpenMP 5.0 [2.19.7.1, Restrictions, p.7] 17007 // A list item cannot appear in both a map clause and a data-sharing 17008 // attribute clause on the same construct unless the construct is a 17009 // combined construct. 17010 if (VD && ((SemaRef.LangOpts.OpenMP <= 45 && 17011 isOpenMPTargetExecutionDirective(DKind)) || 17012 DKind == OMPD_target)) { 17013 DSAStackTy::DSAVarData DVar = DSAS->getTopDSA(VD, /*FromParent=*/false); 17014 if (isOpenMPPrivate(DVar.CKind)) { 17015 SemaRef.Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa) 17016 << getOpenMPClauseName(DVar.CKind) 17017 << getOpenMPClauseName(OMPC_map) 17018 << getOpenMPDirectiveName(DSAS->getCurrentDirective()); 17019 reportOriginalDsa(SemaRef, DSAS, CurDeclaration, DVar); 17020 continue; 17021 } 17022 } 17023 } 17024 17025 // Try to find the associated user-defined mapper. 17026 ExprResult ER = buildUserDefinedMapperRef( 17027 SemaRef, DSAS->getCurScope(), MapperIdScopeSpec, MapperId, 17028 Type.getCanonicalType(), UnresolvedMapper); 17029 if (ER.isInvalid()) 17030 continue; 17031 MVLI.UDMapperList.push_back(ER.get()); 17032 17033 // Save the current expression. 17034 MVLI.ProcessedVarList.push_back(RE); 17035 17036 // Store the components in the stack so that they can be used to check 17037 // against other clauses later on. 17038 DSAS->addMappableExpressionComponents(CurDeclaration, CurComponents, 17039 /*WhereFoundClauseKind=*/OMPC_map); 17040 17041 // Save the components and declaration to create the clause. For purposes of 17042 // the clause creation, any component list that has has base 'this' uses 17043 // null as base declaration. 17044 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1); 17045 MVLI.VarComponents.back().append(CurComponents.begin(), 17046 CurComponents.end()); 17047 MVLI.VarBaseDeclarations.push_back(isa<MemberExpr>(BE) ? nullptr 17048 : CurDeclaration); 17049 } 17050 } 17051 17052 OMPClause *Sema::ActOnOpenMPMapClause( 17053 ArrayRef<OpenMPMapModifierKind> MapTypeModifiers, 17054 ArrayRef<SourceLocation> MapTypeModifiersLoc, 17055 CXXScopeSpec &MapperIdScopeSpec, DeclarationNameInfo &MapperId, 17056 OpenMPMapClauseKind MapType, bool IsMapTypeImplicit, SourceLocation MapLoc, 17057 SourceLocation ColonLoc, ArrayRef<Expr *> VarList, 17058 const OMPVarListLocTy &Locs, ArrayRef<Expr *> UnresolvedMappers) { 17059 OpenMPMapModifierKind Modifiers[] = {OMPC_MAP_MODIFIER_unknown, 17060 OMPC_MAP_MODIFIER_unknown, 17061 OMPC_MAP_MODIFIER_unknown}; 17062 SourceLocation ModifiersLoc[NumberOfOMPMapClauseModifiers]; 17063 17064 // Process map-type-modifiers, flag errors for duplicate modifiers. 17065 unsigned Count = 0; 17066 for (unsigned I = 0, E = MapTypeModifiers.size(); I < E; ++I) { 17067 if (MapTypeModifiers[I] != OMPC_MAP_MODIFIER_unknown && 17068 llvm::find(Modifiers, MapTypeModifiers[I]) != std::end(Modifiers)) { 17069 Diag(MapTypeModifiersLoc[I], diag::err_omp_duplicate_map_type_modifier); 17070 continue; 17071 } 17072 assert(Count < NumberOfOMPMapClauseModifiers && 17073 "Modifiers exceed the allowed number of map type modifiers"); 17074 Modifiers[Count] = MapTypeModifiers[I]; 17075 ModifiersLoc[Count] = MapTypeModifiersLoc[I]; 17076 ++Count; 17077 } 17078 17079 MappableVarListInfo MVLI(VarList); 17080 checkMappableExpressionList(*this, DSAStack, OMPC_map, MVLI, Locs.StartLoc, 17081 MapperIdScopeSpec, MapperId, UnresolvedMappers, 17082 MapType, IsMapTypeImplicit); 17083 17084 // We need to produce a map clause even if we don't have variables so that 17085 // other diagnostics related with non-existing map clauses are accurate. 17086 return OMPMapClause::Create(Context, Locs, MVLI.ProcessedVarList, 17087 MVLI.VarBaseDeclarations, MVLI.VarComponents, 17088 MVLI.UDMapperList, Modifiers, ModifiersLoc, 17089 MapperIdScopeSpec.getWithLocInContext(Context), 17090 MapperId, MapType, IsMapTypeImplicit, MapLoc); 17091 } 17092 17093 QualType Sema::ActOnOpenMPDeclareReductionType(SourceLocation TyLoc, 17094 TypeResult ParsedType) { 17095 assert(ParsedType.isUsable()); 17096 17097 QualType ReductionType = GetTypeFromParser(ParsedType.get()); 17098 if (ReductionType.isNull()) 17099 return QualType(); 17100 17101 // [OpenMP 4.0], 2.15 declare reduction Directive, Restrictions, C\C++ 17102 // A type name in a declare reduction directive cannot be a function type, an 17103 // array type, a reference type, or a type qualified with const, volatile or 17104 // restrict. 17105 if (ReductionType.hasQualifiers()) { 17106 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 0; 17107 return QualType(); 17108 } 17109 17110 if (ReductionType->isFunctionType()) { 17111 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 1; 17112 return QualType(); 17113 } 17114 if (ReductionType->isReferenceType()) { 17115 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 2; 17116 return QualType(); 17117 } 17118 if (ReductionType->isArrayType()) { 17119 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 3; 17120 return QualType(); 17121 } 17122 return ReductionType; 17123 } 17124 17125 Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareReductionDirectiveStart( 17126 Scope *S, DeclContext *DC, DeclarationName Name, 17127 ArrayRef<std::pair<QualType, SourceLocation>> ReductionTypes, 17128 AccessSpecifier AS, Decl *PrevDeclInScope) { 17129 SmallVector<Decl *, 8> Decls; 17130 Decls.reserve(ReductionTypes.size()); 17131 17132 LookupResult Lookup(*this, Name, SourceLocation(), LookupOMPReductionName, 17133 forRedeclarationInCurContext()); 17134 // [OpenMP 4.0], 2.15 declare reduction Directive, Restrictions 17135 // A reduction-identifier may not be re-declared in the current scope for the 17136 // same type or for a type that is compatible according to the base language 17137 // rules. 17138 llvm::DenseMap<QualType, SourceLocation> PreviousRedeclTypes; 17139 OMPDeclareReductionDecl *PrevDRD = nullptr; 17140 bool InCompoundScope = true; 17141 if (S != nullptr) { 17142 // Find previous declaration with the same name not referenced in other 17143 // declarations. 17144 FunctionScopeInfo *ParentFn = getEnclosingFunction(); 17145 InCompoundScope = 17146 (ParentFn != nullptr) && !ParentFn->CompoundScopes.empty(); 17147 LookupName(Lookup, S); 17148 FilterLookupForScope(Lookup, DC, S, /*ConsiderLinkage=*/false, 17149 /*AllowInlineNamespace=*/false); 17150 llvm::DenseMap<OMPDeclareReductionDecl *, bool> UsedAsPrevious; 17151 LookupResult::Filter Filter = Lookup.makeFilter(); 17152 while (Filter.hasNext()) { 17153 auto *PrevDecl = cast<OMPDeclareReductionDecl>(Filter.next()); 17154 if (InCompoundScope) { 17155 auto I = UsedAsPrevious.find(PrevDecl); 17156 if (I == UsedAsPrevious.end()) 17157 UsedAsPrevious[PrevDecl] = false; 17158 if (OMPDeclareReductionDecl *D = PrevDecl->getPrevDeclInScope()) 17159 UsedAsPrevious[D] = true; 17160 } 17161 PreviousRedeclTypes[PrevDecl->getType().getCanonicalType()] = 17162 PrevDecl->getLocation(); 17163 } 17164 Filter.done(); 17165 if (InCompoundScope) { 17166 for (const auto &PrevData : UsedAsPrevious) { 17167 if (!PrevData.second) { 17168 PrevDRD = PrevData.first; 17169 break; 17170 } 17171 } 17172 } 17173 } else if (PrevDeclInScope != nullptr) { 17174 auto *PrevDRDInScope = PrevDRD = 17175 cast<OMPDeclareReductionDecl>(PrevDeclInScope); 17176 do { 17177 PreviousRedeclTypes[PrevDRDInScope->getType().getCanonicalType()] = 17178 PrevDRDInScope->getLocation(); 17179 PrevDRDInScope = PrevDRDInScope->getPrevDeclInScope(); 17180 } while (PrevDRDInScope != nullptr); 17181 } 17182 for (const auto &TyData : ReductionTypes) { 17183 const auto I = PreviousRedeclTypes.find(TyData.first.getCanonicalType()); 17184 bool Invalid = false; 17185 if (I != PreviousRedeclTypes.end()) { 17186 Diag(TyData.second, diag::err_omp_declare_reduction_redefinition) 17187 << TyData.first; 17188 Diag(I->second, diag::note_previous_definition); 17189 Invalid = true; 17190 } 17191 PreviousRedeclTypes[TyData.first.getCanonicalType()] = TyData.second; 17192 auto *DRD = OMPDeclareReductionDecl::Create(Context, DC, TyData.second, 17193 Name, TyData.first, PrevDRD); 17194 DC->addDecl(DRD); 17195 DRD->setAccess(AS); 17196 Decls.push_back(DRD); 17197 if (Invalid) 17198 DRD->setInvalidDecl(); 17199 else 17200 PrevDRD = DRD; 17201 } 17202 17203 return DeclGroupPtrTy::make( 17204 DeclGroupRef::Create(Context, Decls.begin(), Decls.size())); 17205 } 17206 17207 void Sema::ActOnOpenMPDeclareReductionCombinerStart(Scope *S, Decl *D) { 17208 auto *DRD = cast<OMPDeclareReductionDecl>(D); 17209 17210 // Enter new function scope. 17211 PushFunctionScope(); 17212 setFunctionHasBranchProtectedScope(); 17213 getCurFunction()->setHasOMPDeclareReductionCombiner(); 17214 17215 if (S != nullptr) 17216 PushDeclContext(S, DRD); 17217 else 17218 CurContext = DRD; 17219 17220 PushExpressionEvaluationContext( 17221 ExpressionEvaluationContext::PotentiallyEvaluated); 17222 17223 QualType ReductionType = DRD->getType(); 17224 // Create 'T* omp_parm;T omp_in;'. All references to 'omp_in' will 17225 // be replaced by '*omp_parm' during codegen. This required because 'omp_in' 17226 // uses semantics of argument handles by value, but it should be passed by 17227 // reference. C lang does not support references, so pass all parameters as 17228 // pointers. 17229 // Create 'T omp_in;' variable. 17230 VarDecl *OmpInParm = 17231 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_in"); 17232 // Create 'T* omp_parm;T omp_out;'. All references to 'omp_out' will 17233 // be replaced by '*omp_parm' during codegen. This required because 'omp_out' 17234 // uses semantics of argument handles by value, but it should be passed by 17235 // reference. C lang does not support references, so pass all parameters as 17236 // pointers. 17237 // Create 'T omp_out;' variable. 17238 VarDecl *OmpOutParm = 17239 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_out"); 17240 if (S != nullptr) { 17241 PushOnScopeChains(OmpInParm, S); 17242 PushOnScopeChains(OmpOutParm, S); 17243 } else { 17244 DRD->addDecl(OmpInParm); 17245 DRD->addDecl(OmpOutParm); 17246 } 17247 Expr *InE = 17248 ::buildDeclRefExpr(*this, OmpInParm, ReductionType, D->getLocation()); 17249 Expr *OutE = 17250 ::buildDeclRefExpr(*this, OmpOutParm, ReductionType, D->getLocation()); 17251 DRD->setCombinerData(InE, OutE); 17252 } 17253 17254 void Sema::ActOnOpenMPDeclareReductionCombinerEnd(Decl *D, Expr *Combiner) { 17255 auto *DRD = cast<OMPDeclareReductionDecl>(D); 17256 DiscardCleanupsInEvaluationContext(); 17257 PopExpressionEvaluationContext(); 17258 17259 PopDeclContext(); 17260 PopFunctionScopeInfo(); 17261 17262 if (Combiner != nullptr) 17263 DRD->setCombiner(Combiner); 17264 else 17265 DRD->setInvalidDecl(); 17266 } 17267 17268 VarDecl *Sema::ActOnOpenMPDeclareReductionInitializerStart(Scope *S, Decl *D) { 17269 auto *DRD = cast<OMPDeclareReductionDecl>(D); 17270 17271 // Enter new function scope. 17272 PushFunctionScope(); 17273 setFunctionHasBranchProtectedScope(); 17274 17275 if (S != nullptr) 17276 PushDeclContext(S, DRD); 17277 else 17278 CurContext = DRD; 17279 17280 PushExpressionEvaluationContext( 17281 ExpressionEvaluationContext::PotentiallyEvaluated); 17282 17283 QualType ReductionType = DRD->getType(); 17284 // Create 'T* omp_parm;T omp_priv;'. All references to 'omp_priv' will 17285 // be replaced by '*omp_parm' during codegen. This required because 'omp_priv' 17286 // uses semantics of argument handles by value, but it should be passed by 17287 // reference. C lang does not support references, so pass all parameters as 17288 // pointers. 17289 // Create 'T omp_priv;' variable. 17290 VarDecl *OmpPrivParm = 17291 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_priv"); 17292 // Create 'T* omp_parm;T omp_orig;'. All references to 'omp_orig' will 17293 // be replaced by '*omp_parm' during codegen. This required because 'omp_orig' 17294 // uses semantics of argument handles by value, but it should be passed by 17295 // reference. C lang does not support references, so pass all parameters as 17296 // pointers. 17297 // Create 'T omp_orig;' variable. 17298 VarDecl *OmpOrigParm = 17299 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_orig"); 17300 if (S != nullptr) { 17301 PushOnScopeChains(OmpPrivParm, S); 17302 PushOnScopeChains(OmpOrigParm, S); 17303 } else { 17304 DRD->addDecl(OmpPrivParm); 17305 DRD->addDecl(OmpOrigParm); 17306 } 17307 Expr *OrigE = 17308 ::buildDeclRefExpr(*this, OmpOrigParm, ReductionType, D->getLocation()); 17309 Expr *PrivE = 17310 ::buildDeclRefExpr(*this, OmpPrivParm, ReductionType, D->getLocation()); 17311 DRD->setInitializerData(OrigE, PrivE); 17312 return OmpPrivParm; 17313 } 17314 17315 void Sema::ActOnOpenMPDeclareReductionInitializerEnd(Decl *D, Expr *Initializer, 17316 VarDecl *OmpPrivParm) { 17317 auto *DRD = cast<OMPDeclareReductionDecl>(D); 17318 DiscardCleanupsInEvaluationContext(); 17319 PopExpressionEvaluationContext(); 17320 17321 PopDeclContext(); 17322 PopFunctionScopeInfo(); 17323 17324 if (Initializer != nullptr) { 17325 DRD->setInitializer(Initializer, OMPDeclareReductionDecl::CallInit); 17326 } else if (OmpPrivParm->hasInit()) { 17327 DRD->setInitializer(OmpPrivParm->getInit(), 17328 OmpPrivParm->isDirectInit() 17329 ? OMPDeclareReductionDecl::DirectInit 17330 : OMPDeclareReductionDecl::CopyInit); 17331 } else { 17332 DRD->setInvalidDecl(); 17333 } 17334 } 17335 17336 Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareReductionDirectiveEnd( 17337 Scope *S, DeclGroupPtrTy DeclReductions, bool IsValid) { 17338 for (Decl *D : DeclReductions.get()) { 17339 if (IsValid) { 17340 if (S) 17341 PushOnScopeChains(cast<OMPDeclareReductionDecl>(D), S, 17342 /*AddToContext=*/false); 17343 } else { 17344 D->setInvalidDecl(); 17345 } 17346 } 17347 return DeclReductions; 17348 } 17349 17350 TypeResult Sema::ActOnOpenMPDeclareMapperVarDecl(Scope *S, Declarator &D) { 17351 TypeSourceInfo *TInfo = GetTypeForDeclarator(D, S); 17352 QualType T = TInfo->getType(); 17353 if (D.isInvalidType()) 17354 return true; 17355 17356 if (getLangOpts().CPlusPlus) { 17357 // Check that there are no default arguments (C++ only). 17358 CheckExtraCXXDefaultArguments(D); 17359 } 17360 17361 return CreateParsedType(T, TInfo); 17362 } 17363 17364 QualType Sema::ActOnOpenMPDeclareMapperType(SourceLocation TyLoc, 17365 TypeResult ParsedType) { 17366 assert(ParsedType.isUsable() && "Expect usable parsed mapper type"); 17367 17368 QualType MapperType = GetTypeFromParser(ParsedType.get()); 17369 assert(!MapperType.isNull() && "Expect valid mapper type"); 17370 17371 // [OpenMP 5.0], 2.19.7.3 declare mapper Directive, Restrictions 17372 // The type must be of struct, union or class type in C and C++ 17373 if (!MapperType->isStructureOrClassType() && !MapperType->isUnionType()) { 17374 Diag(TyLoc, diag::err_omp_mapper_wrong_type); 17375 return QualType(); 17376 } 17377 return MapperType; 17378 } 17379 17380 OMPDeclareMapperDecl *Sema::ActOnOpenMPDeclareMapperDirectiveStart( 17381 Scope *S, DeclContext *DC, DeclarationName Name, QualType MapperType, 17382 SourceLocation StartLoc, DeclarationName VN, AccessSpecifier AS, 17383 Decl *PrevDeclInScope) { 17384 LookupResult Lookup(*this, Name, SourceLocation(), LookupOMPMapperName, 17385 forRedeclarationInCurContext()); 17386 // [OpenMP 5.0], 2.19.7.3 declare mapper Directive, Restrictions 17387 // A mapper-identifier may not be redeclared in the current scope for the 17388 // same type or for a type that is compatible according to the base language 17389 // rules. 17390 llvm::DenseMap<QualType, SourceLocation> PreviousRedeclTypes; 17391 OMPDeclareMapperDecl *PrevDMD = nullptr; 17392 bool InCompoundScope = true; 17393 if (S != nullptr) { 17394 // Find previous declaration with the same name not referenced in other 17395 // declarations. 17396 FunctionScopeInfo *ParentFn = getEnclosingFunction(); 17397 InCompoundScope = 17398 (ParentFn != nullptr) && !ParentFn->CompoundScopes.empty(); 17399 LookupName(Lookup, S); 17400 FilterLookupForScope(Lookup, DC, S, /*ConsiderLinkage=*/false, 17401 /*AllowInlineNamespace=*/false); 17402 llvm::DenseMap<OMPDeclareMapperDecl *, bool> UsedAsPrevious; 17403 LookupResult::Filter Filter = Lookup.makeFilter(); 17404 while (Filter.hasNext()) { 17405 auto *PrevDecl = cast<OMPDeclareMapperDecl>(Filter.next()); 17406 if (InCompoundScope) { 17407 auto I = UsedAsPrevious.find(PrevDecl); 17408 if (I == UsedAsPrevious.end()) 17409 UsedAsPrevious[PrevDecl] = false; 17410 if (OMPDeclareMapperDecl *D = PrevDecl->getPrevDeclInScope()) 17411 UsedAsPrevious[D] = true; 17412 } 17413 PreviousRedeclTypes[PrevDecl->getType().getCanonicalType()] = 17414 PrevDecl->getLocation(); 17415 } 17416 Filter.done(); 17417 if (InCompoundScope) { 17418 for (const auto &PrevData : UsedAsPrevious) { 17419 if (!PrevData.second) { 17420 PrevDMD = PrevData.first; 17421 break; 17422 } 17423 } 17424 } 17425 } else if (PrevDeclInScope) { 17426 auto *PrevDMDInScope = PrevDMD = 17427 cast<OMPDeclareMapperDecl>(PrevDeclInScope); 17428 do { 17429 PreviousRedeclTypes[PrevDMDInScope->getType().getCanonicalType()] = 17430 PrevDMDInScope->getLocation(); 17431 PrevDMDInScope = PrevDMDInScope->getPrevDeclInScope(); 17432 } while (PrevDMDInScope != nullptr); 17433 } 17434 const auto I = PreviousRedeclTypes.find(MapperType.getCanonicalType()); 17435 bool Invalid = false; 17436 if (I != PreviousRedeclTypes.end()) { 17437 Diag(StartLoc, diag::err_omp_declare_mapper_redefinition) 17438 << MapperType << Name; 17439 Diag(I->second, diag::note_previous_definition); 17440 Invalid = true; 17441 } 17442 auto *DMD = OMPDeclareMapperDecl::Create(Context, DC, StartLoc, Name, 17443 MapperType, VN, PrevDMD); 17444 DC->addDecl(DMD); 17445 DMD->setAccess(AS); 17446 if (Invalid) 17447 DMD->setInvalidDecl(); 17448 17449 // Enter new function scope. 17450 PushFunctionScope(); 17451 setFunctionHasBranchProtectedScope(); 17452 17453 CurContext = DMD; 17454 17455 return DMD; 17456 } 17457 17458 void Sema::ActOnOpenMPDeclareMapperDirectiveVarDecl(OMPDeclareMapperDecl *DMD, 17459 Scope *S, 17460 QualType MapperType, 17461 SourceLocation StartLoc, 17462 DeclarationName VN) { 17463 VarDecl *VD = buildVarDecl(*this, StartLoc, MapperType, VN.getAsString()); 17464 if (S) 17465 PushOnScopeChains(VD, S); 17466 else 17467 DMD->addDecl(VD); 17468 Expr *MapperVarRefExpr = buildDeclRefExpr(*this, VD, MapperType, StartLoc); 17469 DMD->setMapperVarRef(MapperVarRefExpr); 17470 } 17471 17472 Sema::DeclGroupPtrTy 17473 Sema::ActOnOpenMPDeclareMapperDirectiveEnd(OMPDeclareMapperDecl *D, Scope *S, 17474 ArrayRef<OMPClause *> ClauseList) { 17475 PopDeclContext(); 17476 PopFunctionScopeInfo(); 17477 17478 if (D) { 17479 if (S) 17480 PushOnScopeChains(D, S, /*AddToContext=*/false); 17481 D->CreateClauses(Context, ClauseList); 17482 } 17483 17484 return DeclGroupPtrTy::make(DeclGroupRef(D)); 17485 } 17486 17487 OMPClause *Sema::ActOnOpenMPNumTeamsClause(Expr *NumTeams, 17488 SourceLocation StartLoc, 17489 SourceLocation LParenLoc, 17490 SourceLocation EndLoc) { 17491 Expr *ValExpr = NumTeams; 17492 Stmt *HelperValStmt = nullptr; 17493 17494 // OpenMP [teams Constrcut, Restrictions] 17495 // The num_teams expression must evaluate to a positive integer value. 17496 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_num_teams, 17497 /*StrictlyPositive=*/true)) 17498 return nullptr; 17499 17500 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 17501 OpenMPDirectiveKind CaptureRegion = 17502 getOpenMPCaptureRegionForClause(DKind, OMPC_num_teams, LangOpts.OpenMP); 17503 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 17504 ValExpr = MakeFullExpr(ValExpr).get(); 17505 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 17506 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 17507 HelperValStmt = buildPreInits(Context, Captures); 17508 } 17509 17510 return new (Context) OMPNumTeamsClause(ValExpr, HelperValStmt, CaptureRegion, 17511 StartLoc, LParenLoc, EndLoc); 17512 } 17513 17514 OMPClause *Sema::ActOnOpenMPThreadLimitClause(Expr *ThreadLimit, 17515 SourceLocation StartLoc, 17516 SourceLocation LParenLoc, 17517 SourceLocation EndLoc) { 17518 Expr *ValExpr = ThreadLimit; 17519 Stmt *HelperValStmt = nullptr; 17520 17521 // OpenMP [teams Constrcut, Restrictions] 17522 // The thread_limit expression must evaluate to a positive integer value. 17523 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_thread_limit, 17524 /*StrictlyPositive=*/true)) 17525 return nullptr; 17526 17527 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 17528 OpenMPDirectiveKind CaptureRegion = getOpenMPCaptureRegionForClause( 17529 DKind, OMPC_thread_limit, LangOpts.OpenMP); 17530 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 17531 ValExpr = MakeFullExpr(ValExpr).get(); 17532 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 17533 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 17534 HelperValStmt = buildPreInits(Context, Captures); 17535 } 17536 17537 return new (Context) OMPThreadLimitClause( 17538 ValExpr, HelperValStmt, CaptureRegion, StartLoc, LParenLoc, EndLoc); 17539 } 17540 17541 OMPClause *Sema::ActOnOpenMPPriorityClause(Expr *Priority, 17542 SourceLocation StartLoc, 17543 SourceLocation LParenLoc, 17544 SourceLocation EndLoc) { 17545 Expr *ValExpr = Priority; 17546 Stmt *HelperValStmt = nullptr; 17547 OpenMPDirectiveKind CaptureRegion = OMPD_unknown; 17548 17549 // OpenMP [2.9.1, task Constrcut] 17550 // The priority-value is a non-negative numerical scalar expression. 17551 if (!isNonNegativeIntegerValue( 17552 ValExpr, *this, OMPC_priority, 17553 /*StrictlyPositive=*/false, /*BuildCapture=*/true, 17554 DSAStack->getCurrentDirective(), &CaptureRegion, &HelperValStmt)) 17555 return nullptr; 17556 17557 return new (Context) OMPPriorityClause(ValExpr, HelperValStmt, CaptureRegion, 17558 StartLoc, LParenLoc, EndLoc); 17559 } 17560 17561 OMPClause *Sema::ActOnOpenMPGrainsizeClause(Expr *Grainsize, 17562 SourceLocation StartLoc, 17563 SourceLocation LParenLoc, 17564 SourceLocation EndLoc) { 17565 Expr *ValExpr = Grainsize; 17566 Stmt *HelperValStmt = nullptr; 17567 OpenMPDirectiveKind CaptureRegion = OMPD_unknown; 17568 17569 // OpenMP [2.9.2, taskloop Constrcut] 17570 // The parameter of the grainsize clause must be a positive integer 17571 // expression. 17572 if (!isNonNegativeIntegerValue( 17573 ValExpr, *this, OMPC_grainsize, 17574 /*StrictlyPositive=*/true, /*BuildCapture=*/true, 17575 DSAStack->getCurrentDirective(), &CaptureRegion, &HelperValStmt)) 17576 return nullptr; 17577 17578 return new (Context) OMPGrainsizeClause(ValExpr, HelperValStmt, CaptureRegion, 17579 StartLoc, LParenLoc, EndLoc); 17580 } 17581 17582 OMPClause *Sema::ActOnOpenMPNumTasksClause(Expr *NumTasks, 17583 SourceLocation StartLoc, 17584 SourceLocation LParenLoc, 17585 SourceLocation EndLoc) { 17586 Expr *ValExpr = NumTasks; 17587 Stmt *HelperValStmt = nullptr; 17588 OpenMPDirectiveKind CaptureRegion = OMPD_unknown; 17589 17590 // OpenMP [2.9.2, taskloop Constrcut] 17591 // The parameter of the num_tasks clause must be a positive integer 17592 // expression. 17593 if (!isNonNegativeIntegerValue( 17594 ValExpr, *this, OMPC_num_tasks, 17595 /*StrictlyPositive=*/true, /*BuildCapture=*/true, 17596 DSAStack->getCurrentDirective(), &CaptureRegion, &HelperValStmt)) 17597 return nullptr; 17598 17599 return new (Context) OMPNumTasksClause(ValExpr, HelperValStmt, CaptureRegion, 17600 StartLoc, LParenLoc, EndLoc); 17601 } 17602 17603 OMPClause *Sema::ActOnOpenMPHintClause(Expr *Hint, SourceLocation StartLoc, 17604 SourceLocation LParenLoc, 17605 SourceLocation EndLoc) { 17606 // OpenMP [2.13.2, critical construct, Description] 17607 // ... where hint-expression is an integer constant expression that evaluates 17608 // to a valid lock hint. 17609 ExprResult HintExpr = VerifyPositiveIntegerConstantInClause(Hint, OMPC_hint); 17610 if (HintExpr.isInvalid()) 17611 return nullptr; 17612 return new (Context) 17613 OMPHintClause(HintExpr.get(), StartLoc, LParenLoc, EndLoc); 17614 } 17615 17616 /// Tries to find omp_event_handle_t type. 17617 static bool findOMPEventHandleT(Sema &S, SourceLocation Loc, 17618 DSAStackTy *Stack) { 17619 QualType OMPEventHandleT = Stack->getOMPEventHandleT(); 17620 if (!OMPEventHandleT.isNull()) 17621 return true; 17622 IdentifierInfo *II = &S.PP.getIdentifierTable().get("omp_event_handle_t"); 17623 ParsedType PT = S.getTypeName(*II, Loc, S.getCurScope()); 17624 if (!PT.getAsOpaquePtr() || PT.get().isNull()) { 17625 S.Diag(Loc, diag::err_omp_implied_type_not_found) << "omp_event_handle_t"; 17626 return false; 17627 } 17628 Stack->setOMPEventHandleT(PT.get()); 17629 return true; 17630 } 17631 17632 OMPClause *Sema::ActOnOpenMPDetachClause(Expr *Evt, SourceLocation StartLoc, 17633 SourceLocation LParenLoc, 17634 SourceLocation EndLoc) { 17635 if (!Evt->isValueDependent() && !Evt->isTypeDependent() && 17636 !Evt->isInstantiationDependent() && 17637 !Evt->containsUnexpandedParameterPack()) { 17638 if (!findOMPEventHandleT(*this, Evt->getExprLoc(), DSAStack)) 17639 return nullptr; 17640 // OpenMP 5.0, 2.10.1 task Construct. 17641 // event-handle is a variable of the omp_event_handle_t type. 17642 auto *Ref = dyn_cast<DeclRefExpr>(Evt->IgnoreParenImpCasts()); 17643 if (!Ref) { 17644 Diag(Evt->getExprLoc(), diag::err_omp_event_var_expected) 17645 << 0 << Evt->getSourceRange(); 17646 return nullptr; 17647 } 17648 auto *VD = dyn_cast_or_null<VarDecl>(Ref->getDecl()); 17649 if (!VD) { 17650 Diag(Evt->getExprLoc(), diag::err_omp_event_var_expected) 17651 << 0 << Evt->getSourceRange(); 17652 return nullptr; 17653 } 17654 if (!Context.hasSameUnqualifiedType(DSAStack->getOMPEventHandleT(), 17655 VD->getType()) || 17656 VD->getType().isConstant(Context)) { 17657 Diag(Evt->getExprLoc(), diag::err_omp_event_var_expected) 17658 << 1 << VD->getType() << Evt->getSourceRange(); 17659 return nullptr; 17660 } 17661 // OpenMP 5.0, 2.10.1 task Construct 17662 // [detach clause]... The event-handle will be considered as if it was 17663 // specified on a firstprivate clause. 17664 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(VD, /*FromParent=*/false); 17665 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_firstprivate && 17666 DVar.RefExpr) { 17667 Diag(Evt->getExprLoc(), diag::err_omp_wrong_dsa) 17668 << getOpenMPClauseName(DVar.CKind) 17669 << getOpenMPClauseName(OMPC_firstprivate); 17670 reportOriginalDsa(*this, DSAStack, VD, DVar); 17671 return nullptr; 17672 } 17673 } 17674 17675 return new (Context) OMPDetachClause(Evt, StartLoc, LParenLoc, EndLoc); 17676 } 17677 17678 OMPClause *Sema::ActOnOpenMPDistScheduleClause( 17679 OpenMPDistScheduleClauseKind Kind, Expr *ChunkSize, SourceLocation StartLoc, 17680 SourceLocation LParenLoc, SourceLocation KindLoc, SourceLocation CommaLoc, 17681 SourceLocation EndLoc) { 17682 if (Kind == OMPC_DIST_SCHEDULE_unknown) { 17683 std::string Values; 17684 Values += "'"; 17685 Values += getOpenMPSimpleClauseTypeName(OMPC_dist_schedule, 0); 17686 Values += "'"; 17687 Diag(KindLoc, diag::err_omp_unexpected_clause_value) 17688 << Values << getOpenMPClauseName(OMPC_dist_schedule); 17689 return nullptr; 17690 } 17691 Expr *ValExpr = ChunkSize; 17692 Stmt *HelperValStmt = nullptr; 17693 if (ChunkSize) { 17694 if (!ChunkSize->isValueDependent() && !ChunkSize->isTypeDependent() && 17695 !ChunkSize->isInstantiationDependent() && 17696 !ChunkSize->containsUnexpandedParameterPack()) { 17697 SourceLocation ChunkSizeLoc = ChunkSize->getBeginLoc(); 17698 ExprResult Val = 17699 PerformOpenMPImplicitIntegerConversion(ChunkSizeLoc, ChunkSize); 17700 if (Val.isInvalid()) 17701 return nullptr; 17702 17703 ValExpr = Val.get(); 17704 17705 // OpenMP [2.7.1, Restrictions] 17706 // chunk_size must be a loop invariant integer expression with a positive 17707 // value. 17708 llvm::APSInt Result; 17709 if (ValExpr->isIntegerConstantExpr(Result, Context)) { 17710 if (Result.isSigned() && !Result.isStrictlyPositive()) { 17711 Diag(ChunkSizeLoc, diag::err_omp_negative_expression_in_clause) 17712 << "dist_schedule" << ChunkSize->getSourceRange(); 17713 return nullptr; 17714 } 17715 } else if (getOpenMPCaptureRegionForClause( 17716 DSAStack->getCurrentDirective(), OMPC_dist_schedule, 17717 LangOpts.OpenMP) != OMPD_unknown && 17718 !CurContext->isDependentContext()) { 17719 ValExpr = MakeFullExpr(ValExpr).get(); 17720 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 17721 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 17722 HelperValStmt = buildPreInits(Context, Captures); 17723 } 17724 } 17725 } 17726 17727 return new (Context) 17728 OMPDistScheduleClause(StartLoc, LParenLoc, KindLoc, CommaLoc, EndLoc, 17729 Kind, ValExpr, HelperValStmt); 17730 } 17731 17732 OMPClause *Sema::ActOnOpenMPDefaultmapClause( 17733 OpenMPDefaultmapClauseModifier M, OpenMPDefaultmapClauseKind Kind, 17734 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation MLoc, 17735 SourceLocation KindLoc, SourceLocation EndLoc) { 17736 if (getLangOpts().OpenMP < 50) { 17737 if (M != OMPC_DEFAULTMAP_MODIFIER_tofrom || 17738 Kind != OMPC_DEFAULTMAP_scalar) { 17739 std::string Value; 17740 SourceLocation Loc; 17741 Value += "'"; 17742 if (M != OMPC_DEFAULTMAP_MODIFIER_tofrom) { 17743 Value += getOpenMPSimpleClauseTypeName(OMPC_defaultmap, 17744 OMPC_DEFAULTMAP_MODIFIER_tofrom); 17745 Loc = MLoc; 17746 } else { 17747 Value += getOpenMPSimpleClauseTypeName(OMPC_defaultmap, 17748 OMPC_DEFAULTMAP_scalar); 17749 Loc = KindLoc; 17750 } 17751 Value += "'"; 17752 Diag(Loc, diag::err_omp_unexpected_clause_value) 17753 << Value << getOpenMPClauseName(OMPC_defaultmap); 17754 return nullptr; 17755 } 17756 } else { 17757 bool isDefaultmapModifier = (M != OMPC_DEFAULTMAP_MODIFIER_unknown); 17758 bool isDefaultmapKind = (Kind != OMPC_DEFAULTMAP_unknown); 17759 if (!isDefaultmapKind || !isDefaultmapModifier) { 17760 std::string ModifierValue = "'alloc', 'from', 'to', 'tofrom', " 17761 "'firstprivate', 'none', 'default'"; 17762 std::string KindValue = "'scalar', 'aggregate', 'pointer'"; 17763 if (!isDefaultmapKind && isDefaultmapModifier) { 17764 Diag(KindLoc, diag::err_omp_unexpected_clause_value) 17765 << KindValue << getOpenMPClauseName(OMPC_defaultmap); 17766 } else if (isDefaultmapKind && !isDefaultmapModifier) { 17767 Diag(MLoc, diag::err_omp_unexpected_clause_value) 17768 << ModifierValue << getOpenMPClauseName(OMPC_defaultmap); 17769 } else { 17770 Diag(MLoc, diag::err_omp_unexpected_clause_value) 17771 << ModifierValue << getOpenMPClauseName(OMPC_defaultmap); 17772 Diag(KindLoc, diag::err_omp_unexpected_clause_value) 17773 << KindValue << getOpenMPClauseName(OMPC_defaultmap); 17774 } 17775 return nullptr; 17776 } 17777 17778 // OpenMP [5.0, 2.12.5, Restrictions, p. 174] 17779 // At most one defaultmap clause for each category can appear on the 17780 // directive. 17781 if (DSAStack->checkDefaultmapCategory(Kind)) { 17782 Diag(StartLoc, diag::err_omp_one_defaultmap_each_category); 17783 return nullptr; 17784 } 17785 } 17786 DSAStack->setDefaultDMAAttr(M, Kind, StartLoc); 17787 17788 return new (Context) 17789 OMPDefaultmapClause(StartLoc, LParenLoc, MLoc, KindLoc, EndLoc, Kind, M); 17790 } 17791 17792 bool Sema::ActOnStartOpenMPDeclareTargetDirective(SourceLocation Loc) { 17793 DeclContext *CurLexicalContext = getCurLexicalContext(); 17794 if (!CurLexicalContext->isFileContext() && 17795 !CurLexicalContext->isExternCContext() && 17796 !CurLexicalContext->isExternCXXContext() && 17797 !isa<CXXRecordDecl>(CurLexicalContext) && 17798 !isa<ClassTemplateDecl>(CurLexicalContext) && 17799 !isa<ClassTemplatePartialSpecializationDecl>(CurLexicalContext) && 17800 !isa<ClassTemplateSpecializationDecl>(CurLexicalContext)) { 17801 Diag(Loc, diag::err_omp_region_not_file_context); 17802 return false; 17803 } 17804 ++DeclareTargetNestingLevel; 17805 return true; 17806 } 17807 17808 void Sema::ActOnFinishOpenMPDeclareTargetDirective() { 17809 assert(DeclareTargetNestingLevel > 0 && 17810 "Unexpected ActOnFinishOpenMPDeclareTargetDirective"); 17811 --DeclareTargetNestingLevel; 17812 } 17813 17814 NamedDecl * 17815 Sema::lookupOpenMPDeclareTargetName(Scope *CurScope, CXXScopeSpec &ScopeSpec, 17816 const DeclarationNameInfo &Id, 17817 NamedDeclSetType &SameDirectiveDecls) { 17818 LookupResult Lookup(*this, Id, LookupOrdinaryName); 17819 LookupParsedName(Lookup, CurScope, &ScopeSpec, true); 17820 17821 if (Lookup.isAmbiguous()) 17822 return nullptr; 17823 Lookup.suppressDiagnostics(); 17824 17825 if (!Lookup.isSingleResult()) { 17826 VarOrFuncDeclFilterCCC CCC(*this); 17827 if (TypoCorrection Corrected = 17828 CorrectTypo(Id, LookupOrdinaryName, CurScope, nullptr, CCC, 17829 CTK_ErrorRecovery)) { 17830 diagnoseTypo(Corrected, PDiag(diag::err_undeclared_var_use_suggest) 17831 << Id.getName()); 17832 checkDeclIsAllowedInOpenMPTarget(nullptr, Corrected.getCorrectionDecl()); 17833 return nullptr; 17834 } 17835 17836 Diag(Id.getLoc(), diag::err_undeclared_var_use) << Id.getName(); 17837 return nullptr; 17838 } 17839 17840 NamedDecl *ND = Lookup.getAsSingle<NamedDecl>(); 17841 if (!isa<VarDecl>(ND) && !isa<FunctionDecl>(ND) && 17842 !isa<FunctionTemplateDecl>(ND)) { 17843 Diag(Id.getLoc(), diag::err_omp_invalid_target_decl) << Id.getName(); 17844 return nullptr; 17845 } 17846 if (!SameDirectiveDecls.insert(cast<NamedDecl>(ND->getCanonicalDecl()))) 17847 Diag(Id.getLoc(), diag::err_omp_declare_target_multiple) << Id.getName(); 17848 return ND; 17849 } 17850 17851 void Sema::ActOnOpenMPDeclareTargetName( 17852 NamedDecl *ND, SourceLocation Loc, OMPDeclareTargetDeclAttr::MapTypeTy MT, 17853 OMPDeclareTargetDeclAttr::DevTypeTy DT) { 17854 assert((isa<VarDecl>(ND) || isa<FunctionDecl>(ND) || 17855 isa<FunctionTemplateDecl>(ND)) && 17856 "Expected variable, function or function template."); 17857 17858 // Diagnose marking after use as it may lead to incorrect diagnosis and 17859 // codegen. 17860 if (LangOpts.OpenMP >= 50 && 17861 (ND->isUsed(/*CheckUsedAttr=*/false) || ND->isReferenced())) 17862 Diag(Loc, diag::warn_omp_declare_target_after_first_use); 17863 17864 Optional<OMPDeclareTargetDeclAttr::DevTypeTy> DevTy = 17865 OMPDeclareTargetDeclAttr::getDeviceType(cast<ValueDecl>(ND)); 17866 if (DevTy.hasValue() && *DevTy != DT) { 17867 Diag(Loc, diag::err_omp_device_type_mismatch) 17868 << OMPDeclareTargetDeclAttr::ConvertDevTypeTyToStr(DT) 17869 << OMPDeclareTargetDeclAttr::ConvertDevTypeTyToStr(*DevTy); 17870 return; 17871 } 17872 Optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res = 17873 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(cast<ValueDecl>(ND)); 17874 if (!Res) { 17875 auto *A = OMPDeclareTargetDeclAttr::CreateImplicit(Context, MT, DT, 17876 SourceRange(Loc, Loc)); 17877 ND->addAttr(A); 17878 if (ASTMutationListener *ML = Context.getASTMutationListener()) 17879 ML->DeclarationMarkedOpenMPDeclareTarget(ND, A); 17880 checkDeclIsAllowedInOpenMPTarget(nullptr, ND, Loc); 17881 } else if (*Res != MT) { 17882 Diag(Loc, diag::err_omp_declare_target_to_and_link) << ND; 17883 } 17884 } 17885 17886 static void checkDeclInTargetContext(SourceLocation SL, SourceRange SR, 17887 Sema &SemaRef, Decl *D) { 17888 if (!D || !isa<VarDecl>(D)) 17889 return; 17890 auto *VD = cast<VarDecl>(D); 17891 Optional<OMPDeclareTargetDeclAttr::MapTypeTy> MapTy = 17892 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD); 17893 if (SemaRef.LangOpts.OpenMP >= 50 && 17894 (SemaRef.getCurLambda(/*IgnoreNonLambdaCapturingScope=*/true) || 17895 SemaRef.getCurBlock() || SemaRef.getCurCapturedRegion()) && 17896 VD->hasGlobalStorage()) { 17897 llvm::Optional<OMPDeclareTargetDeclAttr::MapTypeTy> MapTy = 17898 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD); 17899 if (!MapTy || *MapTy != OMPDeclareTargetDeclAttr::MT_To) { 17900 // OpenMP 5.0, 2.12.7 declare target Directive, Restrictions 17901 // If a lambda declaration and definition appears between a 17902 // declare target directive and the matching end declare target 17903 // directive, all variables that are captured by the lambda 17904 // expression must also appear in a to clause. 17905 SemaRef.Diag(VD->getLocation(), 17906 diag::err_omp_lambda_capture_in_declare_target_not_to); 17907 SemaRef.Diag(SL, diag::note_var_explicitly_captured_here) 17908 << VD << 0 << SR; 17909 return; 17910 } 17911 } 17912 if (MapTy.hasValue()) 17913 return; 17914 SemaRef.Diag(VD->getLocation(), diag::warn_omp_not_in_target_context); 17915 SemaRef.Diag(SL, diag::note_used_here) << SR; 17916 } 17917 17918 static bool checkValueDeclInTarget(SourceLocation SL, SourceRange SR, 17919 Sema &SemaRef, DSAStackTy *Stack, 17920 ValueDecl *VD) { 17921 return OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD) || 17922 checkTypeMappable(SL, SR, SemaRef, Stack, VD->getType(), 17923 /*FullCheck=*/false); 17924 } 17925 17926 void Sema::checkDeclIsAllowedInOpenMPTarget(Expr *E, Decl *D, 17927 SourceLocation IdLoc) { 17928 if (!D || D->isInvalidDecl()) 17929 return; 17930 SourceRange SR = E ? E->getSourceRange() : D->getSourceRange(); 17931 SourceLocation SL = E ? E->getBeginLoc() : D->getLocation(); 17932 if (auto *VD = dyn_cast<VarDecl>(D)) { 17933 // Only global variables can be marked as declare target. 17934 if (!VD->isFileVarDecl() && !VD->isStaticLocal() && 17935 !VD->isStaticDataMember()) 17936 return; 17937 // 2.10.6: threadprivate variable cannot appear in a declare target 17938 // directive. 17939 if (DSAStack->isThreadPrivate(VD)) { 17940 Diag(SL, diag::err_omp_threadprivate_in_target); 17941 reportOriginalDsa(*this, DSAStack, VD, DSAStack->getTopDSA(VD, false)); 17942 return; 17943 } 17944 } 17945 if (const auto *FTD = dyn_cast<FunctionTemplateDecl>(D)) 17946 D = FTD->getTemplatedDecl(); 17947 if (auto *FD = dyn_cast<FunctionDecl>(D)) { 17948 llvm::Optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res = 17949 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(FD); 17950 if (IdLoc.isValid() && Res && *Res == OMPDeclareTargetDeclAttr::MT_Link) { 17951 Diag(IdLoc, diag::err_omp_function_in_link_clause); 17952 Diag(FD->getLocation(), diag::note_defined_here) << FD; 17953 return; 17954 } 17955 } 17956 if (auto *VD = dyn_cast<ValueDecl>(D)) { 17957 // Problem if any with var declared with incomplete type will be reported 17958 // as normal, so no need to check it here. 17959 if ((E || !VD->getType()->isIncompleteType()) && 17960 !checkValueDeclInTarget(SL, SR, *this, DSAStack, VD)) 17961 return; 17962 if (!E && !OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD)) { 17963 // Checking declaration inside declare target region. 17964 if (isa<VarDecl>(D) || isa<FunctionDecl>(D) || 17965 isa<FunctionTemplateDecl>(D)) { 17966 auto *A = OMPDeclareTargetDeclAttr::CreateImplicit( 17967 Context, OMPDeclareTargetDeclAttr::MT_To, 17968 OMPDeclareTargetDeclAttr::DT_Any, SourceRange(IdLoc, IdLoc)); 17969 D->addAttr(A); 17970 if (ASTMutationListener *ML = Context.getASTMutationListener()) 17971 ML->DeclarationMarkedOpenMPDeclareTarget(D, A); 17972 } 17973 return; 17974 } 17975 } 17976 if (!E) 17977 return; 17978 checkDeclInTargetContext(E->getExprLoc(), E->getSourceRange(), *this, D); 17979 } 17980 17981 OMPClause *Sema::ActOnOpenMPToClause(ArrayRef<Expr *> VarList, 17982 CXXScopeSpec &MapperIdScopeSpec, 17983 DeclarationNameInfo &MapperId, 17984 const OMPVarListLocTy &Locs, 17985 ArrayRef<Expr *> UnresolvedMappers) { 17986 MappableVarListInfo MVLI(VarList); 17987 checkMappableExpressionList(*this, DSAStack, OMPC_to, MVLI, Locs.StartLoc, 17988 MapperIdScopeSpec, MapperId, UnresolvedMappers); 17989 if (MVLI.ProcessedVarList.empty()) 17990 return nullptr; 17991 17992 return OMPToClause::Create( 17993 Context, Locs, MVLI.ProcessedVarList, MVLI.VarBaseDeclarations, 17994 MVLI.VarComponents, MVLI.UDMapperList, 17995 MapperIdScopeSpec.getWithLocInContext(Context), MapperId); 17996 } 17997 17998 OMPClause *Sema::ActOnOpenMPFromClause(ArrayRef<Expr *> VarList, 17999 CXXScopeSpec &MapperIdScopeSpec, 18000 DeclarationNameInfo &MapperId, 18001 const OMPVarListLocTy &Locs, 18002 ArrayRef<Expr *> UnresolvedMappers) { 18003 MappableVarListInfo MVLI(VarList); 18004 checkMappableExpressionList(*this, DSAStack, OMPC_from, MVLI, Locs.StartLoc, 18005 MapperIdScopeSpec, MapperId, UnresolvedMappers); 18006 if (MVLI.ProcessedVarList.empty()) 18007 return nullptr; 18008 18009 return OMPFromClause::Create( 18010 Context, Locs, MVLI.ProcessedVarList, MVLI.VarBaseDeclarations, 18011 MVLI.VarComponents, MVLI.UDMapperList, 18012 MapperIdScopeSpec.getWithLocInContext(Context), MapperId); 18013 } 18014 18015 OMPClause *Sema::ActOnOpenMPUseDevicePtrClause(ArrayRef<Expr *> VarList, 18016 const OMPVarListLocTy &Locs) { 18017 MappableVarListInfo MVLI(VarList); 18018 SmallVector<Expr *, 8> PrivateCopies; 18019 SmallVector<Expr *, 8> Inits; 18020 18021 for (Expr *RefExpr : VarList) { 18022 assert(RefExpr && "NULL expr in OpenMP use_device_ptr clause."); 18023 SourceLocation ELoc; 18024 SourceRange ERange; 18025 Expr *SimpleRefExpr = RefExpr; 18026 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 18027 if (Res.second) { 18028 // It will be analyzed later. 18029 MVLI.ProcessedVarList.push_back(RefExpr); 18030 PrivateCopies.push_back(nullptr); 18031 Inits.push_back(nullptr); 18032 } 18033 ValueDecl *D = Res.first; 18034 if (!D) 18035 continue; 18036 18037 QualType Type = D->getType(); 18038 Type = Type.getNonReferenceType().getUnqualifiedType(); 18039 18040 auto *VD = dyn_cast<VarDecl>(D); 18041 18042 // Item should be a pointer or reference to pointer. 18043 if (!Type->isPointerType()) { 18044 Diag(ELoc, diag::err_omp_usedeviceptr_not_a_pointer) 18045 << 0 << RefExpr->getSourceRange(); 18046 continue; 18047 } 18048 18049 // Build the private variable and the expression that refers to it. 18050 auto VDPrivate = 18051 buildVarDecl(*this, ELoc, Type, D->getName(), 18052 D->hasAttrs() ? &D->getAttrs() : nullptr, 18053 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr); 18054 if (VDPrivate->isInvalidDecl()) 18055 continue; 18056 18057 CurContext->addDecl(VDPrivate); 18058 DeclRefExpr *VDPrivateRefExpr = buildDeclRefExpr( 18059 *this, VDPrivate, RefExpr->getType().getUnqualifiedType(), ELoc); 18060 18061 // Add temporary variable to initialize the private copy of the pointer. 18062 VarDecl *VDInit = 18063 buildVarDecl(*this, RefExpr->getExprLoc(), Type, ".devptr.temp"); 18064 DeclRefExpr *VDInitRefExpr = buildDeclRefExpr( 18065 *this, VDInit, RefExpr->getType(), RefExpr->getExprLoc()); 18066 AddInitializerToDecl(VDPrivate, 18067 DefaultLvalueConversion(VDInitRefExpr).get(), 18068 /*DirectInit=*/false); 18069 18070 // If required, build a capture to implement the privatization initialized 18071 // with the current list item value. 18072 DeclRefExpr *Ref = nullptr; 18073 if (!VD) 18074 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true); 18075 MVLI.ProcessedVarList.push_back(VD ? RefExpr->IgnoreParens() : Ref); 18076 PrivateCopies.push_back(VDPrivateRefExpr); 18077 Inits.push_back(VDInitRefExpr); 18078 18079 // We need to add a data sharing attribute for this variable to make sure it 18080 // is correctly captured. A variable that shows up in a use_device_ptr has 18081 // similar properties of a first private variable. 18082 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_firstprivate, Ref); 18083 18084 // Create a mappable component for the list item. List items in this clause 18085 // only need a component. 18086 MVLI.VarBaseDeclarations.push_back(D); 18087 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1); 18088 MVLI.VarComponents.back().push_back( 18089 OMPClauseMappableExprCommon::MappableComponent(SimpleRefExpr, D)); 18090 } 18091 18092 if (MVLI.ProcessedVarList.empty()) 18093 return nullptr; 18094 18095 return OMPUseDevicePtrClause::Create( 18096 Context, Locs, MVLI.ProcessedVarList, PrivateCopies, Inits, 18097 MVLI.VarBaseDeclarations, MVLI.VarComponents); 18098 } 18099 18100 OMPClause *Sema::ActOnOpenMPIsDevicePtrClause(ArrayRef<Expr *> VarList, 18101 const OMPVarListLocTy &Locs) { 18102 MappableVarListInfo MVLI(VarList); 18103 for (Expr *RefExpr : VarList) { 18104 assert(RefExpr && "NULL expr in OpenMP is_device_ptr clause."); 18105 SourceLocation ELoc; 18106 SourceRange ERange; 18107 Expr *SimpleRefExpr = RefExpr; 18108 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 18109 if (Res.second) { 18110 // It will be analyzed later. 18111 MVLI.ProcessedVarList.push_back(RefExpr); 18112 } 18113 ValueDecl *D = Res.first; 18114 if (!D) 18115 continue; 18116 18117 QualType Type = D->getType(); 18118 // item should be a pointer or array or reference to pointer or array 18119 if (!Type.getNonReferenceType()->isPointerType() && 18120 !Type.getNonReferenceType()->isArrayType()) { 18121 Diag(ELoc, diag::err_omp_argument_type_isdeviceptr) 18122 << 0 << RefExpr->getSourceRange(); 18123 continue; 18124 } 18125 18126 // Check if the declaration in the clause does not show up in any data 18127 // sharing attribute. 18128 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false); 18129 if (isOpenMPPrivate(DVar.CKind)) { 18130 Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa) 18131 << getOpenMPClauseName(DVar.CKind) 18132 << getOpenMPClauseName(OMPC_is_device_ptr) 18133 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 18134 reportOriginalDsa(*this, DSAStack, D, DVar); 18135 continue; 18136 } 18137 18138 const Expr *ConflictExpr; 18139 if (DSAStack->checkMappableExprComponentListsForDecl( 18140 D, /*CurrentRegionOnly=*/true, 18141 [&ConflictExpr]( 18142 OMPClauseMappableExprCommon::MappableExprComponentListRef R, 18143 OpenMPClauseKind) -> bool { 18144 ConflictExpr = R.front().getAssociatedExpression(); 18145 return true; 18146 })) { 18147 Diag(ELoc, diag::err_omp_map_shared_storage) << RefExpr->getSourceRange(); 18148 Diag(ConflictExpr->getExprLoc(), diag::note_used_here) 18149 << ConflictExpr->getSourceRange(); 18150 continue; 18151 } 18152 18153 // Store the components in the stack so that they can be used to check 18154 // against other clauses later on. 18155 OMPClauseMappableExprCommon::MappableComponent MC(SimpleRefExpr, D); 18156 DSAStack->addMappableExpressionComponents( 18157 D, MC, /*WhereFoundClauseKind=*/OMPC_is_device_ptr); 18158 18159 // Record the expression we've just processed. 18160 MVLI.ProcessedVarList.push_back(SimpleRefExpr); 18161 18162 // Create a mappable component for the list item. List items in this clause 18163 // only need a component. We use a null declaration to signal fields in 18164 // 'this'. 18165 assert((isa<DeclRefExpr>(SimpleRefExpr) || 18166 isa<CXXThisExpr>(cast<MemberExpr>(SimpleRefExpr)->getBase())) && 18167 "Unexpected device pointer expression!"); 18168 MVLI.VarBaseDeclarations.push_back( 18169 isa<DeclRefExpr>(SimpleRefExpr) ? D : nullptr); 18170 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1); 18171 MVLI.VarComponents.back().push_back(MC); 18172 } 18173 18174 if (MVLI.ProcessedVarList.empty()) 18175 return nullptr; 18176 18177 return OMPIsDevicePtrClause::Create(Context, Locs, MVLI.ProcessedVarList, 18178 MVLI.VarBaseDeclarations, 18179 MVLI.VarComponents); 18180 } 18181 18182 OMPClause *Sema::ActOnOpenMPAllocateClause( 18183 Expr *Allocator, ArrayRef<Expr *> VarList, SourceLocation StartLoc, 18184 SourceLocation ColonLoc, SourceLocation LParenLoc, SourceLocation EndLoc) { 18185 if (Allocator) { 18186 // OpenMP [2.11.4 allocate Clause, Description] 18187 // allocator is an expression of omp_allocator_handle_t type. 18188 if (!findOMPAllocatorHandleT(*this, Allocator->getExprLoc(), DSAStack)) 18189 return nullptr; 18190 18191 ExprResult AllocatorRes = DefaultLvalueConversion(Allocator); 18192 if (AllocatorRes.isInvalid()) 18193 return nullptr; 18194 AllocatorRes = PerformImplicitConversion(AllocatorRes.get(), 18195 DSAStack->getOMPAllocatorHandleT(), 18196 Sema::AA_Initializing, 18197 /*AllowExplicit=*/true); 18198 if (AllocatorRes.isInvalid()) 18199 return nullptr; 18200 Allocator = AllocatorRes.get(); 18201 } else { 18202 // OpenMP 5.0, 2.11.4 allocate Clause, Restrictions. 18203 // allocate clauses that appear on a target construct or on constructs in a 18204 // target region must specify an allocator expression unless a requires 18205 // directive with the dynamic_allocators clause is present in the same 18206 // compilation unit. 18207 if (LangOpts.OpenMPIsDevice && 18208 !DSAStack->hasRequiresDeclWithClause<OMPDynamicAllocatorsClause>()) 18209 targetDiag(StartLoc, diag::err_expected_allocator_expression); 18210 } 18211 // Analyze and build list of variables. 18212 SmallVector<Expr *, 8> Vars; 18213 for (Expr *RefExpr : VarList) { 18214 assert(RefExpr && "NULL expr in OpenMP private clause."); 18215 SourceLocation ELoc; 18216 SourceRange ERange; 18217 Expr *SimpleRefExpr = RefExpr; 18218 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 18219 if (Res.second) { 18220 // It will be analyzed later. 18221 Vars.push_back(RefExpr); 18222 } 18223 ValueDecl *D = Res.first; 18224 if (!D) 18225 continue; 18226 18227 auto *VD = dyn_cast<VarDecl>(D); 18228 DeclRefExpr *Ref = nullptr; 18229 if (!VD && !CurContext->isDependentContext()) 18230 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false); 18231 Vars.push_back((VD || CurContext->isDependentContext()) 18232 ? RefExpr->IgnoreParens() 18233 : Ref); 18234 } 18235 18236 if (Vars.empty()) 18237 return nullptr; 18238 18239 if (Allocator) 18240 DSAStack->addInnerAllocatorExpr(Allocator); 18241 return OMPAllocateClause::Create(Context, StartLoc, LParenLoc, Allocator, 18242 ColonLoc, EndLoc, Vars); 18243 } 18244 18245 OMPClause *Sema::ActOnOpenMPNontemporalClause(ArrayRef<Expr *> VarList, 18246 SourceLocation StartLoc, 18247 SourceLocation LParenLoc, 18248 SourceLocation EndLoc) { 18249 SmallVector<Expr *, 8> Vars; 18250 for (Expr *RefExpr : VarList) { 18251 assert(RefExpr && "NULL expr in OpenMP nontemporal clause."); 18252 SourceLocation ELoc; 18253 SourceRange ERange; 18254 Expr *SimpleRefExpr = RefExpr; 18255 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 18256 if (Res.second) 18257 // It will be analyzed later. 18258 Vars.push_back(RefExpr); 18259 ValueDecl *D = Res.first; 18260 if (!D) 18261 continue; 18262 18263 // OpenMP 5.0, 2.9.3.1 simd Construct, Restrictions. 18264 // A list-item cannot appear in more than one nontemporal clause. 18265 if (const Expr *PrevRef = 18266 DSAStack->addUniqueNontemporal(D, SimpleRefExpr)) { 18267 Diag(ELoc, diag::err_omp_used_in_clause_twice) 18268 << 0 << getOpenMPClauseName(OMPC_nontemporal) << ERange; 18269 Diag(PrevRef->getExprLoc(), diag::note_omp_explicit_dsa) 18270 << getOpenMPClauseName(OMPC_nontemporal); 18271 continue; 18272 } 18273 18274 Vars.push_back(RefExpr); 18275 } 18276 18277 if (Vars.empty()) 18278 return nullptr; 18279 18280 return OMPNontemporalClause::Create(Context, StartLoc, LParenLoc, EndLoc, 18281 Vars); 18282 } 18283 18284 OMPClause *Sema::ActOnOpenMPInclusiveClause(ArrayRef<Expr *> VarList, 18285 SourceLocation StartLoc, 18286 SourceLocation LParenLoc, 18287 SourceLocation EndLoc) { 18288 SmallVector<Expr *, 8> Vars; 18289 for (Expr *RefExpr : VarList) { 18290 assert(RefExpr && "NULL expr in OpenMP nontemporal clause."); 18291 SourceLocation ELoc; 18292 SourceRange ERange; 18293 Expr *SimpleRefExpr = RefExpr; 18294 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange, 18295 /*AllowArraySection=*/true); 18296 if (Res.second) 18297 // It will be analyzed later. 18298 Vars.push_back(RefExpr); 18299 ValueDecl *D = Res.first; 18300 if (!D) 18301 continue; 18302 18303 const DSAStackTy::DSAVarData DVar = 18304 DSAStack->getTopDSA(D, /*FromParent=*/true); 18305 // OpenMP 5.0, 2.9.6, scan Directive, Restrictions. 18306 // A list item that appears in the inclusive or exclusive clause must appear 18307 // in a reduction clause with the inscan modifier on the enclosing 18308 // worksharing-loop, worksharing-loop SIMD, or simd construct. 18309 if (DVar.CKind != OMPC_reduction || 18310 DVar.Modifier != OMPC_REDUCTION_inscan) 18311 Diag(ELoc, diag::err_omp_inclusive_exclusive_not_reduction) 18312 << RefExpr->getSourceRange(); 18313 18314 if (DSAStack->getParentDirective() != OMPD_unknown) 18315 DSAStack->markDeclAsUsedInScanDirective(D); 18316 Vars.push_back(RefExpr); 18317 } 18318 18319 if (Vars.empty()) 18320 return nullptr; 18321 18322 return OMPInclusiveClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars); 18323 } 18324 18325 OMPClause *Sema::ActOnOpenMPExclusiveClause(ArrayRef<Expr *> VarList, 18326 SourceLocation StartLoc, 18327 SourceLocation LParenLoc, 18328 SourceLocation EndLoc) { 18329 SmallVector<Expr *, 8> Vars; 18330 for (Expr *RefExpr : VarList) { 18331 assert(RefExpr && "NULL expr in OpenMP nontemporal clause."); 18332 SourceLocation ELoc; 18333 SourceRange ERange; 18334 Expr *SimpleRefExpr = RefExpr; 18335 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange, 18336 /*AllowArraySection=*/true); 18337 if (Res.second) 18338 // It will be analyzed later. 18339 Vars.push_back(RefExpr); 18340 ValueDecl *D = Res.first; 18341 if (!D) 18342 continue; 18343 18344 OpenMPDirectiveKind ParentDirective = DSAStack->getParentDirective(); 18345 DSAStackTy::DSAVarData DVar; 18346 if (ParentDirective != OMPD_unknown) 18347 DVar = DSAStack->getTopDSA(D, /*FromParent=*/true); 18348 // OpenMP 5.0, 2.9.6, scan Directive, Restrictions. 18349 // A list item that appears in the inclusive or exclusive clause must appear 18350 // in a reduction clause with the inscan modifier on the enclosing 18351 // worksharing-loop, worksharing-loop SIMD, or simd construct. 18352 if (ParentDirective == OMPD_unknown || DVar.CKind != OMPC_reduction || 18353 DVar.Modifier != OMPC_REDUCTION_inscan) { 18354 Diag(ELoc, diag::err_omp_inclusive_exclusive_not_reduction) 18355 << RefExpr->getSourceRange(); 18356 } else { 18357 DSAStack->markDeclAsUsedInScanDirective(D); 18358 } 18359 Vars.push_back(RefExpr); 18360 } 18361 18362 if (Vars.empty()) 18363 return nullptr; 18364 18365 return OMPExclusiveClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars); 18366 } 18367