1 //===--- SemaOpenMP.cpp - Semantic Analysis for OpenMP constructs ---------===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 /// \file 9 /// This file implements semantic analysis for OpenMP directives and 10 /// clauses. 11 /// 12 //===----------------------------------------------------------------------===// 13 14 #include "TreeTransform.h" 15 #include "clang/AST/ASTContext.h" 16 #include "clang/AST/ASTMutationListener.h" 17 #include "clang/AST/CXXInheritance.h" 18 #include "clang/AST/Decl.h" 19 #include "clang/AST/DeclCXX.h" 20 #include "clang/AST/DeclOpenMP.h" 21 #include "clang/AST/OpenMPClause.h" 22 #include "clang/AST/StmtCXX.h" 23 #include "clang/AST/StmtOpenMP.h" 24 #include "clang/AST/StmtVisitor.h" 25 #include "clang/AST/TypeOrdering.h" 26 #include "clang/Basic/DiagnosticSema.h" 27 #include "clang/Basic/OpenMPKinds.h" 28 #include "clang/Basic/PartialDiagnostic.h" 29 #include "clang/Basic/TargetInfo.h" 30 #include "clang/Sema/Initialization.h" 31 #include "clang/Sema/Lookup.h" 32 #include "clang/Sema/Scope.h" 33 #include "clang/Sema/ScopeInfo.h" 34 #include "clang/Sema/SemaInternal.h" 35 #include "llvm/ADT/IndexedMap.h" 36 #include "llvm/ADT/PointerEmbeddedInt.h" 37 #include "llvm/ADT/STLExtras.h" 38 #include "llvm/ADT/StringExtras.h" 39 #include "llvm/Frontend/OpenMP/OMPConstants.h" 40 #include <set> 41 42 using namespace clang; 43 using namespace llvm::omp; 44 45 //===----------------------------------------------------------------------===// 46 // Stack of data-sharing attributes for variables 47 //===----------------------------------------------------------------------===// 48 49 static const Expr *checkMapClauseExpressionBase( 50 Sema &SemaRef, Expr *E, 51 OMPClauseMappableExprCommon::MappableExprComponentList &CurComponents, 52 OpenMPClauseKind CKind, OpenMPDirectiveKind DKind, bool NoDiagnose); 53 54 namespace { 55 /// Default data sharing attributes, which can be applied to directive. 56 enum DefaultDataSharingAttributes { 57 DSA_unspecified = 0, /// Data sharing attribute not specified. 58 DSA_none = 1 << 0, /// Default data sharing attribute 'none'. 59 DSA_shared = 1 << 1, /// Default data sharing attribute 'shared'. 60 DSA_firstprivate = 1 << 2, /// Default data sharing attribute 'firstprivate'. 61 }; 62 63 /// Stack for tracking declarations used in OpenMP directives and 64 /// clauses and their data-sharing attributes. 65 class DSAStackTy { 66 public: 67 struct DSAVarData { 68 OpenMPDirectiveKind DKind = OMPD_unknown; 69 OpenMPClauseKind CKind = OMPC_unknown; 70 unsigned Modifier = 0; 71 const Expr *RefExpr = nullptr; 72 DeclRefExpr *PrivateCopy = nullptr; 73 SourceLocation ImplicitDSALoc; 74 bool AppliedToPointee = false; 75 DSAVarData() = default; 76 DSAVarData(OpenMPDirectiveKind DKind, OpenMPClauseKind CKind, 77 const Expr *RefExpr, DeclRefExpr *PrivateCopy, 78 SourceLocation ImplicitDSALoc, unsigned Modifier, 79 bool AppliedToPointee) 80 : DKind(DKind), CKind(CKind), Modifier(Modifier), RefExpr(RefExpr), 81 PrivateCopy(PrivateCopy), ImplicitDSALoc(ImplicitDSALoc), 82 AppliedToPointee(AppliedToPointee) {} 83 }; 84 using OperatorOffsetTy = 85 llvm::SmallVector<std::pair<Expr *, OverloadedOperatorKind>, 4>; 86 using DoacrossDependMapTy = 87 llvm::DenseMap<OMPDependClause *, OperatorOffsetTy>; 88 /// Kind of the declaration used in the uses_allocators clauses. 89 enum class UsesAllocatorsDeclKind { 90 /// Predefined allocator 91 PredefinedAllocator, 92 /// User-defined allocator 93 UserDefinedAllocator, 94 /// The declaration that represent allocator trait 95 AllocatorTrait, 96 }; 97 98 private: 99 struct DSAInfo { 100 OpenMPClauseKind Attributes = OMPC_unknown; 101 unsigned Modifier = 0; 102 /// Pointer to a reference expression and a flag which shows that the 103 /// variable is marked as lastprivate(true) or not (false). 104 llvm::PointerIntPair<const Expr *, 1, bool> RefExpr; 105 DeclRefExpr *PrivateCopy = nullptr; 106 /// true if the attribute is applied to the pointee, not the variable 107 /// itself. 108 bool AppliedToPointee = false; 109 }; 110 using DeclSAMapTy = llvm::SmallDenseMap<const ValueDecl *, DSAInfo, 8>; 111 using UsedRefMapTy = llvm::SmallDenseMap<const ValueDecl *, const Expr *, 8>; 112 using LCDeclInfo = std::pair<unsigned, VarDecl *>; 113 using LoopControlVariablesMapTy = 114 llvm::SmallDenseMap<const ValueDecl *, LCDeclInfo, 8>; 115 /// Struct that associates a component with the clause kind where they are 116 /// found. 117 struct MappedExprComponentTy { 118 OMPClauseMappableExprCommon::MappableExprComponentLists Components; 119 OpenMPClauseKind Kind = OMPC_unknown; 120 }; 121 using MappedExprComponentsTy = 122 llvm::DenseMap<const ValueDecl *, MappedExprComponentTy>; 123 using CriticalsWithHintsTy = 124 llvm::StringMap<std::pair<const OMPCriticalDirective *, llvm::APSInt>>; 125 struct ReductionData { 126 using BOKPtrType = llvm::PointerEmbeddedInt<BinaryOperatorKind, 16>; 127 SourceRange ReductionRange; 128 llvm::PointerUnion<const Expr *, BOKPtrType> ReductionOp; 129 ReductionData() = default; 130 void set(BinaryOperatorKind BO, SourceRange RR) { 131 ReductionRange = RR; 132 ReductionOp = BO; 133 } 134 void set(const Expr *RefExpr, SourceRange RR) { 135 ReductionRange = RR; 136 ReductionOp = RefExpr; 137 } 138 }; 139 using DeclReductionMapTy = 140 llvm::SmallDenseMap<const ValueDecl *, ReductionData, 4>; 141 struct DefaultmapInfo { 142 OpenMPDefaultmapClauseModifier ImplicitBehavior = 143 OMPC_DEFAULTMAP_MODIFIER_unknown; 144 SourceLocation SLoc; 145 DefaultmapInfo() = default; 146 DefaultmapInfo(OpenMPDefaultmapClauseModifier M, SourceLocation Loc) 147 : ImplicitBehavior(M), SLoc(Loc) {} 148 }; 149 150 struct SharingMapTy { 151 DeclSAMapTy SharingMap; 152 DeclReductionMapTy ReductionMap; 153 UsedRefMapTy AlignedMap; 154 UsedRefMapTy NontemporalMap; 155 MappedExprComponentsTy MappedExprComponents; 156 LoopControlVariablesMapTy LCVMap; 157 DefaultDataSharingAttributes DefaultAttr = DSA_unspecified; 158 SourceLocation DefaultAttrLoc; 159 DefaultmapInfo DefaultmapMap[OMPC_DEFAULTMAP_unknown]; 160 OpenMPDirectiveKind Directive = OMPD_unknown; 161 DeclarationNameInfo DirectiveName; 162 Scope *CurScope = nullptr; 163 DeclContext *Context = nullptr; 164 SourceLocation ConstructLoc; 165 /// Set of 'depend' clauses with 'sink|source' dependence kind. Required to 166 /// get the data (loop counters etc.) about enclosing loop-based construct. 167 /// This data is required during codegen. 168 DoacrossDependMapTy DoacrossDepends; 169 /// First argument (Expr *) contains optional argument of the 170 /// 'ordered' clause, the second one is true if the regions has 'ordered' 171 /// clause, false otherwise. 172 llvm::Optional<std::pair<const Expr *, OMPOrderedClause *>> OrderedRegion; 173 unsigned AssociatedLoops = 1; 174 bool HasMutipleLoops = false; 175 const Decl *PossiblyLoopCounter = nullptr; 176 bool NowaitRegion = false; 177 bool CancelRegion = false; 178 bool LoopStart = false; 179 bool BodyComplete = false; 180 SourceLocation PrevScanLocation; 181 SourceLocation PrevOrderedLocation; 182 SourceLocation InnerTeamsRegionLoc; 183 /// Reference to the taskgroup task_reduction reference expression. 184 Expr *TaskgroupReductionRef = nullptr; 185 llvm::DenseSet<QualType> MappedClassesQualTypes; 186 SmallVector<Expr *, 4> InnerUsedAllocators; 187 llvm::DenseSet<CanonicalDeclPtr<Decl>> ImplicitTaskFirstprivates; 188 /// List of globals marked as declare target link in this target region 189 /// (isOpenMPTargetExecutionDirective(Directive) == true). 190 llvm::SmallVector<DeclRefExpr *, 4> DeclareTargetLinkVarDecls; 191 /// List of decls used in inclusive/exclusive clauses of the scan directive. 192 llvm::DenseSet<CanonicalDeclPtr<Decl>> UsedInScanDirective; 193 llvm::DenseMap<CanonicalDeclPtr<const Decl>, UsesAllocatorsDeclKind> 194 UsesAllocatorsDecls; 195 Expr *DeclareMapperVar = nullptr; 196 SharingMapTy(OpenMPDirectiveKind DKind, DeclarationNameInfo Name, 197 Scope *CurScope, SourceLocation Loc) 198 : Directive(DKind), DirectiveName(Name), CurScope(CurScope), 199 ConstructLoc(Loc) {} 200 SharingMapTy() = default; 201 }; 202 203 using StackTy = SmallVector<SharingMapTy, 4>; 204 205 /// Stack of used declaration and their data-sharing attributes. 206 DeclSAMapTy Threadprivates; 207 const FunctionScopeInfo *CurrentNonCapturingFunctionScope = nullptr; 208 SmallVector<std::pair<StackTy, const FunctionScopeInfo *>, 4> Stack; 209 /// true, if check for DSA must be from parent directive, false, if 210 /// from current directive. 211 OpenMPClauseKind ClauseKindMode = OMPC_unknown; 212 Sema &SemaRef; 213 bool ForceCapturing = false; 214 /// true if all the variables in the target executable directives must be 215 /// captured by reference. 216 bool ForceCaptureByReferenceInTargetExecutable = false; 217 CriticalsWithHintsTy Criticals; 218 unsigned IgnoredStackElements = 0; 219 220 /// Iterators over the stack iterate in order from innermost to outermost 221 /// directive. 222 using const_iterator = StackTy::const_reverse_iterator; 223 const_iterator begin() const { 224 return Stack.empty() ? const_iterator() 225 : Stack.back().first.rbegin() + IgnoredStackElements; 226 } 227 const_iterator end() const { 228 return Stack.empty() ? const_iterator() : Stack.back().first.rend(); 229 } 230 using iterator = StackTy::reverse_iterator; 231 iterator begin() { 232 return Stack.empty() ? iterator() 233 : Stack.back().first.rbegin() + IgnoredStackElements; 234 } 235 iterator end() { 236 return Stack.empty() ? iterator() : Stack.back().first.rend(); 237 } 238 239 // Convenience operations to get at the elements of the stack. 240 241 bool isStackEmpty() const { 242 return Stack.empty() || 243 Stack.back().second != CurrentNonCapturingFunctionScope || 244 Stack.back().first.size() <= IgnoredStackElements; 245 } 246 size_t getStackSize() const { 247 return isStackEmpty() ? 0 248 : Stack.back().first.size() - IgnoredStackElements; 249 } 250 251 SharingMapTy *getTopOfStackOrNull() { 252 size_t Size = getStackSize(); 253 if (Size == 0) 254 return nullptr; 255 return &Stack.back().first[Size - 1]; 256 } 257 const SharingMapTy *getTopOfStackOrNull() const { 258 return const_cast<DSAStackTy&>(*this).getTopOfStackOrNull(); 259 } 260 SharingMapTy &getTopOfStack() { 261 assert(!isStackEmpty() && "no current directive"); 262 return *getTopOfStackOrNull(); 263 } 264 const SharingMapTy &getTopOfStack() const { 265 return const_cast<DSAStackTy&>(*this).getTopOfStack(); 266 } 267 268 SharingMapTy *getSecondOnStackOrNull() { 269 size_t Size = getStackSize(); 270 if (Size <= 1) 271 return nullptr; 272 return &Stack.back().first[Size - 2]; 273 } 274 const SharingMapTy *getSecondOnStackOrNull() const { 275 return const_cast<DSAStackTy&>(*this).getSecondOnStackOrNull(); 276 } 277 278 /// Get the stack element at a certain level (previously returned by 279 /// \c getNestingLevel). 280 /// 281 /// Note that nesting levels count from outermost to innermost, and this is 282 /// the reverse of our iteration order where new inner levels are pushed at 283 /// the front of the stack. 284 SharingMapTy &getStackElemAtLevel(unsigned Level) { 285 assert(Level < getStackSize() && "no such stack element"); 286 return Stack.back().first[Level]; 287 } 288 const SharingMapTy &getStackElemAtLevel(unsigned Level) const { 289 return const_cast<DSAStackTy&>(*this).getStackElemAtLevel(Level); 290 } 291 292 DSAVarData getDSA(const_iterator &Iter, ValueDecl *D) const; 293 294 /// Checks if the variable is a local for OpenMP region. 295 bool isOpenMPLocal(VarDecl *D, const_iterator Iter) const; 296 297 /// Vector of previously declared requires directives 298 SmallVector<const OMPRequiresDecl *, 2> RequiresDecls; 299 /// omp_allocator_handle_t type. 300 QualType OMPAllocatorHandleT; 301 /// omp_depend_t type. 302 QualType OMPDependT; 303 /// omp_event_handle_t type. 304 QualType OMPEventHandleT; 305 /// omp_alloctrait_t type. 306 QualType OMPAlloctraitT; 307 /// Expression for the predefined allocators. 308 Expr *OMPPredefinedAllocators[OMPAllocateDeclAttr::OMPUserDefinedMemAlloc] = { 309 nullptr}; 310 /// Vector of previously encountered target directives 311 SmallVector<SourceLocation, 2> TargetLocations; 312 SourceLocation AtomicLocation; 313 314 public: 315 explicit DSAStackTy(Sema &S) : SemaRef(S) {} 316 317 /// Sets omp_allocator_handle_t type. 318 void setOMPAllocatorHandleT(QualType Ty) { OMPAllocatorHandleT = Ty; } 319 /// Gets omp_allocator_handle_t type. 320 QualType getOMPAllocatorHandleT() const { return OMPAllocatorHandleT; } 321 /// Sets omp_alloctrait_t type. 322 void setOMPAlloctraitT(QualType Ty) { OMPAlloctraitT = Ty; } 323 /// Gets omp_alloctrait_t type. 324 QualType getOMPAlloctraitT() const { return OMPAlloctraitT; } 325 /// Sets the given default allocator. 326 void setAllocator(OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind, 327 Expr *Allocator) { 328 OMPPredefinedAllocators[AllocatorKind] = Allocator; 329 } 330 /// Returns the specified default allocator. 331 Expr *getAllocator(OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind) const { 332 return OMPPredefinedAllocators[AllocatorKind]; 333 } 334 /// Sets omp_depend_t type. 335 void setOMPDependT(QualType Ty) { OMPDependT = Ty; } 336 /// Gets omp_depend_t type. 337 QualType getOMPDependT() const { return OMPDependT; } 338 339 /// Sets omp_event_handle_t type. 340 void setOMPEventHandleT(QualType Ty) { OMPEventHandleT = Ty; } 341 /// Gets omp_event_handle_t type. 342 QualType getOMPEventHandleT() const { return OMPEventHandleT; } 343 344 bool isClauseParsingMode() const { return ClauseKindMode != OMPC_unknown; } 345 OpenMPClauseKind getClauseParsingMode() const { 346 assert(isClauseParsingMode() && "Must be in clause parsing mode."); 347 return ClauseKindMode; 348 } 349 void setClauseParsingMode(OpenMPClauseKind K) { ClauseKindMode = K; } 350 351 bool isBodyComplete() const { 352 const SharingMapTy *Top = getTopOfStackOrNull(); 353 return Top && Top->BodyComplete; 354 } 355 void setBodyComplete() { 356 getTopOfStack().BodyComplete = true; 357 } 358 359 bool isForceVarCapturing() const { return ForceCapturing; } 360 void setForceVarCapturing(bool V) { ForceCapturing = V; } 361 362 void setForceCaptureByReferenceInTargetExecutable(bool V) { 363 ForceCaptureByReferenceInTargetExecutable = V; 364 } 365 bool isForceCaptureByReferenceInTargetExecutable() const { 366 return ForceCaptureByReferenceInTargetExecutable; 367 } 368 369 void push(OpenMPDirectiveKind DKind, const DeclarationNameInfo &DirName, 370 Scope *CurScope, SourceLocation Loc) { 371 assert(!IgnoredStackElements && 372 "cannot change stack while ignoring elements"); 373 if (Stack.empty() || 374 Stack.back().second != CurrentNonCapturingFunctionScope) 375 Stack.emplace_back(StackTy(), CurrentNonCapturingFunctionScope); 376 Stack.back().first.emplace_back(DKind, DirName, CurScope, Loc); 377 Stack.back().first.back().DefaultAttrLoc = Loc; 378 } 379 380 void pop() { 381 assert(!IgnoredStackElements && 382 "cannot change stack while ignoring elements"); 383 assert(!Stack.back().first.empty() && 384 "Data-sharing attributes stack is empty!"); 385 Stack.back().first.pop_back(); 386 } 387 388 /// RAII object to temporarily leave the scope of a directive when we want to 389 /// logically operate in its parent. 390 class ParentDirectiveScope { 391 DSAStackTy &Self; 392 bool Active; 393 public: 394 ParentDirectiveScope(DSAStackTy &Self, bool Activate) 395 : Self(Self), Active(false) { 396 if (Activate) 397 enable(); 398 } 399 ~ParentDirectiveScope() { disable(); } 400 void disable() { 401 if (Active) { 402 --Self.IgnoredStackElements; 403 Active = false; 404 } 405 } 406 void enable() { 407 if (!Active) { 408 ++Self.IgnoredStackElements; 409 Active = true; 410 } 411 } 412 }; 413 414 /// Marks that we're started loop parsing. 415 void loopInit() { 416 assert(isOpenMPLoopDirective(getCurrentDirective()) && 417 "Expected loop-based directive."); 418 getTopOfStack().LoopStart = true; 419 } 420 /// Start capturing of the variables in the loop context. 421 void loopStart() { 422 assert(isOpenMPLoopDirective(getCurrentDirective()) && 423 "Expected loop-based directive."); 424 getTopOfStack().LoopStart = false; 425 } 426 /// true, if variables are captured, false otherwise. 427 bool isLoopStarted() const { 428 assert(isOpenMPLoopDirective(getCurrentDirective()) && 429 "Expected loop-based directive."); 430 return !getTopOfStack().LoopStart; 431 } 432 /// Marks (or clears) declaration as possibly loop counter. 433 void resetPossibleLoopCounter(const Decl *D = nullptr) { 434 getTopOfStack().PossiblyLoopCounter = 435 D ? D->getCanonicalDecl() : D; 436 } 437 /// Gets the possible loop counter decl. 438 const Decl *getPossiblyLoopCunter() const { 439 return getTopOfStack().PossiblyLoopCounter; 440 } 441 /// Start new OpenMP region stack in new non-capturing function. 442 void pushFunction() { 443 assert(!IgnoredStackElements && 444 "cannot change stack while ignoring elements"); 445 const FunctionScopeInfo *CurFnScope = SemaRef.getCurFunction(); 446 assert(!isa<CapturingScopeInfo>(CurFnScope)); 447 CurrentNonCapturingFunctionScope = CurFnScope; 448 } 449 /// Pop region stack for non-capturing function. 450 void popFunction(const FunctionScopeInfo *OldFSI) { 451 assert(!IgnoredStackElements && 452 "cannot change stack while ignoring elements"); 453 if (!Stack.empty() && Stack.back().second == OldFSI) { 454 assert(Stack.back().first.empty()); 455 Stack.pop_back(); 456 } 457 CurrentNonCapturingFunctionScope = nullptr; 458 for (const FunctionScopeInfo *FSI : llvm::reverse(SemaRef.FunctionScopes)) { 459 if (!isa<CapturingScopeInfo>(FSI)) { 460 CurrentNonCapturingFunctionScope = FSI; 461 break; 462 } 463 } 464 } 465 466 void addCriticalWithHint(const OMPCriticalDirective *D, llvm::APSInt Hint) { 467 Criticals.try_emplace(D->getDirectiveName().getAsString(), D, Hint); 468 } 469 const std::pair<const OMPCriticalDirective *, llvm::APSInt> 470 getCriticalWithHint(const DeclarationNameInfo &Name) const { 471 auto I = Criticals.find(Name.getAsString()); 472 if (I != Criticals.end()) 473 return I->second; 474 return std::make_pair(nullptr, llvm::APSInt()); 475 } 476 /// If 'aligned' declaration for given variable \a D was not seen yet, 477 /// add it and return NULL; otherwise return previous occurrence's expression 478 /// for diagnostics. 479 const Expr *addUniqueAligned(const ValueDecl *D, const Expr *NewDE); 480 /// If 'nontemporal' declaration for given variable \a D was not seen yet, 481 /// add it and return NULL; otherwise return previous occurrence's expression 482 /// for diagnostics. 483 const Expr *addUniqueNontemporal(const ValueDecl *D, const Expr *NewDE); 484 485 /// Register specified variable as loop control variable. 486 void addLoopControlVariable(const ValueDecl *D, VarDecl *Capture); 487 /// Check if the specified variable is a loop control variable for 488 /// current region. 489 /// \return The index of the loop control variable in the list of associated 490 /// for-loops (from outer to inner). 491 const LCDeclInfo isLoopControlVariable(const ValueDecl *D) const; 492 /// Check if the specified variable is a loop control variable for 493 /// parent region. 494 /// \return The index of the loop control variable in the list of associated 495 /// for-loops (from outer to inner). 496 const LCDeclInfo isParentLoopControlVariable(const ValueDecl *D) const; 497 /// Check if the specified variable is a loop control variable for 498 /// current region. 499 /// \return The index of the loop control variable in the list of associated 500 /// for-loops (from outer to inner). 501 const LCDeclInfo isLoopControlVariable(const ValueDecl *D, 502 unsigned Level) const; 503 /// Get the loop control variable for the I-th loop (or nullptr) in 504 /// parent directive. 505 const ValueDecl *getParentLoopControlVariable(unsigned I) const; 506 507 /// Marks the specified decl \p D as used in scan directive. 508 void markDeclAsUsedInScanDirective(ValueDecl *D) { 509 if (SharingMapTy *Stack = getSecondOnStackOrNull()) 510 Stack->UsedInScanDirective.insert(D); 511 } 512 513 /// Checks if the specified declaration was used in the inner scan directive. 514 bool isUsedInScanDirective(ValueDecl *D) const { 515 if (const SharingMapTy *Stack = getTopOfStackOrNull()) 516 return Stack->UsedInScanDirective.count(D) > 0; 517 return false; 518 } 519 520 /// Adds explicit data sharing attribute to the specified declaration. 521 void addDSA(const ValueDecl *D, const Expr *E, OpenMPClauseKind A, 522 DeclRefExpr *PrivateCopy = nullptr, unsigned Modifier = 0, 523 bool AppliedToPointee = false); 524 525 /// Adds additional information for the reduction items with the reduction id 526 /// represented as an operator. 527 void addTaskgroupReductionData(const ValueDecl *D, SourceRange SR, 528 BinaryOperatorKind BOK); 529 /// Adds additional information for the reduction items with the reduction id 530 /// represented as reduction identifier. 531 void addTaskgroupReductionData(const ValueDecl *D, SourceRange SR, 532 const Expr *ReductionRef); 533 /// Returns the location and reduction operation from the innermost parent 534 /// region for the given \p D. 535 const DSAVarData 536 getTopMostTaskgroupReductionData(const ValueDecl *D, SourceRange &SR, 537 BinaryOperatorKind &BOK, 538 Expr *&TaskgroupDescriptor) const; 539 /// Returns the location and reduction operation from the innermost parent 540 /// region for the given \p D. 541 const DSAVarData 542 getTopMostTaskgroupReductionData(const ValueDecl *D, SourceRange &SR, 543 const Expr *&ReductionRef, 544 Expr *&TaskgroupDescriptor) const; 545 /// Return reduction reference expression for the current taskgroup or 546 /// parallel/worksharing directives with task reductions. 547 Expr *getTaskgroupReductionRef() const { 548 assert((getTopOfStack().Directive == OMPD_taskgroup || 549 ((isOpenMPParallelDirective(getTopOfStack().Directive) || 550 isOpenMPWorksharingDirective(getTopOfStack().Directive)) && 551 !isOpenMPSimdDirective(getTopOfStack().Directive))) && 552 "taskgroup reference expression requested for non taskgroup or " 553 "parallel/worksharing directive."); 554 return getTopOfStack().TaskgroupReductionRef; 555 } 556 /// Checks if the given \p VD declaration is actually a taskgroup reduction 557 /// descriptor variable at the \p Level of OpenMP regions. 558 bool isTaskgroupReductionRef(const ValueDecl *VD, unsigned Level) const { 559 return getStackElemAtLevel(Level).TaskgroupReductionRef && 560 cast<DeclRefExpr>(getStackElemAtLevel(Level).TaskgroupReductionRef) 561 ->getDecl() == VD; 562 } 563 564 /// Returns data sharing attributes from top of the stack for the 565 /// specified declaration. 566 const DSAVarData getTopDSA(ValueDecl *D, bool FromParent); 567 /// Returns data-sharing attributes for the specified declaration. 568 const DSAVarData getImplicitDSA(ValueDecl *D, bool FromParent) const; 569 /// Returns data-sharing attributes for the specified declaration. 570 const DSAVarData getImplicitDSA(ValueDecl *D, unsigned Level) const; 571 /// Checks if the specified variables has data-sharing attributes which 572 /// match specified \a CPred predicate in any directive which matches \a DPred 573 /// predicate. 574 const DSAVarData 575 hasDSA(ValueDecl *D, 576 const llvm::function_ref<bool(OpenMPClauseKind, bool)> CPred, 577 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred, 578 bool FromParent) const; 579 /// Checks if the specified variables has data-sharing attributes which 580 /// match specified \a CPred predicate in any innermost directive which 581 /// matches \a DPred predicate. 582 const DSAVarData 583 hasInnermostDSA(ValueDecl *D, 584 const llvm::function_ref<bool(OpenMPClauseKind, bool)> CPred, 585 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred, 586 bool FromParent) const; 587 /// Checks if the specified variables has explicit data-sharing 588 /// attributes which match specified \a CPred predicate at the specified 589 /// OpenMP region. 590 bool 591 hasExplicitDSA(const ValueDecl *D, 592 const llvm::function_ref<bool(OpenMPClauseKind, bool)> CPred, 593 unsigned Level, bool NotLastprivate = false) const; 594 595 /// Returns true if the directive at level \Level matches in the 596 /// specified \a DPred predicate. 597 bool hasExplicitDirective( 598 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred, 599 unsigned Level) const; 600 601 /// Finds a directive which matches specified \a DPred predicate. 602 bool hasDirective( 603 const llvm::function_ref<bool( 604 OpenMPDirectiveKind, const DeclarationNameInfo &, SourceLocation)> 605 DPred, 606 bool FromParent) const; 607 608 /// Returns currently analyzed directive. 609 OpenMPDirectiveKind getCurrentDirective() const { 610 const SharingMapTy *Top = getTopOfStackOrNull(); 611 return Top ? Top->Directive : OMPD_unknown; 612 } 613 /// Returns directive kind at specified level. 614 OpenMPDirectiveKind getDirective(unsigned Level) const { 615 assert(!isStackEmpty() && "No directive at specified level."); 616 return getStackElemAtLevel(Level).Directive; 617 } 618 /// Returns the capture region at the specified level. 619 OpenMPDirectiveKind getCaptureRegion(unsigned Level, 620 unsigned OpenMPCaptureLevel) const { 621 SmallVector<OpenMPDirectiveKind, 4> CaptureRegions; 622 getOpenMPCaptureRegions(CaptureRegions, getDirective(Level)); 623 return CaptureRegions[OpenMPCaptureLevel]; 624 } 625 /// Returns parent directive. 626 OpenMPDirectiveKind getParentDirective() const { 627 const SharingMapTy *Parent = getSecondOnStackOrNull(); 628 return Parent ? Parent->Directive : OMPD_unknown; 629 } 630 631 /// Add requires decl to internal vector 632 void addRequiresDecl(OMPRequiresDecl *RD) { 633 RequiresDecls.push_back(RD); 634 } 635 636 /// Checks if the defined 'requires' directive has specified type of clause. 637 template <typename ClauseType> 638 bool hasRequiresDeclWithClause() const { 639 return llvm::any_of(RequiresDecls, [](const OMPRequiresDecl *D) { 640 return llvm::any_of(D->clauselists(), [](const OMPClause *C) { 641 return isa<ClauseType>(C); 642 }); 643 }); 644 } 645 646 /// Checks for a duplicate clause amongst previously declared requires 647 /// directives 648 bool hasDuplicateRequiresClause(ArrayRef<OMPClause *> ClauseList) const { 649 bool IsDuplicate = false; 650 for (OMPClause *CNew : ClauseList) { 651 for (const OMPRequiresDecl *D : RequiresDecls) { 652 for (const OMPClause *CPrev : D->clauselists()) { 653 if (CNew->getClauseKind() == CPrev->getClauseKind()) { 654 SemaRef.Diag(CNew->getBeginLoc(), 655 diag::err_omp_requires_clause_redeclaration) 656 << getOpenMPClauseName(CNew->getClauseKind()); 657 SemaRef.Diag(CPrev->getBeginLoc(), 658 diag::note_omp_requires_previous_clause) 659 << getOpenMPClauseName(CPrev->getClauseKind()); 660 IsDuplicate = true; 661 } 662 } 663 } 664 } 665 return IsDuplicate; 666 } 667 668 /// Add location of previously encountered target to internal vector 669 void addTargetDirLocation(SourceLocation LocStart) { 670 TargetLocations.push_back(LocStart); 671 } 672 673 /// Add location for the first encountered atomicc directive. 674 void addAtomicDirectiveLoc(SourceLocation Loc) { 675 if (AtomicLocation.isInvalid()) 676 AtomicLocation = Loc; 677 } 678 679 /// Returns the location of the first encountered atomic directive in the 680 /// module. 681 SourceLocation getAtomicDirectiveLoc() const { 682 return AtomicLocation; 683 } 684 685 // Return previously encountered target region locations. 686 ArrayRef<SourceLocation> getEncounteredTargetLocs() const { 687 return TargetLocations; 688 } 689 690 /// Set default data sharing attribute to none. 691 void setDefaultDSANone(SourceLocation Loc) { 692 getTopOfStack().DefaultAttr = DSA_none; 693 getTopOfStack().DefaultAttrLoc = Loc; 694 } 695 /// Set default data sharing attribute to shared. 696 void setDefaultDSAShared(SourceLocation Loc) { 697 getTopOfStack().DefaultAttr = DSA_shared; 698 getTopOfStack().DefaultAttrLoc = Loc; 699 } 700 /// Set default data sharing attribute to firstprivate. 701 void setDefaultDSAFirstPrivate(SourceLocation Loc) { 702 getTopOfStack().DefaultAttr = DSA_firstprivate; 703 getTopOfStack().DefaultAttrLoc = Loc; 704 } 705 /// Set default data mapping attribute to Modifier:Kind 706 void setDefaultDMAAttr(OpenMPDefaultmapClauseModifier M, 707 OpenMPDefaultmapClauseKind Kind, 708 SourceLocation Loc) { 709 DefaultmapInfo &DMI = getTopOfStack().DefaultmapMap[Kind]; 710 DMI.ImplicitBehavior = M; 711 DMI.SLoc = Loc; 712 } 713 /// Check whether the implicit-behavior has been set in defaultmap 714 bool checkDefaultmapCategory(OpenMPDefaultmapClauseKind VariableCategory) { 715 if (VariableCategory == OMPC_DEFAULTMAP_unknown) 716 return getTopOfStack() 717 .DefaultmapMap[OMPC_DEFAULTMAP_aggregate] 718 .ImplicitBehavior != OMPC_DEFAULTMAP_MODIFIER_unknown || 719 getTopOfStack() 720 .DefaultmapMap[OMPC_DEFAULTMAP_scalar] 721 .ImplicitBehavior != OMPC_DEFAULTMAP_MODIFIER_unknown || 722 getTopOfStack() 723 .DefaultmapMap[OMPC_DEFAULTMAP_pointer] 724 .ImplicitBehavior != OMPC_DEFAULTMAP_MODIFIER_unknown; 725 return getTopOfStack().DefaultmapMap[VariableCategory].ImplicitBehavior != 726 OMPC_DEFAULTMAP_MODIFIER_unknown; 727 } 728 729 DefaultDataSharingAttributes getDefaultDSA(unsigned Level) const { 730 return getStackSize() <= Level ? DSA_unspecified 731 : getStackElemAtLevel(Level).DefaultAttr; 732 } 733 DefaultDataSharingAttributes getDefaultDSA() const { 734 return isStackEmpty() ? DSA_unspecified 735 : getTopOfStack().DefaultAttr; 736 } 737 SourceLocation getDefaultDSALocation() const { 738 return isStackEmpty() ? SourceLocation() 739 : getTopOfStack().DefaultAttrLoc; 740 } 741 OpenMPDefaultmapClauseModifier 742 getDefaultmapModifier(OpenMPDefaultmapClauseKind Kind) const { 743 return isStackEmpty() 744 ? OMPC_DEFAULTMAP_MODIFIER_unknown 745 : getTopOfStack().DefaultmapMap[Kind].ImplicitBehavior; 746 } 747 OpenMPDefaultmapClauseModifier 748 getDefaultmapModifierAtLevel(unsigned Level, 749 OpenMPDefaultmapClauseKind Kind) const { 750 return getStackElemAtLevel(Level).DefaultmapMap[Kind].ImplicitBehavior; 751 } 752 bool isDefaultmapCapturedByRef(unsigned Level, 753 OpenMPDefaultmapClauseKind Kind) const { 754 OpenMPDefaultmapClauseModifier M = 755 getDefaultmapModifierAtLevel(Level, Kind); 756 if (Kind == OMPC_DEFAULTMAP_scalar || Kind == OMPC_DEFAULTMAP_pointer) { 757 return (M == OMPC_DEFAULTMAP_MODIFIER_alloc) || 758 (M == OMPC_DEFAULTMAP_MODIFIER_to) || 759 (M == OMPC_DEFAULTMAP_MODIFIER_from) || 760 (M == OMPC_DEFAULTMAP_MODIFIER_tofrom); 761 } 762 return true; 763 } 764 static bool mustBeFirstprivateBase(OpenMPDefaultmapClauseModifier M, 765 OpenMPDefaultmapClauseKind Kind) { 766 switch (Kind) { 767 case OMPC_DEFAULTMAP_scalar: 768 case OMPC_DEFAULTMAP_pointer: 769 return (M == OMPC_DEFAULTMAP_MODIFIER_unknown) || 770 (M == OMPC_DEFAULTMAP_MODIFIER_firstprivate) || 771 (M == OMPC_DEFAULTMAP_MODIFIER_default); 772 case OMPC_DEFAULTMAP_aggregate: 773 return M == OMPC_DEFAULTMAP_MODIFIER_firstprivate; 774 default: 775 break; 776 } 777 llvm_unreachable("Unexpected OpenMPDefaultmapClauseKind enum"); 778 } 779 bool mustBeFirstprivateAtLevel(unsigned Level, 780 OpenMPDefaultmapClauseKind Kind) const { 781 OpenMPDefaultmapClauseModifier M = 782 getDefaultmapModifierAtLevel(Level, Kind); 783 return mustBeFirstprivateBase(M, Kind); 784 } 785 bool mustBeFirstprivate(OpenMPDefaultmapClauseKind Kind) const { 786 OpenMPDefaultmapClauseModifier M = getDefaultmapModifier(Kind); 787 return mustBeFirstprivateBase(M, Kind); 788 } 789 790 /// Checks if the specified variable is a threadprivate. 791 bool isThreadPrivate(VarDecl *D) { 792 const DSAVarData DVar = getTopDSA(D, false); 793 return isOpenMPThreadPrivate(DVar.CKind); 794 } 795 796 /// Marks current region as ordered (it has an 'ordered' clause). 797 void setOrderedRegion(bool IsOrdered, const Expr *Param, 798 OMPOrderedClause *Clause) { 799 if (IsOrdered) 800 getTopOfStack().OrderedRegion.emplace(Param, Clause); 801 else 802 getTopOfStack().OrderedRegion.reset(); 803 } 804 /// Returns true, if region is ordered (has associated 'ordered' clause), 805 /// false - otherwise. 806 bool isOrderedRegion() const { 807 if (const SharingMapTy *Top = getTopOfStackOrNull()) 808 return Top->OrderedRegion.hasValue(); 809 return false; 810 } 811 /// Returns optional parameter for the ordered region. 812 std::pair<const Expr *, OMPOrderedClause *> getOrderedRegionParam() const { 813 if (const SharingMapTy *Top = getTopOfStackOrNull()) 814 if (Top->OrderedRegion.hasValue()) 815 return Top->OrderedRegion.getValue(); 816 return std::make_pair(nullptr, nullptr); 817 } 818 /// Returns true, if parent region is ordered (has associated 819 /// 'ordered' clause), false - otherwise. 820 bool isParentOrderedRegion() const { 821 if (const SharingMapTy *Parent = getSecondOnStackOrNull()) 822 return Parent->OrderedRegion.hasValue(); 823 return false; 824 } 825 /// Returns optional parameter for the ordered region. 826 std::pair<const Expr *, OMPOrderedClause *> 827 getParentOrderedRegionParam() const { 828 if (const SharingMapTy *Parent = getSecondOnStackOrNull()) 829 if (Parent->OrderedRegion.hasValue()) 830 return Parent->OrderedRegion.getValue(); 831 return std::make_pair(nullptr, nullptr); 832 } 833 /// Marks current region as nowait (it has a 'nowait' clause). 834 void setNowaitRegion(bool IsNowait = true) { 835 getTopOfStack().NowaitRegion = IsNowait; 836 } 837 /// Returns true, if parent region is nowait (has associated 838 /// 'nowait' clause), false - otherwise. 839 bool isParentNowaitRegion() const { 840 if (const SharingMapTy *Parent = getSecondOnStackOrNull()) 841 return Parent->NowaitRegion; 842 return false; 843 } 844 /// Marks parent region as cancel region. 845 void setParentCancelRegion(bool Cancel = true) { 846 if (SharingMapTy *Parent = getSecondOnStackOrNull()) 847 Parent->CancelRegion |= Cancel; 848 } 849 /// Return true if current region has inner cancel construct. 850 bool isCancelRegion() const { 851 const SharingMapTy *Top = getTopOfStackOrNull(); 852 return Top ? Top->CancelRegion : false; 853 } 854 855 /// Mark that parent region already has scan directive. 856 void setParentHasScanDirective(SourceLocation Loc) { 857 if (SharingMapTy *Parent = getSecondOnStackOrNull()) 858 Parent->PrevScanLocation = Loc; 859 } 860 /// Return true if current region has inner cancel construct. 861 bool doesParentHasScanDirective() const { 862 const SharingMapTy *Top = getSecondOnStackOrNull(); 863 return Top ? Top->PrevScanLocation.isValid() : false; 864 } 865 /// Return true if current region has inner cancel construct. 866 SourceLocation getParentScanDirectiveLoc() const { 867 const SharingMapTy *Top = getSecondOnStackOrNull(); 868 return Top ? Top->PrevScanLocation : SourceLocation(); 869 } 870 /// Mark that parent region already has ordered directive. 871 void setParentHasOrderedDirective(SourceLocation Loc) { 872 if (SharingMapTy *Parent = getSecondOnStackOrNull()) 873 Parent->PrevOrderedLocation = Loc; 874 } 875 /// Return true if current region has inner ordered construct. 876 bool doesParentHasOrderedDirective() const { 877 const SharingMapTy *Top = getSecondOnStackOrNull(); 878 return Top ? Top->PrevOrderedLocation.isValid() : false; 879 } 880 /// Returns the location of the previously specified ordered directive. 881 SourceLocation getParentOrderedDirectiveLoc() const { 882 const SharingMapTy *Top = getSecondOnStackOrNull(); 883 return Top ? Top->PrevOrderedLocation : SourceLocation(); 884 } 885 886 /// Set collapse value for the region. 887 void setAssociatedLoops(unsigned Val) { 888 getTopOfStack().AssociatedLoops = Val; 889 if (Val > 1) 890 getTopOfStack().HasMutipleLoops = true; 891 } 892 /// Return collapse value for region. 893 unsigned getAssociatedLoops() const { 894 const SharingMapTy *Top = getTopOfStackOrNull(); 895 return Top ? Top->AssociatedLoops : 0; 896 } 897 /// Returns true if the construct is associated with multiple loops. 898 bool hasMutipleLoops() const { 899 const SharingMapTy *Top = getTopOfStackOrNull(); 900 return Top ? Top->HasMutipleLoops : false; 901 } 902 903 /// Marks current target region as one with closely nested teams 904 /// region. 905 void setParentTeamsRegionLoc(SourceLocation TeamsRegionLoc) { 906 if (SharingMapTy *Parent = getSecondOnStackOrNull()) 907 Parent->InnerTeamsRegionLoc = TeamsRegionLoc; 908 } 909 /// Returns true, if current region has closely nested teams region. 910 bool hasInnerTeamsRegion() const { 911 return getInnerTeamsRegionLoc().isValid(); 912 } 913 /// Returns location of the nested teams region (if any). 914 SourceLocation getInnerTeamsRegionLoc() const { 915 const SharingMapTy *Top = getTopOfStackOrNull(); 916 return Top ? Top->InnerTeamsRegionLoc : SourceLocation(); 917 } 918 919 Scope *getCurScope() const { 920 const SharingMapTy *Top = getTopOfStackOrNull(); 921 return Top ? Top->CurScope : nullptr; 922 } 923 void setContext(DeclContext *DC) { getTopOfStack().Context = DC; } 924 SourceLocation getConstructLoc() const { 925 const SharingMapTy *Top = getTopOfStackOrNull(); 926 return Top ? Top->ConstructLoc : SourceLocation(); 927 } 928 929 /// Do the check specified in \a Check to all component lists and return true 930 /// if any issue is found. 931 bool checkMappableExprComponentListsForDecl( 932 const ValueDecl *VD, bool CurrentRegionOnly, 933 const llvm::function_ref< 934 bool(OMPClauseMappableExprCommon::MappableExprComponentListRef, 935 OpenMPClauseKind)> 936 Check) const { 937 if (isStackEmpty()) 938 return false; 939 auto SI = begin(); 940 auto SE = end(); 941 942 if (SI == SE) 943 return false; 944 945 if (CurrentRegionOnly) 946 SE = std::next(SI); 947 else 948 std::advance(SI, 1); 949 950 for (; SI != SE; ++SI) { 951 auto MI = SI->MappedExprComponents.find(VD); 952 if (MI != SI->MappedExprComponents.end()) 953 for (OMPClauseMappableExprCommon::MappableExprComponentListRef L : 954 MI->second.Components) 955 if (Check(L, MI->second.Kind)) 956 return true; 957 } 958 return false; 959 } 960 961 /// Do the check specified in \a Check to all component lists at a given level 962 /// and return true if any issue is found. 963 bool checkMappableExprComponentListsForDeclAtLevel( 964 const ValueDecl *VD, unsigned Level, 965 const llvm::function_ref< 966 bool(OMPClauseMappableExprCommon::MappableExprComponentListRef, 967 OpenMPClauseKind)> 968 Check) const { 969 if (getStackSize() <= Level) 970 return false; 971 972 const SharingMapTy &StackElem = getStackElemAtLevel(Level); 973 auto MI = StackElem.MappedExprComponents.find(VD); 974 if (MI != StackElem.MappedExprComponents.end()) 975 for (OMPClauseMappableExprCommon::MappableExprComponentListRef L : 976 MI->second.Components) 977 if (Check(L, MI->second.Kind)) 978 return true; 979 return false; 980 } 981 982 /// Create a new mappable expression component list associated with a given 983 /// declaration and initialize it with the provided list of components. 984 void addMappableExpressionComponents( 985 const ValueDecl *VD, 986 OMPClauseMappableExprCommon::MappableExprComponentListRef Components, 987 OpenMPClauseKind WhereFoundClauseKind) { 988 MappedExprComponentTy &MEC = getTopOfStack().MappedExprComponents[VD]; 989 // Create new entry and append the new components there. 990 MEC.Components.resize(MEC.Components.size() + 1); 991 MEC.Components.back().append(Components.begin(), Components.end()); 992 MEC.Kind = WhereFoundClauseKind; 993 } 994 995 unsigned getNestingLevel() const { 996 assert(!isStackEmpty()); 997 return getStackSize() - 1; 998 } 999 void addDoacrossDependClause(OMPDependClause *C, 1000 const OperatorOffsetTy &OpsOffs) { 1001 SharingMapTy *Parent = getSecondOnStackOrNull(); 1002 assert(Parent && isOpenMPWorksharingDirective(Parent->Directive)); 1003 Parent->DoacrossDepends.try_emplace(C, OpsOffs); 1004 } 1005 llvm::iterator_range<DoacrossDependMapTy::const_iterator> 1006 getDoacrossDependClauses() const { 1007 const SharingMapTy &StackElem = getTopOfStack(); 1008 if (isOpenMPWorksharingDirective(StackElem.Directive)) { 1009 const DoacrossDependMapTy &Ref = StackElem.DoacrossDepends; 1010 return llvm::make_range(Ref.begin(), Ref.end()); 1011 } 1012 return llvm::make_range(StackElem.DoacrossDepends.end(), 1013 StackElem.DoacrossDepends.end()); 1014 } 1015 1016 // Store types of classes which have been explicitly mapped 1017 void addMappedClassesQualTypes(QualType QT) { 1018 SharingMapTy &StackElem = getTopOfStack(); 1019 StackElem.MappedClassesQualTypes.insert(QT); 1020 } 1021 1022 // Return set of mapped classes types 1023 bool isClassPreviouslyMapped(QualType QT) const { 1024 const SharingMapTy &StackElem = getTopOfStack(); 1025 return StackElem.MappedClassesQualTypes.count(QT) != 0; 1026 } 1027 1028 /// Adds global declare target to the parent target region. 1029 void addToParentTargetRegionLinkGlobals(DeclRefExpr *E) { 1030 assert(*OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration( 1031 E->getDecl()) == OMPDeclareTargetDeclAttr::MT_Link && 1032 "Expected declare target link global."); 1033 for (auto &Elem : *this) { 1034 if (isOpenMPTargetExecutionDirective(Elem.Directive)) { 1035 Elem.DeclareTargetLinkVarDecls.push_back(E); 1036 return; 1037 } 1038 } 1039 } 1040 1041 /// Returns the list of globals with declare target link if current directive 1042 /// is target. 1043 ArrayRef<DeclRefExpr *> getLinkGlobals() const { 1044 assert(isOpenMPTargetExecutionDirective(getCurrentDirective()) && 1045 "Expected target executable directive."); 1046 return getTopOfStack().DeclareTargetLinkVarDecls; 1047 } 1048 1049 /// Adds list of allocators expressions. 1050 void addInnerAllocatorExpr(Expr *E) { 1051 getTopOfStack().InnerUsedAllocators.push_back(E); 1052 } 1053 /// Return list of used allocators. 1054 ArrayRef<Expr *> getInnerAllocators() const { 1055 return getTopOfStack().InnerUsedAllocators; 1056 } 1057 /// Marks the declaration as implicitly firstprivate nin the task-based 1058 /// regions. 1059 void addImplicitTaskFirstprivate(unsigned Level, Decl *D) { 1060 getStackElemAtLevel(Level).ImplicitTaskFirstprivates.insert(D); 1061 } 1062 /// Checks if the decl is implicitly firstprivate in the task-based region. 1063 bool isImplicitTaskFirstprivate(Decl *D) const { 1064 return getTopOfStack().ImplicitTaskFirstprivates.count(D) > 0; 1065 } 1066 1067 /// Marks decl as used in uses_allocators clause as the allocator. 1068 void addUsesAllocatorsDecl(const Decl *D, UsesAllocatorsDeclKind Kind) { 1069 getTopOfStack().UsesAllocatorsDecls.try_emplace(D, Kind); 1070 } 1071 /// Checks if specified decl is used in uses allocator clause as the 1072 /// allocator. 1073 Optional<UsesAllocatorsDeclKind> isUsesAllocatorsDecl(unsigned Level, 1074 const Decl *D) const { 1075 const SharingMapTy &StackElem = getTopOfStack(); 1076 auto I = StackElem.UsesAllocatorsDecls.find(D); 1077 if (I == StackElem.UsesAllocatorsDecls.end()) 1078 return None; 1079 return I->getSecond(); 1080 } 1081 Optional<UsesAllocatorsDeclKind> isUsesAllocatorsDecl(const Decl *D) const { 1082 const SharingMapTy &StackElem = getTopOfStack(); 1083 auto I = StackElem.UsesAllocatorsDecls.find(D); 1084 if (I == StackElem.UsesAllocatorsDecls.end()) 1085 return None; 1086 return I->getSecond(); 1087 } 1088 1089 void addDeclareMapperVarRef(Expr *Ref) { 1090 SharingMapTy &StackElem = getTopOfStack(); 1091 StackElem.DeclareMapperVar = Ref; 1092 } 1093 const Expr *getDeclareMapperVarRef() const { 1094 const SharingMapTy *Top = getTopOfStackOrNull(); 1095 return Top ? Top->DeclareMapperVar : nullptr; 1096 } 1097 }; 1098 1099 bool isImplicitTaskingRegion(OpenMPDirectiveKind DKind) { 1100 return isOpenMPParallelDirective(DKind) || isOpenMPTeamsDirective(DKind); 1101 } 1102 1103 bool isImplicitOrExplicitTaskingRegion(OpenMPDirectiveKind DKind) { 1104 return isImplicitTaskingRegion(DKind) || isOpenMPTaskingDirective(DKind) || 1105 DKind == OMPD_unknown; 1106 } 1107 1108 } // namespace 1109 1110 static const Expr *getExprAsWritten(const Expr *E) { 1111 if (const auto *FE = dyn_cast<FullExpr>(E)) 1112 E = FE->getSubExpr(); 1113 1114 if (const auto *MTE = dyn_cast<MaterializeTemporaryExpr>(E)) 1115 E = MTE->getSubExpr(); 1116 1117 while (const auto *Binder = dyn_cast<CXXBindTemporaryExpr>(E)) 1118 E = Binder->getSubExpr(); 1119 1120 if (const auto *ICE = dyn_cast<ImplicitCastExpr>(E)) 1121 E = ICE->getSubExprAsWritten(); 1122 return E->IgnoreParens(); 1123 } 1124 1125 static Expr *getExprAsWritten(Expr *E) { 1126 return const_cast<Expr *>(getExprAsWritten(const_cast<const Expr *>(E))); 1127 } 1128 1129 static const ValueDecl *getCanonicalDecl(const ValueDecl *D) { 1130 if (const auto *CED = dyn_cast<OMPCapturedExprDecl>(D)) 1131 if (const auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit()))) 1132 D = ME->getMemberDecl(); 1133 const auto *VD = dyn_cast<VarDecl>(D); 1134 const auto *FD = dyn_cast<FieldDecl>(D); 1135 if (VD != nullptr) { 1136 VD = VD->getCanonicalDecl(); 1137 D = VD; 1138 } else { 1139 assert(FD); 1140 FD = FD->getCanonicalDecl(); 1141 D = FD; 1142 } 1143 return D; 1144 } 1145 1146 static ValueDecl *getCanonicalDecl(ValueDecl *D) { 1147 return const_cast<ValueDecl *>( 1148 getCanonicalDecl(const_cast<const ValueDecl *>(D))); 1149 } 1150 1151 DSAStackTy::DSAVarData DSAStackTy::getDSA(const_iterator &Iter, 1152 ValueDecl *D) const { 1153 D = getCanonicalDecl(D); 1154 auto *VD = dyn_cast<VarDecl>(D); 1155 const auto *FD = dyn_cast<FieldDecl>(D); 1156 DSAVarData DVar; 1157 if (Iter == end()) { 1158 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 1159 // in a region but not in construct] 1160 // File-scope or namespace-scope variables referenced in called routines 1161 // in the region are shared unless they appear in a threadprivate 1162 // directive. 1163 if (VD && !VD->isFunctionOrMethodVarDecl() && !isa<ParmVarDecl>(VD)) 1164 DVar.CKind = OMPC_shared; 1165 1166 // OpenMP [2.9.1.2, Data-sharing Attribute Rules for Variables Referenced 1167 // in a region but not in construct] 1168 // Variables with static storage duration that are declared in called 1169 // routines in the region are shared. 1170 if (VD && VD->hasGlobalStorage()) 1171 DVar.CKind = OMPC_shared; 1172 1173 // Non-static data members are shared by default. 1174 if (FD) 1175 DVar.CKind = OMPC_shared; 1176 1177 return DVar; 1178 } 1179 1180 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 1181 // in a Construct, C/C++, predetermined, p.1] 1182 // Variables with automatic storage duration that are declared in a scope 1183 // inside the construct are private. 1184 if (VD && isOpenMPLocal(VD, Iter) && VD->isLocalVarDecl() && 1185 (VD->getStorageClass() == SC_Auto || VD->getStorageClass() == SC_None)) { 1186 DVar.CKind = OMPC_private; 1187 return DVar; 1188 } 1189 1190 DVar.DKind = Iter->Directive; 1191 // Explicitly specified attributes and local variables with predetermined 1192 // attributes. 1193 if (Iter->SharingMap.count(D)) { 1194 const DSAInfo &Data = Iter->SharingMap.lookup(D); 1195 DVar.RefExpr = Data.RefExpr.getPointer(); 1196 DVar.PrivateCopy = Data.PrivateCopy; 1197 DVar.CKind = Data.Attributes; 1198 DVar.ImplicitDSALoc = Iter->DefaultAttrLoc; 1199 DVar.Modifier = Data.Modifier; 1200 DVar.AppliedToPointee = Data.AppliedToPointee; 1201 return DVar; 1202 } 1203 1204 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 1205 // in a Construct, C/C++, implicitly determined, p.1] 1206 // In a parallel or task construct, the data-sharing attributes of these 1207 // variables are determined by the default clause, if present. 1208 switch (Iter->DefaultAttr) { 1209 case DSA_shared: 1210 DVar.CKind = OMPC_shared; 1211 DVar.ImplicitDSALoc = Iter->DefaultAttrLoc; 1212 return DVar; 1213 case DSA_none: 1214 return DVar; 1215 case DSA_firstprivate: 1216 if (VD->getStorageDuration() == SD_Static && 1217 VD->getDeclContext()->isFileContext()) { 1218 DVar.CKind = OMPC_unknown; 1219 } else { 1220 DVar.CKind = OMPC_firstprivate; 1221 } 1222 DVar.ImplicitDSALoc = Iter->DefaultAttrLoc; 1223 return DVar; 1224 case DSA_unspecified: 1225 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 1226 // in a Construct, implicitly determined, p.2] 1227 // In a parallel construct, if no default clause is present, these 1228 // variables are shared. 1229 DVar.ImplicitDSALoc = Iter->DefaultAttrLoc; 1230 if ((isOpenMPParallelDirective(DVar.DKind) && 1231 !isOpenMPTaskLoopDirective(DVar.DKind)) || 1232 isOpenMPTeamsDirective(DVar.DKind)) { 1233 DVar.CKind = OMPC_shared; 1234 return DVar; 1235 } 1236 1237 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 1238 // in a Construct, implicitly determined, p.4] 1239 // In a task construct, if no default clause is present, a variable that in 1240 // the enclosing context is determined to be shared by all implicit tasks 1241 // bound to the current team is shared. 1242 if (isOpenMPTaskingDirective(DVar.DKind)) { 1243 DSAVarData DVarTemp; 1244 const_iterator I = Iter, E = end(); 1245 do { 1246 ++I; 1247 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables 1248 // Referenced in a Construct, implicitly determined, p.6] 1249 // In a task construct, if no default clause is present, a variable 1250 // whose data-sharing attribute is not determined by the rules above is 1251 // firstprivate. 1252 DVarTemp = getDSA(I, D); 1253 if (DVarTemp.CKind != OMPC_shared) { 1254 DVar.RefExpr = nullptr; 1255 DVar.CKind = OMPC_firstprivate; 1256 return DVar; 1257 } 1258 } while (I != E && !isImplicitTaskingRegion(I->Directive)); 1259 DVar.CKind = 1260 (DVarTemp.CKind == OMPC_unknown) ? OMPC_firstprivate : OMPC_shared; 1261 return DVar; 1262 } 1263 } 1264 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 1265 // in a Construct, implicitly determined, p.3] 1266 // For constructs other than task, if no default clause is present, these 1267 // variables inherit their data-sharing attributes from the enclosing 1268 // context. 1269 return getDSA(++Iter, D); 1270 } 1271 1272 const Expr *DSAStackTy::addUniqueAligned(const ValueDecl *D, 1273 const Expr *NewDE) { 1274 assert(!isStackEmpty() && "Data sharing attributes stack is empty"); 1275 D = getCanonicalDecl(D); 1276 SharingMapTy &StackElem = getTopOfStack(); 1277 auto It = StackElem.AlignedMap.find(D); 1278 if (It == StackElem.AlignedMap.end()) { 1279 assert(NewDE && "Unexpected nullptr expr to be added into aligned map"); 1280 StackElem.AlignedMap[D] = NewDE; 1281 return nullptr; 1282 } 1283 assert(It->second && "Unexpected nullptr expr in the aligned map"); 1284 return It->second; 1285 } 1286 1287 const Expr *DSAStackTy::addUniqueNontemporal(const ValueDecl *D, 1288 const Expr *NewDE) { 1289 assert(!isStackEmpty() && "Data sharing attributes stack is empty"); 1290 D = getCanonicalDecl(D); 1291 SharingMapTy &StackElem = getTopOfStack(); 1292 auto It = StackElem.NontemporalMap.find(D); 1293 if (It == StackElem.NontemporalMap.end()) { 1294 assert(NewDE && "Unexpected nullptr expr to be added into aligned map"); 1295 StackElem.NontemporalMap[D] = NewDE; 1296 return nullptr; 1297 } 1298 assert(It->second && "Unexpected nullptr expr in the aligned map"); 1299 return It->second; 1300 } 1301 1302 void DSAStackTy::addLoopControlVariable(const ValueDecl *D, VarDecl *Capture) { 1303 assert(!isStackEmpty() && "Data-sharing attributes stack is empty"); 1304 D = getCanonicalDecl(D); 1305 SharingMapTy &StackElem = getTopOfStack(); 1306 StackElem.LCVMap.try_emplace( 1307 D, LCDeclInfo(StackElem.LCVMap.size() + 1, Capture)); 1308 } 1309 1310 const DSAStackTy::LCDeclInfo 1311 DSAStackTy::isLoopControlVariable(const ValueDecl *D) const { 1312 assert(!isStackEmpty() && "Data-sharing attributes stack is empty"); 1313 D = getCanonicalDecl(D); 1314 const SharingMapTy &StackElem = getTopOfStack(); 1315 auto It = StackElem.LCVMap.find(D); 1316 if (It != StackElem.LCVMap.end()) 1317 return It->second; 1318 return {0, nullptr}; 1319 } 1320 1321 const DSAStackTy::LCDeclInfo 1322 DSAStackTy::isLoopControlVariable(const ValueDecl *D, unsigned Level) const { 1323 assert(!isStackEmpty() && "Data-sharing attributes stack is empty"); 1324 D = getCanonicalDecl(D); 1325 for (unsigned I = Level + 1; I > 0; --I) { 1326 const SharingMapTy &StackElem = getStackElemAtLevel(I - 1); 1327 auto It = StackElem.LCVMap.find(D); 1328 if (It != StackElem.LCVMap.end()) 1329 return It->second; 1330 } 1331 return {0, nullptr}; 1332 } 1333 1334 const DSAStackTy::LCDeclInfo 1335 DSAStackTy::isParentLoopControlVariable(const ValueDecl *D) const { 1336 const SharingMapTy *Parent = getSecondOnStackOrNull(); 1337 assert(Parent && "Data-sharing attributes stack is empty"); 1338 D = getCanonicalDecl(D); 1339 auto It = Parent->LCVMap.find(D); 1340 if (It != Parent->LCVMap.end()) 1341 return It->second; 1342 return {0, nullptr}; 1343 } 1344 1345 const ValueDecl *DSAStackTy::getParentLoopControlVariable(unsigned I) const { 1346 const SharingMapTy *Parent = getSecondOnStackOrNull(); 1347 assert(Parent && "Data-sharing attributes stack is empty"); 1348 if (Parent->LCVMap.size() < I) 1349 return nullptr; 1350 for (const auto &Pair : Parent->LCVMap) 1351 if (Pair.second.first == I) 1352 return Pair.first; 1353 return nullptr; 1354 } 1355 1356 void DSAStackTy::addDSA(const ValueDecl *D, const Expr *E, OpenMPClauseKind A, 1357 DeclRefExpr *PrivateCopy, unsigned Modifier, 1358 bool AppliedToPointee) { 1359 D = getCanonicalDecl(D); 1360 if (A == OMPC_threadprivate) { 1361 DSAInfo &Data = Threadprivates[D]; 1362 Data.Attributes = A; 1363 Data.RefExpr.setPointer(E); 1364 Data.PrivateCopy = nullptr; 1365 Data.Modifier = Modifier; 1366 } else { 1367 DSAInfo &Data = getTopOfStack().SharingMap[D]; 1368 assert(Data.Attributes == OMPC_unknown || (A == Data.Attributes) || 1369 (A == OMPC_firstprivate && Data.Attributes == OMPC_lastprivate) || 1370 (A == OMPC_lastprivate && Data.Attributes == OMPC_firstprivate) || 1371 (isLoopControlVariable(D).first && A == OMPC_private)); 1372 Data.Modifier = Modifier; 1373 if (A == OMPC_lastprivate && Data.Attributes == OMPC_firstprivate) { 1374 Data.RefExpr.setInt(/*IntVal=*/true); 1375 return; 1376 } 1377 const bool IsLastprivate = 1378 A == OMPC_lastprivate || Data.Attributes == OMPC_lastprivate; 1379 Data.Attributes = A; 1380 Data.RefExpr.setPointerAndInt(E, IsLastprivate); 1381 Data.PrivateCopy = PrivateCopy; 1382 Data.AppliedToPointee = AppliedToPointee; 1383 if (PrivateCopy) { 1384 DSAInfo &Data = getTopOfStack().SharingMap[PrivateCopy->getDecl()]; 1385 Data.Modifier = Modifier; 1386 Data.Attributes = A; 1387 Data.RefExpr.setPointerAndInt(PrivateCopy, IsLastprivate); 1388 Data.PrivateCopy = nullptr; 1389 Data.AppliedToPointee = AppliedToPointee; 1390 } 1391 } 1392 } 1393 1394 /// Build a variable declaration for OpenMP loop iteration variable. 1395 static VarDecl *buildVarDecl(Sema &SemaRef, SourceLocation Loc, QualType Type, 1396 StringRef Name, const AttrVec *Attrs = nullptr, 1397 DeclRefExpr *OrigRef = nullptr) { 1398 DeclContext *DC = SemaRef.CurContext; 1399 IdentifierInfo *II = &SemaRef.PP.getIdentifierTable().get(Name); 1400 TypeSourceInfo *TInfo = SemaRef.Context.getTrivialTypeSourceInfo(Type, Loc); 1401 auto *Decl = 1402 VarDecl::Create(SemaRef.Context, DC, Loc, Loc, II, Type, TInfo, SC_None); 1403 if (Attrs) { 1404 for (specific_attr_iterator<AlignedAttr> I(Attrs->begin()), E(Attrs->end()); 1405 I != E; ++I) 1406 Decl->addAttr(*I); 1407 } 1408 Decl->setImplicit(); 1409 if (OrigRef) { 1410 Decl->addAttr( 1411 OMPReferencedVarAttr::CreateImplicit(SemaRef.Context, OrigRef)); 1412 } 1413 return Decl; 1414 } 1415 1416 static DeclRefExpr *buildDeclRefExpr(Sema &S, VarDecl *D, QualType Ty, 1417 SourceLocation Loc, 1418 bool RefersToCapture = false) { 1419 D->setReferenced(); 1420 D->markUsed(S.Context); 1421 return DeclRefExpr::Create(S.getASTContext(), NestedNameSpecifierLoc(), 1422 SourceLocation(), D, RefersToCapture, Loc, Ty, 1423 VK_LValue); 1424 } 1425 1426 void DSAStackTy::addTaskgroupReductionData(const ValueDecl *D, SourceRange SR, 1427 BinaryOperatorKind BOK) { 1428 D = getCanonicalDecl(D); 1429 assert(!isStackEmpty() && "Data-sharing attributes stack is empty"); 1430 assert( 1431 getTopOfStack().SharingMap[D].Attributes == OMPC_reduction && 1432 "Additional reduction info may be specified only for reduction items."); 1433 ReductionData &ReductionData = getTopOfStack().ReductionMap[D]; 1434 assert(ReductionData.ReductionRange.isInvalid() && 1435 (getTopOfStack().Directive == OMPD_taskgroup || 1436 ((isOpenMPParallelDirective(getTopOfStack().Directive) || 1437 isOpenMPWorksharingDirective(getTopOfStack().Directive)) && 1438 !isOpenMPSimdDirective(getTopOfStack().Directive))) && 1439 "Additional reduction info may be specified only once for reduction " 1440 "items."); 1441 ReductionData.set(BOK, SR); 1442 Expr *&TaskgroupReductionRef = 1443 getTopOfStack().TaskgroupReductionRef; 1444 if (!TaskgroupReductionRef) { 1445 VarDecl *VD = buildVarDecl(SemaRef, SR.getBegin(), 1446 SemaRef.Context.VoidPtrTy, ".task_red."); 1447 TaskgroupReductionRef = 1448 buildDeclRefExpr(SemaRef, VD, SemaRef.Context.VoidPtrTy, SR.getBegin()); 1449 } 1450 } 1451 1452 void DSAStackTy::addTaskgroupReductionData(const ValueDecl *D, SourceRange SR, 1453 const Expr *ReductionRef) { 1454 D = getCanonicalDecl(D); 1455 assert(!isStackEmpty() && "Data-sharing attributes stack is empty"); 1456 assert( 1457 getTopOfStack().SharingMap[D].Attributes == OMPC_reduction && 1458 "Additional reduction info may be specified only for reduction items."); 1459 ReductionData &ReductionData = getTopOfStack().ReductionMap[D]; 1460 assert(ReductionData.ReductionRange.isInvalid() && 1461 (getTopOfStack().Directive == OMPD_taskgroup || 1462 ((isOpenMPParallelDirective(getTopOfStack().Directive) || 1463 isOpenMPWorksharingDirective(getTopOfStack().Directive)) && 1464 !isOpenMPSimdDirective(getTopOfStack().Directive))) && 1465 "Additional reduction info may be specified only once for reduction " 1466 "items."); 1467 ReductionData.set(ReductionRef, SR); 1468 Expr *&TaskgroupReductionRef = 1469 getTopOfStack().TaskgroupReductionRef; 1470 if (!TaskgroupReductionRef) { 1471 VarDecl *VD = buildVarDecl(SemaRef, SR.getBegin(), 1472 SemaRef.Context.VoidPtrTy, ".task_red."); 1473 TaskgroupReductionRef = 1474 buildDeclRefExpr(SemaRef, VD, SemaRef.Context.VoidPtrTy, SR.getBegin()); 1475 } 1476 } 1477 1478 const DSAStackTy::DSAVarData DSAStackTy::getTopMostTaskgroupReductionData( 1479 const ValueDecl *D, SourceRange &SR, BinaryOperatorKind &BOK, 1480 Expr *&TaskgroupDescriptor) const { 1481 D = getCanonicalDecl(D); 1482 assert(!isStackEmpty() && "Data-sharing attributes stack is empty."); 1483 for (const_iterator I = begin() + 1, E = end(); I != E; ++I) { 1484 const DSAInfo &Data = I->SharingMap.lookup(D); 1485 if (Data.Attributes != OMPC_reduction || 1486 Data.Modifier != OMPC_REDUCTION_task) 1487 continue; 1488 const ReductionData &ReductionData = I->ReductionMap.lookup(D); 1489 if (!ReductionData.ReductionOp || 1490 ReductionData.ReductionOp.is<const Expr *>()) 1491 return DSAVarData(); 1492 SR = ReductionData.ReductionRange; 1493 BOK = ReductionData.ReductionOp.get<ReductionData::BOKPtrType>(); 1494 assert(I->TaskgroupReductionRef && "taskgroup reduction reference " 1495 "expression for the descriptor is not " 1496 "set."); 1497 TaskgroupDescriptor = I->TaskgroupReductionRef; 1498 return DSAVarData(I->Directive, OMPC_reduction, Data.RefExpr.getPointer(), 1499 Data.PrivateCopy, I->DefaultAttrLoc, OMPC_REDUCTION_task, 1500 /*AppliedToPointee=*/false); 1501 } 1502 return DSAVarData(); 1503 } 1504 1505 const DSAStackTy::DSAVarData DSAStackTy::getTopMostTaskgroupReductionData( 1506 const ValueDecl *D, SourceRange &SR, const Expr *&ReductionRef, 1507 Expr *&TaskgroupDescriptor) const { 1508 D = getCanonicalDecl(D); 1509 assert(!isStackEmpty() && "Data-sharing attributes stack is empty."); 1510 for (const_iterator I = begin() + 1, E = end(); I != E; ++I) { 1511 const DSAInfo &Data = I->SharingMap.lookup(D); 1512 if (Data.Attributes != OMPC_reduction || 1513 Data.Modifier != OMPC_REDUCTION_task) 1514 continue; 1515 const ReductionData &ReductionData = I->ReductionMap.lookup(D); 1516 if (!ReductionData.ReductionOp || 1517 !ReductionData.ReductionOp.is<const Expr *>()) 1518 return DSAVarData(); 1519 SR = ReductionData.ReductionRange; 1520 ReductionRef = ReductionData.ReductionOp.get<const Expr *>(); 1521 assert(I->TaskgroupReductionRef && "taskgroup reduction reference " 1522 "expression for the descriptor is not " 1523 "set."); 1524 TaskgroupDescriptor = I->TaskgroupReductionRef; 1525 return DSAVarData(I->Directive, OMPC_reduction, Data.RefExpr.getPointer(), 1526 Data.PrivateCopy, I->DefaultAttrLoc, OMPC_REDUCTION_task, 1527 /*AppliedToPointee=*/false); 1528 } 1529 return DSAVarData(); 1530 } 1531 1532 bool DSAStackTy::isOpenMPLocal(VarDecl *D, const_iterator I) const { 1533 D = D->getCanonicalDecl(); 1534 for (const_iterator E = end(); I != E; ++I) { 1535 if (isImplicitOrExplicitTaskingRegion(I->Directive) || 1536 isOpenMPTargetExecutionDirective(I->Directive)) { 1537 if (I->CurScope) { 1538 Scope *TopScope = I->CurScope->getParent(); 1539 Scope *CurScope = getCurScope(); 1540 while (CurScope && CurScope != TopScope && !CurScope->isDeclScope(D)) 1541 CurScope = CurScope->getParent(); 1542 return CurScope != TopScope; 1543 } 1544 for (DeclContext *DC = D->getDeclContext(); DC; DC = DC->getParent()) 1545 if (I->Context == DC) 1546 return true; 1547 return false; 1548 } 1549 } 1550 return false; 1551 } 1552 1553 static bool isConstNotMutableType(Sema &SemaRef, QualType Type, 1554 bool AcceptIfMutable = true, 1555 bool *IsClassType = nullptr) { 1556 ASTContext &Context = SemaRef.getASTContext(); 1557 Type = Type.getNonReferenceType().getCanonicalType(); 1558 bool IsConstant = Type.isConstant(Context); 1559 Type = Context.getBaseElementType(Type); 1560 const CXXRecordDecl *RD = AcceptIfMutable && SemaRef.getLangOpts().CPlusPlus 1561 ? Type->getAsCXXRecordDecl() 1562 : nullptr; 1563 if (const auto *CTSD = dyn_cast_or_null<ClassTemplateSpecializationDecl>(RD)) 1564 if (const ClassTemplateDecl *CTD = CTSD->getSpecializedTemplate()) 1565 RD = CTD->getTemplatedDecl(); 1566 if (IsClassType) 1567 *IsClassType = RD; 1568 return IsConstant && !(SemaRef.getLangOpts().CPlusPlus && RD && 1569 RD->hasDefinition() && RD->hasMutableFields()); 1570 } 1571 1572 static bool rejectConstNotMutableType(Sema &SemaRef, const ValueDecl *D, 1573 QualType Type, OpenMPClauseKind CKind, 1574 SourceLocation ELoc, 1575 bool AcceptIfMutable = true, 1576 bool ListItemNotVar = false) { 1577 ASTContext &Context = SemaRef.getASTContext(); 1578 bool IsClassType; 1579 if (isConstNotMutableType(SemaRef, Type, AcceptIfMutable, &IsClassType)) { 1580 unsigned Diag = ListItemNotVar 1581 ? diag::err_omp_const_list_item 1582 : IsClassType ? diag::err_omp_const_not_mutable_variable 1583 : diag::err_omp_const_variable; 1584 SemaRef.Diag(ELoc, Diag) << getOpenMPClauseName(CKind); 1585 if (!ListItemNotVar && D) { 1586 const VarDecl *VD = dyn_cast<VarDecl>(D); 1587 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) == 1588 VarDecl::DeclarationOnly; 1589 SemaRef.Diag(D->getLocation(), 1590 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 1591 << D; 1592 } 1593 return true; 1594 } 1595 return false; 1596 } 1597 1598 const DSAStackTy::DSAVarData DSAStackTy::getTopDSA(ValueDecl *D, 1599 bool FromParent) { 1600 D = getCanonicalDecl(D); 1601 DSAVarData DVar; 1602 1603 auto *VD = dyn_cast<VarDecl>(D); 1604 auto TI = Threadprivates.find(D); 1605 if (TI != Threadprivates.end()) { 1606 DVar.RefExpr = TI->getSecond().RefExpr.getPointer(); 1607 DVar.CKind = OMPC_threadprivate; 1608 DVar.Modifier = TI->getSecond().Modifier; 1609 return DVar; 1610 } 1611 if (VD && VD->hasAttr<OMPThreadPrivateDeclAttr>()) { 1612 DVar.RefExpr = buildDeclRefExpr( 1613 SemaRef, VD, D->getType().getNonReferenceType(), 1614 VD->getAttr<OMPThreadPrivateDeclAttr>()->getLocation()); 1615 DVar.CKind = OMPC_threadprivate; 1616 addDSA(D, DVar.RefExpr, OMPC_threadprivate); 1617 return DVar; 1618 } 1619 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 1620 // in a Construct, C/C++, predetermined, p.1] 1621 // Variables appearing in threadprivate directives are threadprivate. 1622 if ((VD && VD->getTLSKind() != VarDecl::TLS_None && 1623 !(VD->hasAttr<OMPThreadPrivateDeclAttr>() && 1624 SemaRef.getLangOpts().OpenMPUseTLS && 1625 SemaRef.getASTContext().getTargetInfo().isTLSSupported())) || 1626 (VD && VD->getStorageClass() == SC_Register && 1627 VD->hasAttr<AsmLabelAttr>() && !VD->isLocalVarDecl())) { 1628 DVar.RefExpr = buildDeclRefExpr( 1629 SemaRef, VD, D->getType().getNonReferenceType(), D->getLocation()); 1630 DVar.CKind = OMPC_threadprivate; 1631 addDSA(D, DVar.RefExpr, OMPC_threadprivate); 1632 return DVar; 1633 } 1634 if (SemaRef.getLangOpts().OpenMPCUDAMode && VD && 1635 VD->isLocalVarDeclOrParm() && !isStackEmpty() && 1636 !isLoopControlVariable(D).first) { 1637 const_iterator IterTarget = 1638 std::find_if(begin(), end(), [](const SharingMapTy &Data) { 1639 return isOpenMPTargetExecutionDirective(Data.Directive); 1640 }); 1641 if (IterTarget != end()) { 1642 const_iterator ParentIterTarget = IterTarget + 1; 1643 for (const_iterator Iter = begin(); 1644 Iter != ParentIterTarget; ++Iter) { 1645 if (isOpenMPLocal(VD, Iter)) { 1646 DVar.RefExpr = 1647 buildDeclRefExpr(SemaRef, VD, D->getType().getNonReferenceType(), 1648 D->getLocation()); 1649 DVar.CKind = OMPC_threadprivate; 1650 return DVar; 1651 } 1652 } 1653 if (!isClauseParsingMode() || IterTarget != begin()) { 1654 auto DSAIter = IterTarget->SharingMap.find(D); 1655 if (DSAIter != IterTarget->SharingMap.end() && 1656 isOpenMPPrivate(DSAIter->getSecond().Attributes)) { 1657 DVar.RefExpr = DSAIter->getSecond().RefExpr.getPointer(); 1658 DVar.CKind = OMPC_threadprivate; 1659 return DVar; 1660 } 1661 const_iterator End = end(); 1662 if (!SemaRef.isOpenMPCapturedByRef( 1663 D, std::distance(ParentIterTarget, End), 1664 /*OpenMPCaptureLevel=*/0)) { 1665 DVar.RefExpr = 1666 buildDeclRefExpr(SemaRef, VD, D->getType().getNonReferenceType(), 1667 IterTarget->ConstructLoc); 1668 DVar.CKind = OMPC_threadprivate; 1669 return DVar; 1670 } 1671 } 1672 } 1673 } 1674 1675 if (isStackEmpty()) 1676 // Not in OpenMP execution region and top scope was already checked. 1677 return DVar; 1678 1679 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 1680 // in a Construct, C/C++, predetermined, p.4] 1681 // Static data members are shared. 1682 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 1683 // in a Construct, C/C++, predetermined, p.7] 1684 // Variables with static storage duration that are declared in a scope 1685 // inside the construct are shared. 1686 if (VD && VD->isStaticDataMember()) { 1687 // Check for explicitly specified attributes. 1688 const_iterator I = begin(); 1689 const_iterator EndI = end(); 1690 if (FromParent && I != EndI) 1691 ++I; 1692 if (I != EndI) { 1693 auto It = I->SharingMap.find(D); 1694 if (It != I->SharingMap.end()) { 1695 const DSAInfo &Data = It->getSecond(); 1696 DVar.RefExpr = Data.RefExpr.getPointer(); 1697 DVar.PrivateCopy = Data.PrivateCopy; 1698 DVar.CKind = Data.Attributes; 1699 DVar.ImplicitDSALoc = I->DefaultAttrLoc; 1700 DVar.DKind = I->Directive; 1701 DVar.Modifier = Data.Modifier; 1702 DVar.AppliedToPointee = Data.AppliedToPointee; 1703 return DVar; 1704 } 1705 } 1706 1707 DVar.CKind = OMPC_shared; 1708 return DVar; 1709 } 1710 1711 auto &&MatchesAlways = [](OpenMPDirectiveKind) { return true; }; 1712 // The predetermined shared attribute for const-qualified types having no 1713 // mutable members was removed after OpenMP 3.1. 1714 if (SemaRef.LangOpts.OpenMP <= 31) { 1715 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 1716 // in a Construct, C/C++, predetermined, p.6] 1717 // Variables with const qualified type having no mutable member are 1718 // shared. 1719 if (isConstNotMutableType(SemaRef, D->getType())) { 1720 // Variables with const-qualified type having no mutable member may be 1721 // listed in a firstprivate clause, even if they are static data members. 1722 DSAVarData DVarTemp = hasInnermostDSA( 1723 D, 1724 [](OpenMPClauseKind C, bool) { 1725 return C == OMPC_firstprivate || C == OMPC_shared; 1726 }, 1727 MatchesAlways, FromParent); 1728 if (DVarTemp.CKind != OMPC_unknown && DVarTemp.RefExpr) 1729 return DVarTemp; 1730 1731 DVar.CKind = OMPC_shared; 1732 return DVar; 1733 } 1734 } 1735 1736 // Explicitly specified attributes and local variables with predetermined 1737 // attributes. 1738 const_iterator I = begin(); 1739 const_iterator EndI = end(); 1740 if (FromParent && I != EndI) 1741 ++I; 1742 if (I == EndI) 1743 return DVar; 1744 auto It = I->SharingMap.find(D); 1745 if (It != I->SharingMap.end()) { 1746 const DSAInfo &Data = It->getSecond(); 1747 DVar.RefExpr = Data.RefExpr.getPointer(); 1748 DVar.PrivateCopy = Data.PrivateCopy; 1749 DVar.CKind = Data.Attributes; 1750 DVar.ImplicitDSALoc = I->DefaultAttrLoc; 1751 DVar.DKind = I->Directive; 1752 DVar.Modifier = Data.Modifier; 1753 DVar.AppliedToPointee = Data.AppliedToPointee; 1754 } 1755 1756 return DVar; 1757 } 1758 1759 const DSAStackTy::DSAVarData DSAStackTy::getImplicitDSA(ValueDecl *D, 1760 bool FromParent) const { 1761 if (isStackEmpty()) { 1762 const_iterator I; 1763 return getDSA(I, D); 1764 } 1765 D = getCanonicalDecl(D); 1766 const_iterator StartI = begin(); 1767 const_iterator EndI = end(); 1768 if (FromParent && StartI != EndI) 1769 ++StartI; 1770 return getDSA(StartI, D); 1771 } 1772 1773 const DSAStackTy::DSAVarData DSAStackTy::getImplicitDSA(ValueDecl *D, 1774 unsigned Level) const { 1775 if (getStackSize() <= Level) 1776 return DSAVarData(); 1777 D = getCanonicalDecl(D); 1778 const_iterator StartI = std::next(begin(), getStackSize() - 1 - Level); 1779 return getDSA(StartI, D); 1780 } 1781 1782 const DSAStackTy::DSAVarData 1783 DSAStackTy::hasDSA(ValueDecl *D, 1784 const llvm::function_ref<bool(OpenMPClauseKind, bool)> CPred, 1785 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred, 1786 bool FromParent) const { 1787 if (isStackEmpty()) 1788 return {}; 1789 D = getCanonicalDecl(D); 1790 const_iterator I = begin(); 1791 const_iterator EndI = end(); 1792 if (FromParent && I != EndI) 1793 ++I; 1794 for (; I != EndI; ++I) { 1795 if (!DPred(I->Directive) && 1796 !isImplicitOrExplicitTaskingRegion(I->Directive)) 1797 continue; 1798 const_iterator NewI = I; 1799 DSAVarData DVar = getDSA(NewI, D); 1800 if (I == NewI && CPred(DVar.CKind, DVar.AppliedToPointee)) 1801 return DVar; 1802 } 1803 return {}; 1804 } 1805 1806 const DSAStackTy::DSAVarData DSAStackTy::hasInnermostDSA( 1807 ValueDecl *D, const llvm::function_ref<bool(OpenMPClauseKind, bool)> CPred, 1808 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred, 1809 bool FromParent) const { 1810 if (isStackEmpty()) 1811 return {}; 1812 D = getCanonicalDecl(D); 1813 const_iterator StartI = begin(); 1814 const_iterator EndI = end(); 1815 if (FromParent && StartI != EndI) 1816 ++StartI; 1817 if (StartI == EndI || !DPred(StartI->Directive)) 1818 return {}; 1819 const_iterator NewI = StartI; 1820 DSAVarData DVar = getDSA(NewI, D); 1821 return (NewI == StartI && CPred(DVar.CKind, DVar.AppliedToPointee)) 1822 ? DVar 1823 : DSAVarData(); 1824 } 1825 1826 bool DSAStackTy::hasExplicitDSA( 1827 const ValueDecl *D, 1828 const llvm::function_ref<bool(OpenMPClauseKind, bool)> CPred, 1829 unsigned Level, bool NotLastprivate) const { 1830 if (getStackSize() <= Level) 1831 return false; 1832 D = getCanonicalDecl(D); 1833 const SharingMapTy &StackElem = getStackElemAtLevel(Level); 1834 auto I = StackElem.SharingMap.find(D); 1835 if (I != StackElem.SharingMap.end() && I->getSecond().RefExpr.getPointer() && 1836 CPred(I->getSecond().Attributes, I->getSecond().AppliedToPointee) && 1837 (!NotLastprivate || !I->getSecond().RefExpr.getInt())) 1838 return true; 1839 // Check predetermined rules for the loop control variables. 1840 auto LI = StackElem.LCVMap.find(D); 1841 if (LI != StackElem.LCVMap.end()) 1842 return CPred(OMPC_private, /*AppliedToPointee=*/false); 1843 return false; 1844 } 1845 1846 bool DSAStackTy::hasExplicitDirective( 1847 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred, 1848 unsigned Level) const { 1849 if (getStackSize() <= Level) 1850 return false; 1851 const SharingMapTy &StackElem = getStackElemAtLevel(Level); 1852 return DPred(StackElem.Directive); 1853 } 1854 1855 bool DSAStackTy::hasDirective( 1856 const llvm::function_ref<bool(OpenMPDirectiveKind, 1857 const DeclarationNameInfo &, SourceLocation)> 1858 DPred, 1859 bool FromParent) const { 1860 // We look only in the enclosing region. 1861 size_t Skip = FromParent ? 2 : 1; 1862 for (const_iterator I = begin() + std::min(Skip, getStackSize()), E = end(); 1863 I != E; ++I) { 1864 if (DPred(I->Directive, I->DirectiveName, I->ConstructLoc)) 1865 return true; 1866 } 1867 return false; 1868 } 1869 1870 void Sema::InitDataSharingAttributesStack() { 1871 VarDataSharingAttributesStack = new DSAStackTy(*this); 1872 } 1873 1874 #define DSAStack static_cast<DSAStackTy *>(VarDataSharingAttributesStack) 1875 1876 void Sema::pushOpenMPFunctionRegion() { 1877 DSAStack->pushFunction(); 1878 } 1879 1880 void Sema::popOpenMPFunctionRegion(const FunctionScopeInfo *OldFSI) { 1881 DSAStack->popFunction(OldFSI); 1882 } 1883 1884 static bool isOpenMPDeviceDelayedContext(Sema &S) { 1885 assert(S.LangOpts.OpenMP && S.LangOpts.OpenMPIsDevice && 1886 "Expected OpenMP device compilation."); 1887 return !S.isInOpenMPTargetExecutionDirective(); 1888 } 1889 1890 namespace { 1891 /// Status of the function emission on the host/device. 1892 enum class FunctionEmissionStatus { 1893 Emitted, 1894 Discarded, 1895 Unknown, 1896 }; 1897 } // anonymous namespace 1898 1899 Sema::SemaDiagnosticBuilder Sema::diagIfOpenMPDeviceCode(SourceLocation Loc, 1900 unsigned DiagID, 1901 FunctionDecl *FD) { 1902 assert(LangOpts.OpenMP && LangOpts.OpenMPIsDevice && 1903 "Expected OpenMP device compilation."); 1904 1905 SemaDiagnosticBuilder::Kind Kind = SemaDiagnosticBuilder::K_Nop; 1906 if (FD) { 1907 FunctionEmissionStatus FES = getEmissionStatus(FD); 1908 switch (FES) { 1909 case FunctionEmissionStatus::Emitted: 1910 Kind = SemaDiagnosticBuilder::K_Immediate; 1911 break; 1912 case FunctionEmissionStatus::Unknown: 1913 // TODO: We should always delay diagnostics here in case a target 1914 // region is in a function we do not emit. However, as the 1915 // current diagnostics are associated with the function containing 1916 // the target region and we do not emit that one, we would miss out 1917 // on diagnostics for the target region itself. We need to anchor 1918 // the diagnostics with the new generated function *or* ensure we 1919 // emit diagnostics associated with the surrounding function. 1920 Kind = isOpenMPDeviceDelayedContext(*this) 1921 ? SemaDiagnosticBuilder::K_Deferred 1922 : SemaDiagnosticBuilder::K_Immediate; 1923 break; 1924 case FunctionEmissionStatus::TemplateDiscarded: 1925 case FunctionEmissionStatus::OMPDiscarded: 1926 Kind = SemaDiagnosticBuilder::K_Nop; 1927 break; 1928 case FunctionEmissionStatus::CUDADiscarded: 1929 llvm_unreachable("CUDADiscarded unexpected in OpenMP device compilation"); 1930 break; 1931 } 1932 } 1933 1934 return SemaDiagnosticBuilder(Kind, Loc, DiagID, FD, *this); 1935 } 1936 1937 Sema::SemaDiagnosticBuilder Sema::diagIfOpenMPHostCode(SourceLocation Loc, 1938 unsigned DiagID, 1939 FunctionDecl *FD) { 1940 assert(LangOpts.OpenMP && !LangOpts.OpenMPIsDevice && 1941 "Expected OpenMP host compilation."); 1942 1943 SemaDiagnosticBuilder::Kind Kind = SemaDiagnosticBuilder::K_Nop; 1944 if (FD) { 1945 FunctionEmissionStatus FES = getEmissionStatus(FD); 1946 switch (FES) { 1947 case FunctionEmissionStatus::Emitted: 1948 Kind = SemaDiagnosticBuilder::K_Immediate; 1949 break; 1950 case FunctionEmissionStatus::Unknown: 1951 Kind = SemaDiagnosticBuilder::K_Deferred; 1952 break; 1953 case FunctionEmissionStatus::TemplateDiscarded: 1954 case FunctionEmissionStatus::OMPDiscarded: 1955 case FunctionEmissionStatus::CUDADiscarded: 1956 Kind = SemaDiagnosticBuilder::K_Nop; 1957 break; 1958 } 1959 } 1960 1961 return SemaDiagnosticBuilder(Kind, Loc, DiagID, FD, *this); 1962 } 1963 1964 static OpenMPDefaultmapClauseKind 1965 getVariableCategoryFromDecl(const LangOptions &LO, const ValueDecl *VD) { 1966 if (LO.OpenMP <= 45) { 1967 if (VD->getType().getNonReferenceType()->isScalarType()) 1968 return OMPC_DEFAULTMAP_scalar; 1969 return OMPC_DEFAULTMAP_aggregate; 1970 } 1971 if (VD->getType().getNonReferenceType()->isAnyPointerType()) 1972 return OMPC_DEFAULTMAP_pointer; 1973 if (VD->getType().getNonReferenceType()->isScalarType()) 1974 return OMPC_DEFAULTMAP_scalar; 1975 return OMPC_DEFAULTMAP_aggregate; 1976 } 1977 1978 bool Sema::isOpenMPCapturedByRef(const ValueDecl *D, unsigned Level, 1979 unsigned OpenMPCaptureLevel) const { 1980 assert(LangOpts.OpenMP && "OpenMP is not allowed"); 1981 1982 ASTContext &Ctx = getASTContext(); 1983 bool IsByRef = true; 1984 1985 // Find the directive that is associated with the provided scope. 1986 D = cast<ValueDecl>(D->getCanonicalDecl()); 1987 QualType Ty = D->getType(); 1988 1989 bool IsVariableUsedInMapClause = false; 1990 if (DSAStack->hasExplicitDirective(isOpenMPTargetExecutionDirective, Level)) { 1991 // This table summarizes how a given variable should be passed to the device 1992 // given its type and the clauses where it appears. This table is based on 1993 // the description in OpenMP 4.5 [2.10.4, target Construct] and 1994 // OpenMP 4.5 [2.15.5, Data-mapping Attribute Rules and Clauses]. 1995 // 1996 // ========================================================================= 1997 // | type | defaultmap | pvt | first | is_device_ptr | map | res. | 1998 // | |(tofrom:scalar)| | pvt | | | | 1999 // ========================================================================= 2000 // | scl | | | | - | | bycopy| 2001 // | scl | | - | x | - | - | bycopy| 2002 // | scl | | x | - | - | - | null | 2003 // | scl | x | | | - | | byref | 2004 // | scl | x | - | x | - | - | bycopy| 2005 // | scl | x | x | - | - | - | null | 2006 // | scl | | - | - | - | x | byref | 2007 // | scl | x | - | - | - | x | byref | 2008 // 2009 // | agg | n.a. | | | - | | byref | 2010 // | agg | n.a. | - | x | - | - | byref | 2011 // | agg | n.a. | x | - | - | - | null | 2012 // | agg | n.a. | - | - | - | x | byref | 2013 // | agg | n.a. | - | - | - | x[] | byref | 2014 // 2015 // | ptr | n.a. | | | - | | bycopy| 2016 // | ptr | n.a. | - | x | - | - | bycopy| 2017 // | ptr | n.a. | x | - | - | - | null | 2018 // | ptr | n.a. | - | - | - | x | byref | 2019 // | ptr | n.a. | - | - | - | x[] | bycopy| 2020 // | ptr | n.a. | - | - | x | | bycopy| 2021 // | ptr | n.a. | - | - | x | x | bycopy| 2022 // | ptr | n.a. | - | - | x | x[] | bycopy| 2023 // ========================================================================= 2024 // Legend: 2025 // scl - scalar 2026 // ptr - pointer 2027 // agg - aggregate 2028 // x - applies 2029 // - - invalid in this combination 2030 // [] - mapped with an array section 2031 // byref - should be mapped by reference 2032 // byval - should be mapped by value 2033 // null - initialize a local variable to null on the device 2034 // 2035 // Observations: 2036 // - All scalar declarations that show up in a map clause have to be passed 2037 // by reference, because they may have been mapped in the enclosing data 2038 // environment. 2039 // - If the scalar value does not fit the size of uintptr, it has to be 2040 // passed by reference, regardless the result in the table above. 2041 // - For pointers mapped by value that have either an implicit map or an 2042 // array section, the runtime library may pass the NULL value to the 2043 // device instead of the value passed to it by the compiler. 2044 2045 if (Ty->isReferenceType()) 2046 Ty = Ty->castAs<ReferenceType>()->getPointeeType(); 2047 2048 // Locate map clauses and see if the variable being captured is referred to 2049 // in any of those clauses. Here we only care about variables, not fields, 2050 // because fields are part of aggregates. 2051 bool IsVariableAssociatedWithSection = false; 2052 2053 DSAStack->checkMappableExprComponentListsForDeclAtLevel( 2054 D, Level, 2055 [&IsVariableUsedInMapClause, &IsVariableAssociatedWithSection, D]( 2056 OMPClauseMappableExprCommon::MappableExprComponentListRef 2057 MapExprComponents, 2058 OpenMPClauseKind WhereFoundClauseKind) { 2059 // Only the map clause information influences how a variable is 2060 // captured. E.g. is_device_ptr does not require changing the default 2061 // behavior. 2062 if (WhereFoundClauseKind != OMPC_map) 2063 return false; 2064 2065 auto EI = MapExprComponents.rbegin(); 2066 auto EE = MapExprComponents.rend(); 2067 2068 assert(EI != EE && "Invalid map expression!"); 2069 2070 if (isa<DeclRefExpr>(EI->getAssociatedExpression())) 2071 IsVariableUsedInMapClause |= EI->getAssociatedDeclaration() == D; 2072 2073 ++EI; 2074 if (EI == EE) 2075 return false; 2076 2077 if (isa<ArraySubscriptExpr>(EI->getAssociatedExpression()) || 2078 isa<OMPArraySectionExpr>(EI->getAssociatedExpression()) || 2079 isa<MemberExpr>(EI->getAssociatedExpression()) || 2080 isa<OMPArrayShapingExpr>(EI->getAssociatedExpression())) { 2081 IsVariableAssociatedWithSection = true; 2082 // There is nothing more we need to know about this variable. 2083 return true; 2084 } 2085 2086 // Keep looking for more map info. 2087 return false; 2088 }); 2089 2090 if (IsVariableUsedInMapClause) { 2091 // If variable is identified in a map clause it is always captured by 2092 // reference except if it is a pointer that is dereferenced somehow. 2093 IsByRef = !(Ty->isPointerType() && IsVariableAssociatedWithSection); 2094 } else { 2095 // By default, all the data that has a scalar type is mapped by copy 2096 // (except for reduction variables). 2097 // Defaultmap scalar is mutual exclusive to defaultmap pointer 2098 IsByRef = (DSAStack->isForceCaptureByReferenceInTargetExecutable() && 2099 !Ty->isAnyPointerType()) || 2100 !Ty->isScalarType() || 2101 DSAStack->isDefaultmapCapturedByRef( 2102 Level, getVariableCategoryFromDecl(LangOpts, D)) || 2103 DSAStack->hasExplicitDSA( 2104 D, 2105 [](OpenMPClauseKind K, bool AppliedToPointee) { 2106 return K == OMPC_reduction && !AppliedToPointee; 2107 }, 2108 Level); 2109 } 2110 } 2111 2112 if (IsByRef && Ty.getNonReferenceType()->isScalarType()) { 2113 IsByRef = 2114 ((IsVariableUsedInMapClause && 2115 DSAStack->getCaptureRegion(Level, OpenMPCaptureLevel) == 2116 OMPD_target) || 2117 !(DSAStack->hasExplicitDSA( 2118 D, 2119 [](OpenMPClauseKind K, bool AppliedToPointee) -> bool { 2120 return K == OMPC_firstprivate || 2121 (K == OMPC_reduction && AppliedToPointee); 2122 }, 2123 Level, /*NotLastprivate=*/true) || 2124 DSAStack->isUsesAllocatorsDecl(Level, D))) && 2125 // If the variable is artificial and must be captured by value - try to 2126 // capture by value. 2127 !(isa<OMPCapturedExprDecl>(D) && !D->hasAttr<OMPCaptureNoInitAttr>() && 2128 !cast<OMPCapturedExprDecl>(D)->getInit()->isGLValue()) && 2129 // If the variable is implicitly firstprivate and scalar - capture by 2130 // copy 2131 !(DSAStack->getDefaultDSA() == DSA_firstprivate && 2132 !DSAStack->hasExplicitDSA( 2133 D, [](OpenMPClauseKind K, bool) { return K != OMPC_unknown; }, 2134 Level) && 2135 !DSAStack->isLoopControlVariable(D, Level).first); 2136 } 2137 2138 // When passing data by copy, we need to make sure it fits the uintptr size 2139 // and alignment, because the runtime library only deals with uintptr types. 2140 // If it does not fit the uintptr size, we need to pass the data by reference 2141 // instead. 2142 if (!IsByRef && 2143 (Ctx.getTypeSizeInChars(Ty) > 2144 Ctx.getTypeSizeInChars(Ctx.getUIntPtrType()) || 2145 Ctx.getDeclAlign(D) > Ctx.getTypeAlignInChars(Ctx.getUIntPtrType()))) { 2146 IsByRef = true; 2147 } 2148 2149 return IsByRef; 2150 } 2151 2152 unsigned Sema::getOpenMPNestingLevel() const { 2153 assert(getLangOpts().OpenMP); 2154 return DSAStack->getNestingLevel(); 2155 } 2156 2157 bool Sema::isInOpenMPTargetExecutionDirective() const { 2158 return (isOpenMPTargetExecutionDirective(DSAStack->getCurrentDirective()) && 2159 !DSAStack->isClauseParsingMode()) || 2160 DSAStack->hasDirective( 2161 [](OpenMPDirectiveKind K, const DeclarationNameInfo &, 2162 SourceLocation) -> bool { 2163 return isOpenMPTargetExecutionDirective(K); 2164 }, 2165 false); 2166 } 2167 2168 VarDecl *Sema::isOpenMPCapturedDecl(ValueDecl *D, bool CheckScopeInfo, 2169 unsigned StopAt) { 2170 assert(LangOpts.OpenMP && "OpenMP is not allowed"); 2171 D = getCanonicalDecl(D); 2172 2173 auto *VD = dyn_cast<VarDecl>(D); 2174 // Do not capture constexpr variables. 2175 if (VD && VD->isConstexpr()) 2176 return nullptr; 2177 2178 // If we want to determine whether the variable should be captured from the 2179 // perspective of the current capturing scope, and we've already left all the 2180 // capturing scopes of the top directive on the stack, check from the 2181 // perspective of its parent directive (if any) instead. 2182 DSAStackTy::ParentDirectiveScope InParentDirectiveRAII( 2183 *DSAStack, CheckScopeInfo && DSAStack->isBodyComplete()); 2184 2185 // If we are attempting to capture a global variable in a directive with 2186 // 'target' we return true so that this global is also mapped to the device. 2187 // 2188 if (VD && !VD->hasLocalStorage() && 2189 (getCurCapturedRegion() || getCurBlock() || getCurLambda())) { 2190 if (isInOpenMPTargetExecutionDirective()) { 2191 DSAStackTy::DSAVarData DVarTop = 2192 DSAStack->getTopDSA(D, DSAStack->isClauseParsingMode()); 2193 if (DVarTop.CKind != OMPC_unknown && DVarTop.RefExpr) 2194 return VD; 2195 // If the declaration is enclosed in a 'declare target' directive, 2196 // then it should not be captured. 2197 // 2198 if (OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD)) 2199 return nullptr; 2200 CapturedRegionScopeInfo *CSI = nullptr; 2201 for (FunctionScopeInfo *FSI : llvm::drop_begin( 2202 llvm::reverse(FunctionScopes), 2203 CheckScopeInfo ? (FunctionScopes.size() - (StopAt + 1)) : 0)) { 2204 if (!isa<CapturingScopeInfo>(FSI)) 2205 return nullptr; 2206 if (auto *RSI = dyn_cast<CapturedRegionScopeInfo>(FSI)) 2207 if (RSI->CapRegionKind == CR_OpenMP) { 2208 CSI = RSI; 2209 break; 2210 } 2211 } 2212 assert(CSI && "Failed to find CapturedRegionScopeInfo"); 2213 SmallVector<OpenMPDirectiveKind, 4> Regions; 2214 getOpenMPCaptureRegions(Regions, 2215 DSAStack->getDirective(CSI->OpenMPLevel)); 2216 if (Regions[CSI->OpenMPCaptureLevel] != OMPD_task) 2217 return VD; 2218 } 2219 if (isInOpenMPDeclareTargetContext()) { 2220 // Try to mark variable as declare target if it is used in capturing 2221 // regions. 2222 if (LangOpts.OpenMP <= 45 && 2223 !OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD)) 2224 checkDeclIsAllowedInOpenMPTarget(nullptr, VD); 2225 return nullptr; 2226 } 2227 } 2228 2229 if (CheckScopeInfo) { 2230 bool OpenMPFound = false; 2231 for (unsigned I = StopAt + 1; I > 0; --I) { 2232 FunctionScopeInfo *FSI = FunctionScopes[I - 1]; 2233 if(!isa<CapturingScopeInfo>(FSI)) 2234 return nullptr; 2235 if (auto *RSI = dyn_cast<CapturedRegionScopeInfo>(FSI)) 2236 if (RSI->CapRegionKind == CR_OpenMP) { 2237 OpenMPFound = true; 2238 break; 2239 } 2240 } 2241 if (!OpenMPFound) 2242 return nullptr; 2243 } 2244 2245 if (DSAStack->getCurrentDirective() != OMPD_unknown && 2246 (!DSAStack->isClauseParsingMode() || 2247 DSAStack->getParentDirective() != OMPD_unknown)) { 2248 auto &&Info = DSAStack->isLoopControlVariable(D); 2249 if (Info.first || 2250 (VD && VD->hasLocalStorage() && 2251 isImplicitOrExplicitTaskingRegion(DSAStack->getCurrentDirective())) || 2252 (VD && DSAStack->isForceVarCapturing())) 2253 return VD ? VD : Info.second; 2254 DSAStackTy::DSAVarData DVarTop = 2255 DSAStack->getTopDSA(D, DSAStack->isClauseParsingMode()); 2256 if (DVarTop.CKind != OMPC_unknown && isOpenMPPrivate(DVarTop.CKind) && 2257 (!VD || VD->hasLocalStorage() || !DVarTop.AppliedToPointee)) 2258 return VD ? VD : cast<VarDecl>(DVarTop.PrivateCopy->getDecl()); 2259 // Threadprivate variables must not be captured. 2260 if (isOpenMPThreadPrivate(DVarTop.CKind)) 2261 return nullptr; 2262 // The variable is not private or it is the variable in the directive with 2263 // default(none) clause and not used in any clause. 2264 DSAStackTy::DSAVarData DVarPrivate = DSAStack->hasDSA( 2265 D, 2266 [](OpenMPClauseKind C, bool AppliedToPointee) { 2267 return isOpenMPPrivate(C) && !AppliedToPointee; 2268 }, 2269 [](OpenMPDirectiveKind) { return true; }, 2270 DSAStack->isClauseParsingMode()); 2271 // Global shared must not be captured. 2272 if (VD && !VD->hasLocalStorage() && DVarPrivate.CKind == OMPC_unknown && 2273 ((DSAStack->getDefaultDSA() != DSA_none && 2274 DSAStack->getDefaultDSA() != DSA_firstprivate) || 2275 DVarTop.CKind == OMPC_shared)) 2276 return nullptr; 2277 if (DVarPrivate.CKind != OMPC_unknown || 2278 (VD && (DSAStack->getDefaultDSA() == DSA_none || 2279 DSAStack->getDefaultDSA() == DSA_firstprivate))) 2280 return VD ? VD : cast<VarDecl>(DVarPrivate.PrivateCopy->getDecl()); 2281 } 2282 return nullptr; 2283 } 2284 2285 void Sema::adjustOpenMPTargetScopeIndex(unsigned &FunctionScopesIndex, 2286 unsigned Level) const { 2287 FunctionScopesIndex -= getOpenMPCaptureLevels(DSAStack->getDirective(Level)); 2288 } 2289 2290 void Sema::startOpenMPLoop() { 2291 assert(LangOpts.OpenMP && "OpenMP must be enabled."); 2292 if (isOpenMPLoopDirective(DSAStack->getCurrentDirective())) 2293 DSAStack->loopInit(); 2294 } 2295 2296 void Sema::startOpenMPCXXRangeFor() { 2297 assert(LangOpts.OpenMP && "OpenMP must be enabled."); 2298 if (isOpenMPLoopDirective(DSAStack->getCurrentDirective())) { 2299 DSAStack->resetPossibleLoopCounter(); 2300 DSAStack->loopStart(); 2301 } 2302 } 2303 2304 OpenMPClauseKind Sema::isOpenMPPrivateDecl(ValueDecl *D, unsigned Level, 2305 unsigned CapLevel) const { 2306 assert(LangOpts.OpenMP && "OpenMP is not allowed"); 2307 if (DSAStack->hasExplicitDirective( 2308 [](OpenMPDirectiveKind K) { return isOpenMPTaskingDirective(K); }, 2309 Level)) { 2310 bool IsTriviallyCopyable = 2311 D->getType().getNonReferenceType().isTriviallyCopyableType(Context) && 2312 !D->getType() 2313 .getNonReferenceType() 2314 .getCanonicalType() 2315 ->getAsCXXRecordDecl(); 2316 OpenMPDirectiveKind DKind = DSAStack->getDirective(Level); 2317 SmallVector<OpenMPDirectiveKind, 4> CaptureRegions; 2318 getOpenMPCaptureRegions(CaptureRegions, DKind); 2319 if (isOpenMPTaskingDirective(CaptureRegions[CapLevel]) && 2320 (IsTriviallyCopyable || 2321 !isOpenMPTaskLoopDirective(CaptureRegions[CapLevel]))) { 2322 if (DSAStack->hasExplicitDSA( 2323 D, 2324 [](OpenMPClauseKind K, bool) { return K == OMPC_firstprivate; }, 2325 Level, /*NotLastprivate=*/true)) 2326 return OMPC_firstprivate; 2327 DSAStackTy::DSAVarData DVar = DSAStack->getImplicitDSA(D, Level); 2328 if (DVar.CKind != OMPC_shared && 2329 !DSAStack->isLoopControlVariable(D, Level).first && !DVar.RefExpr) { 2330 DSAStack->addImplicitTaskFirstprivate(Level, D); 2331 return OMPC_firstprivate; 2332 } 2333 } 2334 } 2335 if (isOpenMPLoopDirective(DSAStack->getCurrentDirective())) { 2336 if (DSAStack->getAssociatedLoops() > 0 && 2337 !DSAStack->isLoopStarted()) { 2338 DSAStack->resetPossibleLoopCounter(D); 2339 DSAStack->loopStart(); 2340 return OMPC_private; 2341 } 2342 if ((DSAStack->getPossiblyLoopCunter() == D->getCanonicalDecl() || 2343 DSAStack->isLoopControlVariable(D).first) && 2344 !DSAStack->hasExplicitDSA( 2345 D, [](OpenMPClauseKind K, bool) { return K != OMPC_private; }, 2346 Level) && 2347 !isOpenMPSimdDirective(DSAStack->getCurrentDirective())) 2348 return OMPC_private; 2349 } 2350 if (const auto *VD = dyn_cast<VarDecl>(D)) { 2351 if (DSAStack->isThreadPrivate(const_cast<VarDecl *>(VD)) && 2352 DSAStack->isForceVarCapturing() && 2353 !DSAStack->hasExplicitDSA( 2354 D, [](OpenMPClauseKind K, bool) { return K == OMPC_copyin; }, 2355 Level)) 2356 return OMPC_private; 2357 } 2358 // User-defined allocators are private since they must be defined in the 2359 // context of target region. 2360 if (DSAStack->hasExplicitDirective(isOpenMPTargetExecutionDirective, Level) && 2361 DSAStack->isUsesAllocatorsDecl(Level, D).getValueOr( 2362 DSAStackTy::UsesAllocatorsDeclKind::AllocatorTrait) == 2363 DSAStackTy::UsesAllocatorsDeclKind::UserDefinedAllocator) 2364 return OMPC_private; 2365 return (DSAStack->hasExplicitDSA( 2366 D, [](OpenMPClauseKind K, bool) { return K == OMPC_private; }, 2367 Level) || 2368 (DSAStack->isClauseParsingMode() && 2369 DSAStack->getClauseParsingMode() == OMPC_private) || 2370 // Consider taskgroup reduction descriptor variable a private 2371 // to avoid possible capture in the region. 2372 (DSAStack->hasExplicitDirective( 2373 [](OpenMPDirectiveKind K) { 2374 return K == OMPD_taskgroup || 2375 ((isOpenMPParallelDirective(K) || 2376 isOpenMPWorksharingDirective(K)) && 2377 !isOpenMPSimdDirective(K)); 2378 }, 2379 Level) && 2380 DSAStack->isTaskgroupReductionRef(D, Level))) 2381 ? OMPC_private 2382 : OMPC_unknown; 2383 } 2384 2385 void Sema::setOpenMPCaptureKind(FieldDecl *FD, const ValueDecl *D, 2386 unsigned Level) { 2387 assert(LangOpts.OpenMP && "OpenMP is not allowed"); 2388 D = getCanonicalDecl(D); 2389 OpenMPClauseKind OMPC = OMPC_unknown; 2390 for (unsigned I = DSAStack->getNestingLevel() + 1; I > Level; --I) { 2391 const unsigned NewLevel = I - 1; 2392 if (DSAStack->hasExplicitDSA( 2393 D, 2394 [&OMPC](const OpenMPClauseKind K, bool AppliedToPointee) { 2395 if (isOpenMPPrivate(K) && !AppliedToPointee) { 2396 OMPC = K; 2397 return true; 2398 } 2399 return false; 2400 }, 2401 NewLevel)) 2402 break; 2403 if (DSAStack->checkMappableExprComponentListsForDeclAtLevel( 2404 D, NewLevel, 2405 [](OMPClauseMappableExprCommon::MappableExprComponentListRef, 2406 OpenMPClauseKind) { return true; })) { 2407 OMPC = OMPC_map; 2408 break; 2409 } 2410 if (DSAStack->hasExplicitDirective(isOpenMPTargetExecutionDirective, 2411 NewLevel)) { 2412 OMPC = OMPC_map; 2413 if (DSAStack->mustBeFirstprivateAtLevel( 2414 NewLevel, getVariableCategoryFromDecl(LangOpts, D))) 2415 OMPC = OMPC_firstprivate; 2416 break; 2417 } 2418 } 2419 if (OMPC != OMPC_unknown) 2420 FD->addAttr(OMPCaptureKindAttr::CreateImplicit(Context, unsigned(OMPC))); 2421 } 2422 2423 bool Sema::isOpenMPTargetCapturedDecl(const ValueDecl *D, unsigned Level, 2424 unsigned CaptureLevel) const { 2425 assert(LangOpts.OpenMP && "OpenMP is not allowed"); 2426 // Return true if the current level is no longer enclosed in a target region. 2427 2428 SmallVector<OpenMPDirectiveKind, 4> Regions; 2429 getOpenMPCaptureRegions(Regions, DSAStack->getDirective(Level)); 2430 const auto *VD = dyn_cast<VarDecl>(D); 2431 return VD && !VD->hasLocalStorage() && 2432 DSAStack->hasExplicitDirective(isOpenMPTargetExecutionDirective, 2433 Level) && 2434 Regions[CaptureLevel] != OMPD_task; 2435 } 2436 2437 bool Sema::isOpenMPGlobalCapturedDecl(ValueDecl *D, unsigned Level, 2438 unsigned CaptureLevel) const { 2439 assert(LangOpts.OpenMP && "OpenMP is not allowed"); 2440 // Return true if the current level is no longer enclosed in a target region. 2441 2442 if (const auto *VD = dyn_cast<VarDecl>(D)) { 2443 if (!VD->hasLocalStorage()) { 2444 if (isInOpenMPTargetExecutionDirective()) 2445 return true; 2446 DSAStackTy::DSAVarData TopDVar = 2447 DSAStack->getTopDSA(D, /*FromParent=*/false); 2448 unsigned NumLevels = 2449 getOpenMPCaptureLevels(DSAStack->getDirective(Level)); 2450 if (Level == 0) 2451 return (NumLevels == CaptureLevel + 1) && TopDVar.CKind != OMPC_shared; 2452 do { 2453 --Level; 2454 DSAStackTy::DSAVarData DVar = DSAStack->getImplicitDSA(D, Level); 2455 if (DVar.CKind != OMPC_shared) 2456 return true; 2457 } while (Level > 0); 2458 } 2459 } 2460 return true; 2461 } 2462 2463 void Sema::DestroyDataSharingAttributesStack() { delete DSAStack; } 2464 2465 void Sema::ActOnOpenMPBeginDeclareVariant(SourceLocation Loc, 2466 OMPTraitInfo &TI) { 2467 OMPDeclareVariantScopes.push_back(OMPDeclareVariantScope(TI)); 2468 } 2469 2470 void Sema::ActOnOpenMPEndDeclareVariant() { 2471 assert(isInOpenMPDeclareVariantScope() && 2472 "Not in OpenMP declare variant scope!"); 2473 2474 OMPDeclareVariantScopes.pop_back(); 2475 } 2476 2477 void Sema::finalizeOpenMPDelayedAnalysis(const FunctionDecl *Caller, 2478 const FunctionDecl *Callee, 2479 SourceLocation Loc) { 2480 assert(LangOpts.OpenMP && "Expected OpenMP compilation mode."); 2481 Optional<OMPDeclareTargetDeclAttr::DevTypeTy> DevTy = 2482 OMPDeclareTargetDeclAttr::getDeviceType(Caller->getMostRecentDecl()); 2483 // Ignore host functions during device analyzis. 2484 if (LangOpts.OpenMPIsDevice && DevTy && 2485 *DevTy == OMPDeclareTargetDeclAttr::DT_Host) 2486 return; 2487 // Ignore nohost functions during host analyzis. 2488 if (!LangOpts.OpenMPIsDevice && DevTy && 2489 *DevTy == OMPDeclareTargetDeclAttr::DT_NoHost) 2490 return; 2491 const FunctionDecl *FD = Callee->getMostRecentDecl(); 2492 DevTy = OMPDeclareTargetDeclAttr::getDeviceType(FD); 2493 if (LangOpts.OpenMPIsDevice && DevTy && 2494 *DevTy == OMPDeclareTargetDeclAttr::DT_Host) { 2495 // Diagnose host function called during device codegen. 2496 StringRef HostDevTy = 2497 getOpenMPSimpleClauseTypeName(OMPC_device_type, OMPC_DEVICE_TYPE_host); 2498 Diag(Loc, diag::err_omp_wrong_device_function_call) << HostDevTy << 0; 2499 Diag(*OMPDeclareTargetDeclAttr::getLocation(FD), 2500 diag::note_omp_marked_device_type_here) 2501 << HostDevTy; 2502 return; 2503 } 2504 if (!LangOpts.OpenMPIsDevice && DevTy && 2505 *DevTy == OMPDeclareTargetDeclAttr::DT_NoHost) { 2506 // Diagnose nohost function called during host codegen. 2507 StringRef NoHostDevTy = getOpenMPSimpleClauseTypeName( 2508 OMPC_device_type, OMPC_DEVICE_TYPE_nohost); 2509 Diag(Loc, diag::err_omp_wrong_device_function_call) << NoHostDevTy << 1; 2510 Diag(*OMPDeclareTargetDeclAttr::getLocation(FD), 2511 diag::note_omp_marked_device_type_here) 2512 << NoHostDevTy; 2513 } 2514 } 2515 2516 void Sema::StartOpenMPDSABlock(OpenMPDirectiveKind DKind, 2517 const DeclarationNameInfo &DirName, 2518 Scope *CurScope, SourceLocation Loc) { 2519 DSAStack->push(DKind, DirName, CurScope, Loc); 2520 PushExpressionEvaluationContext( 2521 ExpressionEvaluationContext::PotentiallyEvaluated); 2522 } 2523 2524 void Sema::StartOpenMPClause(OpenMPClauseKind K) { 2525 DSAStack->setClauseParsingMode(K); 2526 } 2527 2528 void Sema::EndOpenMPClause() { 2529 DSAStack->setClauseParsingMode(/*K=*/OMPC_unknown); 2530 } 2531 2532 static std::pair<ValueDecl *, bool> 2533 getPrivateItem(Sema &S, Expr *&RefExpr, SourceLocation &ELoc, 2534 SourceRange &ERange, bool AllowArraySection = false); 2535 2536 /// Check consistency of the reduction clauses. 2537 static void checkReductionClauses(Sema &S, DSAStackTy *Stack, 2538 ArrayRef<OMPClause *> Clauses) { 2539 bool InscanFound = false; 2540 SourceLocation InscanLoc; 2541 // OpenMP 5.0, 2.19.5.4 reduction Clause, Restrictions. 2542 // A reduction clause without the inscan reduction-modifier may not appear on 2543 // a construct on which a reduction clause with the inscan reduction-modifier 2544 // appears. 2545 for (OMPClause *C : Clauses) { 2546 if (C->getClauseKind() != OMPC_reduction) 2547 continue; 2548 auto *RC = cast<OMPReductionClause>(C); 2549 if (RC->getModifier() == OMPC_REDUCTION_inscan) { 2550 InscanFound = true; 2551 InscanLoc = RC->getModifierLoc(); 2552 continue; 2553 } 2554 if (RC->getModifier() == OMPC_REDUCTION_task) { 2555 // OpenMP 5.0, 2.19.5.4 reduction Clause. 2556 // A reduction clause with the task reduction-modifier may only appear on 2557 // a parallel construct, a worksharing construct or a combined or 2558 // composite construct for which any of the aforementioned constructs is a 2559 // constituent construct and simd or loop are not constituent constructs. 2560 OpenMPDirectiveKind CurDir = Stack->getCurrentDirective(); 2561 if (!(isOpenMPParallelDirective(CurDir) || 2562 isOpenMPWorksharingDirective(CurDir)) || 2563 isOpenMPSimdDirective(CurDir)) 2564 S.Diag(RC->getModifierLoc(), 2565 diag::err_omp_reduction_task_not_parallel_or_worksharing); 2566 continue; 2567 } 2568 } 2569 if (InscanFound) { 2570 for (OMPClause *C : Clauses) { 2571 if (C->getClauseKind() != OMPC_reduction) 2572 continue; 2573 auto *RC = cast<OMPReductionClause>(C); 2574 if (RC->getModifier() != OMPC_REDUCTION_inscan) { 2575 S.Diag(RC->getModifier() == OMPC_REDUCTION_unknown 2576 ? RC->getBeginLoc() 2577 : RC->getModifierLoc(), 2578 diag::err_omp_inscan_reduction_expected); 2579 S.Diag(InscanLoc, diag::note_omp_previous_inscan_reduction); 2580 continue; 2581 } 2582 for (Expr *Ref : RC->varlists()) { 2583 assert(Ref && "NULL expr in OpenMP nontemporal clause."); 2584 SourceLocation ELoc; 2585 SourceRange ERange; 2586 Expr *SimpleRefExpr = Ref; 2587 auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange, 2588 /*AllowArraySection=*/true); 2589 ValueDecl *D = Res.first; 2590 if (!D) 2591 continue; 2592 if (!Stack->isUsedInScanDirective(getCanonicalDecl(D))) { 2593 S.Diag(Ref->getExprLoc(), 2594 diag::err_omp_reduction_not_inclusive_exclusive) 2595 << Ref->getSourceRange(); 2596 } 2597 } 2598 } 2599 } 2600 } 2601 2602 static void checkAllocateClauses(Sema &S, DSAStackTy *Stack, 2603 ArrayRef<OMPClause *> Clauses); 2604 static DeclRefExpr *buildCapture(Sema &S, ValueDecl *D, Expr *CaptureExpr, 2605 bool WithInit); 2606 2607 static void reportOriginalDsa(Sema &SemaRef, const DSAStackTy *Stack, 2608 const ValueDecl *D, 2609 const DSAStackTy::DSAVarData &DVar, 2610 bool IsLoopIterVar = false); 2611 2612 void Sema::EndOpenMPDSABlock(Stmt *CurDirective) { 2613 // OpenMP [2.14.3.5, Restrictions, C/C++, p.1] 2614 // A variable of class type (or array thereof) that appears in a lastprivate 2615 // clause requires an accessible, unambiguous default constructor for the 2616 // class type, unless the list item is also specified in a firstprivate 2617 // clause. 2618 if (const auto *D = dyn_cast_or_null<OMPExecutableDirective>(CurDirective)) { 2619 for (OMPClause *C : D->clauses()) { 2620 if (auto *Clause = dyn_cast<OMPLastprivateClause>(C)) { 2621 SmallVector<Expr *, 8> PrivateCopies; 2622 for (Expr *DE : Clause->varlists()) { 2623 if (DE->isValueDependent() || DE->isTypeDependent()) { 2624 PrivateCopies.push_back(nullptr); 2625 continue; 2626 } 2627 auto *DRE = cast<DeclRefExpr>(DE->IgnoreParens()); 2628 auto *VD = cast<VarDecl>(DRE->getDecl()); 2629 QualType Type = VD->getType().getNonReferenceType(); 2630 const DSAStackTy::DSAVarData DVar = 2631 DSAStack->getTopDSA(VD, /*FromParent=*/false); 2632 if (DVar.CKind == OMPC_lastprivate) { 2633 // Generate helper private variable and initialize it with the 2634 // default value. The address of the original variable is replaced 2635 // by the address of the new private variable in CodeGen. This new 2636 // variable is not added to IdResolver, so the code in the OpenMP 2637 // region uses original variable for proper diagnostics. 2638 VarDecl *VDPrivate = buildVarDecl( 2639 *this, DE->getExprLoc(), Type.getUnqualifiedType(), 2640 VD->getName(), VD->hasAttrs() ? &VD->getAttrs() : nullptr, DRE); 2641 ActOnUninitializedDecl(VDPrivate); 2642 if (VDPrivate->isInvalidDecl()) { 2643 PrivateCopies.push_back(nullptr); 2644 continue; 2645 } 2646 PrivateCopies.push_back(buildDeclRefExpr( 2647 *this, VDPrivate, DE->getType(), DE->getExprLoc())); 2648 } else { 2649 // The variable is also a firstprivate, so initialization sequence 2650 // for private copy is generated already. 2651 PrivateCopies.push_back(nullptr); 2652 } 2653 } 2654 Clause->setPrivateCopies(PrivateCopies); 2655 continue; 2656 } 2657 // Finalize nontemporal clause by handling private copies, if any. 2658 if (auto *Clause = dyn_cast<OMPNontemporalClause>(C)) { 2659 SmallVector<Expr *, 8> PrivateRefs; 2660 for (Expr *RefExpr : Clause->varlists()) { 2661 assert(RefExpr && "NULL expr in OpenMP nontemporal clause."); 2662 SourceLocation ELoc; 2663 SourceRange ERange; 2664 Expr *SimpleRefExpr = RefExpr; 2665 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 2666 if (Res.second) 2667 // It will be analyzed later. 2668 PrivateRefs.push_back(RefExpr); 2669 ValueDecl *D = Res.first; 2670 if (!D) 2671 continue; 2672 2673 const DSAStackTy::DSAVarData DVar = 2674 DSAStack->getTopDSA(D, /*FromParent=*/false); 2675 PrivateRefs.push_back(DVar.PrivateCopy ? DVar.PrivateCopy 2676 : SimpleRefExpr); 2677 } 2678 Clause->setPrivateRefs(PrivateRefs); 2679 continue; 2680 } 2681 if (auto *Clause = dyn_cast<OMPUsesAllocatorsClause>(C)) { 2682 for (unsigned I = 0, E = Clause->getNumberOfAllocators(); I < E; ++I) { 2683 OMPUsesAllocatorsClause::Data D = Clause->getAllocatorData(I); 2684 auto *DRE = dyn_cast<DeclRefExpr>(D.Allocator->IgnoreParenImpCasts()); 2685 if (!DRE) 2686 continue; 2687 ValueDecl *VD = DRE->getDecl(); 2688 if (!VD || !isa<VarDecl>(VD)) 2689 continue; 2690 DSAStackTy::DSAVarData DVar = 2691 DSAStack->getTopDSA(VD, /*FromParent=*/false); 2692 // OpenMP [2.12.5, target Construct] 2693 // Memory allocators that appear in a uses_allocators clause cannot 2694 // appear in other data-sharing attribute clauses or data-mapping 2695 // attribute clauses in the same construct. 2696 Expr *MapExpr = nullptr; 2697 if (DVar.RefExpr || 2698 DSAStack->checkMappableExprComponentListsForDecl( 2699 VD, /*CurrentRegionOnly=*/true, 2700 [VD, &MapExpr]( 2701 OMPClauseMappableExprCommon::MappableExprComponentListRef 2702 MapExprComponents, 2703 OpenMPClauseKind C) { 2704 auto MI = MapExprComponents.rbegin(); 2705 auto ME = MapExprComponents.rend(); 2706 if (MI != ME && 2707 MI->getAssociatedDeclaration()->getCanonicalDecl() == 2708 VD->getCanonicalDecl()) { 2709 MapExpr = MI->getAssociatedExpression(); 2710 return true; 2711 } 2712 return false; 2713 })) { 2714 Diag(D.Allocator->getExprLoc(), 2715 diag::err_omp_allocator_used_in_clauses) 2716 << D.Allocator->getSourceRange(); 2717 if (DVar.RefExpr) 2718 reportOriginalDsa(*this, DSAStack, VD, DVar); 2719 else 2720 Diag(MapExpr->getExprLoc(), diag::note_used_here) 2721 << MapExpr->getSourceRange(); 2722 } 2723 } 2724 continue; 2725 } 2726 } 2727 // Check allocate clauses. 2728 if (!CurContext->isDependentContext()) 2729 checkAllocateClauses(*this, DSAStack, D->clauses()); 2730 checkReductionClauses(*this, DSAStack, D->clauses()); 2731 } 2732 2733 DSAStack->pop(); 2734 DiscardCleanupsInEvaluationContext(); 2735 PopExpressionEvaluationContext(); 2736 } 2737 2738 static bool FinishOpenMPLinearClause(OMPLinearClause &Clause, DeclRefExpr *IV, 2739 Expr *NumIterations, Sema &SemaRef, 2740 Scope *S, DSAStackTy *Stack); 2741 2742 namespace { 2743 2744 class VarDeclFilterCCC final : public CorrectionCandidateCallback { 2745 private: 2746 Sema &SemaRef; 2747 2748 public: 2749 explicit VarDeclFilterCCC(Sema &S) : SemaRef(S) {} 2750 bool ValidateCandidate(const TypoCorrection &Candidate) override { 2751 NamedDecl *ND = Candidate.getCorrectionDecl(); 2752 if (const auto *VD = dyn_cast_or_null<VarDecl>(ND)) { 2753 return VD->hasGlobalStorage() && 2754 SemaRef.isDeclInScope(ND, SemaRef.getCurLexicalContext(), 2755 SemaRef.getCurScope()); 2756 } 2757 return false; 2758 } 2759 2760 std::unique_ptr<CorrectionCandidateCallback> clone() override { 2761 return std::make_unique<VarDeclFilterCCC>(*this); 2762 } 2763 2764 }; 2765 2766 class VarOrFuncDeclFilterCCC final : public CorrectionCandidateCallback { 2767 private: 2768 Sema &SemaRef; 2769 2770 public: 2771 explicit VarOrFuncDeclFilterCCC(Sema &S) : SemaRef(S) {} 2772 bool ValidateCandidate(const TypoCorrection &Candidate) override { 2773 NamedDecl *ND = Candidate.getCorrectionDecl(); 2774 if (ND && ((isa<VarDecl>(ND) && ND->getKind() == Decl::Var) || 2775 isa<FunctionDecl>(ND))) { 2776 return SemaRef.isDeclInScope(ND, SemaRef.getCurLexicalContext(), 2777 SemaRef.getCurScope()); 2778 } 2779 return false; 2780 } 2781 2782 std::unique_ptr<CorrectionCandidateCallback> clone() override { 2783 return std::make_unique<VarOrFuncDeclFilterCCC>(*this); 2784 } 2785 }; 2786 2787 } // namespace 2788 2789 ExprResult Sema::ActOnOpenMPIdExpression(Scope *CurScope, 2790 CXXScopeSpec &ScopeSpec, 2791 const DeclarationNameInfo &Id, 2792 OpenMPDirectiveKind Kind) { 2793 LookupResult Lookup(*this, Id, LookupOrdinaryName); 2794 LookupParsedName(Lookup, CurScope, &ScopeSpec, true); 2795 2796 if (Lookup.isAmbiguous()) 2797 return ExprError(); 2798 2799 VarDecl *VD; 2800 if (!Lookup.isSingleResult()) { 2801 VarDeclFilterCCC CCC(*this); 2802 if (TypoCorrection Corrected = 2803 CorrectTypo(Id, LookupOrdinaryName, CurScope, nullptr, CCC, 2804 CTK_ErrorRecovery)) { 2805 diagnoseTypo(Corrected, 2806 PDiag(Lookup.empty() 2807 ? diag::err_undeclared_var_use_suggest 2808 : diag::err_omp_expected_var_arg_suggest) 2809 << Id.getName()); 2810 VD = Corrected.getCorrectionDeclAs<VarDecl>(); 2811 } else { 2812 Diag(Id.getLoc(), Lookup.empty() ? diag::err_undeclared_var_use 2813 : diag::err_omp_expected_var_arg) 2814 << Id.getName(); 2815 return ExprError(); 2816 } 2817 } else if (!(VD = Lookup.getAsSingle<VarDecl>())) { 2818 Diag(Id.getLoc(), diag::err_omp_expected_var_arg) << Id.getName(); 2819 Diag(Lookup.getFoundDecl()->getLocation(), diag::note_declared_at); 2820 return ExprError(); 2821 } 2822 Lookup.suppressDiagnostics(); 2823 2824 // OpenMP [2.9.2, Syntax, C/C++] 2825 // Variables must be file-scope, namespace-scope, or static block-scope. 2826 if (Kind == OMPD_threadprivate && !VD->hasGlobalStorage()) { 2827 Diag(Id.getLoc(), diag::err_omp_global_var_arg) 2828 << getOpenMPDirectiveName(Kind) << !VD->isStaticLocal(); 2829 bool IsDecl = 2830 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 2831 Diag(VD->getLocation(), 2832 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 2833 << VD; 2834 return ExprError(); 2835 } 2836 2837 VarDecl *CanonicalVD = VD->getCanonicalDecl(); 2838 NamedDecl *ND = CanonicalVD; 2839 // OpenMP [2.9.2, Restrictions, C/C++, p.2] 2840 // A threadprivate directive for file-scope variables must appear outside 2841 // any definition or declaration. 2842 if (CanonicalVD->getDeclContext()->isTranslationUnit() && 2843 !getCurLexicalContext()->isTranslationUnit()) { 2844 Diag(Id.getLoc(), diag::err_omp_var_scope) 2845 << getOpenMPDirectiveName(Kind) << VD; 2846 bool IsDecl = 2847 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 2848 Diag(VD->getLocation(), 2849 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 2850 << VD; 2851 return ExprError(); 2852 } 2853 // OpenMP [2.9.2, Restrictions, C/C++, p.3] 2854 // A threadprivate directive for static class member variables must appear 2855 // in the class definition, in the same scope in which the member 2856 // variables are declared. 2857 if (CanonicalVD->isStaticDataMember() && 2858 !CanonicalVD->getDeclContext()->Equals(getCurLexicalContext())) { 2859 Diag(Id.getLoc(), diag::err_omp_var_scope) 2860 << getOpenMPDirectiveName(Kind) << VD; 2861 bool IsDecl = 2862 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 2863 Diag(VD->getLocation(), 2864 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 2865 << VD; 2866 return ExprError(); 2867 } 2868 // OpenMP [2.9.2, Restrictions, C/C++, p.4] 2869 // A threadprivate directive for namespace-scope variables must appear 2870 // outside any definition or declaration other than the namespace 2871 // definition itself. 2872 if (CanonicalVD->getDeclContext()->isNamespace() && 2873 (!getCurLexicalContext()->isFileContext() || 2874 !getCurLexicalContext()->Encloses(CanonicalVD->getDeclContext()))) { 2875 Diag(Id.getLoc(), diag::err_omp_var_scope) 2876 << getOpenMPDirectiveName(Kind) << VD; 2877 bool IsDecl = 2878 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 2879 Diag(VD->getLocation(), 2880 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 2881 << VD; 2882 return ExprError(); 2883 } 2884 // OpenMP [2.9.2, Restrictions, C/C++, p.6] 2885 // A threadprivate directive for static block-scope variables must appear 2886 // in the scope of the variable and not in a nested scope. 2887 if (CanonicalVD->isLocalVarDecl() && CurScope && 2888 !isDeclInScope(ND, getCurLexicalContext(), CurScope)) { 2889 Diag(Id.getLoc(), diag::err_omp_var_scope) 2890 << getOpenMPDirectiveName(Kind) << VD; 2891 bool IsDecl = 2892 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 2893 Diag(VD->getLocation(), 2894 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 2895 << VD; 2896 return ExprError(); 2897 } 2898 2899 // OpenMP [2.9.2, Restrictions, C/C++, p.2-6] 2900 // A threadprivate directive must lexically precede all references to any 2901 // of the variables in its list. 2902 if (Kind == OMPD_threadprivate && VD->isUsed() && 2903 !DSAStack->isThreadPrivate(VD)) { 2904 Diag(Id.getLoc(), diag::err_omp_var_used) 2905 << getOpenMPDirectiveName(Kind) << VD; 2906 return ExprError(); 2907 } 2908 2909 QualType ExprType = VD->getType().getNonReferenceType(); 2910 return DeclRefExpr::Create(Context, NestedNameSpecifierLoc(), 2911 SourceLocation(), VD, 2912 /*RefersToEnclosingVariableOrCapture=*/false, 2913 Id.getLoc(), ExprType, VK_LValue); 2914 } 2915 2916 Sema::DeclGroupPtrTy 2917 Sema::ActOnOpenMPThreadprivateDirective(SourceLocation Loc, 2918 ArrayRef<Expr *> VarList) { 2919 if (OMPThreadPrivateDecl *D = CheckOMPThreadPrivateDecl(Loc, VarList)) { 2920 CurContext->addDecl(D); 2921 return DeclGroupPtrTy::make(DeclGroupRef(D)); 2922 } 2923 return nullptr; 2924 } 2925 2926 namespace { 2927 class LocalVarRefChecker final 2928 : public ConstStmtVisitor<LocalVarRefChecker, bool> { 2929 Sema &SemaRef; 2930 2931 public: 2932 bool VisitDeclRefExpr(const DeclRefExpr *E) { 2933 if (const auto *VD = dyn_cast<VarDecl>(E->getDecl())) { 2934 if (VD->hasLocalStorage()) { 2935 SemaRef.Diag(E->getBeginLoc(), 2936 diag::err_omp_local_var_in_threadprivate_init) 2937 << E->getSourceRange(); 2938 SemaRef.Diag(VD->getLocation(), diag::note_defined_here) 2939 << VD << VD->getSourceRange(); 2940 return true; 2941 } 2942 } 2943 return false; 2944 } 2945 bool VisitStmt(const Stmt *S) { 2946 for (const Stmt *Child : S->children()) { 2947 if (Child && Visit(Child)) 2948 return true; 2949 } 2950 return false; 2951 } 2952 explicit LocalVarRefChecker(Sema &SemaRef) : SemaRef(SemaRef) {} 2953 }; 2954 } // namespace 2955 2956 OMPThreadPrivateDecl * 2957 Sema::CheckOMPThreadPrivateDecl(SourceLocation Loc, ArrayRef<Expr *> VarList) { 2958 SmallVector<Expr *, 8> Vars; 2959 for (Expr *RefExpr : VarList) { 2960 auto *DE = cast<DeclRefExpr>(RefExpr); 2961 auto *VD = cast<VarDecl>(DE->getDecl()); 2962 SourceLocation ILoc = DE->getExprLoc(); 2963 2964 // Mark variable as used. 2965 VD->setReferenced(); 2966 VD->markUsed(Context); 2967 2968 QualType QType = VD->getType(); 2969 if (QType->isDependentType() || QType->isInstantiationDependentType()) { 2970 // It will be analyzed later. 2971 Vars.push_back(DE); 2972 continue; 2973 } 2974 2975 // OpenMP [2.9.2, Restrictions, C/C++, p.10] 2976 // A threadprivate variable must not have an incomplete type. 2977 if (RequireCompleteType(ILoc, VD->getType(), 2978 diag::err_omp_threadprivate_incomplete_type)) { 2979 continue; 2980 } 2981 2982 // OpenMP [2.9.2, Restrictions, C/C++, p.10] 2983 // A threadprivate variable must not have a reference type. 2984 if (VD->getType()->isReferenceType()) { 2985 Diag(ILoc, diag::err_omp_ref_type_arg) 2986 << getOpenMPDirectiveName(OMPD_threadprivate) << VD->getType(); 2987 bool IsDecl = 2988 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 2989 Diag(VD->getLocation(), 2990 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 2991 << VD; 2992 continue; 2993 } 2994 2995 // Check if this is a TLS variable. If TLS is not being supported, produce 2996 // the corresponding diagnostic. 2997 if ((VD->getTLSKind() != VarDecl::TLS_None && 2998 !(VD->hasAttr<OMPThreadPrivateDeclAttr>() && 2999 getLangOpts().OpenMPUseTLS && 3000 getASTContext().getTargetInfo().isTLSSupported())) || 3001 (VD->getStorageClass() == SC_Register && VD->hasAttr<AsmLabelAttr>() && 3002 !VD->isLocalVarDecl())) { 3003 Diag(ILoc, diag::err_omp_var_thread_local) 3004 << VD << ((VD->getTLSKind() != VarDecl::TLS_None) ? 0 : 1); 3005 bool IsDecl = 3006 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 3007 Diag(VD->getLocation(), 3008 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 3009 << VD; 3010 continue; 3011 } 3012 3013 // Check if initial value of threadprivate variable reference variable with 3014 // local storage (it is not supported by runtime). 3015 if (const Expr *Init = VD->getAnyInitializer()) { 3016 LocalVarRefChecker Checker(*this); 3017 if (Checker.Visit(Init)) 3018 continue; 3019 } 3020 3021 Vars.push_back(RefExpr); 3022 DSAStack->addDSA(VD, DE, OMPC_threadprivate); 3023 VD->addAttr(OMPThreadPrivateDeclAttr::CreateImplicit( 3024 Context, SourceRange(Loc, Loc))); 3025 if (ASTMutationListener *ML = Context.getASTMutationListener()) 3026 ML->DeclarationMarkedOpenMPThreadPrivate(VD); 3027 } 3028 OMPThreadPrivateDecl *D = nullptr; 3029 if (!Vars.empty()) { 3030 D = OMPThreadPrivateDecl::Create(Context, getCurLexicalContext(), Loc, 3031 Vars); 3032 D->setAccess(AS_public); 3033 } 3034 return D; 3035 } 3036 3037 static OMPAllocateDeclAttr::AllocatorTypeTy 3038 getAllocatorKind(Sema &S, DSAStackTy *Stack, Expr *Allocator) { 3039 if (!Allocator) 3040 return OMPAllocateDeclAttr::OMPNullMemAlloc; 3041 if (Allocator->isTypeDependent() || Allocator->isValueDependent() || 3042 Allocator->isInstantiationDependent() || 3043 Allocator->containsUnexpandedParameterPack()) 3044 return OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; 3045 auto AllocatorKindRes = OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; 3046 const Expr *AE = Allocator->IgnoreParenImpCasts(); 3047 for (int I = 0; I < OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; ++I) { 3048 auto AllocatorKind = static_cast<OMPAllocateDeclAttr::AllocatorTypeTy>(I); 3049 const Expr *DefAllocator = Stack->getAllocator(AllocatorKind); 3050 llvm::FoldingSetNodeID AEId, DAEId; 3051 AE->Profile(AEId, S.getASTContext(), /*Canonical=*/true); 3052 DefAllocator->Profile(DAEId, S.getASTContext(), /*Canonical=*/true); 3053 if (AEId == DAEId) { 3054 AllocatorKindRes = AllocatorKind; 3055 break; 3056 } 3057 } 3058 return AllocatorKindRes; 3059 } 3060 3061 static bool checkPreviousOMPAllocateAttribute( 3062 Sema &S, DSAStackTy *Stack, Expr *RefExpr, VarDecl *VD, 3063 OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind, Expr *Allocator) { 3064 if (!VD->hasAttr<OMPAllocateDeclAttr>()) 3065 return false; 3066 const auto *A = VD->getAttr<OMPAllocateDeclAttr>(); 3067 Expr *PrevAllocator = A->getAllocator(); 3068 OMPAllocateDeclAttr::AllocatorTypeTy PrevAllocatorKind = 3069 getAllocatorKind(S, Stack, PrevAllocator); 3070 bool AllocatorsMatch = AllocatorKind == PrevAllocatorKind; 3071 if (AllocatorsMatch && 3072 AllocatorKind == OMPAllocateDeclAttr::OMPUserDefinedMemAlloc && 3073 Allocator && PrevAllocator) { 3074 const Expr *AE = Allocator->IgnoreParenImpCasts(); 3075 const Expr *PAE = PrevAllocator->IgnoreParenImpCasts(); 3076 llvm::FoldingSetNodeID AEId, PAEId; 3077 AE->Profile(AEId, S.Context, /*Canonical=*/true); 3078 PAE->Profile(PAEId, S.Context, /*Canonical=*/true); 3079 AllocatorsMatch = AEId == PAEId; 3080 } 3081 if (!AllocatorsMatch) { 3082 SmallString<256> AllocatorBuffer; 3083 llvm::raw_svector_ostream AllocatorStream(AllocatorBuffer); 3084 if (Allocator) 3085 Allocator->printPretty(AllocatorStream, nullptr, S.getPrintingPolicy()); 3086 SmallString<256> PrevAllocatorBuffer; 3087 llvm::raw_svector_ostream PrevAllocatorStream(PrevAllocatorBuffer); 3088 if (PrevAllocator) 3089 PrevAllocator->printPretty(PrevAllocatorStream, nullptr, 3090 S.getPrintingPolicy()); 3091 3092 SourceLocation AllocatorLoc = 3093 Allocator ? Allocator->getExprLoc() : RefExpr->getExprLoc(); 3094 SourceRange AllocatorRange = 3095 Allocator ? Allocator->getSourceRange() : RefExpr->getSourceRange(); 3096 SourceLocation PrevAllocatorLoc = 3097 PrevAllocator ? PrevAllocator->getExprLoc() : A->getLocation(); 3098 SourceRange PrevAllocatorRange = 3099 PrevAllocator ? PrevAllocator->getSourceRange() : A->getRange(); 3100 S.Diag(AllocatorLoc, diag::warn_omp_used_different_allocator) 3101 << (Allocator ? 1 : 0) << AllocatorStream.str() 3102 << (PrevAllocator ? 1 : 0) << PrevAllocatorStream.str() 3103 << AllocatorRange; 3104 S.Diag(PrevAllocatorLoc, diag::note_omp_previous_allocator) 3105 << PrevAllocatorRange; 3106 return true; 3107 } 3108 return false; 3109 } 3110 3111 static void 3112 applyOMPAllocateAttribute(Sema &S, VarDecl *VD, 3113 OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind, 3114 Expr *Allocator, SourceRange SR) { 3115 if (VD->hasAttr<OMPAllocateDeclAttr>()) 3116 return; 3117 if (Allocator && 3118 (Allocator->isTypeDependent() || Allocator->isValueDependent() || 3119 Allocator->isInstantiationDependent() || 3120 Allocator->containsUnexpandedParameterPack())) 3121 return; 3122 auto *A = OMPAllocateDeclAttr::CreateImplicit(S.Context, AllocatorKind, 3123 Allocator, SR); 3124 VD->addAttr(A); 3125 if (ASTMutationListener *ML = S.Context.getASTMutationListener()) 3126 ML->DeclarationMarkedOpenMPAllocate(VD, A); 3127 } 3128 3129 Sema::DeclGroupPtrTy Sema::ActOnOpenMPAllocateDirective( 3130 SourceLocation Loc, ArrayRef<Expr *> VarList, 3131 ArrayRef<OMPClause *> Clauses, DeclContext *Owner) { 3132 assert(Clauses.size() <= 1 && "Expected at most one clause."); 3133 Expr *Allocator = nullptr; 3134 if (Clauses.empty()) { 3135 // OpenMP 5.0, 2.11.3 allocate Directive, Restrictions. 3136 // allocate directives that appear in a target region must specify an 3137 // allocator clause unless a requires directive with the dynamic_allocators 3138 // clause is present in the same compilation unit. 3139 if (LangOpts.OpenMPIsDevice && 3140 !DSAStack->hasRequiresDeclWithClause<OMPDynamicAllocatorsClause>()) 3141 targetDiag(Loc, diag::err_expected_allocator_clause); 3142 } else { 3143 Allocator = cast<OMPAllocatorClause>(Clauses.back())->getAllocator(); 3144 } 3145 OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind = 3146 getAllocatorKind(*this, DSAStack, Allocator); 3147 SmallVector<Expr *, 8> Vars; 3148 for (Expr *RefExpr : VarList) { 3149 auto *DE = cast<DeclRefExpr>(RefExpr); 3150 auto *VD = cast<VarDecl>(DE->getDecl()); 3151 3152 // Check if this is a TLS variable or global register. 3153 if (VD->getTLSKind() != VarDecl::TLS_None || 3154 VD->hasAttr<OMPThreadPrivateDeclAttr>() || 3155 (VD->getStorageClass() == SC_Register && VD->hasAttr<AsmLabelAttr>() && 3156 !VD->isLocalVarDecl())) 3157 continue; 3158 3159 // If the used several times in the allocate directive, the same allocator 3160 // must be used. 3161 if (checkPreviousOMPAllocateAttribute(*this, DSAStack, RefExpr, VD, 3162 AllocatorKind, Allocator)) 3163 continue; 3164 3165 // OpenMP, 2.11.3 allocate Directive, Restrictions, C / C++ 3166 // If a list item has a static storage type, the allocator expression in the 3167 // allocator clause must be a constant expression that evaluates to one of 3168 // the predefined memory allocator values. 3169 if (Allocator && VD->hasGlobalStorage()) { 3170 if (AllocatorKind == OMPAllocateDeclAttr::OMPUserDefinedMemAlloc) { 3171 Diag(Allocator->getExprLoc(), 3172 diag::err_omp_expected_predefined_allocator) 3173 << Allocator->getSourceRange(); 3174 bool IsDecl = VD->isThisDeclarationADefinition(Context) == 3175 VarDecl::DeclarationOnly; 3176 Diag(VD->getLocation(), 3177 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 3178 << VD; 3179 continue; 3180 } 3181 } 3182 3183 Vars.push_back(RefExpr); 3184 applyOMPAllocateAttribute(*this, VD, AllocatorKind, Allocator, 3185 DE->getSourceRange()); 3186 } 3187 if (Vars.empty()) 3188 return nullptr; 3189 if (!Owner) 3190 Owner = getCurLexicalContext(); 3191 auto *D = OMPAllocateDecl::Create(Context, Owner, Loc, Vars, Clauses); 3192 D->setAccess(AS_public); 3193 Owner->addDecl(D); 3194 return DeclGroupPtrTy::make(DeclGroupRef(D)); 3195 } 3196 3197 Sema::DeclGroupPtrTy 3198 Sema::ActOnOpenMPRequiresDirective(SourceLocation Loc, 3199 ArrayRef<OMPClause *> ClauseList) { 3200 OMPRequiresDecl *D = nullptr; 3201 if (!CurContext->isFileContext()) { 3202 Diag(Loc, diag::err_omp_invalid_scope) << "requires"; 3203 } else { 3204 D = CheckOMPRequiresDecl(Loc, ClauseList); 3205 if (D) { 3206 CurContext->addDecl(D); 3207 DSAStack->addRequiresDecl(D); 3208 } 3209 } 3210 return DeclGroupPtrTy::make(DeclGroupRef(D)); 3211 } 3212 3213 void Sema::ActOnOpenMPAssumesDirective(SourceLocation Loc, 3214 OpenMPDirectiveKind DKind, 3215 ArrayRef<StringRef> Assumptions, 3216 bool SkippedClauses) { 3217 if (!SkippedClauses && Assumptions.empty()) 3218 Diag(Loc, diag::err_omp_no_clause_for_directive) 3219 << llvm::omp::getAllAssumeClauseOptions() 3220 << llvm::omp::getOpenMPDirectiveName(DKind); 3221 3222 auto *AA = AssumptionAttr::Create(Context, llvm::join(Assumptions, ","), Loc); 3223 if (DKind == llvm::omp::Directive::OMPD_begin_assumes) { 3224 OMPAssumeScoped.push_back(AA); 3225 return; 3226 } 3227 3228 // Global assumes without assumption clauses are ignored. 3229 if (Assumptions.empty()) 3230 return; 3231 3232 assert(DKind == llvm::omp::Directive::OMPD_assumes && 3233 "Unexpected omp assumption directive!"); 3234 OMPAssumeGlobal.push_back(AA); 3235 3236 // The OMPAssumeGlobal scope above will take care of new declarations but 3237 // we also want to apply the assumption to existing ones, e.g., to 3238 // declarations in included headers. To this end, we traverse all existing 3239 // declaration contexts and annotate function declarations here. 3240 SmallVector<DeclContext *, 8> DeclContexts; 3241 auto *Ctx = CurContext; 3242 while (Ctx->getLexicalParent()) 3243 Ctx = Ctx->getLexicalParent(); 3244 DeclContexts.push_back(Ctx); 3245 while (!DeclContexts.empty()) { 3246 DeclContext *DC = DeclContexts.pop_back_val(); 3247 for (auto *SubDC : DC->decls()) { 3248 if (SubDC->isInvalidDecl()) 3249 continue; 3250 if (auto *CTD = dyn_cast<ClassTemplateDecl>(SubDC)) { 3251 DeclContexts.push_back(CTD->getTemplatedDecl()); 3252 for (auto *S : CTD->specializations()) 3253 DeclContexts.push_back(S); 3254 continue; 3255 } 3256 if (auto *DC = dyn_cast<DeclContext>(SubDC)) 3257 DeclContexts.push_back(DC); 3258 if (auto *F = dyn_cast<FunctionDecl>(SubDC)) { 3259 F->addAttr(AA); 3260 continue; 3261 } 3262 } 3263 } 3264 } 3265 3266 void Sema::ActOnOpenMPEndAssumesDirective() { 3267 assert(isInOpenMPAssumeScope() && "Not in OpenMP assumes scope!"); 3268 OMPAssumeScoped.pop_back(); 3269 } 3270 3271 OMPRequiresDecl *Sema::CheckOMPRequiresDecl(SourceLocation Loc, 3272 ArrayRef<OMPClause *> ClauseList) { 3273 /// For target specific clauses, the requires directive cannot be 3274 /// specified after the handling of any of the target regions in the 3275 /// current compilation unit. 3276 ArrayRef<SourceLocation> TargetLocations = 3277 DSAStack->getEncounteredTargetLocs(); 3278 SourceLocation AtomicLoc = DSAStack->getAtomicDirectiveLoc(); 3279 if (!TargetLocations.empty() || !AtomicLoc.isInvalid()) { 3280 for (const OMPClause *CNew : ClauseList) { 3281 // Check if any of the requires clauses affect target regions. 3282 if (isa<OMPUnifiedSharedMemoryClause>(CNew) || 3283 isa<OMPUnifiedAddressClause>(CNew) || 3284 isa<OMPReverseOffloadClause>(CNew) || 3285 isa<OMPDynamicAllocatorsClause>(CNew)) { 3286 Diag(Loc, diag::err_omp_directive_before_requires) 3287 << "target" << getOpenMPClauseName(CNew->getClauseKind()); 3288 for (SourceLocation TargetLoc : TargetLocations) { 3289 Diag(TargetLoc, diag::note_omp_requires_encountered_directive) 3290 << "target"; 3291 } 3292 } else if (!AtomicLoc.isInvalid() && 3293 isa<OMPAtomicDefaultMemOrderClause>(CNew)) { 3294 Diag(Loc, diag::err_omp_directive_before_requires) 3295 << "atomic" << getOpenMPClauseName(CNew->getClauseKind()); 3296 Diag(AtomicLoc, diag::note_omp_requires_encountered_directive) 3297 << "atomic"; 3298 } 3299 } 3300 } 3301 3302 if (!DSAStack->hasDuplicateRequiresClause(ClauseList)) 3303 return OMPRequiresDecl::Create(Context, getCurLexicalContext(), Loc, 3304 ClauseList); 3305 return nullptr; 3306 } 3307 3308 static void reportOriginalDsa(Sema &SemaRef, const DSAStackTy *Stack, 3309 const ValueDecl *D, 3310 const DSAStackTy::DSAVarData &DVar, 3311 bool IsLoopIterVar) { 3312 if (DVar.RefExpr) { 3313 SemaRef.Diag(DVar.RefExpr->getExprLoc(), diag::note_omp_explicit_dsa) 3314 << getOpenMPClauseName(DVar.CKind); 3315 return; 3316 } 3317 enum { 3318 PDSA_StaticMemberShared, 3319 PDSA_StaticLocalVarShared, 3320 PDSA_LoopIterVarPrivate, 3321 PDSA_LoopIterVarLinear, 3322 PDSA_LoopIterVarLastprivate, 3323 PDSA_ConstVarShared, 3324 PDSA_GlobalVarShared, 3325 PDSA_TaskVarFirstprivate, 3326 PDSA_LocalVarPrivate, 3327 PDSA_Implicit 3328 } Reason = PDSA_Implicit; 3329 bool ReportHint = false; 3330 auto ReportLoc = D->getLocation(); 3331 auto *VD = dyn_cast<VarDecl>(D); 3332 if (IsLoopIterVar) { 3333 if (DVar.CKind == OMPC_private) 3334 Reason = PDSA_LoopIterVarPrivate; 3335 else if (DVar.CKind == OMPC_lastprivate) 3336 Reason = PDSA_LoopIterVarLastprivate; 3337 else 3338 Reason = PDSA_LoopIterVarLinear; 3339 } else if (isOpenMPTaskingDirective(DVar.DKind) && 3340 DVar.CKind == OMPC_firstprivate) { 3341 Reason = PDSA_TaskVarFirstprivate; 3342 ReportLoc = DVar.ImplicitDSALoc; 3343 } else if (VD && VD->isStaticLocal()) 3344 Reason = PDSA_StaticLocalVarShared; 3345 else if (VD && VD->isStaticDataMember()) 3346 Reason = PDSA_StaticMemberShared; 3347 else if (VD && VD->isFileVarDecl()) 3348 Reason = PDSA_GlobalVarShared; 3349 else if (D->getType().isConstant(SemaRef.getASTContext())) 3350 Reason = PDSA_ConstVarShared; 3351 else if (VD && VD->isLocalVarDecl() && DVar.CKind == OMPC_private) { 3352 ReportHint = true; 3353 Reason = PDSA_LocalVarPrivate; 3354 } 3355 if (Reason != PDSA_Implicit) { 3356 SemaRef.Diag(ReportLoc, diag::note_omp_predetermined_dsa) 3357 << Reason << ReportHint 3358 << getOpenMPDirectiveName(Stack->getCurrentDirective()); 3359 } else if (DVar.ImplicitDSALoc.isValid()) { 3360 SemaRef.Diag(DVar.ImplicitDSALoc, diag::note_omp_implicit_dsa) 3361 << getOpenMPClauseName(DVar.CKind); 3362 } 3363 } 3364 3365 static OpenMPMapClauseKind 3366 getMapClauseKindFromModifier(OpenMPDefaultmapClauseModifier M, 3367 bool IsAggregateOrDeclareTarget) { 3368 OpenMPMapClauseKind Kind = OMPC_MAP_unknown; 3369 switch (M) { 3370 case OMPC_DEFAULTMAP_MODIFIER_alloc: 3371 Kind = OMPC_MAP_alloc; 3372 break; 3373 case OMPC_DEFAULTMAP_MODIFIER_to: 3374 Kind = OMPC_MAP_to; 3375 break; 3376 case OMPC_DEFAULTMAP_MODIFIER_from: 3377 Kind = OMPC_MAP_from; 3378 break; 3379 case OMPC_DEFAULTMAP_MODIFIER_tofrom: 3380 Kind = OMPC_MAP_tofrom; 3381 break; 3382 case OMPC_DEFAULTMAP_MODIFIER_present: 3383 // OpenMP 5.1 [2.21.7.3] defaultmap clause, Description] 3384 // If implicit-behavior is present, each variable referenced in the 3385 // construct in the category specified by variable-category is treated as if 3386 // it had been listed in a map clause with the map-type of alloc and 3387 // map-type-modifier of present. 3388 Kind = OMPC_MAP_alloc; 3389 break; 3390 case OMPC_DEFAULTMAP_MODIFIER_firstprivate: 3391 case OMPC_DEFAULTMAP_MODIFIER_last: 3392 llvm_unreachable("Unexpected defaultmap implicit behavior"); 3393 case OMPC_DEFAULTMAP_MODIFIER_none: 3394 case OMPC_DEFAULTMAP_MODIFIER_default: 3395 case OMPC_DEFAULTMAP_MODIFIER_unknown: 3396 // IsAggregateOrDeclareTarget could be true if: 3397 // 1. the implicit behavior for aggregate is tofrom 3398 // 2. it's a declare target link 3399 if (IsAggregateOrDeclareTarget) { 3400 Kind = OMPC_MAP_tofrom; 3401 break; 3402 } 3403 llvm_unreachable("Unexpected defaultmap implicit behavior"); 3404 } 3405 assert(Kind != OMPC_MAP_unknown && "Expect map kind to be known"); 3406 return Kind; 3407 } 3408 3409 namespace { 3410 class DSAAttrChecker final : public StmtVisitor<DSAAttrChecker, void> { 3411 DSAStackTy *Stack; 3412 Sema &SemaRef; 3413 bool ErrorFound = false; 3414 bool TryCaptureCXXThisMembers = false; 3415 CapturedStmt *CS = nullptr; 3416 const static unsigned DefaultmapKindNum = OMPC_DEFAULTMAP_pointer + 1; 3417 llvm::SmallVector<Expr *, 4> ImplicitFirstprivate; 3418 llvm::SmallVector<Expr *, 4> ImplicitMap[DefaultmapKindNum][OMPC_MAP_delete]; 3419 llvm::SmallVector<OpenMPMapModifierKind, NumberOfOMPMapClauseModifiers> 3420 ImplicitMapModifier[DefaultmapKindNum]; 3421 Sema::VarsWithInheritedDSAType VarsWithInheritedDSA; 3422 llvm::SmallDenseSet<const ValueDecl *, 4> ImplicitDeclarations; 3423 3424 void VisitSubCaptures(OMPExecutableDirective *S) { 3425 // Check implicitly captured variables. 3426 if (!S->hasAssociatedStmt() || !S->getAssociatedStmt()) 3427 return; 3428 if (S->getDirectiveKind() == OMPD_atomic || 3429 S->getDirectiveKind() == OMPD_critical || 3430 S->getDirectiveKind() == OMPD_section || 3431 S->getDirectiveKind() == OMPD_master || 3432 S->getDirectiveKind() == OMPD_masked || 3433 isOpenMPLoopTransformationDirective(S->getDirectiveKind())) { 3434 Visit(S->getAssociatedStmt()); 3435 return; 3436 } 3437 visitSubCaptures(S->getInnermostCapturedStmt()); 3438 // Try to capture inner this->member references to generate correct mappings 3439 // and diagnostics. 3440 if (TryCaptureCXXThisMembers || 3441 (isOpenMPTargetExecutionDirective(Stack->getCurrentDirective()) && 3442 llvm::any_of(S->getInnermostCapturedStmt()->captures(), 3443 [](const CapturedStmt::Capture &C) { 3444 return C.capturesThis(); 3445 }))) { 3446 bool SavedTryCaptureCXXThisMembers = TryCaptureCXXThisMembers; 3447 TryCaptureCXXThisMembers = true; 3448 Visit(S->getInnermostCapturedStmt()->getCapturedStmt()); 3449 TryCaptureCXXThisMembers = SavedTryCaptureCXXThisMembers; 3450 } 3451 // In tasks firstprivates are not captured anymore, need to analyze them 3452 // explicitly. 3453 if (isOpenMPTaskingDirective(S->getDirectiveKind()) && 3454 !isOpenMPTaskLoopDirective(S->getDirectiveKind())) { 3455 for (OMPClause *C : S->clauses()) 3456 if (auto *FC = dyn_cast<OMPFirstprivateClause>(C)) { 3457 for (Expr *Ref : FC->varlists()) 3458 Visit(Ref); 3459 } 3460 } 3461 } 3462 3463 public: 3464 void VisitDeclRefExpr(DeclRefExpr *E) { 3465 if (TryCaptureCXXThisMembers || E->isTypeDependent() || 3466 E->isValueDependent() || E->containsUnexpandedParameterPack() || 3467 E->isInstantiationDependent()) 3468 return; 3469 if (auto *VD = dyn_cast<VarDecl>(E->getDecl())) { 3470 // Check the datasharing rules for the expressions in the clauses. 3471 if (!CS) { 3472 if (auto *CED = dyn_cast<OMPCapturedExprDecl>(VD)) 3473 if (!CED->hasAttr<OMPCaptureNoInitAttr>()) { 3474 Visit(CED->getInit()); 3475 return; 3476 } 3477 } else if (VD->isImplicit() || isa<OMPCapturedExprDecl>(VD)) 3478 // Do not analyze internal variables and do not enclose them into 3479 // implicit clauses. 3480 return; 3481 VD = VD->getCanonicalDecl(); 3482 // Skip internally declared variables. 3483 if (VD->hasLocalStorage() && CS && !CS->capturesVariable(VD) && 3484 !Stack->isImplicitTaskFirstprivate(VD)) 3485 return; 3486 // Skip allocators in uses_allocators clauses. 3487 if (Stack->isUsesAllocatorsDecl(VD).hasValue()) 3488 return; 3489 3490 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(VD, /*FromParent=*/false); 3491 // Check if the variable has explicit DSA set and stop analysis if it so. 3492 if (DVar.RefExpr || !ImplicitDeclarations.insert(VD).second) 3493 return; 3494 3495 // Skip internally declared static variables. 3496 llvm::Optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res = 3497 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD); 3498 if (VD->hasGlobalStorage() && CS && !CS->capturesVariable(VD) && 3499 (Stack->hasRequiresDeclWithClause<OMPUnifiedSharedMemoryClause>() || 3500 !Res || *Res != OMPDeclareTargetDeclAttr::MT_Link) && 3501 !Stack->isImplicitTaskFirstprivate(VD)) 3502 return; 3503 3504 SourceLocation ELoc = E->getExprLoc(); 3505 OpenMPDirectiveKind DKind = Stack->getCurrentDirective(); 3506 // The default(none) clause requires that each variable that is referenced 3507 // in the construct, and does not have a predetermined data-sharing 3508 // attribute, must have its data-sharing attribute explicitly determined 3509 // by being listed in a data-sharing attribute clause. 3510 if (DVar.CKind == OMPC_unknown && 3511 (Stack->getDefaultDSA() == DSA_none || 3512 Stack->getDefaultDSA() == DSA_firstprivate) && 3513 isImplicitOrExplicitTaskingRegion(DKind) && 3514 VarsWithInheritedDSA.count(VD) == 0) { 3515 bool InheritedDSA = Stack->getDefaultDSA() == DSA_none; 3516 if (!InheritedDSA && Stack->getDefaultDSA() == DSA_firstprivate) { 3517 DSAStackTy::DSAVarData DVar = 3518 Stack->getImplicitDSA(VD, /*FromParent=*/false); 3519 InheritedDSA = DVar.CKind == OMPC_unknown; 3520 } 3521 if (InheritedDSA) 3522 VarsWithInheritedDSA[VD] = E; 3523 return; 3524 } 3525 3526 // OpenMP 5.0 [2.19.7.2, defaultmap clause, Description] 3527 // If implicit-behavior is none, each variable referenced in the 3528 // construct that does not have a predetermined data-sharing attribute 3529 // and does not appear in a to or link clause on a declare target 3530 // directive must be listed in a data-mapping attribute clause, a 3531 // data-haring attribute clause (including a data-sharing attribute 3532 // clause on a combined construct where target. is one of the 3533 // constituent constructs), or an is_device_ptr clause. 3534 OpenMPDefaultmapClauseKind ClauseKind = 3535 getVariableCategoryFromDecl(SemaRef.getLangOpts(), VD); 3536 if (SemaRef.getLangOpts().OpenMP >= 50) { 3537 bool IsModifierNone = Stack->getDefaultmapModifier(ClauseKind) == 3538 OMPC_DEFAULTMAP_MODIFIER_none; 3539 if (DVar.CKind == OMPC_unknown && IsModifierNone && 3540 VarsWithInheritedDSA.count(VD) == 0 && !Res) { 3541 // Only check for data-mapping attribute and is_device_ptr here 3542 // since we have already make sure that the declaration does not 3543 // have a data-sharing attribute above 3544 if (!Stack->checkMappableExprComponentListsForDecl( 3545 VD, /*CurrentRegionOnly=*/true, 3546 [VD](OMPClauseMappableExprCommon::MappableExprComponentListRef 3547 MapExprComponents, 3548 OpenMPClauseKind) { 3549 auto MI = MapExprComponents.rbegin(); 3550 auto ME = MapExprComponents.rend(); 3551 return MI != ME && MI->getAssociatedDeclaration() == VD; 3552 })) { 3553 VarsWithInheritedDSA[VD] = E; 3554 return; 3555 } 3556 } 3557 } 3558 if (SemaRef.getLangOpts().OpenMP > 50) { 3559 bool IsModifierPresent = Stack->getDefaultmapModifier(ClauseKind) == 3560 OMPC_DEFAULTMAP_MODIFIER_present; 3561 if (IsModifierPresent) { 3562 if (llvm::find(ImplicitMapModifier[ClauseKind], 3563 OMPC_MAP_MODIFIER_present) == 3564 std::end(ImplicitMapModifier[ClauseKind])) { 3565 ImplicitMapModifier[ClauseKind].push_back( 3566 OMPC_MAP_MODIFIER_present); 3567 } 3568 } 3569 } 3570 3571 if (isOpenMPTargetExecutionDirective(DKind) && 3572 !Stack->isLoopControlVariable(VD).first) { 3573 if (!Stack->checkMappableExprComponentListsForDecl( 3574 VD, /*CurrentRegionOnly=*/true, 3575 [this](OMPClauseMappableExprCommon::MappableExprComponentListRef 3576 StackComponents, 3577 OpenMPClauseKind) { 3578 if (SemaRef.LangOpts.OpenMP >= 50) 3579 return !StackComponents.empty(); 3580 // Variable is used if it has been marked as an array, array 3581 // section, array shaping or the variable iself. 3582 return StackComponents.size() == 1 || 3583 std::all_of( 3584 std::next(StackComponents.rbegin()), 3585 StackComponents.rend(), 3586 [](const OMPClauseMappableExprCommon:: 3587 MappableComponent &MC) { 3588 return MC.getAssociatedDeclaration() == 3589 nullptr && 3590 (isa<OMPArraySectionExpr>( 3591 MC.getAssociatedExpression()) || 3592 isa<OMPArrayShapingExpr>( 3593 MC.getAssociatedExpression()) || 3594 isa<ArraySubscriptExpr>( 3595 MC.getAssociatedExpression())); 3596 }); 3597 })) { 3598 bool IsFirstprivate = false; 3599 // By default lambdas are captured as firstprivates. 3600 if (const auto *RD = 3601 VD->getType().getNonReferenceType()->getAsCXXRecordDecl()) 3602 IsFirstprivate = RD->isLambda(); 3603 IsFirstprivate = 3604 IsFirstprivate || (Stack->mustBeFirstprivate(ClauseKind) && !Res); 3605 if (IsFirstprivate) { 3606 ImplicitFirstprivate.emplace_back(E); 3607 } else { 3608 OpenMPDefaultmapClauseModifier M = 3609 Stack->getDefaultmapModifier(ClauseKind); 3610 OpenMPMapClauseKind Kind = getMapClauseKindFromModifier( 3611 M, ClauseKind == OMPC_DEFAULTMAP_aggregate || Res); 3612 ImplicitMap[ClauseKind][Kind].emplace_back(E); 3613 } 3614 return; 3615 } 3616 } 3617 3618 // OpenMP [2.9.3.6, Restrictions, p.2] 3619 // A list item that appears in a reduction clause of the innermost 3620 // enclosing worksharing or parallel construct may not be accessed in an 3621 // explicit task. 3622 DVar = Stack->hasInnermostDSA( 3623 VD, 3624 [](OpenMPClauseKind C, bool AppliedToPointee) { 3625 return C == OMPC_reduction && !AppliedToPointee; 3626 }, 3627 [](OpenMPDirectiveKind K) { 3628 return isOpenMPParallelDirective(K) || 3629 isOpenMPWorksharingDirective(K) || isOpenMPTeamsDirective(K); 3630 }, 3631 /*FromParent=*/true); 3632 if (isOpenMPTaskingDirective(DKind) && DVar.CKind == OMPC_reduction) { 3633 ErrorFound = true; 3634 SemaRef.Diag(ELoc, diag::err_omp_reduction_in_task); 3635 reportOriginalDsa(SemaRef, Stack, VD, DVar); 3636 return; 3637 } 3638 3639 // Define implicit data-sharing attributes for task. 3640 DVar = Stack->getImplicitDSA(VD, /*FromParent=*/false); 3641 if (((isOpenMPTaskingDirective(DKind) && DVar.CKind != OMPC_shared) || 3642 (Stack->getDefaultDSA() == DSA_firstprivate && 3643 DVar.CKind == OMPC_firstprivate && !DVar.RefExpr)) && 3644 !Stack->isLoopControlVariable(VD).first) { 3645 ImplicitFirstprivate.push_back(E); 3646 return; 3647 } 3648 3649 // Store implicitly used globals with declare target link for parent 3650 // target. 3651 if (!isOpenMPTargetExecutionDirective(DKind) && Res && 3652 *Res == OMPDeclareTargetDeclAttr::MT_Link) { 3653 Stack->addToParentTargetRegionLinkGlobals(E); 3654 return; 3655 } 3656 } 3657 } 3658 void VisitMemberExpr(MemberExpr *E) { 3659 if (E->isTypeDependent() || E->isValueDependent() || 3660 E->containsUnexpandedParameterPack() || E->isInstantiationDependent()) 3661 return; 3662 auto *FD = dyn_cast<FieldDecl>(E->getMemberDecl()); 3663 OpenMPDirectiveKind DKind = Stack->getCurrentDirective(); 3664 if (auto *TE = dyn_cast<CXXThisExpr>(E->getBase()->IgnoreParenCasts())) { 3665 if (!FD) 3666 return; 3667 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(FD, /*FromParent=*/false); 3668 // Check if the variable has explicit DSA set and stop analysis if it 3669 // so. 3670 if (DVar.RefExpr || !ImplicitDeclarations.insert(FD).second) 3671 return; 3672 3673 if (isOpenMPTargetExecutionDirective(DKind) && 3674 !Stack->isLoopControlVariable(FD).first && 3675 !Stack->checkMappableExprComponentListsForDecl( 3676 FD, /*CurrentRegionOnly=*/true, 3677 [](OMPClauseMappableExprCommon::MappableExprComponentListRef 3678 StackComponents, 3679 OpenMPClauseKind) { 3680 return isa<CXXThisExpr>( 3681 cast<MemberExpr>( 3682 StackComponents.back().getAssociatedExpression()) 3683 ->getBase() 3684 ->IgnoreParens()); 3685 })) { 3686 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.3] 3687 // A bit-field cannot appear in a map clause. 3688 // 3689 if (FD->isBitField()) 3690 return; 3691 3692 // Check to see if the member expression is referencing a class that 3693 // has already been explicitly mapped 3694 if (Stack->isClassPreviouslyMapped(TE->getType())) 3695 return; 3696 3697 OpenMPDefaultmapClauseModifier Modifier = 3698 Stack->getDefaultmapModifier(OMPC_DEFAULTMAP_aggregate); 3699 OpenMPDefaultmapClauseKind ClauseKind = 3700 getVariableCategoryFromDecl(SemaRef.getLangOpts(), FD); 3701 OpenMPMapClauseKind Kind = getMapClauseKindFromModifier( 3702 Modifier, /*IsAggregateOrDeclareTarget*/ true); 3703 ImplicitMap[ClauseKind][Kind].emplace_back(E); 3704 return; 3705 } 3706 3707 SourceLocation ELoc = E->getExprLoc(); 3708 // OpenMP [2.9.3.6, Restrictions, p.2] 3709 // A list item that appears in a reduction clause of the innermost 3710 // enclosing worksharing or parallel construct may not be accessed in 3711 // an explicit task. 3712 DVar = Stack->hasInnermostDSA( 3713 FD, 3714 [](OpenMPClauseKind C, bool AppliedToPointee) { 3715 return C == OMPC_reduction && !AppliedToPointee; 3716 }, 3717 [](OpenMPDirectiveKind K) { 3718 return isOpenMPParallelDirective(K) || 3719 isOpenMPWorksharingDirective(K) || isOpenMPTeamsDirective(K); 3720 }, 3721 /*FromParent=*/true); 3722 if (isOpenMPTaskingDirective(DKind) && DVar.CKind == OMPC_reduction) { 3723 ErrorFound = true; 3724 SemaRef.Diag(ELoc, diag::err_omp_reduction_in_task); 3725 reportOriginalDsa(SemaRef, Stack, FD, DVar); 3726 return; 3727 } 3728 3729 // Define implicit data-sharing attributes for task. 3730 DVar = Stack->getImplicitDSA(FD, /*FromParent=*/false); 3731 if (isOpenMPTaskingDirective(DKind) && DVar.CKind != OMPC_shared && 3732 !Stack->isLoopControlVariable(FD).first) { 3733 // Check if there is a captured expression for the current field in the 3734 // region. Do not mark it as firstprivate unless there is no captured 3735 // expression. 3736 // TODO: try to make it firstprivate. 3737 if (DVar.CKind != OMPC_unknown) 3738 ImplicitFirstprivate.push_back(E); 3739 } 3740 return; 3741 } 3742 if (isOpenMPTargetExecutionDirective(DKind)) { 3743 OMPClauseMappableExprCommon::MappableExprComponentList CurComponents; 3744 if (!checkMapClauseExpressionBase(SemaRef, E, CurComponents, OMPC_map, 3745 Stack->getCurrentDirective(), 3746 /*NoDiagnose=*/true)) 3747 return; 3748 const auto *VD = cast<ValueDecl>( 3749 CurComponents.back().getAssociatedDeclaration()->getCanonicalDecl()); 3750 if (!Stack->checkMappableExprComponentListsForDecl( 3751 VD, /*CurrentRegionOnly=*/true, 3752 [&CurComponents]( 3753 OMPClauseMappableExprCommon::MappableExprComponentListRef 3754 StackComponents, 3755 OpenMPClauseKind) { 3756 auto CCI = CurComponents.rbegin(); 3757 auto CCE = CurComponents.rend(); 3758 for (const auto &SC : llvm::reverse(StackComponents)) { 3759 // Do both expressions have the same kind? 3760 if (CCI->getAssociatedExpression()->getStmtClass() != 3761 SC.getAssociatedExpression()->getStmtClass()) 3762 if (!((isa<OMPArraySectionExpr>( 3763 SC.getAssociatedExpression()) || 3764 isa<OMPArrayShapingExpr>( 3765 SC.getAssociatedExpression())) && 3766 isa<ArraySubscriptExpr>( 3767 CCI->getAssociatedExpression()))) 3768 return false; 3769 3770 const Decl *CCD = CCI->getAssociatedDeclaration(); 3771 const Decl *SCD = SC.getAssociatedDeclaration(); 3772 CCD = CCD ? CCD->getCanonicalDecl() : nullptr; 3773 SCD = SCD ? SCD->getCanonicalDecl() : nullptr; 3774 if (SCD != CCD) 3775 return false; 3776 std::advance(CCI, 1); 3777 if (CCI == CCE) 3778 break; 3779 } 3780 return true; 3781 })) { 3782 Visit(E->getBase()); 3783 } 3784 } else if (!TryCaptureCXXThisMembers) { 3785 Visit(E->getBase()); 3786 } 3787 } 3788 void VisitOMPExecutableDirective(OMPExecutableDirective *S) { 3789 for (OMPClause *C : S->clauses()) { 3790 // Skip analysis of arguments of implicitly defined firstprivate clause 3791 // for task|target directives. 3792 // Skip analysis of arguments of implicitly defined map clause for target 3793 // directives. 3794 if (C && !((isa<OMPFirstprivateClause>(C) || isa<OMPMapClause>(C)) && 3795 C->isImplicit() && 3796 !isOpenMPTaskingDirective(Stack->getCurrentDirective()))) { 3797 for (Stmt *CC : C->children()) { 3798 if (CC) 3799 Visit(CC); 3800 } 3801 } 3802 } 3803 // Check implicitly captured variables. 3804 VisitSubCaptures(S); 3805 } 3806 3807 void VisitOMPTileDirective(OMPTileDirective *S) { 3808 // #pragma omp tile does not introduce data sharing. 3809 VisitStmt(S); 3810 } 3811 3812 void VisitStmt(Stmt *S) { 3813 for (Stmt *C : S->children()) { 3814 if (C) { 3815 // Check implicitly captured variables in the task-based directives to 3816 // check if they must be firstprivatized. 3817 Visit(C); 3818 } 3819 } 3820 } 3821 3822 void visitSubCaptures(CapturedStmt *S) { 3823 for (const CapturedStmt::Capture &Cap : S->captures()) { 3824 if (!Cap.capturesVariable() && !Cap.capturesVariableByCopy()) 3825 continue; 3826 VarDecl *VD = Cap.getCapturedVar(); 3827 // Do not try to map the variable if it or its sub-component was mapped 3828 // already. 3829 if (isOpenMPTargetExecutionDirective(Stack->getCurrentDirective()) && 3830 Stack->checkMappableExprComponentListsForDecl( 3831 VD, /*CurrentRegionOnly=*/true, 3832 [](OMPClauseMappableExprCommon::MappableExprComponentListRef, 3833 OpenMPClauseKind) { return true; })) 3834 continue; 3835 DeclRefExpr *DRE = buildDeclRefExpr( 3836 SemaRef, VD, VD->getType().getNonLValueExprType(SemaRef.Context), 3837 Cap.getLocation(), /*RefersToCapture=*/true); 3838 Visit(DRE); 3839 } 3840 } 3841 bool isErrorFound() const { return ErrorFound; } 3842 ArrayRef<Expr *> getImplicitFirstprivate() const { 3843 return ImplicitFirstprivate; 3844 } 3845 ArrayRef<Expr *> getImplicitMap(OpenMPDefaultmapClauseKind DK, 3846 OpenMPMapClauseKind MK) const { 3847 return ImplicitMap[DK][MK]; 3848 } 3849 ArrayRef<OpenMPMapModifierKind> 3850 getImplicitMapModifier(OpenMPDefaultmapClauseKind Kind) const { 3851 return ImplicitMapModifier[Kind]; 3852 } 3853 const Sema::VarsWithInheritedDSAType &getVarsWithInheritedDSA() const { 3854 return VarsWithInheritedDSA; 3855 } 3856 3857 DSAAttrChecker(DSAStackTy *S, Sema &SemaRef, CapturedStmt *CS) 3858 : Stack(S), SemaRef(SemaRef), ErrorFound(false), CS(CS) { 3859 // Process declare target link variables for the target directives. 3860 if (isOpenMPTargetExecutionDirective(S->getCurrentDirective())) { 3861 for (DeclRefExpr *E : Stack->getLinkGlobals()) 3862 Visit(E); 3863 } 3864 } 3865 }; 3866 } // namespace 3867 3868 void Sema::ActOnOpenMPRegionStart(OpenMPDirectiveKind DKind, Scope *CurScope) { 3869 switch (DKind) { 3870 case OMPD_parallel: 3871 case OMPD_parallel_for: 3872 case OMPD_parallel_for_simd: 3873 case OMPD_parallel_sections: 3874 case OMPD_parallel_master: 3875 case OMPD_teams: 3876 case OMPD_teams_distribute: 3877 case OMPD_teams_distribute_simd: { 3878 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 3879 QualType KmpInt32PtrTy = 3880 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3881 Sema::CapturedParamNameType Params[] = { 3882 std::make_pair(".global_tid.", KmpInt32PtrTy), 3883 std::make_pair(".bound_tid.", KmpInt32PtrTy), 3884 std::make_pair(StringRef(), QualType()) // __context with shared vars 3885 }; 3886 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3887 Params); 3888 break; 3889 } 3890 case OMPD_target_teams: 3891 case OMPD_target_parallel: 3892 case OMPD_target_parallel_for: 3893 case OMPD_target_parallel_for_simd: 3894 case OMPD_target_teams_distribute: 3895 case OMPD_target_teams_distribute_simd: { 3896 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 3897 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 3898 QualType KmpInt32PtrTy = 3899 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3900 QualType Args[] = {VoidPtrTy}; 3901 FunctionProtoType::ExtProtoInfo EPI; 3902 EPI.Variadic = true; 3903 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 3904 Sema::CapturedParamNameType Params[] = { 3905 std::make_pair(".global_tid.", KmpInt32Ty), 3906 std::make_pair(".part_id.", KmpInt32PtrTy), 3907 std::make_pair(".privates.", VoidPtrTy), 3908 std::make_pair( 3909 ".copy_fn.", 3910 Context.getPointerType(CopyFnType).withConst().withRestrict()), 3911 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 3912 std::make_pair(StringRef(), QualType()) // __context with shared vars 3913 }; 3914 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3915 Params, /*OpenMPCaptureLevel=*/0); 3916 // Mark this captured region as inlined, because we don't use outlined 3917 // function directly. 3918 getCurCapturedRegion()->TheCapturedDecl->addAttr( 3919 AlwaysInlineAttr::CreateImplicit( 3920 Context, {}, AttributeCommonInfo::AS_Keyword, 3921 AlwaysInlineAttr::Keyword_forceinline)); 3922 Sema::CapturedParamNameType ParamsTarget[] = { 3923 std::make_pair(StringRef(), QualType()) // __context with shared vars 3924 }; 3925 // Start a captured region for 'target' with no implicit parameters. 3926 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3927 ParamsTarget, /*OpenMPCaptureLevel=*/1); 3928 Sema::CapturedParamNameType ParamsTeamsOrParallel[] = { 3929 std::make_pair(".global_tid.", KmpInt32PtrTy), 3930 std::make_pair(".bound_tid.", KmpInt32PtrTy), 3931 std::make_pair(StringRef(), QualType()) // __context with shared vars 3932 }; 3933 // Start a captured region for 'teams' or 'parallel'. Both regions have 3934 // the same implicit parameters. 3935 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3936 ParamsTeamsOrParallel, /*OpenMPCaptureLevel=*/2); 3937 break; 3938 } 3939 case OMPD_target: 3940 case OMPD_target_simd: { 3941 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 3942 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 3943 QualType KmpInt32PtrTy = 3944 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3945 QualType Args[] = {VoidPtrTy}; 3946 FunctionProtoType::ExtProtoInfo EPI; 3947 EPI.Variadic = true; 3948 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 3949 Sema::CapturedParamNameType Params[] = { 3950 std::make_pair(".global_tid.", KmpInt32Ty), 3951 std::make_pair(".part_id.", KmpInt32PtrTy), 3952 std::make_pair(".privates.", VoidPtrTy), 3953 std::make_pair( 3954 ".copy_fn.", 3955 Context.getPointerType(CopyFnType).withConst().withRestrict()), 3956 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 3957 std::make_pair(StringRef(), QualType()) // __context with shared vars 3958 }; 3959 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3960 Params, /*OpenMPCaptureLevel=*/0); 3961 // Mark this captured region as inlined, because we don't use outlined 3962 // function directly. 3963 getCurCapturedRegion()->TheCapturedDecl->addAttr( 3964 AlwaysInlineAttr::CreateImplicit( 3965 Context, {}, AttributeCommonInfo::AS_Keyword, 3966 AlwaysInlineAttr::Keyword_forceinline)); 3967 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3968 std::make_pair(StringRef(), QualType()), 3969 /*OpenMPCaptureLevel=*/1); 3970 break; 3971 } 3972 case OMPD_atomic: 3973 case OMPD_critical: 3974 case OMPD_section: 3975 case OMPD_master: 3976 case OMPD_masked: 3977 case OMPD_tile: 3978 break; 3979 case OMPD_simd: 3980 case OMPD_for: 3981 case OMPD_for_simd: 3982 case OMPD_sections: 3983 case OMPD_single: 3984 case OMPD_taskgroup: 3985 case OMPD_distribute: 3986 case OMPD_distribute_simd: 3987 case OMPD_ordered: 3988 case OMPD_target_data: 3989 case OMPD_dispatch: { 3990 Sema::CapturedParamNameType Params[] = { 3991 std::make_pair(StringRef(), QualType()) // __context with shared vars 3992 }; 3993 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3994 Params); 3995 break; 3996 } 3997 case OMPD_task: { 3998 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 3999 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 4000 QualType KmpInt32PtrTy = 4001 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 4002 QualType Args[] = {VoidPtrTy}; 4003 FunctionProtoType::ExtProtoInfo EPI; 4004 EPI.Variadic = true; 4005 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 4006 Sema::CapturedParamNameType Params[] = { 4007 std::make_pair(".global_tid.", KmpInt32Ty), 4008 std::make_pair(".part_id.", KmpInt32PtrTy), 4009 std::make_pair(".privates.", VoidPtrTy), 4010 std::make_pair( 4011 ".copy_fn.", 4012 Context.getPointerType(CopyFnType).withConst().withRestrict()), 4013 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 4014 std::make_pair(StringRef(), QualType()) // __context with shared vars 4015 }; 4016 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 4017 Params); 4018 // Mark this captured region as inlined, because we don't use outlined 4019 // function directly. 4020 getCurCapturedRegion()->TheCapturedDecl->addAttr( 4021 AlwaysInlineAttr::CreateImplicit( 4022 Context, {}, AttributeCommonInfo::AS_Keyword, 4023 AlwaysInlineAttr::Keyword_forceinline)); 4024 break; 4025 } 4026 case OMPD_taskloop: 4027 case OMPD_taskloop_simd: 4028 case OMPD_master_taskloop: 4029 case OMPD_master_taskloop_simd: { 4030 QualType KmpInt32Ty = 4031 Context.getIntTypeForBitwidth(/*DestWidth=*/32, /*Signed=*/1) 4032 .withConst(); 4033 QualType KmpUInt64Ty = 4034 Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/0) 4035 .withConst(); 4036 QualType KmpInt64Ty = 4037 Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/1) 4038 .withConst(); 4039 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 4040 QualType KmpInt32PtrTy = 4041 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 4042 QualType Args[] = {VoidPtrTy}; 4043 FunctionProtoType::ExtProtoInfo EPI; 4044 EPI.Variadic = true; 4045 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 4046 Sema::CapturedParamNameType Params[] = { 4047 std::make_pair(".global_tid.", KmpInt32Ty), 4048 std::make_pair(".part_id.", KmpInt32PtrTy), 4049 std::make_pair(".privates.", VoidPtrTy), 4050 std::make_pair( 4051 ".copy_fn.", 4052 Context.getPointerType(CopyFnType).withConst().withRestrict()), 4053 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 4054 std::make_pair(".lb.", KmpUInt64Ty), 4055 std::make_pair(".ub.", KmpUInt64Ty), 4056 std::make_pair(".st.", KmpInt64Ty), 4057 std::make_pair(".liter.", KmpInt32Ty), 4058 std::make_pair(".reductions.", VoidPtrTy), 4059 std::make_pair(StringRef(), QualType()) // __context with shared vars 4060 }; 4061 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 4062 Params); 4063 // Mark this captured region as inlined, because we don't use outlined 4064 // function directly. 4065 getCurCapturedRegion()->TheCapturedDecl->addAttr( 4066 AlwaysInlineAttr::CreateImplicit( 4067 Context, {}, AttributeCommonInfo::AS_Keyword, 4068 AlwaysInlineAttr::Keyword_forceinline)); 4069 break; 4070 } 4071 case OMPD_parallel_master_taskloop: 4072 case OMPD_parallel_master_taskloop_simd: { 4073 QualType KmpInt32Ty = 4074 Context.getIntTypeForBitwidth(/*DestWidth=*/32, /*Signed=*/1) 4075 .withConst(); 4076 QualType KmpUInt64Ty = 4077 Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/0) 4078 .withConst(); 4079 QualType KmpInt64Ty = 4080 Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/1) 4081 .withConst(); 4082 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 4083 QualType KmpInt32PtrTy = 4084 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 4085 Sema::CapturedParamNameType ParamsParallel[] = { 4086 std::make_pair(".global_tid.", KmpInt32PtrTy), 4087 std::make_pair(".bound_tid.", KmpInt32PtrTy), 4088 std::make_pair(StringRef(), QualType()) // __context with shared vars 4089 }; 4090 // Start a captured region for 'parallel'. 4091 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 4092 ParamsParallel, /*OpenMPCaptureLevel=*/0); 4093 QualType Args[] = {VoidPtrTy}; 4094 FunctionProtoType::ExtProtoInfo EPI; 4095 EPI.Variadic = true; 4096 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 4097 Sema::CapturedParamNameType Params[] = { 4098 std::make_pair(".global_tid.", KmpInt32Ty), 4099 std::make_pair(".part_id.", KmpInt32PtrTy), 4100 std::make_pair(".privates.", VoidPtrTy), 4101 std::make_pair( 4102 ".copy_fn.", 4103 Context.getPointerType(CopyFnType).withConst().withRestrict()), 4104 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 4105 std::make_pair(".lb.", KmpUInt64Ty), 4106 std::make_pair(".ub.", KmpUInt64Ty), 4107 std::make_pair(".st.", KmpInt64Ty), 4108 std::make_pair(".liter.", KmpInt32Ty), 4109 std::make_pair(".reductions.", VoidPtrTy), 4110 std::make_pair(StringRef(), QualType()) // __context with shared vars 4111 }; 4112 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 4113 Params, /*OpenMPCaptureLevel=*/1); 4114 // Mark this captured region as inlined, because we don't use outlined 4115 // function directly. 4116 getCurCapturedRegion()->TheCapturedDecl->addAttr( 4117 AlwaysInlineAttr::CreateImplicit( 4118 Context, {}, AttributeCommonInfo::AS_Keyword, 4119 AlwaysInlineAttr::Keyword_forceinline)); 4120 break; 4121 } 4122 case OMPD_distribute_parallel_for_simd: 4123 case OMPD_distribute_parallel_for: { 4124 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 4125 QualType KmpInt32PtrTy = 4126 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 4127 Sema::CapturedParamNameType Params[] = { 4128 std::make_pair(".global_tid.", KmpInt32PtrTy), 4129 std::make_pair(".bound_tid.", KmpInt32PtrTy), 4130 std::make_pair(".previous.lb.", Context.getSizeType().withConst()), 4131 std::make_pair(".previous.ub.", Context.getSizeType().withConst()), 4132 std::make_pair(StringRef(), QualType()) // __context with shared vars 4133 }; 4134 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 4135 Params); 4136 break; 4137 } 4138 case OMPD_target_teams_distribute_parallel_for: 4139 case OMPD_target_teams_distribute_parallel_for_simd: { 4140 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 4141 QualType KmpInt32PtrTy = 4142 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 4143 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 4144 4145 QualType Args[] = {VoidPtrTy}; 4146 FunctionProtoType::ExtProtoInfo EPI; 4147 EPI.Variadic = true; 4148 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 4149 Sema::CapturedParamNameType Params[] = { 4150 std::make_pair(".global_tid.", KmpInt32Ty), 4151 std::make_pair(".part_id.", KmpInt32PtrTy), 4152 std::make_pair(".privates.", VoidPtrTy), 4153 std::make_pair( 4154 ".copy_fn.", 4155 Context.getPointerType(CopyFnType).withConst().withRestrict()), 4156 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 4157 std::make_pair(StringRef(), QualType()) // __context with shared vars 4158 }; 4159 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 4160 Params, /*OpenMPCaptureLevel=*/0); 4161 // Mark this captured region as inlined, because we don't use outlined 4162 // function directly. 4163 getCurCapturedRegion()->TheCapturedDecl->addAttr( 4164 AlwaysInlineAttr::CreateImplicit( 4165 Context, {}, AttributeCommonInfo::AS_Keyword, 4166 AlwaysInlineAttr::Keyword_forceinline)); 4167 Sema::CapturedParamNameType ParamsTarget[] = { 4168 std::make_pair(StringRef(), QualType()) // __context with shared vars 4169 }; 4170 // Start a captured region for 'target' with no implicit parameters. 4171 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 4172 ParamsTarget, /*OpenMPCaptureLevel=*/1); 4173 4174 Sema::CapturedParamNameType ParamsTeams[] = { 4175 std::make_pair(".global_tid.", KmpInt32PtrTy), 4176 std::make_pair(".bound_tid.", KmpInt32PtrTy), 4177 std::make_pair(StringRef(), QualType()) // __context with shared vars 4178 }; 4179 // Start a captured region for 'target' with no implicit parameters. 4180 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 4181 ParamsTeams, /*OpenMPCaptureLevel=*/2); 4182 4183 Sema::CapturedParamNameType ParamsParallel[] = { 4184 std::make_pair(".global_tid.", KmpInt32PtrTy), 4185 std::make_pair(".bound_tid.", KmpInt32PtrTy), 4186 std::make_pair(".previous.lb.", Context.getSizeType().withConst()), 4187 std::make_pair(".previous.ub.", Context.getSizeType().withConst()), 4188 std::make_pair(StringRef(), QualType()) // __context with shared vars 4189 }; 4190 // Start a captured region for 'teams' or 'parallel'. Both regions have 4191 // the same implicit parameters. 4192 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 4193 ParamsParallel, /*OpenMPCaptureLevel=*/3); 4194 break; 4195 } 4196 4197 case OMPD_teams_distribute_parallel_for: 4198 case OMPD_teams_distribute_parallel_for_simd: { 4199 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 4200 QualType KmpInt32PtrTy = 4201 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 4202 4203 Sema::CapturedParamNameType ParamsTeams[] = { 4204 std::make_pair(".global_tid.", KmpInt32PtrTy), 4205 std::make_pair(".bound_tid.", KmpInt32PtrTy), 4206 std::make_pair(StringRef(), QualType()) // __context with shared vars 4207 }; 4208 // Start a captured region for 'target' with no implicit parameters. 4209 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 4210 ParamsTeams, /*OpenMPCaptureLevel=*/0); 4211 4212 Sema::CapturedParamNameType ParamsParallel[] = { 4213 std::make_pair(".global_tid.", KmpInt32PtrTy), 4214 std::make_pair(".bound_tid.", KmpInt32PtrTy), 4215 std::make_pair(".previous.lb.", Context.getSizeType().withConst()), 4216 std::make_pair(".previous.ub.", Context.getSizeType().withConst()), 4217 std::make_pair(StringRef(), QualType()) // __context with shared vars 4218 }; 4219 // Start a captured region for 'teams' or 'parallel'. Both regions have 4220 // the same implicit parameters. 4221 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 4222 ParamsParallel, /*OpenMPCaptureLevel=*/1); 4223 break; 4224 } 4225 case OMPD_target_update: 4226 case OMPD_target_enter_data: 4227 case OMPD_target_exit_data: { 4228 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 4229 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 4230 QualType KmpInt32PtrTy = 4231 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 4232 QualType Args[] = {VoidPtrTy}; 4233 FunctionProtoType::ExtProtoInfo EPI; 4234 EPI.Variadic = true; 4235 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 4236 Sema::CapturedParamNameType Params[] = { 4237 std::make_pair(".global_tid.", KmpInt32Ty), 4238 std::make_pair(".part_id.", KmpInt32PtrTy), 4239 std::make_pair(".privates.", VoidPtrTy), 4240 std::make_pair( 4241 ".copy_fn.", 4242 Context.getPointerType(CopyFnType).withConst().withRestrict()), 4243 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 4244 std::make_pair(StringRef(), QualType()) // __context with shared vars 4245 }; 4246 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 4247 Params); 4248 // Mark this captured region as inlined, because we don't use outlined 4249 // function directly. 4250 getCurCapturedRegion()->TheCapturedDecl->addAttr( 4251 AlwaysInlineAttr::CreateImplicit( 4252 Context, {}, AttributeCommonInfo::AS_Keyword, 4253 AlwaysInlineAttr::Keyword_forceinline)); 4254 break; 4255 } 4256 case OMPD_threadprivate: 4257 case OMPD_allocate: 4258 case OMPD_taskyield: 4259 case OMPD_barrier: 4260 case OMPD_taskwait: 4261 case OMPD_cancellation_point: 4262 case OMPD_cancel: 4263 case OMPD_flush: 4264 case OMPD_depobj: 4265 case OMPD_scan: 4266 case OMPD_declare_reduction: 4267 case OMPD_declare_mapper: 4268 case OMPD_declare_simd: 4269 case OMPD_declare_target: 4270 case OMPD_end_declare_target: 4271 case OMPD_requires: 4272 case OMPD_declare_variant: 4273 case OMPD_begin_declare_variant: 4274 case OMPD_end_declare_variant: 4275 llvm_unreachable("OpenMP Directive is not allowed"); 4276 case OMPD_unknown: 4277 default: 4278 llvm_unreachable("Unknown OpenMP directive"); 4279 } 4280 DSAStack->setContext(CurContext); 4281 } 4282 4283 int Sema::getNumberOfConstructScopes(unsigned Level) const { 4284 return getOpenMPCaptureLevels(DSAStack->getDirective(Level)); 4285 } 4286 4287 int Sema::getOpenMPCaptureLevels(OpenMPDirectiveKind DKind) { 4288 SmallVector<OpenMPDirectiveKind, 4> CaptureRegions; 4289 getOpenMPCaptureRegions(CaptureRegions, DKind); 4290 return CaptureRegions.size(); 4291 } 4292 4293 static OMPCapturedExprDecl *buildCaptureDecl(Sema &S, IdentifierInfo *Id, 4294 Expr *CaptureExpr, bool WithInit, 4295 bool AsExpression) { 4296 assert(CaptureExpr); 4297 ASTContext &C = S.getASTContext(); 4298 Expr *Init = AsExpression ? CaptureExpr : CaptureExpr->IgnoreImpCasts(); 4299 QualType Ty = Init->getType(); 4300 if (CaptureExpr->getObjectKind() == OK_Ordinary && CaptureExpr->isGLValue()) { 4301 if (S.getLangOpts().CPlusPlus) { 4302 Ty = C.getLValueReferenceType(Ty); 4303 } else { 4304 Ty = C.getPointerType(Ty); 4305 ExprResult Res = 4306 S.CreateBuiltinUnaryOp(CaptureExpr->getExprLoc(), UO_AddrOf, Init); 4307 if (!Res.isUsable()) 4308 return nullptr; 4309 Init = Res.get(); 4310 } 4311 WithInit = true; 4312 } 4313 auto *CED = OMPCapturedExprDecl::Create(C, S.CurContext, Id, Ty, 4314 CaptureExpr->getBeginLoc()); 4315 if (!WithInit) 4316 CED->addAttr(OMPCaptureNoInitAttr::CreateImplicit(C)); 4317 S.CurContext->addHiddenDecl(CED); 4318 Sema::TentativeAnalysisScope Trap(S); 4319 S.AddInitializerToDecl(CED, Init, /*DirectInit=*/false); 4320 return CED; 4321 } 4322 4323 static DeclRefExpr *buildCapture(Sema &S, ValueDecl *D, Expr *CaptureExpr, 4324 bool WithInit) { 4325 OMPCapturedExprDecl *CD; 4326 if (VarDecl *VD = S.isOpenMPCapturedDecl(D)) 4327 CD = cast<OMPCapturedExprDecl>(VD); 4328 else 4329 CD = buildCaptureDecl(S, D->getIdentifier(), CaptureExpr, WithInit, 4330 /*AsExpression=*/false); 4331 return buildDeclRefExpr(S, CD, CD->getType().getNonReferenceType(), 4332 CaptureExpr->getExprLoc()); 4333 } 4334 4335 static ExprResult buildCapture(Sema &S, Expr *CaptureExpr, DeclRefExpr *&Ref) { 4336 CaptureExpr = S.DefaultLvalueConversion(CaptureExpr).get(); 4337 if (!Ref) { 4338 OMPCapturedExprDecl *CD = buildCaptureDecl( 4339 S, &S.getASTContext().Idents.get(".capture_expr."), CaptureExpr, 4340 /*WithInit=*/true, /*AsExpression=*/true); 4341 Ref = buildDeclRefExpr(S, CD, CD->getType().getNonReferenceType(), 4342 CaptureExpr->getExprLoc()); 4343 } 4344 ExprResult Res = Ref; 4345 if (!S.getLangOpts().CPlusPlus && 4346 CaptureExpr->getObjectKind() == OK_Ordinary && CaptureExpr->isGLValue() && 4347 Ref->getType()->isPointerType()) { 4348 Res = S.CreateBuiltinUnaryOp(CaptureExpr->getExprLoc(), UO_Deref, Ref); 4349 if (!Res.isUsable()) 4350 return ExprError(); 4351 } 4352 return S.DefaultLvalueConversion(Res.get()); 4353 } 4354 4355 namespace { 4356 // OpenMP directives parsed in this section are represented as a 4357 // CapturedStatement with an associated statement. If a syntax error 4358 // is detected during the parsing of the associated statement, the 4359 // compiler must abort processing and close the CapturedStatement. 4360 // 4361 // Combined directives such as 'target parallel' have more than one 4362 // nested CapturedStatements. This RAII ensures that we unwind out 4363 // of all the nested CapturedStatements when an error is found. 4364 class CaptureRegionUnwinderRAII { 4365 private: 4366 Sema &S; 4367 bool &ErrorFound; 4368 OpenMPDirectiveKind DKind = OMPD_unknown; 4369 4370 public: 4371 CaptureRegionUnwinderRAII(Sema &S, bool &ErrorFound, 4372 OpenMPDirectiveKind DKind) 4373 : S(S), ErrorFound(ErrorFound), DKind(DKind) {} 4374 ~CaptureRegionUnwinderRAII() { 4375 if (ErrorFound) { 4376 int ThisCaptureLevel = S.getOpenMPCaptureLevels(DKind); 4377 while (--ThisCaptureLevel >= 0) 4378 S.ActOnCapturedRegionError(); 4379 } 4380 } 4381 }; 4382 } // namespace 4383 4384 void Sema::tryCaptureOpenMPLambdas(ValueDecl *V) { 4385 // Capture variables captured by reference in lambdas for target-based 4386 // directives. 4387 if (!CurContext->isDependentContext() && 4388 (isOpenMPTargetExecutionDirective(DSAStack->getCurrentDirective()) || 4389 isOpenMPTargetDataManagementDirective( 4390 DSAStack->getCurrentDirective()))) { 4391 QualType Type = V->getType(); 4392 if (const auto *RD = Type.getCanonicalType() 4393 .getNonReferenceType() 4394 ->getAsCXXRecordDecl()) { 4395 bool SavedForceCaptureByReferenceInTargetExecutable = 4396 DSAStack->isForceCaptureByReferenceInTargetExecutable(); 4397 DSAStack->setForceCaptureByReferenceInTargetExecutable( 4398 /*V=*/true); 4399 if (RD->isLambda()) { 4400 llvm::DenseMap<const VarDecl *, FieldDecl *> Captures; 4401 FieldDecl *ThisCapture; 4402 RD->getCaptureFields(Captures, ThisCapture); 4403 for (const LambdaCapture &LC : RD->captures()) { 4404 if (LC.getCaptureKind() == LCK_ByRef) { 4405 VarDecl *VD = LC.getCapturedVar(); 4406 DeclContext *VDC = VD->getDeclContext(); 4407 if (!VDC->Encloses(CurContext)) 4408 continue; 4409 MarkVariableReferenced(LC.getLocation(), VD); 4410 } else if (LC.getCaptureKind() == LCK_This) { 4411 QualType ThisTy = getCurrentThisType(); 4412 if (!ThisTy.isNull() && 4413 Context.typesAreCompatible(ThisTy, ThisCapture->getType())) 4414 CheckCXXThisCapture(LC.getLocation()); 4415 } 4416 } 4417 } 4418 DSAStack->setForceCaptureByReferenceInTargetExecutable( 4419 SavedForceCaptureByReferenceInTargetExecutable); 4420 } 4421 } 4422 } 4423 4424 static bool checkOrderedOrderSpecified(Sema &S, 4425 const ArrayRef<OMPClause *> Clauses) { 4426 const OMPOrderedClause *Ordered = nullptr; 4427 const OMPOrderClause *Order = nullptr; 4428 4429 for (const OMPClause *Clause : Clauses) { 4430 if (Clause->getClauseKind() == OMPC_ordered) 4431 Ordered = cast<OMPOrderedClause>(Clause); 4432 else if (Clause->getClauseKind() == OMPC_order) { 4433 Order = cast<OMPOrderClause>(Clause); 4434 if (Order->getKind() != OMPC_ORDER_concurrent) 4435 Order = nullptr; 4436 } 4437 if (Ordered && Order) 4438 break; 4439 } 4440 4441 if (Ordered && Order) { 4442 S.Diag(Order->getKindKwLoc(), 4443 diag::err_omp_simple_clause_incompatible_with_ordered) 4444 << getOpenMPClauseName(OMPC_order) 4445 << getOpenMPSimpleClauseTypeName(OMPC_order, OMPC_ORDER_concurrent) 4446 << SourceRange(Order->getBeginLoc(), Order->getEndLoc()); 4447 S.Diag(Ordered->getBeginLoc(), diag::note_omp_ordered_param) 4448 << 0 << SourceRange(Ordered->getBeginLoc(), Ordered->getEndLoc()); 4449 return true; 4450 } 4451 return false; 4452 } 4453 4454 StmtResult Sema::ActOnOpenMPRegionEnd(StmtResult S, 4455 ArrayRef<OMPClause *> Clauses) { 4456 if (DSAStack->getCurrentDirective() == OMPD_atomic || 4457 DSAStack->getCurrentDirective() == OMPD_critical || 4458 DSAStack->getCurrentDirective() == OMPD_section || 4459 DSAStack->getCurrentDirective() == OMPD_master || 4460 DSAStack->getCurrentDirective() == OMPD_masked) 4461 return S; 4462 4463 bool ErrorFound = false; 4464 CaptureRegionUnwinderRAII CaptureRegionUnwinder( 4465 *this, ErrorFound, DSAStack->getCurrentDirective()); 4466 if (!S.isUsable()) { 4467 ErrorFound = true; 4468 return StmtError(); 4469 } 4470 4471 SmallVector<OpenMPDirectiveKind, 4> CaptureRegions; 4472 getOpenMPCaptureRegions(CaptureRegions, DSAStack->getCurrentDirective()); 4473 OMPOrderedClause *OC = nullptr; 4474 OMPScheduleClause *SC = nullptr; 4475 SmallVector<const OMPLinearClause *, 4> LCs; 4476 SmallVector<const OMPClauseWithPreInit *, 4> PICs; 4477 // This is required for proper codegen. 4478 for (OMPClause *Clause : Clauses) { 4479 if (!LangOpts.OpenMPSimd && 4480 isOpenMPTaskingDirective(DSAStack->getCurrentDirective()) && 4481 Clause->getClauseKind() == OMPC_in_reduction) { 4482 // Capture taskgroup task_reduction descriptors inside the tasking regions 4483 // with the corresponding in_reduction items. 4484 auto *IRC = cast<OMPInReductionClause>(Clause); 4485 for (Expr *E : IRC->taskgroup_descriptors()) 4486 if (E) 4487 MarkDeclarationsReferencedInExpr(E); 4488 } 4489 if (isOpenMPPrivate(Clause->getClauseKind()) || 4490 Clause->getClauseKind() == OMPC_copyprivate || 4491 (getLangOpts().OpenMPUseTLS && 4492 getASTContext().getTargetInfo().isTLSSupported() && 4493 Clause->getClauseKind() == OMPC_copyin)) { 4494 DSAStack->setForceVarCapturing(Clause->getClauseKind() == OMPC_copyin); 4495 // Mark all variables in private list clauses as used in inner region. 4496 for (Stmt *VarRef : Clause->children()) { 4497 if (auto *E = cast_or_null<Expr>(VarRef)) { 4498 MarkDeclarationsReferencedInExpr(E); 4499 } 4500 } 4501 DSAStack->setForceVarCapturing(/*V=*/false); 4502 } else if (isOpenMPLoopTransformationDirective( 4503 DSAStack->getCurrentDirective())) { 4504 assert(CaptureRegions.empty() && 4505 "No captured regions in loop transformation directives."); 4506 } else if (CaptureRegions.size() > 1 || 4507 CaptureRegions.back() != OMPD_unknown) { 4508 if (auto *C = OMPClauseWithPreInit::get(Clause)) 4509 PICs.push_back(C); 4510 if (auto *C = OMPClauseWithPostUpdate::get(Clause)) { 4511 if (Expr *E = C->getPostUpdateExpr()) 4512 MarkDeclarationsReferencedInExpr(E); 4513 } 4514 } 4515 if (Clause->getClauseKind() == OMPC_schedule) 4516 SC = cast<OMPScheduleClause>(Clause); 4517 else if (Clause->getClauseKind() == OMPC_ordered) 4518 OC = cast<OMPOrderedClause>(Clause); 4519 else if (Clause->getClauseKind() == OMPC_linear) 4520 LCs.push_back(cast<OMPLinearClause>(Clause)); 4521 } 4522 // Capture allocator expressions if used. 4523 for (Expr *E : DSAStack->getInnerAllocators()) 4524 MarkDeclarationsReferencedInExpr(E); 4525 // OpenMP, 2.7.1 Loop Construct, Restrictions 4526 // The nonmonotonic modifier cannot be specified if an ordered clause is 4527 // specified. 4528 if (SC && 4529 (SC->getFirstScheduleModifier() == OMPC_SCHEDULE_MODIFIER_nonmonotonic || 4530 SC->getSecondScheduleModifier() == 4531 OMPC_SCHEDULE_MODIFIER_nonmonotonic) && 4532 OC) { 4533 Diag(SC->getFirstScheduleModifier() == OMPC_SCHEDULE_MODIFIER_nonmonotonic 4534 ? SC->getFirstScheduleModifierLoc() 4535 : SC->getSecondScheduleModifierLoc(), 4536 diag::err_omp_simple_clause_incompatible_with_ordered) 4537 << getOpenMPClauseName(OMPC_schedule) 4538 << getOpenMPSimpleClauseTypeName(OMPC_schedule, 4539 OMPC_SCHEDULE_MODIFIER_nonmonotonic) 4540 << SourceRange(OC->getBeginLoc(), OC->getEndLoc()); 4541 ErrorFound = true; 4542 } 4543 // OpenMP 5.0, 2.9.2 Worksharing-Loop Construct, Restrictions. 4544 // If an order(concurrent) clause is present, an ordered clause may not appear 4545 // on the same directive. 4546 if (checkOrderedOrderSpecified(*this, Clauses)) 4547 ErrorFound = true; 4548 if (!LCs.empty() && OC && OC->getNumForLoops()) { 4549 for (const OMPLinearClause *C : LCs) { 4550 Diag(C->getBeginLoc(), diag::err_omp_linear_ordered) 4551 << SourceRange(OC->getBeginLoc(), OC->getEndLoc()); 4552 } 4553 ErrorFound = true; 4554 } 4555 if (isOpenMPWorksharingDirective(DSAStack->getCurrentDirective()) && 4556 isOpenMPSimdDirective(DSAStack->getCurrentDirective()) && OC && 4557 OC->getNumForLoops()) { 4558 Diag(OC->getBeginLoc(), diag::err_omp_ordered_simd) 4559 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 4560 ErrorFound = true; 4561 } 4562 if (ErrorFound) { 4563 return StmtError(); 4564 } 4565 StmtResult SR = S; 4566 unsigned CompletedRegions = 0; 4567 for (OpenMPDirectiveKind ThisCaptureRegion : llvm::reverse(CaptureRegions)) { 4568 // Mark all variables in private list clauses as used in inner region. 4569 // Required for proper codegen of combined directives. 4570 // TODO: add processing for other clauses. 4571 if (ThisCaptureRegion != OMPD_unknown) { 4572 for (const clang::OMPClauseWithPreInit *C : PICs) { 4573 OpenMPDirectiveKind CaptureRegion = C->getCaptureRegion(); 4574 // Find the particular capture region for the clause if the 4575 // directive is a combined one with multiple capture regions. 4576 // If the directive is not a combined one, the capture region 4577 // associated with the clause is OMPD_unknown and is generated 4578 // only once. 4579 if (CaptureRegion == ThisCaptureRegion || 4580 CaptureRegion == OMPD_unknown) { 4581 if (auto *DS = cast_or_null<DeclStmt>(C->getPreInitStmt())) { 4582 for (Decl *D : DS->decls()) 4583 MarkVariableReferenced(D->getLocation(), cast<VarDecl>(D)); 4584 } 4585 } 4586 } 4587 } 4588 if (ThisCaptureRegion == OMPD_target) { 4589 // Capture allocator traits in the target region. They are used implicitly 4590 // and, thus, are not captured by default. 4591 for (OMPClause *C : Clauses) { 4592 if (const auto *UAC = dyn_cast<OMPUsesAllocatorsClause>(C)) { 4593 for (unsigned I = 0, End = UAC->getNumberOfAllocators(); I < End; 4594 ++I) { 4595 OMPUsesAllocatorsClause::Data D = UAC->getAllocatorData(I); 4596 if (Expr *E = D.AllocatorTraits) 4597 MarkDeclarationsReferencedInExpr(E); 4598 } 4599 continue; 4600 } 4601 } 4602 } 4603 if (ThisCaptureRegion == OMPD_parallel) { 4604 // Capture temp arrays for inscan reductions. 4605 for (OMPClause *C : Clauses) { 4606 if (auto *RC = dyn_cast<OMPReductionClause>(C)) { 4607 if (RC->getModifier() != OMPC_REDUCTION_inscan) 4608 continue; 4609 for (Expr *E : RC->copy_array_temps()) 4610 MarkDeclarationsReferencedInExpr(E); 4611 } 4612 } 4613 } 4614 if (++CompletedRegions == CaptureRegions.size()) 4615 DSAStack->setBodyComplete(); 4616 SR = ActOnCapturedRegionEnd(SR.get()); 4617 } 4618 return SR; 4619 } 4620 4621 static bool checkCancelRegion(Sema &SemaRef, OpenMPDirectiveKind CurrentRegion, 4622 OpenMPDirectiveKind CancelRegion, 4623 SourceLocation StartLoc) { 4624 // CancelRegion is only needed for cancel and cancellation_point. 4625 if (CurrentRegion != OMPD_cancel && CurrentRegion != OMPD_cancellation_point) 4626 return false; 4627 4628 if (CancelRegion == OMPD_parallel || CancelRegion == OMPD_for || 4629 CancelRegion == OMPD_sections || CancelRegion == OMPD_taskgroup) 4630 return false; 4631 4632 SemaRef.Diag(StartLoc, diag::err_omp_wrong_cancel_region) 4633 << getOpenMPDirectiveName(CancelRegion); 4634 return true; 4635 } 4636 4637 static bool checkNestingOfRegions(Sema &SemaRef, const DSAStackTy *Stack, 4638 OpenMPDirectiveKind CurrentRegion, 4639 const DeclarationNameInfo &CurrentName, 4640 OpenMPDirectiveKind CancelRegion, 4641 SourceLocation StartLoc) { 4642 if (Stack->getCurScope()) { 4643 OpenMPDirectiveKind ParentRegion = Stack->getParentDirective(); 4644 OpenMPDirectiveKind OffendingRegion = ParentRegion; 4645 bool NestingProhibited = false; 4646 bool CloseNesting = true; 4647 bool OrphanSeen = false; 4648 enum { 4649 NoRecommend, 4650 ShouldBeInParallelRegion, 4651 ShouldBeInOrderedRegion, 4652 ShouldBeInTargetRegion, 4653 ShouldBeInTeamsRegion, 4654 ShouldBeInLoopSimdRegion, 4655 } Recommend = NoRecommend; 4656 if (isOpenMPSimdDirective(ParentRegion) && 4657 ((SemaRef.LangOpts.OpenMP <= 45 && CurrentRegion != OMPD_ordered) || 4658 (SemaRef.LangOpts.OpenMP >= 50 && CurrentRegion != OMPD_ordered && 4659 CurrentRegion != OMPD_simd && CurrentRegion != OMPD_atomic && 4660 CurrentRegion != OMPD_scan))) { 4661 // OpenMP [2.16, Nesting of Regions] 4662 // OpenMP constructs may not be nested inside a simd region. 4663 // OpenMP [2.8.1,simd Construct, Restrictions] 4664 // An ordered construct with the simd clause is the only OpenMP 4665 // construct that can appear in the simd region. 4666 // Allowing a SIMD construct nested in another SIMD construct is an 4667 // extension. The OpenMP 4.5 spec does not allow it. Issue a warning 4668 // message. 4669 // OpenMP 5.0 [2.9.3.1, simd Construct, Restrictions] 4670 // The only OpenMP constructs that can be encountered during execution of 4671 // a simd region are the atomic construct, the loop construct, the simd 4672 // construct and the ordered construct with the simd clause. 4673 SemaRef.Diag(StartLoc, (CurrentRegion != OMPD_simd) 4674 ? diag::err_omp_prohibited_region_simd 4675 : diag::warn_omp_nesting_simd) 4676 << (SemaRef.LangOpts.OpenMP >= 50 ? 1 : 0); 4677 return CurrentRegion != OMPD_simd; 4678 } 4679 if (ParentRegion == OMPD_atomic) { 4680 // OpenMP [2.16, Nesting of Regions] 4681 // OpenMP constructs may not be nested inside an atomic region. 4682 SemaRef.Diag(StartLoc, diag::err_omp_prohibited_region_atomic); 4683 return true; 4684 } 4685 if (CurrentRegion == OMPD_section) { 4686 // OpenMP [2.7.2, sections Construct, Restrictions] 4687 // Orphaned section directives are prohibited. That is, the section 4688 // directives must appear within the sections construct and must not be 4689 // encountered elsewhere in the sections region. 4690 if (ParentRegion != OMPD_sections && 4691 ParentRegion != OMPD_parallel_sections) { 4692 SemaRef.Diag(StartLoc, diag::err_omp_orphaned_section_directive) 4693 << (ParentRegion != OMPD_unknown) 4694 << getOpenMPDirectiveName(ParentRegion); 4695 return true; 4696 } 4697 return false; 4698 } 4699 // Allow some constructs (except teams and cancellation constructs) to be 4700 // orphaned (they could be used in functions, called from OpenMP regions 4701 // with the required preconditions). 4702 if (ParentRegion == OMPD_unknown && 4703 !isOpenMPNestingTeamsDirective(CurrentRegion) && 4704 CurrentRegion != OMPD_cancellation_point && 4705 CurrentRegion != OMPD_cancel && CurrentRegion != OMPD_scan) 4706 return false; 4707 if (CurrentRegion == OMPD_cancellation_point || 4708 CurrentRegion == OMPD_cancel) { 4709 // OpenMP [2.16, Nesting of Regions] 4710 // A cancellation point construct for which construct-type-clause is 4711 // taskgroup must be nested inside a task construct. A cancellation 4712 // point construct for which construct-type-clause is not taskgroup must 4713 // be closely nested inside an OpenMP construct that matches the type 4714 // specified in construct-type-clause. 4715 // A cancel construct for which construct-type-clause is taskgroup must be 4716 // nested inside a task construct. A cancel construct for which 4717 // construct-type-clause is not taskgroup must be closely nested inside an 4718 // OpenMP construct that matches the type specified in 4719 // construct-type-clause. 4720 NestingProhibited = 4721 !((CancelRegion == OMPD_parallel && 4722 (ParentRegion == OMPD_parallel || 4723 ParentRegion == OMPD_target_parallel)) || 4724 (CancelRegion == OMPD_for && 4725 (ParentRegion == OMPD_for || ParentRegion == OMPD_parallel_for || 4726 ParentRegion == OMPD_target_parallel_for || 4727 ParentRegion == OMPD_distribute_parallel_for || 4728 ParentRegion == OMPD_teams_distribute_parallel_for || 4729 ParentRegion == OMPD_target_teams_distribute_parallel_for)) || 4730 (CancelRegion == OMPD_taskgroup && 4731 (ParentRegion == OMPD_task || 4732 (SemaRef.getLangOpts().OpenMP >= 50 && 4733 (ParentRegion == OMPD_taskloop || 4734 ParentRegion == OMPD_master_taskloop || 4735 ParentRegion == OMPD_parallel_master_taskloop)))) || 4736 (CancelRegion == OMPD_sections && 4737 (ParentRegion == OMPD_section || ParentRegion == OMPD_sections || 4738 ParentRegion == OMPD_parallel_sections))); 4739 OrphanSeen = ParentRegion == OMPD_unknown; 4740 } else if (CurrentRegion == OMPD_master || CurrentRegion == OMPD_masked) { 4741 // OpenMP 5.1 [2.22, Nesting of Regions] 4742 // A masked region may not be closely nested inside a worksharing, loop, 4743 // atomic, task, or taskloop region. 4744 NestingProhibited = isOpenMPWorksharingDirective(ParentRegion) || 4745 isOpenMPTaskingDirective(ParentRegion); 4746 } else if (CurrentRegion == OMPD_critical && CurrentName.getName()) { 4747 // OpenMP [2.16, Nesting of Regions] 4748 // A critical region may not be nested (closely or otherwise) inside a 4749 // critical region with the same name. Note that this restriction is not 4750 // sufficient to prevent deadlock. 4751 SourceLocation PreviousCriticalLoc; 4752 bool DeadLock = Stack->hasDirective( 4753 [CurrentName, &PreviousCriticalLoc](OpenMPDirectiveKind K, 4754 const DeclarationNameInfo &DNI, 4755 SourceLocation Loc) { 4756 if (K == OMPD_critical && DNI.getName() == CurrentName.getName()) { 4757 PreviousCriticalLoc = Loc; 4758 return true; 4759 } 4760 return false; 4761 }, 4762 false /* skip top directive */); 4763 if (DeadLock) { 4764 SemaRef.Diag(StartLoc, 4765 diag::err_omp_prohibited_region_critical_same_name) 4766 << CurrentName.getName(); 4767 if (PreviousCriticalLoc.isValid()) 4768 SemaRef.Diag(PreviousCriticalLoc, 4769 diag::note_omp_previous_critical_region); 4770 return true; 4771 } 4772 } else if (CurrentRegion == OMPD_barrier) { 4773 // OpenMP 5.1 [2.22, Nesting of Regions] 4774 // A barrier region may not be closely nested inside a worksharing, loop, 4775 // task, taskloop, critical, ordered, atomic, or masked region. 4776 NestingProhibited = 4777 isOpenMPWorksharingDirective(ParentRegion) || 4778 isOpenMPTaskingDirective(ParentRegion) || 4779 ParentRegion == OMPD_master || ParentRegion == OMPD_masked || 4780 ParentRegion == OMPD_parallel_master || 4781 ParentRegion == OMPD_critical || ParentRegion == OMPD_ordered; 4782 } else if (isOpenMPWorksharingDirective(CurrentRegion) && 4783 !isOpenMPParallelDirective(CurrentRegion) && 4784 !isOpenMPTeamsDirective(CurrentRegion)) { 4785 // OpenMP 5.1 [2.22, Nesting of Regions] 4786 // A loop region that binds to a parallel region or a worksharing region 4787 // may not be closely nested inside a worksharing, loop, task, taskloop, 4788 // critical, ordered, atomic, or masked region. 4789 NestingProhibited = 4790 isOpenMPWorksharingDirective(ParentRegion) || 4791 isOpenMPTaskingDirective(ParentRegion) || 4792 ParentRegion == OMPD_master || ParentRegion == OMPD_masked || 4793 ParentRegion == OMPD_parallel_master || 4794 ParentRegion == OMPD_critical || ParentRegion == OMPD_ordered; 4795 Recommend = ShouldBeInParallelRegion; 4796 } else if (CurrentRegion == OMPD_ordered) { 4797 // OpenMP [2.16, Nesting of Regions] 4798 // An ordered region may not be closely nested inside a critical, 4799 // atomic, or explicit task region. 4800 // An ordered region must be closely nested inside a loop region (or 4801 // parallel loop region) with an ordered clause. 4802 // OpenMP [2.8.1,simd Construct, Restrictions] 4803 // An ordered construct with the simd clause is the only OpenMP construct 4804 // that can appear in the simd region. 4805 NestingProhibited = ParentRegion == OMPD_critical || 4806 isOpenMPTaskingDirective(ParentRegion) || 4807 !(isOpenMPSimdDirective(ParentRegion) || 4808 Stack->isParentOrderedRegion()); 4809 Recommend = ShouldBeInOrderedRegion; 4810 } else if (isOpenMPNestingTeamsDirective(CurrentRegion)) { 4811 // OpenMP [2.16, Nesting of Regions] 4812 // If specified, a teams construct must be contained within a target 4813 // construct. 4814 NestingProhibited = 4815 (SemaRef.LangOpts.OpenMP <= 45 && ParentRegion != OMPD_target) || 4816 (SemaRef.LangOpts.OpenMP >= 50 && ParentRegion != OMPD_unknown && 4817 ParentRegion != OMPD_target); 4818 OrphanSeen = ParentRegion == OMPD_unknown; 4819 Recommend = ShouldBeInTargetRegion; 4820 } else if (CurrentRegion == OMPD_scan) { 4821 // OpenMP [2.16, Nesting of Regions] 4822 // If specified, a teams construct must be contained within a target 4823 // construct. 4824 NestingProhibited = 4825 SemaRef.LangOpts.OpenMP < 50 || 4826 (ParentRegion != OMPD_simd && ParentRegion != OMPD_for && 4827 ParentRegion != OMPD_for_simd && ParentRegion != OMPD_parallel_for && 4828 ParentRegion != OMPD_parallel_for_simd); 4829 OrphanSeen = ParentRegion == OMPD_unknown; 4830 Recommend = ShouldBeInLoopSimdRegion; 4831 } 4832 if (!NestingProhibited && 4833 !isOpenMPTargetExecutionDirective(CurrentRegion) && 4834 !isOpenMPTargetDataManagementDirective(CurrentRegion) && 4835 (ParentRegion == OMPD_teams || ParentRegion == OMPD_target_teams)) { 4836 // OpenMP [2.16, Nesting of Regions] 4837 // distribute, parallel, parallel sections, parallel workshare, and the 4838 // parallel loop and parallel loop SIMD constructs are the only OpenMP 4839 // constructs that can be closely nested in the teams region. 4840 NestingProhibited = !isOpenMPParallelDirective(CurrentRegion) && 4841 !isOpenMPDistributeDirective(CurrentRegion); 4842 Recommend = ShouldBeInParallelRegion; 4843 } 4844 if (!NestingProhibited && 4845 isOpenMPNestingDistributeDirective(CurrentRegion)) { 4846 // OpenMP 4.5 [2.17 Nesting of Regions] 4847 // The region associated with the distribute construct must be strictly 4848 // nested inside a teams region 4849 NestingProhibited = 4850 (ParentRegion != OMPD_teams && ParentRegion != OMPD_target_teams); 4851 Recommend = ShouldBeInTeamsRegion; 4852 } 4853 if (!NestingProhibited && 4854 (isOpenMPTargetExecutionDirective(CurrentRegion) || 4855 isOpenMPTargetDataManagementDirective(CurrentRegion))) { 4856 // OpenMP 4.5 [2.17 Nesting of Regions] 4857 // If a target, target update, target data, target enter data, or 4858 // target exit data construct is encountered during execution of a 4859 // target region, the behavior is unspecified. 4860 NestingProhibited = Stack->hasDirective( 4861 [&OffendingRegion](OpenMPDirectiveKind K, const DeclarationNameInfo &, 4862 SourceLocation) { 4863 if (isOpenMPTargetExecutionDirective(K)) { 4864 OffendingRegion = K; 4865 return true; 4866 } 4867 return false; 4868 }, 4869 false /* don't skip top directive */); 4870 CloseNesting = false; 4871 } 4872 if (NestingProhibited) { 4873 if (OrphanSeen) { 4874 SemaRef.Diag(StartLoc, diag::err_omp_orphaned_device_directive) 4875 << getOpenMPDirectiveName(CurrentRegion) << Recommend; 4876 } else { 4877 SemaRef.Diag(StartLoc, diag::err_omp_prohibited_region) 4878 << CloseNesting << getOpenMPDirectiveName(OffendingRegion) 4879 << Recommend << getOpenMPDirectiveName(CurrentRegion); 4880 } 4881 return true; 4882 } 4883 } 4884 return false; 4885 } 4886 4887 struct Kind2Unsigned { 4888 using argument_type = OpenMPDirectiveKind; 4889 unsigned operator()(argument_type DK) { return unsigned(DK); } 4890 }; 4891 static bool checkIfClauses(Sema &S, OpenMPDirectiveKind Kind, 4892 ArrayRef<OMPClause *> Clauses, 4893 ArrayRef<OpenMPDirectiveKind> AllowedNameModifiers) { 4894 bool ErrorFound = false; 4895 unsigned NamedModifiersNumber = 0; 4896 llvm::IndexedMap<const OMPIfClause *, Kind2Unsigned> FoundNameModifiers; 4897 FoundNameModifiers.resize(llvm::omp::Directive_enumSize + 1); 4898 SmallVector<SourceLocation, 4> NameModifierLoc; 4899 for (const OMPClause *C : Clauses) { 4900 if (const auto *IC = dyn_cast_or_null<OMPIfClause>(C)) { 4901 // At most one if clause without a directive-name-modifier can appear on 4902 // the directive. 4903 OpenMPDirectiveKind CurNM = IC->getNameModifier(); 4904 if (FoundNameModifiers[CurNM]) { 4905 S.Diag(C->getBeginLoc(), diag::err_omp_more_one_clause) 4906 << getOpenMPDirectiveName(Kind) << getOpenMPClauseName(OMPC_if) 4907 << (CurNM != OMPD_unknown) << getOpenMPDirectiveName(CurNM); 4908 ErrorFound = true; 4909 } else if (CurNM != OMPD_unknown) { 4910 NameModifierLoc.push_back(IC->getNameModifierLoc()); 4911 ++NamedModifiersNumber; 4912 } 4913 FoundNameModifiers[CurNM] = IC; 4914 if (CurNM == OMPD_unknown) 4915 continue; 4916 // Check if the specified name modifier is allowed for the current 4917 // directive. 4918 // At most one if clause with the particular directive-name-modifier can 4919 // appear on the directive. 4920 bool MatchFound = false; 4921 for (auto NM : AllowedNameModifiers) { 4922 if (CurNM == NM) { 4923 MatchFound = true; 4924 break; 4925 } 4926 } 4927 if (!MatchFound) { 4928 S.Diag(IC->getNameModifierLoc(), 4929 diag::err_omp_wrong_if_directive_name_modifier) 4930 << getOpenMPDirectiveName(CurNM) << getOpenMPDirectiveName(Kind); 4931 ErrorFound = true; 4932 } 4933 } 4934 } 4935 // If any if clause on the directive includes a directive-name-modifier then 4936 // all if clauses on the directive must include a directive-name-modifier. 4937 if (FoundNameModifiers[OMPD_unknown] && NamedModifiersNumber > 0) { 4938 if (NamedModifiersNumber == AllowedNameModifiers.size()) { 4939 S.Diag(FoundNameModifiers[OMPD_unknown]->getBeginLoc(), 4940 diag::err_omp_no_more_if_clause); 4941 } else { 4942 std::string Values; 4943 std::string Sep(", "); 4944 unsigned AllowedCnt = 0; 4945 unsigned TotalAllowedNum = 4946 AllowedNameModifiers.size() - NamedModifiersNumber; 4947 for (unsigned Cnt = 0, End = AllowedNameModifiers.size(); Cnt < End; 4948 ++Cnt) { 4949 OpenMPDirectiveKind NM = AllowedNameModifiers[Cnt]; 4950 if (!FoundNameModifiers[NM]) { 4951 Values += "'"; 4952 Values += getOpenMPDirectiveName(NM); 4953 Values += "'"; 4954 if (AllowedCnt + 2 == TotalAllowedNum) 4955 Values += " or "; 4956 else if (AllowedCnt + 1 != TotalAllowedNum) 4957 Values += Sep; 4958 ++AllowedCnt; 4959 } 4960 } 4961 S.Diag(FoundNameModifiers[OMPD_unknown]->getCondition()->getBeginLoc(), 4962 diag::err_omp_unnamed_if_clause) 4963 << (TotalAllowedNum > 1) << Values; 4964 } 4965 for (SourceLocation Loc : NameModifierLoc) { 4966 S.Diag(Loc, diag::note_omp_previous_named_if_clause); 4967 } 4968 ErrorFound = true; 4969 } 4970 return ErrorFound; 4971 } 4972 4973 static std::pair<ValueDecl *, bool> getPrivateItem(Sema &S, Expr *&RefExpr, 4974 SourceLocation &ELoc, 4975 SourceRange &ERange, 4976 bool AllowArraySection) { 4977 if (RefExpr->isTypeDependent() || RefExpr->isValueDependent() || 4978 RefExpr->containsUnexpandedParameterPack()) 4979 return std::make_pair(nullptr, true); 4980 4981 // OpenMP [3.1, C/C++] 4982 // A list item is a variable name. 4983 // OpenMP [2.9.3.3, Restrictions, p.1] 4984 // A variable that is part of another variable (as an array or 4985 // structure element) cannot appear in a private clause. 4986 RefExpr = RefExpr->IgnoreParens(); 4987 enum { 4988 NoArrayExpr = -1, 4989 ArraySubscript = 0, 4990 OMPArraySection = 1 4991 } IsArrayExpr = NoArrayExpr; 4992 if (AllowArraySection) { 4993 if (auto *ASE = dyn_cast_or_null<ArraySubscriptExpr>(RefExpr)) { 4994 Expr *Base = ASE->getBase()->IgnoreParenImpCasts(); 4995 while (auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base)) 4996 Base = TempASE->getBase()->IgnoreParenImpCasts(); 4997 RefExpr = Base; 4998 IsArrayExpr = ArraySubscript; 4999 } else if (auto *OASE = dyn_cast_or_null<OMPArraySectionExpr>(RefExpr)) { 5000 Expr *Base = OASE->getBase()->IgnoreParenImpCasts(); 5001 while (auto *TempOASE = dyn_cast<OMPArraySectionExpr>(Base)) 5002 Base = TempOASE->getBase()->IgnoreParenImpCasts(); 5003 while (auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base)) 5004 Base = TempASE->getBase()->IgnoreParenImpCasts(); 5005 RefExpr = Base; 5006 IsArrayExpr = OMPArraySection; 5007 } 5008 } 5009 ELoc = RefExpr->getExprLoc(); 5010 ERange = RefExpr->getSourceRange(); 5011 RefExpr = RefExpr->IgnoreParenImpCasts(); 5012 auto *DE = dyn_cast_or_null<DeclRefExpr>(RefExpr); 5013 auto *ME = dyn_cast_or_null<MemberExpr>(RefExpr); 5014 if ((!DE || !isa<VarDecl>(DE->getDecl())) && 5015 (S.getCurrentThisType().isNull() || !ME || 5016 !isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts()) || 5017 !isa<FieldDecl>(ME->getMemberDecl()))) { 5018 if (IsArrayExpr != NoArrayExpr) { 5019 S.Diag(ELoc, diag::err_omp_expected_base_var_name) << IsArrayExpr 5020 << ERange; 5021 } else { 5022 S.Diag(ELoc, 5023 AllowArraySection 5024 ? diag::err_omp_expected_var_name_member_expr_or_array_item 5025 : diag::err_omp_expected_var_name_member_expr) 5026 << (S.getCurrentThisType().isNull() ? 0 : 1) << ERange; 5027 } 5028 return std::make_pair(nullptr, false); 5029 } 5030 return std::make_pair( 5031 getCanonicalDecl(DE ? DE->getDecl() : ME->getMemberDecl()), false); 5032 } 5033 5034 namespace { 5035 /// Checks if the allocator is used in uses_allocators clause to be allowed in 5036 /// target regions. 5037 class AllocatorChecker final : public ConstStmtVisitor<AllocatorChecker, bool> { 5038 DSAStackTy *S = nullptr; 5039 5040 public: 5041 bool VisitDeclRefExpr(const DeclRefExpr *E) { 5042 return S->isUsesAllocatorsDecl(E->getDecl()) 5043 .getValueOr( 5044 DSAStackTy::UsesAllocatorsDeclKind::AllocatorTrait) == 5045 DSAStackTy::UsesAllocatorsDeclKind::AllocatorTrait; 5046 } 5047 bool VisitStmt(const Stmt *S) { 5048 for (const Stmt *Child : S->children()) { 5049 if (Child && Visit(Child)) 5050 return true; 5051 } 5052 return false; 5053 } 5054 explicit AllocatorChecker(DSAStackTy *S) : S(S) {} 5055 }; 5056 } // namespace 5057 5058 static void checkAllocateClauses(Sema &S, DSAStackTy *Stack, 5059 ArrayRef<OMPClause *> Clauses) { 5060 assert(!S.CurContext->isDependentContext() && 5061 "Expected non-dependent context."); 5062 auto AllocateRange = 5063 llvm::make_filter_range(Clauses, OMPAllocateClause::classof); 5064 llvm::DenseMap<CanonicalDeclPtr<Decl>, CanonicalDeclPtr<VarDecl>> 5065 DeclToCopy; 5066 auto PrivateRange = llvm::make_filter_range(Clauses, [](const OMPClause *C) { 5067 return isOpenMPPrivate(C->getClauseKind()); 5068 }); 5069 for (OMPClause *Cl : PrivateRange) { 5070 MutableArrayRef<Expr *>::iterator I, It, Et; 5071 if (Cl->getClauseKind() == OMPC_private) { 5072 auto *PC = cast<OMPPrivateClause>(Cl); 5073 I = PC->private_copies().begin(); 5074 It = PC->varlist_begin(); 5075 Et = PC->varlist_end(); 5076 } else if (Cl->getClauseKind() == OMPC_firstprivate) { 5077 auto *PC = cast<OMPFirstprivateClause>(Cl); 5078 I = PC->private_copies().begin(); 5079 It = PC->varlist_begin(); 5080 Et = PC->varlist_end(); 5081 } else if (Cl->getClauseKind() == OMPC_lastprivate) { 5082 auto *PC = cast<OMPLastprivateClause>(Cl); 5083 I = PC->private_copies().begin(); 5084 It = PC->varlist_begin(); 5085 Et = PC->varlist_end(); 5086 } else if (Cl->getClauseKind() == OMPC_linear) { 5087 auto *PC = cast<OMPLinearClause>(Cl); 5088 I = PC->privates().begin(); 5089 It = PC->varlist_begin(); 5090 Et = PC->varlist_end(); 5091 } else if (Cl->getClauseKind() == OMPC_reduction) { 5092 auto *PC = cast<OMPReductionClause>(Cl); 5093 I = PC->privates().begin(); 5094 It = PC->varlist_begin(); 5095 Et = PC->varlist_end(); 5096 } else if (Cl->getClauseKind() == OMPC_task_reduction) { 5097 auto *PC = cast<OMPTaskReductionClause>(Cl); 5098 I = PC->privates().begin(); 5099 It = PC->varlist_begin(); 5100 Et = PC->varlist_end(); 5101 } else if (Cl->getClauseKind() == OMPC_in_reduction) { 5102 auto *PC = cast<OMPInReductionClause>(Cl); 5103 I = PC->privates().begin(); 5104 It = PC->varlist_begin(); 5105 Et = PC->varlist_end(); 5106 } else { 5107 llvm_unreachable("Expected private clause."); 5108 } 5109 for (Expr *E : llvm::make_range(It, Et)) { 5110 if (!*I) { 5111 ++I; 5112 continue; 5113 } 5114 SourceLocation ELoc; 5115 SourceRange ERange; 5116 Expr *SimpleRefExpr = E; 5117 auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange, 5118 /*AllowArraySection=*/true); 5119 DeclToCopy.try_emplace(Res.first, 5120 cast<VarDecl>(cast<DeclRefExpr>(*I)->getDecl())); 5121 ++I; 5122 } 5123 } 5124 for (OMPClause *C : AllocateRange) { 5125 auto *AC = cast<OMPAllocateClause>(C); 5126 if (S.getLangOpts().OpenMP >= 50 && 5127 !Stack->hasRequiresDeclWithClause<OMPDynamicAllocatorsClause>() && 5128 isOpenMPTargetExecutionDirective(Stack->getCurrentDirective()) && 5129 AC->getAllocator()) { 5130 Expr *Allocator = AC->getAllocator(); 5131 // OpenMP, 2.12.5 target Construct 5132 // Memory allocators that do not appear in a uses_allocators clause cannot 5133 // appear as an allocator in an allocate clause or be used in the target 5134 // region unless a requires directive with the dynamic_allocators clause 5135 // is present in the same compilation unit. 5136 AllocatorChecker Checker(Stack); 5137 if (Checker.Visit(Allocator)) 5138 S.Diag(Allocator->getExprLoc(), 5139 diag::err_omp_allocator_not_in_uses_allocators) 5140 << Allocator->getSourceRange(); 5141 } 5142 OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind = 5143 getAllocatorKind(S, Stack, AC->getAllocator()); 5144 // OpenMP, 2.11.4 allocate Clause, Restrictions. 5145 // For task, taskloop or target directives, allocation requests to memory 5146 // allocators with the trait access set to thread result in unspecified 5147 // behavior. 5148 if (AllocatorKind == OMPAllocateDeclAttr::OMPThreadMemAlloc && 5149 (isOpenMPTaskingDirective(Stack->getCurrentDirective()) || 5150 isOpenMPTargetExecutionDirective(Stack->getCurrentDirective()))) { 5151 S.Diag(AC->getAllocator()->getExprLoc(), 5152 diag::warn_omp_allocate_thread_on_task_target_directive) 5153 << getOpenMPDirectiveName(Stack->getCurrentDirective()); 5154 } 5155 for (Expr *E : AC->varlists()) { 5156 SourceLocation ELoc; 5157 SourceRange ERange; 5158 Expr *SimpleRefExpr = E; 5159 auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange); 5160 ValueDecl *VD = Res.first; 5161 DSAStackTy::DSAVarData Data = Stack->getTopDSA(VD, /*FromParent=*/false); 5162 if (!isOpenMPPrivate(Data.CKind)) { 5163 S.Diag(E->getExprLoc(), 5164 diag::err_omp_expected_private_copy_for_allocate); 5165 continue; 5166 } 5167 VarDecl *PrivateVD = DeclToCopy[VD]; 5168 if (checkPreviousOMPAllocateAttribute(S, Stack, E, PrivateVD, 5169 AllocatorKind, AC->getAllocator())) 5170 continue; 5171 applyOMPAllocateAttribute(S, PrivateVD, AllocatorKind, AC->getAllocator(), 5172 E->getSourceRange()); 5173 } 5174 } 5175 } 5176 5177 namespace { 5178 /// Rewrite statements and expressions for Sema \p Actions CurContext. 5179 /// 5180 /// Used to wrap already parsed statements/expressions into a new CapturedStmt 5181 /// context. DeclRefExpr used inside the new context are changed to refer to the 5182 /// captured variable instead. 5183 class CaptureVars : public TreeTransform<CaptureVars> { 5184 using BaseTransform = TreeTransform<CaptureVars>; 5185 5186 public: 5187 CaptureVars(Sema &Actions) : BaseTransform(Actions) {} 5188 5189 bool AlwaysRebuild() { return true; } 5190 }; 5191 } // namespace 5192 5193 static VarDecl *precomputeExpr(Sema &Actions, 5194 SmallVectorImpl<Stmt *> &BodyStmts, Expr *E, 5195 StringRef Name) { 5196 Expr *NewE = AssertSuccess(CaptureVars(Actions).TransformExpr(E)); 5197 VarDecl *NewVar = buildVarDecl(Actions, {}, NewE->getType(), Name, nullptr, 5198 dyn_cast<DeclRefExpr>(E->IgnoreImplicit())); 5199 auto *NewDeclStmt = cast<DeclStmt>(AssertSuccess( 5200 Actions.ActOnDeclStmt(Actions.ConvertDeclToDeclGroup(NewVar), {}, {}))); 5201 Actions.AddInitializerToDecl(NewDeclStmt->getSingleDecl(), NewE, false); 5202 BodyStmts.push_back(NewDeclStmt); 5203 return NewVar; 5204 } 5205 5206 /// Create a closure that computes the number of iterations of a loop. 5207 /// 5208 /// \param Actions The Sema object. 5209 /// \param LogicalTy Type for the logical iteration number. 5210 /// \param Rel Comparison operator of the loop condition. 5211 /// \param StartExpr Value of the loop counter at the first iteration. 5212 /// \param StopExpr Expression the loop counter is compared against in the loop 5213 /// condition. \param StepExpr Amount of increment after each iteration. 5214 /// 5215 /// \return Closure (CapturedStmt) of the distance calculation. 5216 static CapturedStmt *buildDistanceFunc(Sema &Actions, QualType LogicalTy, 5217 BinaryOperator::Opcode Rel, 5218 Expr *StartExpr, Expr *StopExpr, 5219 Expr *StepExpr) { 5220 ASTContext &Ctx = Actions.getASTContext(); 5221 TypeSourceInfo *LogicalTSI = Ctx.getTrivialTypeSourceInfo(LogicalTy); 5222 5223 // Captured regions currently don't support return values, we use an 5224 // out-parameter instead. All inputs are implicit captures. 5225 // TODO: Instead of capturing each DeclRefExpr occurring in 5226 // StartExpr/StopExpr/Step, these could also be passed as a value capture. 5227 QualType ResultTy = Ctx.getLValueReferenceType(LogicalTy); 5228 Sema::CapturedParamNameType Params[] = {{"Distance", ResultTy}, 5229 {StringRef(), QualType()}}; 5230 Actions.ActOnCapturedRegionStart({}, nullptr, CR_Default, Params); 5231 5232 Stmt *Body; 5233 { 5234 Sema::CompoundScopeRAII CompoundScope(Actions); 5235 CapturedDecl *CS = cast<CapturedDecl>(Actions.CurContext); 5236 5237 // Get the LValue expression for the result. 5238 ImplicitParamDecl *DistParam = CS->getParam(0); 5239 DeclRefExpr *DistRef = Actions.BuildDeclRefExpr( 5240 DistParam, LogicalTy, VK_LValue, {}, nullptr, nullptr, {}, nullptr); 5241 5242 SmallVector<Stmt *, 4> BodyStmts; 5243 5244 // Capture all referenced variable references. 5245 // TODO: Instead of computing NewStart/NewStop/NewStep inside the 5246 // CapturedStmt, we could compute them before and capture the result, to be 5247 // used jointly with the LoopVar function. 5248 VarDecl *NewStart = precomputeExpr(Actions, BodyStmts, StartExpr, ".start"); 5249 VarDecl *NewStop = precomputeExpr(Actions, BodyStmts, StopExpr, ".stop"); 5250 VarDecl *NewStep = precomputeExpr(Actions, BodyStmts, StepExpr, ".step"); 5251 auto BuildVarRef = [&](VarDecl *VD) { 5252 return buildDeclRefExpr(Actions, VD, VD->getType(), {}); 5253 }; 5254 5255 IntegerLiteral *Zero = IntegerLiteral::Create( 5256 Ctx, llvm::APInt(Ctx.getIntWidth(LogicalTy), 0), LogicalTy, {}); 5257 Expr *Dist; 5258 if (Rel == BO_NE) { 5259 // When using a != comparison, the increment can be +1 or -1. This can be 5260 // dynamic at runtime, so we need to check for the direction. 5261 Expr *IsNegStep = AssertSuccess( 5262 Actions.BuildBinOp(nullptr, {}, BO_LT, BuildVarRef(NewStep), Zero)); 5263 5264 // Positive increment. 5265 Expr *ForwardRange = AssertSuccess(Actions.BuildBinOp( 5266 nullptr, {}, BO_Sub, BuildVarRef(NewStop), BuildVarRef(NewStart))); 5267 ForwardRange = AssertSuccess( 5268 Actions.BuildCStyleCastExpr({}, LogicalTSI, {}, ForwardRange)); 5269 Expr *ForwardDist = AssertSuccess(Actions.BuildBinOp( 5270 nullptr, {}, BO_Div, ForwardRange, BuildVarRef(NewStep))); 5271 5272 // Negative increment. 5273 Expr *BackwardRange = AssertSuccess(Actions.BuildBinOp( 5274 nullptr, {}, BO_Sub, BuildVarRef(NewStart), BuildVarRef(NewStop))); 5275 BackwardRange = AssertSuccess( 5276 Actions.BuildCStyleCastExpr({}, LogicalTSI, {}, BackwardRange)); 5277 Expr *NegIncAmount = AssertSuccess( 5278 Actions.BuildUnaryOp(nullptr, {}, UO_Minus, BuildVarRef(NewStep))); 5279 Expr *BackwardDist = AssertSuccess( 5280 Actions.BuildBinOp(nullptr, {}, BO_Div, BackwardRange, NegIncAmount)); 5281 5282 // Use the appropriate case. 5283 Dist = AssertSuccess(Actions.ActOnConditionalOp( 5284 {}, {}, IsNegStep, BackwardDist, ForwardDist)); 5285 } else { 5286 assert((Rel == BO_LT || Rel == BO_LE || Rel == BO_GE || Rel == BO_GT) && 5287 "Expected one of these relational operators"); 5288 5289 // We can derive the direction from any other comparison operator. It is 5290 // non well-formed OpenMP if Step increments/decrements in the other 5291 // directions. Whether at least the first iteration passes the loop 5292 // condition. 5293 Expr *HasAnyIteration = AssertSuccess(Actions.BuildBinOp( 5294 nullptr, {}, Rel, BuildVarRef(NewStart), BuildVarRef(NewStop))); 5295 5296 // Compute the range between first and last counter value. 5297 Expr *Range; 5298 if (Rel == BO_GE || Rel == BO_GT) 5299 Range = AssertSuccess(Actions.BuildBinOp( 5300 nullptr, {}, BO_Sub, BuildVarRef(NewStart), BuildVarRef(NewStop))); 5301 else 5302 Range = AssertSuccess(Actions.BuildBinOp( 5303 nullptr, {}, BO_Sub, BuildVarRef(NewStop), BuildVarRef(NewStart))); 5304 5305 // Ensure unsigned range space. 5306 Range = 5307 AssertSuccess(Actions.BuildCStyleCastExpr({}, LogicalTSI, {}, Range)); 5308 5309 if (Rel == BO_LE || Rel == BO_GE) { 5310 // Add one to the range if the relational operator is inclusive. 5311 Range = 5312 AssertSuccess(Actions.BuildUnaryOp(nullptr, {}, UO_PreInc, Range)); 5313 } 5314 5315 // Divide by the absolute step amount. 5316 Expr *Divisor = BuildVarRef(NewStep); 5317 if (Rel == BO_GE || Rel == BO_GT) 5318 Divisor = 5319 AssertSuccess(Actions.BuildUnaryOp(nullptr, {}, UO_Minus, Divisor)); 5320 Dist = AssertSuccess( 5321 Actions.BuildBinOp(nullptr, {}, BO_Div, Range, Divisor)); 5322 5323 // If there is not at least one iteration, the range contains garbage. Fix 5324 // to zero in this case. 5325 Dist = AssertSuccess( 5326 Actions.ActOnConditionalOp({}, {}, HasAnyIteration, Dist, Zero)); 5327 } 5328 5329 // Assign the result to the out-parameter. 5330 Stmt *ResultAssign = AssertSuccess(Actions.BuildBinOp( 5331 Actions.getCurScope(), {}, BO_Assign, DistRef, Dist)); 5332 BodyStmts.push_back(ResultAssign); 5333 5334 Body = AssertSuccess(Actions.ActOnCompoundStmt({}, {}, BodyStmts, false)); 5335 } 5336 5337 return cast<CapturedStmt>( 5338 AssertSuccess(Actions.ActOnCapturedRegionEnd(Body))); 5339 } 5340 5341 /// Create a closure that computes the loop variable from the logical iteration 5342 /// number. 5343 /// 5344 /// \param Actions The Sema object. 5345 /// \param LoopVarTy Type for the loop variable used for result value. 5346 /// \param LogicalTy Type for the logical iteration number. 5347 /// \param StartExpr Value of the loop counter at the first iteration. 5348 /// \param Step Amount of increment after each iteration. 5349 /// \param Deref Whether the loop variable is a dereference of the loop 5350 /// counter variable. 5351 /// 5352 /// \return Closure (CapturedStmt) of the loop value calculation. 5353 static CapturedStmt *buildLoopVarFunc(Sema &Actions, QualType LoopVarTy, 5354 QualType LogicalTy, 5355 DeclRefExpr *StartExpr, Expr *Step, 5356 bool Deref) { 5357 ASTContext &Ctx = Actions.getASTContext(); 5358 5359 // Pass the result as an out-parameter. Passing as return value would require 5360 // the OpenMPIRBuilder to know additional C/C++ semantics, such as how to 5361 // invoke a copy constructor. 5362 QualType TargetParamTy = Ctx.getLValueReferenceType(LoopVarTy); 5363 Sema::CapturedParamNameType Params[] = {{"LoopVar", TargetParamTy}, 5364 {"Logical", LogicalTy}, 5365 {StringRef(), QualType()}}; 5366 Actions.ActOnCapturedRegionStart({}, nullptr, CR_Default, Params); 5367 5368 // Capture the initial iterator which represents the LoopVar value at the 5369 // zero's logical iteration. Since the original ForStmt/CXXForRangeStmt update 5370 // it in every iteration, capture it by value before it is modified. 5371 VarDecl *StartVar = cast<VarDecl>(StartExpr->getDecl()); 5372 bool Invalid = Actions.tryCaptureVariable(StartVar, {}, 5373 Sema::TryCapture_ExplicitByVal, {}); 5374 (void)Invalid; 5375 assert(!Invalid && "Expecting capture-by-value to work."); 5376 5377 Expr *Body; 5378 { 5379 Sema::CompoundScopeRAII CompoundScope(Actions); 5380 auto *CS = cast<CapturedDecl>(Actions.CurContext); 5381 5382 ImplicitParamDecl *TargetParam = CS->getParam(0); 5383 DeclRefExpr *TargetRef = Actions.BuildDeclRefExpr( 5384 TargetParam, LoopVarTy, VK_LValue, {}, nullptr, nullptr, {}, nullptr); 5385 ImplicitParamDecl *IndvarParam = CS->getParam(1); 5386 DeclRefExpr *LogicalRef = Actions.BuildDeclRefExpr( 5387 IndvarParam, LogicalTy, VK_LValue, {}, nullptr, nullptr, {}, nullptr); 5388 5389 // Capture the Start expression. 5390 CaptureVars Recap(Actions); 5391 Expr *NewStart = AssertSuccess(Recap.TransformExpr(StartExpr)); 5392 Expr *NewStep = AssertSuccess(Recap.TransformExpr(Step)); 5393 5394 Expr *Skip = AssertSuccess( 5395 Actions.BuildBinOp(nullptr, {}, BO_Mul, NewStep, LogicalRef)); 5396 // TODO: Explicitly cast to the iterator's difference_type instead of 5397 // relying on implicit conversion. 5398 Expr *Advanced = 5399 AssertSuccess(Actions.BuildBinOp(nullptr, {}, BO_Add, NewStart, Skip)); 5400 5401 if (Deref) { 5402 // For range-based for-loops convert the loop counter value to a concrete 5403 // loop variable value by dereferencing the iterator. 5404 Advanced = 5405 AssertSuccess(Actions.BuildUnaryOp(nullptr, {}, UO_Deref, Advanced)); 5406 } 5407 5408 // Assign the result to the output parameter. 5409 Body = AssertSuccess(Actions.BuildBinOp(Actions.getCurScope(), {}, 5410 BO_Assign, TargetRef, Advanced)); 5411 } 5412 return cast<CapturedStmt>( 5413 AssertSuccess(Actions.ActOnCapturedRegionEnd(Body))); 5414 } 5415 5416 StmtResult Sema::ActOnOpenMPCanonicalLoop(Stmt *AStmt) { 5417 ASTContext &Ctx = getASTContext(); 5418 5419 // Extract the common elements of ForStmt and CXXForRangeStmt: 5420 // Loop variable, repeat condition, increment 5421 Expr *Cond, *Inc; 5422 VarDecl *LIVDecl, *LUVDecl; 5423 if (auto *For = dyn_cast<ForStmt>(AStmt)) { 5424 Stmt *Init = For->getInit(); 5425 if (auto *LCVarDeclStmt = dyn_cast<DeclStmt>(Init)) { 5426 // For statement declares loop variable. 5427 LIVDecl = cast<VarDecl>(LCVarDeclStmt->getSingleDecl()); 5428 } else if (auto *LCAssign = dyn_cast<BinaryOperator>(Init)) { 5429 // For statement reuses variable. 5430 assert(LCAssign->getOpcode() == BO_Assign && 5431 "init part must be a loop variable assignment"); 5432 auto *CounterRef = cast<DeclRefExpr>(LCAssign->getLHS()); 5433 LIVDecl = cast<VarDecl>(CounterRef->getDecl()); 5434 } else 5435 llvm_unreachable("Cannot determine loop variable"); 5436 LUVDecl = LIVDecl; 5437 5438 Cond = For->getCond(); 5439 Inc = For->getInc(); 5440 } else if (auto *RangeFor = dyn_cast<CXXForRangeStmt>(AStmt)) { 5441 DeclStmt *BeginStmt = RangeFor->getBeginStmt(); 5442 LIVDecl = cast<VarDecl>(BeginStmt->getSingleDecl()); 5443 LUVDecl = RangeFor->getLoopVariable(); 5444 5445 Cond = RangeFor->getCond(); 5446 Inc = RangeFor->getInc(); 5447 } else 5448 llvm_unreachable("unhandled kind of loop"); 5449 5450 QualType CounterTy = LIVDecl->getType(); 5451 QualType LVTy = LUVDecl->getType(); 5452 5453 // Analyze the loop condition. 5454 Expr *LHS, *RHS; 5455 BinaryOperator::Opcode CondRel; 5456 Cond = Cond->IgnoreImplicit(); 5457 if (auto *CondBinExpr = dyn_cast<BinaryOperator>(Cond)) { 5458 LHS = CondBinExpr->getLHS(); 5459 RHS = CondBinExpr->getRHS(); 5460 CondRel = CondBinExpr->getOpcode(); 5461 } else if (auto *CondCXXOp = dyn_cast<CXXOperatorCallExpr>(Cond)) { 5462 assert(CondCXXOp->getNumArgs() == 2 && "Comparison should have 2 operands"); 5463 LHS = CondCXXOp->getArg(0); 5464 RHS = CondCXXOp->getArg(1); 5465 switch (CondCXXOp->getOperator()) { 5466 case OO_ExclaimEqual: 5467 CondRel = BO_NE; 5468 break; 5469 case OO_Less: 5470 CondRel = BO_LT; 5471 break; 5472 case OO_LessEqual: 5473 CondRel = BO_LE; 5474 break; 5475 case OO_Greater: 5476 CondRel = BO_GT; 5477 break; 5478 case OO_GreaterEqual: 5479 CondRel = BO_GE; 5480 break; 5481 default: 5482 llvm_unreachable("unexpected iterator operator"); 5483 } 5484 } else 5485 llvm_unreachable("unexpected loop condition"); 5486 5487 // Normalize such that the loop counter is on the LHS. 5488 if (!isa<DeclRefExpr>(LHS->IgnoreImplicit()) || 5489 cast<DeclRefExpr>(LHS->IgnoreImplicit())->getDecl() != LIVDecl) { 5490 std::swap(LHS, RHS); 5491 CondRel = BinaryOperator::reverseComparisonOp(CondRel); 5492 } 5493 auto *CounterRef = cast<DeclRefExpr>(LHS->IgnoreImplicit()); 5494 5495 // Decide the bit width for the logical iteration counter. By default use the 5496 // unsigned ptrdiff_t integer size (for iterators and pointers). 5497 // TODO: For iterators, use iterator::difference_type, 5498 // std::iterator_traits<>::difference_type or decltype(it - end). 5499 QualType LogicalTy = Ctx.getUnsignedPointerDiffType(); 5500 if (CounterTy->isIntegerType()) { 5501 unsigned BitWidth = Ctx.getIntWidth(CounterTy); 5502 LogicalTy = Ctx.getIntTypeForBitwidth(BitWidth, false); 5503 } 5504 5505 // Analyze the loop increment. 5506 Expr *Step; 5507 if (auto *IncUn = dyn_cast<UnaryOperator>(Inc)) { 5508 int Direction; 5509 switch (IncUn->getOpcode()) { 5510 case UO_PreInc: 5511 case UO_PostInc: 5512 Direction = 1; 5513 break; 5514 case UO_PreDec: 5515 case UO_PostDec: 5516 Direction = -1; 5517 break; 5518 default: 5519 llvm_unreachable("unhandled unary increment operator"); 5520 } 5521 Step = IntegerLiteral::Create( 5522 Ctx, llvm::APInt(Ctx.getIntWidth(LogicalTy), Direction), LogicalTy, {}); 5523 } else if (auto *IncBin = dyn_cast<BinaryOperator>(Inc)) { 5524 if (IncBin->getOpcode() == BO_AddAssign) { 5525 Step = IncBin->getRHS(); 5526 } else if (IncBin->getOpcode() == BO_SubAssign) { 5527 Step = 5528 AssertSuccess(BuildUnaryOp(nullptr, {}, UO_Minus, IncBin->getRHS())); 5529 } else 5530 llvm_unreachable("unhandled binary increment operator"); 5531 } else if (auto *CondCXXOp = dyn_cast<CXXOperatorCallExpr>(Inc)) { 5532 switch (CondCXXOp->getOperator()) { 5533 case OO_PlusPlus: 5534 Step = IntegerLiteral::Create( 5535 Ctx, llvm::APInt(Ctx.getIntWidth(LogicalTy), 1), LogicalTy, {}); 5536 break; 5537 case OO_MinusMinus: 5538 Step = IntegerLiteral::Create( 5539 Ctx, llvm::APInt(Ctx.getIntWidth(LogicalTy), -1), LogicalTy, {}); 5540 break; 5541 case OO_PlusEqual: 5542 Step = CondCXXOp->getArg(1); 5543 break; 5544 case OO_MinusEqual: 5545 Step = AssertSuccess( 5546 BuildUnaryOp(nullptr, {}, UO_Minus, CondCXXOp->getArg(1))); 5547 break; 5548 default: 5549 llvm_unreachable("unhandled overloaded increment operator"); 5550 } 5551 } else 5552 llvm_unreachable("unknown increment expression"); 5553 5554 CapturedStmt *DistanceFunc = 5555 buildDistanceFunc(*this, LogicalTy, CondRel, LHS, RHS, Step); 5556 CapturedStmt *LoopVarFunc = buildLoopVarFunc( 5557 *this, LVTy, LogicalTy, CounterRef, Step, isa<CXXForRangeStmt>(AStmt)); 5558 DeclRefExpr *LVRef = BuildDeclRefExpr(LUVDecl, LUVDecl->getType(), VK_LValue, 5559 {}, nullptr, nullptr, {}, nullptr); 5560 return OMPCanonicalLoop::create(getASTContext(), AStmt, DistanceFunc, 5561 LoopVarFunc, LVRef); 5562 } 5563 5564 static ExprResult buildUserDefinedMapperRef(Sema &SemaRef, Scope *S, 5565 CXXScopeSpec &MapperIdScopeSpec, 5566 const DeclarationNameInfo &MapperId, 5567 QualType Type, 5568 Expr *UnresolvedMapper); 5569 5570 /// Perform DFS through the structure/class data members trying to find 5571 /// member(s) with user-defined 'default' mapper and generate implicit map 5572 /// clauses for such members with the found 'default' mapper. 5573 static void 5574 processImplicitMapsWithDefaultMappers(Sema &S, DSAStackTy *Stack, 5575 SmallVectorImpl<OMPClause *> &Clauses) { 5576 // Check for the deault mapper for data members. 5577 if (S.getLangOpts().OpenMP < 50) 5578 return; 5579 SmallVector<OMPClause *, 4> ImplicitMaps; 5580 DeclarationNameInfo DefaultMapperId; 5581 DefaultMapperId.setName(S.Context.DeclarationNames.getIdentifier( 5582 &S.Context.Idents.get("default"))); 5583 for (int Cnt = 0, EndCnt = Clauses.size(); Cnt < EndCnt; ++Cnt) { 5584 auto *C = dyn_cast<OMPMapClause>(Clauses[Cnt]); 5585 if (!C) 5586 continue; 5587 SmallVector<Expr *, 4> SubExprs; 5588 auto *MI = C->mapperlist_begin(); 5589 for (auto I = C->varlist_begin(), End = C->varlist_end(); I != End; 5590 ++I, ++MI) { 5591 // Expression is mapped using mapper - skip it. 5592 if (*MI) 5593 continue; 5594 Expr *E = *I; 5595 // Expression is dependent - skip it, build the mapper when it gets 5596 // instantiated. 5597 if (E->isTypeDependent() || E->isValueDependent() || 5598 E->containsUnexpandedParameterPack()) 5599 continue; 5600 // Array section - need to check for the mapping of the array section 5601 // element. 5602 QualType CanonType = E->getType().getCanonicalType(); 5603 if (CanonType->isSpecificBuiltinType(BuiltinType::OMPArraySection)) { 5604 const auto *OASE = cast<OMPArraySectionExpr>(E->IgnoreParenImpCasts()); 5605 QualType BaseType = 5606 OMPArraySectionExpr::getBaseOriginalType(OASE->getBase()); 5607 QualType ElemType; 5608 if (const auto *ATy = BaseType->getAsArrayTypeUnsafe()) 5609 ElemType = ATy->getElementType(); 5610 else 5611 ElemType = BaseType->getPointeeType(); 5612 CanonType = ElemType; 5613 } 5614 5615 // DFS over data members in structures/classes. 5616 SmallVector<std::pair<QualType, FieldDecl *>, 4> Types( 5617 1, {CanonType, nullptr}); 5618 llvm::DenseMap<const Type *, Expr *> Visited; 5619 SmallVector<std::pair<FieldDecl *, unsigned>, 4> ParentChain( 5620 1, {nullptr, 1}); 5621 while (!Types.empty()) { 5622 QualType BaseType; 5623 FieldDecl *CurFD; 5624 std::tie(BaseType, CurFD) = Types.pop_back_val(); 5625 while (ParentChain.back().second == 0) 5626 ParentChain.pop_back(); 5627 --ParentChain.back().second; 5628 if (BaseType.isNull()) 5629 continue; 5630 // Only structs/classes are allowed to have mappers. 5631 const RecordDecl *RD = BaseType.getCanonicalType()->getAsRecordDecl(); 5632 if (!RD) 5633 continue; 5634 auto It = Visited.find(BaseType.getTypePtr()); 5635 if (It == Visited.end()) { 5636 // Try to find the associated user-defined mapper. 5637 CXXScopeSpec MapperIdScopeSpec; 5638 ExprResult ER = buildUserDefinedMapperRef( 5639 S, Stack->getCurScope(), MapperIdScopeSpec, DefaultMapperId, 5640 BaseType, /*UnresolvedMapper=*/nullptr); 5641 if (ER.isInvalid()) 5642 continue; 5643 It = Visited.try_emplace(BaseType.getTypePtr(), ER.get()).first; 5644 } 5645 // Found default mapper. 5646 if (It->second) { 5647 auto *OE = new (S.Context) OpaqueValueExpr(E->getExprLoc(), CanonType, 5648 VK_LValue, OK_Ordinary, E); 5649 OE->setIsUnique(/*V=*/true); 5650 Expr *BaseExpr = OE; 5651 for (const auto &P : ParentChain) { 5652 if (P.first) { 5653 BaseExpr = S.BuildMemberExpr( 5654 BaseExpr, /*IsArrow=*/false, E->getExprLoc(), 5655 NestedNameSpecifierLoc(), SourceLocation(), P.first, 5656 DeclAccessPair::make(P.first, P.first->getAccess()), 5657 /*HadMultipleCandidates=*/false, DeclarationNameInfo(), 5658 P.first->getType(), VK_LValue, OK_Ordinary); 5659 BaseExpr = S.DefaultLvalueConversion(BaseExpr).get(); 5660 } 5661 } 5662 if (CurFD) 5663 BaseExpr = S.BuildMemberExpr( 5664 BaseExpr, /*IsArrow=*/false, E->getExprLoc(), 5665 NestedNameSpecifierLoc(), SourceLocation(), CurFD, 5666 DeclAccessPair::make(CurFD, CurFD->getAccess()), 5667 /*HadMultipleCandidates=*/false, DeclarationNameInfo(), 5668 CurFD->getType(), VK_LValue, OK_Ordinary); 5669 SubExprs.push_back(BaseExpr); 5670 continue; 5671 } 5672 // Check for the "default" mapper for data memebers. 5673 bool FirstIter = true; 5674 for (FieldDecl *FD : RD->fields()) { 5675 if (!FD) 5676 continue; 5677 QualType FieldTy = FD->getType(); 5678 if (FieldTy.isNull() || 5679 !(FieldTy->isStructureOrClassType() || FieldTy->isUnionType())) 5680 continue; 5681 if (FirstIter) { 5682 FirstIter = false; 5683 ParentChain.emplace_back(CurFD, 1); 5684 } else { 5685 ++ParentChain.back().second; 5686 } 5687 Types.emplace_back(FieldTy, FD); 5688 } 5689 } 5690 } 5691 if (SubExprs.empty()) 5692 continue; 5693 CXXScopeSpec MapperIdScopeSpec; 5694 DeclarationNameInfo MapperId; 5695 if (OMPClause *NewClause = S.ActOnOpenMPMapClause( 5696 C->getMapTypeModifiers(), C->getMapTypeModifiersLoc(), 5697 MapperIdScopeSpec, MapperId, C->getMapType(), 5698 /*IsMapTypeImplicit=*/true, SourceLocation(), SourceLocation(), 5699 SubExprs, OMPVarListLocTy())) 5700 Clauses.push_back(NewClause); 5701 } 5702 } 5703 5704 StmtResult Sema::ActOnOpenMPExecutableDirective( 5705 OpenMPDirectiveKind Kind, const DeclarationNameInfo &DirName, 5706 OpenMPDirectiveKind CancelRegion, ArrayRef<OMPClause *> Clauses, 5707 Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc) { 5708 StmtResult Res = StmtError(); 5709 // First check CancelRegion which is then used in checkNestingOfRegions. 5710 if (checkCancelRegion(*this, Kind, CancelRegion, StartLoc) || 5711 checkNestingOfRegions(*this, DSAStack, Kind, DirName, CancelRegion, 5712 StartLoc)) 5713 return StmtError(); 5714 5715 llvm::SmallVector<OMPClause *, 8> ClausesWithImplicit; 5716 VarsWithInheritedDSAType VarsWithInheritedDSA; 5717 bool ErrorFound = false; 5718 ClausesWithImplicit.append(Clauses.begin(), Clauses.end()); 5719 if (AStmt && !CurContext->isDependentContext() && Kind != OMPD_atomic && 5720 Kind != OMPD_critical && Kind != OMPD_section && Kind != OMPD_master && 5721 Kind != OMPD_masked && !isOpenMPLoopTransformationDirective(Kind)) { 5722 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 5723 5724 // Check default data sharing attributes for referenced variables. 5725 DSAAttrChecker DSAChecker(DSAStack, *this, cast<CapturedStmt>(AStmt)); 5726 int ThisCaptureLevel = getOpenMPCaptureLevels(Kind); 5727 Stmt *S = AStmt; 5728 while (--ThisCaptureLevel >= 0) 5729 S = cast<CapturedStmt>(S)->getCapturedStmt(); 5730 DSAChecker.Visit(S); 5731 if (!isOpenMPTargetDataManagementDirective(Kind) && 5732 !isOpenMPTaskingDirective(Kind)) { 5733 // Visit subcaptures to generate implicit clauses for captured vars. 5734 auto *CS = cast<CapturedStmt>(AStmt); 5735 SmallVector<OpenMPDirectiveKind, 4> CaptureRegions; 5736 getOpenMPCaptureRegions(CaptureRegions, Kind); 5737 // Ignore outer tasking regions for target directives. 5738 if (CaptureRegions.size() > 1 && CaptureRegions.front() == OMPD_task) 5739 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 5740 DSAChecker.visitSubCaptures(CS); 5741 } 5742 if (DSAChecker.isErrorFound()) 5743 return StmtError(); 5744 // Generate list of implicitly defined firstprivate variables. 5745 VarsWithInheritedDSA = DSAChecker.getVarsWithInheritedDSA(); 5746 5747 SmallVector<Expr *, 4> ImplicitFirstprivates( 5748 DSAChecker.getImplicitFirstprivate().begin(), 5749 DSAChecker.getImplicitFirstprivate().end()); 5750 const unsigned DefaultmapKindNum = OMPC_DEFAULTMAP_pointer + 1; 5751 SmallVector<Expr *, 4> ImplicitMaps[DefaultmapKindNum][OMPC_MAP_delete]; 5752 SmallVector<OpenMPMapModifierKind, NumberOfOMPMapClauseModifiers> 5753 ImplicitMapModifiers[DefaultmapKindNum]; 5754 SmallVector<SourceLocation, NumberOfOMPMapClauseModifiers> 5755 ImplicitMapModifiersLoc[DefaultmapKindNum]; 5756 // Get the original location of present modifier from Defaultmap clause. 5757 SourceLocation PresentModifierLocs[DefaultmapKindNum]; 5758 for (OMPClause *C : Clauses) { 5759 if (auto *DMC = dyn_cast<OMPDefaultmapClause>(C)) 5760 if (DMC->getDefaultmapModifier() == OMPC_DEFAULTMAP_MODIFIER_present) 5761 PresentModifierLocs[DMC->getDefaultmapKind()] = 5762 DMC->getDefaultmapModifierLoc(); 5763 } 5764 for (unsigned VC = 0; VC < DefaultmapKindNum; ++VC) { 5765 auto Kind = static_cast<OpenMPDefaultmapClauseKind>(VC); 5766 for (unsigned I = 0; I < OMPC_MAP_delete; ++I) { 5767 ArrayRef<Expr *> ImplicitMap = DSAChecker.getImplicitMap( 5768 Kind, static_cast<OpenMPMapClauseKind>(I)); 5769 ImplicitMaps[VC][I].append(ImplicitMap.begin(), ImplicitMap.end()); 5770 } 5771 ArrayRef<OpenMPMapModifierKind> ImplicitModifier = 5772 DSAChecker.getImplicitMapModifier(Kind); 5773 ImplicitMapModifiers[VC].append(ImplicitModifier.begin(), 5774 ImplicitModifier.end()); 5775 std::fill_n(std::back_inserter(ImplicitMapModifiersLoc[VC]), 5776 ImplicitModifier.size(), PresentModifierLocs[VC]); 5777 } 5778 // Mark taskgroup task_reduction descriptors as implicitly firstprivate. 5779 for (OMPClause *C : Clauses) { 5780 if (auto *IRC = dyn_cast<OMPInReductionClause>(C)) { 5781 for (Expr *E : IRC->taskgroup_descriptors()) 5782 if (E) 5783 ImplicitFirstprivates.emplace_back(E); 5784 } 5785 // OpenMP 5.0, 2.10.1 task Construct 5786 // [detach clause]... The event-handle will be considered as if it was 5787 // specified on a firstprivate clause. 5788 if (auto *DC = dyn_cast<OMPDetachClause>(C)) 5789 ImplicitFirstprivates.push_back(DC->getEventHandler()); 5790 } 5791 if (!ImplicitFirstprivates.empty()) { 5792 if (OMPClause *Implicit = ActOnOpenMPFirstprivateClause( 5793 ImplicitFirstprivates, SourceLocation(), SourceLocation(), 5794 SourceLocation())) { 5795 ClausesWithImplicit.push_back(Implicit); 5796 ErrorFound = cast<OMPFirstprivateClause>(Implicit)->varlist_size() != 5797 ImplicitFirstprivates.size(); 5798 } else { 5799 ErrorFound = true; 5800 } 5801 } 5802 for (unsigned I = 0, E = DefaultmapKindNum; I < E; ++I) { 5803 int ClauseKindCnt = -1; 5804 for (ArrayRef<Expr *> ImplicitMap : ImplicitMaps[I]) { 5805 ++ClauseKindCnt; 5806 if (ImplicitMap.empty()) 5807 continue; 5808 CXXScopeSpec MapperIdScopeSpec; 5809 DeclarationNameInfo MapperId; 5810 auto Kind = static_cast<OpenMPMapClauseKind>(ClauseKindCnt); 5811 if (OMPClause *Implicit = ActOnOpenMPMapClause( 5812 ImplicitMapModifiers[I], ImplicitMapModifiersLoc[I], 5813 MapperIdScopeSpec, MapperId, Kind, /*IsMapTypeImplicit=*/true, 5814 SourceLocation(), SourceLocation(), ImplicitMap, 5815 OMPVarListLocTy())) { 5816 ClausesWithImplicit.emplace_back(Implicit); 5817 ErrorFound |= cast<OMPMapClause>(Implicit)->varlist_size() != 5818 ImplicitMap.size(); 5819 } else { 5820 ErrorFound = true; 5821 } 5822 } 5823 } 5824 // Build expressions for implicit maps of data members with 'default' 5825 // mappers. 5826 if (LangOpts.OpenMP >= 50) 5827 processImplicitMapsWithDefaultMappers(*this, DSAStack, 5828 ClausesWithImplicit); 5829 } 5830 5831 llvm::SmallVector<OpenMPDirectiveKind, 4> AllowedNameModifiers; 5832 switch (Kind) { 5833 case OMPD_parallel: 5834 Res = ActOnOpenMPParallelDirective(ClausesWithImplicit, AStmt, StartLoc, 5835 EndLoc); 5836 AllowedNameModifiers.push_back(OMPD_parallel); 5837 break; 5838 case OMPD_simd: 5839 Res = ActOnOpenMPSimdDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc, 5840 VarsWithInheritedDSA); 5841 if (LangOpts.OpenMP >= 50) 5842 AllowedNameModifiers.push_back(OMPD_simd); 5843 break; 5844 case OMPD_tile: 5845 Res = 5846 ActOnOpenMPTileDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc); 5847 break; 5848 case OMPD_for: 5849 Res = ActOnOpenMPForDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc, 5850 VarsWithInheritedDSA); 5851 break; 5852 case OMPD_for_simd: 5853 Res = ActOnOpenMPForSimdDirective(ClausesWithImplicit, AStmt, StartLoc, 5854 EndLoc, VarsWithInheritedDSA); 5855 if (LangOpts.OpenMP >= 50) 5856 AllowedNameModifiers.push_back(OMPD_simd); 5857 break; 5858 case OMPD_sections: 5859 Res = ActOnOpenMPSectionsDirective(ClausesWithImplicit, AStmt, StartLoc, 5860 EndLoc); 5861 break; 5862 case OMPD_section: 5863 assert(ClausesWithImplicit.empty() && 5864 "No clauses are allowed for 'omp section' directive"); 5865 Res = ActOnOpenMPSectionDirective(AStmt, StartLoc, EndLoc); 5866 break; 5867 case OMPD_single: 5868 Res = ActOnOpenMPSingleDirective(ClausesWithImplicit, AStmt, StartLoc, 5869 EndLoc); 5870 break; 5871 case OMPD_master: 5872 assert(ClausesWithImplicit.empty() && 5873 "No clauses are allowed for 'omp master' directive"); 5874 Res = ActOnOpenMPMasterDirective(AStmt, StartLoc, EndLoc); 5875 break; 5876 case OMPD_masked: 5877 Res = ActOnOpenMPMaskedDirective(ClausesWithImplicit, AStmt, StartLoc, 5878 EndLoc); 5879 break; 5880 case OMPD_critical: 5881 Res = ActOnOpenMPCriticalDirective(DirName, ClausesWithImplicit, AStmt, 5882 StartLoc, EndLoc); 5883 break; 5884 case OMPD_parallel_for: 5885 Res = ActOnOpenMPParallelForDirective(ClausesWithImplicit, AStmt, StartLoc, 5886 EndLoc, VarsWithInheritedDSA); 5887 AllowedNameModifiers.push_back(OMPD_parallel); 5888 break; 5889 case OMPD_parallel_for_simd: 5890 Res = ActOnOpenMPParallelForSimdDirective( 5891 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 5892 AllowedNameModifiers.push_back(OMPD_parallel); 5893 if (LangOpts.OpenMP >= 50) 5894 AllowedNameModifiers.push_back(OMPD_simd); 5895 break; 5896 case OMPD_parallel_master: 5897 Res = ActOnOpenMPParallelMasterDirective(ClausesWithImplicit, AStmt, 5898 StartLoc, EndLoc); 5899 AllowedNameModifiers.push_back(OMPD_parallel); 5900 break; 5901 case OMPD_parallel_sections: 5902 Res = ActOnOpenMPParallelSectionsDirective(ClausesWithImplicit, AStmt, 5903 StartLoc, EndLoc); 5904 AllowedNameModifiers.push_back(OMPD_parallel); 5905 break; 5906 case OMPD_task: 5907 Res = 5908 ActOnOpenMPTaskDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc); 5909 AllowedNameModifiers.push_back(OMPD_task); 5910 break; 5911 case OMPD_taskyield: 5912 assert(ClausesWithImplicit.empty() && 5913 "No clauses are allowed for 'omp taskyield' directive"); 5914 assert(AStmt == nullptr && 5915 "No associated statement allowed for 'omp taskyield' directive"); 5916 Res = ActOnOpenMPTaskyieldDirective(StartLoc, EndLoc); 5917 break; 5918 case OMPD_barrier: 5919 assert(ClausesWithImplicit.empty() && 5920 "No clauses are allowed for 'omp barrier' directive"); 5921 assert(AStmt == nullptr && 5922 "No associated statement allowed for 'omp barrier' directive"); 5923 Res = ActOnOpenMPBarrierDirective(StartLoc, EndLoc); 5924 break; 5925 case OMPD_taskwait: 5926 assert(ClausesWithImplicit.empty() && 5927 "No clauses are allowed for 'omp taskwait' directive"); 5928 assert(AStmt == nullptr && 5929 "No associated statement allowed for 'omp taskwait' directive"); 5930 Res = ActOnOpenMPTaskwaitDirective(StartLoc, EndLoc); 5931 break; 5932 case OMPD_taskgroup: 5933 Res = ActOnOpenMPTaskgroupDirective(ClausesWithImplicit, AStmt, StartLoc, 5934 EndLoc); 5935 break; 5936 case OMPD_flush: 5937 assert(AStmt == nullptr && 5938 "No associated statement allowed for 'omp flush' directive"); 5939 Res = ActOnOpenMPFlushDirective(ClausesWithImplicit, StartLoc, EndLoc); 5940 break; 5941 case OMPD_depobj: 5942 assert(AStmt == nullptr && 5943 "No associated statement allowed for 'omp depobj' directive"); 5944 Res = ActOnOpenMPDepobjDirective(ClausesWithImplicit, StartLoc, EndLoc); 5945 break; 5946 case OMPD_scan: 5947 assert(AStmt == nullptr && 5948 "No associated statement allowed for 'omp scan' directive"); 5949 Res = ActOnOpenMPScanDirective(ClausesWithImplicit, StartLoc, EndLoc); 5950 break; 5951 case OMPD_ordered: 5952 Res = ActOnOpenMPOrderedDirective(ClausesWithImplicit, AStmt, StartLoc, 5953 EndLoc); 5954 break; 5955 case OMPD_atomic: 5956 Res = ActOnOpenMPAtomicDirective(ClausesWithImplicit, AStmt, StartLoc, 5957 EndLoc); 5958 break; 5959 case OMPD_teams: 5960 Res = 5961 ActOnOpenMPTeamsDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc); 5962 break; 5963 case OMPD_target: 5964 Res = ActOnOpenMPTargetDirective(ClausesWithImplicit, AStmt, StartLoc, 5965 EndLoc); 5966 AllowedNameModifiers.push_back(OMPD_target); 5967 break; 5968 case OMPD_target_parallel: 5969 Res = ActOnOpenMPTargetParallelDirective(ClausesWithImplicit, AStmt, 5970 StartLoc, EndLoc); 5971 AllowedNameModifiers.push_back(OMPD_target); 5972 AllowedNameModifiers.push_back(OMPD_parallel); 5973 break; 5974 case OMPD_target_parallel_for: 5975 Res = ActOnOpenMPTargetParallelForDirective( 5976 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 5977 AllowedNameModifiers.push_back(OMPD_target); 5978 AllowedNameModifiers.push_back(OMPD_parallel); 5979 break; 5980 case OMPD_cancellation_point: 5981 assert(ClausesWithImplicit.empty() && 5982 "No clauses are allowed for 'omp cancellation point' directive"); 5983 assert(AStmt == nullptr && "No associated statement allowed for 'omp " 5984 "cancellation point' directive"); 5985 Res = ActOnOpenMPCancellationPointDirective(StartLoc, EndLoc, CancelRegion); 5986 break; 5987 case OMPD_cancel: 5988 assert(AStmt == nullptr && 5989 "No associated statement allowed for 'omp cancel' directive"); 5990 Res = ActOnOpenMPCancelDirective(ClausesWithImplicit, StartLoc, EndLoc, 5991 CancelRegion); 5992 AllowedNameModifiers.push_back(OMPD_cancel); 5993 break; 5994 case OMPD_target_data: 5995 Res = ActOnOpenMPTargetDataDirective(ClausesWithImplicit, AStmt, StartLoc, 5996 EndLoc); 5997 AllowedNameModifiers.push_back(OMPD_target_data); 5998 break; 5999 case OMPD_target_enter_data: 6000 Res = ActOnOpenMPTargetEnterDataDirective(ClausesWithImplicit, StartLoc, 6001 EndLoc, AStmt); 6002 AllowedNameModifiers.push_back(OMPD_target_enter_data); 6003 break; 6004 case OMPD_target_exit_data: 6005 Res = ActOnOpenMPTargetExitDataDirective(ClausesWithImplicit, StartLoc, 6006 EndLoc, AStmt); 6007 AllowedNameModifiers.push_back(OMPD_target_exit_data); 6008 break; 6009 case OMPD_taskloop: 6010 Res = ActOnOpenMPTaskLoopDirective(ClausesWithImplicit, AStmt, StartLoc, 6011 EndLoc, VarsWithInheritedDSA); 6012 AllowedNameModifiers.push_back(OMPD_taskloop); 6013 break; 6014 case OMPD_taskloop_simd: 6015 Res = ActOnOpenMPTaskLoopSimdDirective(ClausesWithImplicit, AStmt, StartLoc, 6016 EndLoc, VarsWithInheritedDSA); 6017 AllowedNameModifiers.push_back(OMPD_taskloop); 6018 if (LangOpts.OpenMP >= 50) 6019 AllowedNameModifiers.push_back(OMPD_simd); 6020 break; 6021 case OMPD_master_taskloop: 6022 Res = ActOnOpenMPMasterTaskLoopDirective( 6023 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 6024 AllowedNameModifiers.push_back(OMPD_taskloop); 6025 break; 6026 case OMPD_master_taskloop_simd: 6027 Res = ActOnOpenMPMasterTaskLoopSimdDirective( 6028 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 6029 AllowedNameModifiers.push_back(OMPD_taskloop); 6030 if (LangOpts.OpenMP >= 50) 6031 AllowedNameModifiers.push_back(OMPD_simd); 6032 break; 6033 case OMPD_parallel_master_taskloop: 6034 Res = ActOnOpenMPParallelMasterTaskLoopDirective( 6035 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 6036 AllowedNameModifiers.push_back(OMPD_taskloop); 6037 AllowedNameModifiers.push_back(OMPD_parallel); 6038 break; 6039 case OMPD_parallel_master_taskloop_simd: 6040 Res = ActOnOpenMPParallelMasterTaskLoopSimdDirective( 6041 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 6042 AllowedNameModifiers.push_back(OMPD_taskloop); 6043 AllowedNameModifiers.push_back(OMPD_parallel); 6044 if (LangOpts.OpenMP >= 50) 6045 AllowedNameModifiers.push_back(OMPD_simd); 6046 break; 6047 case OMPD_distribute: 6048 Res = ActOnOpenMPDistributeDirective(ClausesWithImplicit, AStmt, StartLoc, 6049 EndLoc, VarsWithInheritedDSA); 6050 break; 6051 case OMPD_target_update: 6052 Res = ActOnOpenMPTargetUpdateDirective(ClausesWithImplicit, StartLoc, 6053 EndLoc, AStmt); 6054 AllowedNameModifiers.push_back(OMPD_target_update); 6055 break; 6056 case OMPD_distribute_parallel_for: 6057 Res = ActOnOpenMPDistributeParallelForDirective( 6058 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 6059 AllowedNameModifiers.push_back(OMPD_parallel); 6060 break; 6061 case OMPD_distribute_parallel_for_simd: 6062 Res = ActOnOpenMPDistributeParallelForSimdDirective( 6063 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 6064 AllowedNameModifiers.push_back(OMPD_parallel); 6065 if (LangOpts.OpenMP >= 50) 6066 AllowedNameModifiers.push_back(OMPD_simd); 6067 break; 6068 case OMPD_distribute_simd: 6069 Res = ActOnOpenMPDistributeSimdDirective( 6070 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 6071 if (LangOpts.OpenMP >= 50) 6072 AllowedNameModifiers.push_back(OMPD_simd); 6073 break; 6074 case OMPD_target_parallel_for_simd: 6075 Res = ActOnOpenMPTargetParallelForSimdDirective( 6076 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 6077 AllowedNameModifiers.push_back(OMPD_target); 6078 AllowedNameModifiers.push_back(OMPD_parallel); 6079 if (LangOpts.OpenMP >= 50) 6080 AllowedNameModifiers.push_back(OMPD_simd); 6081 break; 6082 case OMPD_target_simd: 6083 Res = ActOnOpenMPTargetSimdDirective(ClausesWithImplicit, AStmt, StartLoc, 6084 EndLoc, VarsWithInheritedDSA); 6085 AllowedNameModifiers.push_back(OMPD_target); 6086 if (LangOpts.OpenMP >= 50) 6087 AllowedNameModifiers.push_back(OMPD_simd); 6088 break; 6089 case OMPD_teams_distribute: 6090 Res = ActOnOpenMPTeamsDistributeDirective( 6091 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 6092 break; 6093 case OMPD_teams_distribute_simd: 6094 Res = ActOnOpenMPTeamsDistributeSimdDirective( 6095 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 6096 if (LangOpts.OpenMP >= 50) 6097 AllowedNameModifiers.push_back(OMPD_simd); 6098 break; 6099 case OMPD_teams_distribute_parallel_for_simd: 6100 Res = ActOnOpenMPTeamsDistributeParallelForSimdDirective( 6101 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 6102 AllowedNameModifiers.push_back(OMPD_parallel); 6103 if (LangOpts.OpenMP >= 50) 6104 AllowedNameModifiers.push_back(OMPD_simd); 6105 break; 6106 case OMPD_teams_distribute_parallel_for: 6107 Res = ActOnOpenMPTeamsDistributeParallelForDirective( 6108 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 6109 AllowedNameModifiers.push_back(OMPD_parallel); 6110 break; 6111 case OMPD_target_teams: 6112 Res = ActOnOpenMPTargetTeamsDirective(ClausesWithImplicit, AStmt, StartLoc, 6113 EndLoc); 6114 AllowedNameModifiers.push_back(OMPD_target); 6115 break; 6116 case OMPD_target_teams_distribute: 6117 Res = ActOnOpenMPTargetTeamsDistributeDirective( 6118 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 6119 AllowedNameModifiers.push_back(OMPD_target); 6120 break; 6121 case OMPD_target_teams_distribute_parallel_for: 6122 Res = ActOnOpenMPTargetTeamsDistributeParallelForDirective( 6123 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 6124 AllowedNameModifiers.push_back(OMPD_target); 6125 AllowedNameModifiers.push_back(OMPD_parallel); 6126 break; 6127 case OMPD_target_teams_distribute_parallel_for_simd: 6128 Res = ActOnOpenMPTargetTeamsDistributeParallelForSimdDirective( 6129 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 6130 AllowedNameModifiers.push_back(OMPD_target); 6131 AllowedNameModifiers.push_back(OMPD_parallel); 6132 if (LangOpts.OpenMP >= 50) 6133 AllowedNameModifiers.push_back(OMPD_simd); 6134 break; 6135 case OMPD_target_teams_distribute_simd: 6136 Res = ActOnOpenMPTargetTeamsDistributeSimdDirective( 6137 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 6138 AllowedNameModifiers.push_back(OMPD_target); 6139 if (LangOpts.OpenMP >= 50) 6140 AllowedNameModifiers.push_back(OMPD_simd); 6141 break; 6142 case OMPD_interop: 6143 assert(AStmt == nullptr && 6144 "No associated statement allowed for 'omp interop' directive"); 6145 Res = ActOnOpenMPInteropDirective(ClausesWithImplicit, StartLoc, EndLoc); 6146 break; 6147 case OMPD_dispatch: 6148 Res = ActOnOpenMPDispatchDirective(ClausesWithImplicit, AStmt, StartLoc, 6149 EndLoc); 6150 break; 6151 case OMPD_declare_target: 6152 case OMPD_end_declare_target: 6153 case OMPD_threadprivate: 6154 case OMPD_allocate: 6155 case OMPD_declare_reduction: 6156 case OMPD_declare_mapper: 6157 case OMPD_declare_simd: 6158 case OMPD_requires: 6159 case OMPD_declare_variant: 6160 case OMPD_begin_declare_variant: 6161 case OMPD_end_declare_variant: 6162 llvm_unreachable("OpenMP Directive is not allowed"); 6163 case OMPD_unknown: 6164 default: 6165 llvm_unreachable("Unknown OpenMP directive"); 6166 } 6167 6168 ErrorFound = Res.isInvalid() || ErrorFound; 6169 6170 // Check variables in the clauses if default(none) or 6171 // default(firstprivate) was specified. 6172 if (DSAStack->getDefaultDSA() == DSA_none || 6173 DSAStack->getDefaultDSA() == DSA_firstprivate) { 6174 DSAAttrChecker DSAChecker(DSAStack, *this, nullptr); 6175 for (OMPClause *C : Clauses) { 6176 switch (C->getClauseKind()) { 6177 case OMPC_num_threads: 6178 case OMPC_dist_schedule: 6179 // Do not analyse if no parent teams directive. 6180 if (isOpenMPTeamsDirective(Kind)) 6181 break; 6182 continue; 6183 case OMPC_if: 6184 if (isOpenMPTeamsDirective(Kind) && 6185 cast<OMPIfClause>(C)->getNameModifier() != OMPD_target) 6186 break; 6187 if (isOpenMPParallelDirective(Kind) && 6188 isOpenMPTaskLoopDirective(Kind) && 6189 cast<OMPIfClause>(C)->getNameModifier() != OMPD_parallel) 6190 break; 6191 continue; 6192 case OMPC_schedule: 6193 case OMPC_detach: 6194 break; 6195 case OMPC_grainsize: 6196 case OMPC_num_tasks: 6197 case OMPC_final: 6198 case OMPC_priority: 6199 case OMPC_novariants: 6200 case OMPC_nocontext: 6201 // Do not analyze if no parent parallel directive. 6202 if (isOpenMPParallelDirective(Kind)) 6203 break; 6204 continue; 6205 case OMPC_ordered: 6206 case OMPC_device: 6207 case OMPC_num_teams: 6208 case OMPC_thread_limit: 6209 case OMPC_hint: 6210 case OMPC_collapse: 6211 case OMPC_safelen: 6212 case OMPC_simdlen: 6213 case OMPC_sizes: 6214 case OMPC_default: 6215 case OMPC_proc_bind: 6216 case OMPC_private: 6217 case OMPC_firstprivate: 6218 case OMPC_lastprivate: 6219 case OMPC_shared: 6220 case OMPC_reduction: 6221 case OMPC_task_reduction: 6222 case OMPC_in_reduction: 6223 case OMPC_linear: 6224 case OMPC_aligned: 6225 case OMPC_copyin: 6226 case OMPC_copyprivate: 6227 case OMPC_nowait: 6228 case OMPC_untied: 6229 case OMPC_mergeable: 6230 case OMPC_allocate: 6231 case OMPC_read: 6232 case OMPC_write: 6233 case OMPC_update: 6234 case OMPC_capture: 6235 case OMPC_seq_cst: 6236 case OMPC_acq_rel: 6237 case OMPC_acquire: 6238 case OMPC_release: 6239 case OMPC_relaxed: 6240 case OMPC_depend: 6241 case OMPC_threads: 6242 case OMPC_simd: 6243 case OMPC_map: 6244 case OMPC_nogroup: 6245 case OMPC_defaultmap: 6246 case OMPC_to: 6247 case OMPC_from: 6248 case OMPC_use_device_ptr: 6249 case OMPC_use_device_addr: 6250 case OMPC_is_device_ptr: 6251 case OMPC_nontemporal: 6252 case OMPC_order: 6253 case OMPC_destroy: 6254 case OMPC_inclusive: 6255 case OMPC_exclusive: 6256 case OMPC_uses_allocators: 6257 case OMPC_affinity: 6258 continue; 6259 case OMPC_allocator: 6260 case OMPC_flush: 6261 case OMPC_depobj: 6262 case OMPC_threadprivate: 6263 case OMPC_uniform: 6264 case OMPC_unknown: 6265 case OMPC_unified_address: 6266 case OMPC_unified_shared_memory: 6267 case OMPC_reverse_offload: 6268 case OMPC_dynamic_allocators: 6269 case OMPC_atomic_default_mem_order: 6270 case OMPC_device_type: 6271 case OMPC_match: 6272 default: 6273 llvm_unreachable("Unexpected clause"); 6274 } 6275 for (Stmt *CC : C->children()) { 6276 if (CC) 6277 DSAChecker.Visit(CC); 6278 } 6279 } 6280 for (const auto &P : DSAChecker.getVarsWithInheritedDSA()) 6281 VarsWithInheritedDSA[P.getFirst()] = P.getSecond(); 6282 } 6283 for (const auto &P : VarsWithInheritedDSA) { 6284 if (P.getFirst()->isImplicit() || isa<OMPCapturedExprDecl>(P.getFirst())) 6285 continue; 6286 ErrorFound = true; 6287 if (DSAStack->getDefaultDSA() == DSA_none || 6288 DSAStack->getDefaultDSA() == DSA_firstprivate) { 6289 Diag(P.second->getExprLoc(), diag::err_omp_no_dsa_for_variable) 6290 << P.first << P.second->getSourceRange(); 6291 Diag(DSAStack->getDefaultDSALocation(), diag::note_omp_default_dsa_none); 6292 } else if (getLangOpts().OpenMP >= 50) { 6293 Diag(P.second->getExprLoc(), 6294 diag::err_omp_defaultmap_no_attr_for_variable) 6295 << P.first << P.second->getSourceRange(); 6296 Diag(DSAStack->getDefaultDSALocation(), 6297 diag::note_omp_defaultmap_attr_none); 6298 } 6299 } 6300 6301 if (!AllowedNameModifiers.empty()) 6302 ErrorFound = checkIfClauses(*this, Kind, Clauses, AllowedNameModifiers) || 6303 ErrorFound; 6304 6305 if (ErrorFound) 6306 return StmtError(); 6307 6308 if (!CurContext->isDependentContext() && 6309 isOpenMPTargetExecutionDirective(Kind) && 6310 !(DSAStack->hasRequiresDeclWithClause<OMPUnifiedSharedMemoryClause>() || 6311 DSAStack->hasRequiresDeclWithClause<OMPUnifiedAddressClause>() || 6312 DSAStack->hasRequiresDeclWithClause<OMPReverseOffloadClause>() || 6313 DSAStack->hasRequiresDeclWithClause<OMPDynamicAllocatorsClause>())) { 6314 // Register target to DSA Stack. 6315 DSAStack->addTargetDirLocation(StartLoc); 6316 } 6317 6318 return Res; 6319 } 6320 6321 Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareSimdDirective( 6322 DeclGroupPtrTy DG, OMPDeclareSimdDeclAttr::BranchStateTy BS, Expr *Simdlen, 6323 ArrayRef<Expr *> Uniforms, ArrayRef<Expr *> Aligneds, 6324 ArrayRef<Expr *> Alignments, ArrayRef<Expr *> Linears, 6325 ArrayRef<unsigned> LinModifiers, ArrayRef<Expr *> Steps, SourceRange SR) { 6326 assert(Aligneds.size() == Alignments.size()); 6327 assert(Linears.size() == LinModifiers.size()); 6328 assert(Linears.size() == Steps.size()); 6329 if (!DG || DG.get().isNull()) 6330 return DeclGroupPtrTy(); 6331 6332 const int SimdId = 0; 6333 if (!DG.get().isSingleDecl()) { 6334 Diag(SR.getBegin(), diag::err_omp_single_decl_in_declare_simd_variant) 6335 << SimdId; 6336 return DG; 6337 } 6338 Decl *ADecl = DG.get().getSingleDecl(); 6339 if (auto *FTD = dyn_cast<FunctionTemplateDecl>(ADecl)) 6340 ADecl = FTD->getTemplatedDecl(); 6341 6342 auto *FD = dyn_cast<FunctionDecl>(ADecl); 6343 if (!FD) { 6344 Diag(ADecl->getLocation(), diag::err_omp_function_expected) << SimdId; 6345 return DeclGroupPtrTy(); 6346 } 6347 6348 // OpenMP [2.8.2, declare simd construct, Description] 6349 // The parameter of the simdlen clause must be a constant positive integer 6350 // expression. 6351 ExprResult SL; 6352 if (Simdlen) 6353 SL = VerifyPositiveIntegerConstantInClause(Simdlen, OMPC_simdlen); 6354 // OpenMP [2.8.2, declare simd construct, Description] 6355 // The special this pointer can be used as if was one of the arguments to the 6356 // function in any of the linear, aligned, or uniform clauses. 6357 // The uniform clause declares one or more arguments to have an invariant 6358 // value for all concurrent invocations of the function in the execution of a 6359 // single SIMD loop. 6360 llvm::DenseMap<const Decl *, const Expr *> UniformedArgs; 6361 const Expr *UniformedLinearThis = nullptr; 6362 for (const Expr *E : Uniforms) { 6363 E = E->IgnoreParenImpCasts(); 6364 if (const auto *DRE = dyn_cast<DeclRefExpr>(E)) 6365 if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) 6366 if (FD->getNumParams() > PVD->getFunctionScopeIndex() && 6367 FD->getParamDecl(PVD->getFunctionScopeIndex()) 6368 ->getCanonicalDecl() == PVD->getCanonicalDecl()) { 6369 UniformedArgs.try_emplace(PVD->getCanonicalDecl(), E); 6370 continue; 6371 } 6372 if (isa<CXXThisExpr>(E)) { 6373 UniformedLinearThis = E; 6374 continue; 6375 } 6376 Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause) 6377 << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0); 6378 } 6379 // OpenMP [2.8.2, declare simd construct, Description] 6380 // The aligned clause declares that the object to which each list item points 6381 // is aligned to the number of bytes expressed in the optional parameter of 6382 // the aligned clause. 6383 // The special this pointer can be used as if was one of the arguments to the 6384 // function in any of the linear, aligned, or uniform clauses. 6385 // The type of list items appearing in the aligned clause must be array, 6386 // pointer, reference to array, or reference to pointer. 6387 llvm::DenseMap<const Decl *, const Expr *> AlignedArgs; 6388 const Expr *AlignedThis = nullptr; 6389 for (const Expr *E : Aligneds) { 6390 E = E->IgnoreParenImpCasts(); 6391 if (const auto *DRE = dyn_cast<DeclRefExpr>(E)) 6392 if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) { 6393 const VarDecl *CanonPVD = PVD->getCanonicalDecl(); 6394 if (FD->getNumParams() > PVD->getFunctionScopeIndex() && 6395 FD->getParamDecl(PVD->getFunctionScopeIndex()) 6396 ->getCanonicalDecl() == CanonPVD) { 6397 // OpenMP [2.8.1, simd construct, Restrictions] 6398 // A list-item cannot appear in more than one aligned clause. 6399 if (AlignedArgs.count(CanonPVD) > 0) { 6400 Diag(E->getExprLoc(), diag::err_omp_used_in_clause_twice) 6401 << 1 << getOpenMPClauseName(OMPC_aligned) 6402 << E->getSourceRange(); 6403 Diag(AlignedArgs[CanonPVD]->getExprLoc(), 6404 diag::note_omp_explicit_dsa) 6405 << getOpenMPClauseName(OMPC_aligned); 6406 continue; 6407 } 6408 AlignedArgs[CanonPVD] = E; 6409 QualType QTy = PVD->getType() 6410 .getNonReferenceType() 6411 .getUnqualifiedType() 6412 .getCanonicalType(); 6413 const Type *Ty = QTy.getTypePtrOrNull(); 6414 if (!Ty || (!Ty->isArrayType() && !Ty->isPointerType())) { 6415 Diag(E->getExprLoc(), diag::err_omp_aligned_expected_array_or_ptr) 6416 << QTy << getLangOpts().CPlusPlus << E->getSourceRange(); 6417 Diag(PVD->getLocation(), diag::note_previous_decl) << PVD; 6418 } 6419 continue; 6420 } 6421 } 6422 if (isa<CXXThisExpr>(E)) { 6423 if (AlignedThis) { 6424 Diag(E->getExprLoc(), diag::err_omp_used_in_clause_twice) 6425 << 2 << getOpenMPClauseName(OMPC_aligned) << E->getSourceRange(); 6426 Diag(AlignedThis->getExprLoc(), diag::note_omp_explicit_dsa) 6427 << getOpenMPClauseName(OMPC_aligned); 6428 } 6429 AlignedThis = E; 6430 continue; 6431 } 6432 Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause) 6433 << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0); 6434 } 6435 // The optional parameter of the aligned clause, alignment, must be a constant 6436 // positive integer expression. If no optional parameter is specified, 6437 // implementation-defined default alignments for SIMD instructions on the 6438 // target platforms are assumed. 6439 SmallVector<const Expr *, 4> NewAligns; 6440 for (Expr *E : Alignments) { 6441 ExprResult Align; 6442 if (E) 6443 Align = VerifyPositiveIntegerConstantInClause(E, OMPC_aligned); 6444 NewAligns.push_back(Align.get()); 6445 } 6446 // OpenMP [2.8.2, declare simd construct, Description] 6447 // The linear clause declares one or more list items to be private to a SIMD 6448 // lane and to have a linear relationship with respect to the iteration space 6449 // of a loop. 6450 // The special this pointer can be used as if was one of the arguments to the 6451 // function in any of the linear, aligned, or uniform clauses. 6452 // When a linear-step expression is specified in a linear clause it must be 6453 // either a constant integer expression or an integer-typed parameter that is 6454 // specified in a uniform clause on the directive. 6455 llvm::DenseMap<const Decl *, const Expr *> LinearArgs; 6456 const bool IsUniformedThis = UniformedLinearThis != nullptr; 6457 auto MI = LinModifiers.begin(); 6458 for (const Expr *E : Linears) { 6459 auto LinKind = static_cast<OpenMPLinearClauseKind>(*MI); 6460 ++MI; 6461 E = E->IgnoreParenImpCasts(); 6462 if (const auto *DRE = dyn_cast<DeclRefExpr>(E)) 6463 if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) { 6464 const VarDecl *CanonPVD = PVD->getCanonicalDecl(); 6465 if (FD->getNumParams() > PVD->getFunctionScopeIndex() && 6466 FD->getParamDecl(PVD->getFunctionScopeIndex()) 6467 ->getCanonicalDecl() == CanonPVD) { 6468 // OpenMP [2.15.3.7, linear Clause, Restrictions] 6469 // A list-item cannot appear in more than one linear clause. 6470 if (LinearArgs.count(CanonPVD) > 0) { 6471 Diag(E->getExprLoc(), diag::err_omp_wrong_dsa) 6472 << getOpenMPClauseName(OMPC_linear) 6473 << getOpenMPClauseName(OMPC_linear) << E->getSourceRange(); 6474 Diag(LinearArgs[CanonPVD]->getExprLoc(), 6475 diag::note_omp_explicit_dsa) 6476 << getOpenMPClauseName(OMPC_linear); 6477 continue; 6478 } 6479 // Each argument can appear in at most one uniform or linear clause. 6480 if (UniformedArgs.count(CanonPVD) > 0) { 6481 Diag(E->getExprLoc(), diag::err_omp_wrong_dsa) 6482 << getOpenMPClauseName(OMPC_linear) 6483 << getOpenMPClauseName(OMPC_uniform) << E->getSourceRange(); 6484 Diag(UniformedArgs[CanonPVD]->getExprLoc(), 6485 diag::note_omp_explicit_dsa) 6486 << getOpenMPClauseName(OMPC_uniform); 6487 continue; 6488 } 6489 LinearArgs[CanonPVD] = E; 6490 if (E->isValueDependent() || E->isTypeDependent() || 6491 E->isInstantiationDependent() || 6492 E->containsUnexpandedParameterPack()) 6493 continue; 6494 (void)CheckOpenMPLinearDecl(CanonPVD, E->getExprLoc(), LinKind, 6495 PVD->getOriginalType(), 6496 /*IsDeclareSimd=*/true); 6497 continue; 6498 } 6499 } 6500 if (isa<CXXThisExpr>(E)) { 6501 if (UniformedLinearThis) { 6502 Diag(E->getExprLoc(), diag::err_omp_wrong_dsa) 6503 << getOpenMPClauseName(OMPC_linear) 6504 << getOpenMPClauseName(IsUniformedThis ? OMPC_uniform : OMPC_linear) 6505 << E->getSourceRange(); 6506 Diag(UniformedLinearThis->getExprLoc(), diag::note_omp_explicit_dsa) 6507 << getOpenMPClauseName(IsUniformedThis ? OMPC_uniform 6508 : OMPC_linear); 6509 continue; 6510 } 6511 UniformedLinearThis = E; 6512 if (E->isValueDependent() || E->isTypeDependent() || 6513 E->isInstantiationDependent() || E->containsUnexpandedParameterPack()) 6514 continue; 6515 (void)CheckOpenMPLinearDecl(/*D=*/nullptr, E->getExprLoc(), LinKind, 6516 E->getType(), /*IsDeclareSimd=*/true); 6517 continue; 6518 } 6519 Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause) 6520 << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0); 6521 } 6522 Expr *Step = nullptr; 6523 Expr *NewStep = nullptr; 6524 SmallVector<Expr *, 4> NewSteps; 6525 for (Expr *E : Steps) { 6526 // Skip the same step expression, it was checked already. 6527 if (Step == E || !E) { 6528 NewSteps.push_back(E ? NewStep : nullptr); 6529 continue; 6530 } 6531 Step = E; 6532 if (const auto *DRE = dyn_cast<DeclRefExpr>(Step)) 6533 if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) { 6534 const VarDecl *CanonPVD = PVD->getCanonicalDecl(); 6535 if (UniformedArgs.count(CanonPVD) == 0) { 6536 Diag(Step->getExprLoc(), diag::err_omp_expected_uniform_param) 6537 << Step->getSourceRange(); 6538 } else if (E->isValueDependent() || E->isTypeDependent() || 6539 E->isInstantiationDependent() || 6540 E->containsUnexpandedParameterPack() || 6541 CanonPVD->getType()->hasIntegerRepresentation()) { 6542 NewSteps.push_back(Step); 6543 } else { 6544 Diag(Step->getExprLoc(), diag::err_omp_expected_int_param) 6545 << Step->getSourceRange(); 6546 } 6547 continue; 6548 } 6549 NewStep = Step; 6550 if (Step && !Step->isValueDependent() && !Step->isTypeDependent() && 6551 !Step->isInstantiationDependent() && 6552 !Step->containsUnexpandedParameterPack()) { 6553 NewStep = PerformOpenMPImplicitIntegerConversion(Step->getExprLoc(), Step) 6554 .get(); 6555 if (NewStep) 6556 NewStep = 6557 VerifyIntegerConstantExpression(NewStep, /*FIXME*/ AllowFold).get(); 6558 } 6559 NewSteps.push_back(NewStep); 6560 } 6561 auto *NewAttr = OMPDeclareSimdDeclAttr::CreateImplicit( 6562 Context, BS, SL.get(), const_cast<Expr **>(Uniforms.data()), 6563 Uniforms.size(), const_cast<Expr **>(Aligneds.data()), Aligneds.size(), 6564 const_cast<Expr **>(NewAligns.data()), NewAligns.size(), 6565 const_cast<Expr **>(Linears.data()), Linears.size(), 6566 const_cast<unsigned *>(LinModifiers.data()), LinModifiers.size(), 6567 NewSteps.data(), NewSteps.size(), SR); 6568 ADecl->addAttr(NewAttr); 6569 return DG; 6570 } 6571 6572 static void setPrototype(Sema &S, FunctionDecl *FD, FunctionDecl *FDWithProto, 6573 QualType NewType) { 6574 assert(NewType->isFunctionProtoType() && 6575 "Expected function type with prototype."); 6576 assert(FD->getType()->isFunctionNoProtoType() && 6577 "Expected function with type with no prototype."); 6578 assert(FDWithProto->getType()->isFunctionProtoType() && 6579 "Expected function with prototype."); 6580 // Synthesize parameters with the same types. 6581 FD->setType(NewType); 6582 SmallVector<ParmVarDecl *, 16> Params; 6583 for (const ParmVarDecl *P : FDWithProto->parameters()) { 6584 auto *Param = ParmVarDecl::Create(S.getASTContext(), FD, SourceLocation(), 6585 SourceLocation(), nullptr, P->getType(), 6586 /*TInfo=*/nullptr, SC_None, nullptr); 6587 Param->setScopeInfo(0, Params.size()); 6588 Param->setImplicit(); 6589 Params.push_back(Param); 6590 } 6591 6592 FD->setParams(Params); 6593 } 6594 6595 void Sema::ActOnFinishedFunctionDefinitionInOpenMPAssumeScope(Decl *D) { 6596 if (D->isInvalidDecl()) 6597 return; 6598 FunctionDecl *FD = nullptr; 6599 if (auto *UTemplDecl = dyn_cast<FunctionTemplateDecl>(D)) 6600 FD = UTemplDecl->getTemplatedDecl(); 6601 else 6602 FD = cast<FunctionDecl>(D); 6603 assert(FD && "Expected a function declaration!"); 6604 6605 // If we are intantiating templates we do *not* apply scoped assumptions but 6606 // only global ones. We apply scoped assumption to the template definition 6607 // though. 6608 if (!inTemplateInstantiation()) { 6609 for (AssumptionAttr *AA : OMPAssumeScoped) 6610 FD->addAttr(AA); 6611 } 6612 for (AssumptionAttr *AA : OMPAssumeGlobal) 6613 FD->addAttr(AA); 6614 } 6615 6616 Sema::OMPDeclareVariantScope::OMPDeclareVariantScope(OMPTraitInfo &TI) 6617 : TI(&TI), NameSuffix(TI.getMangledName()) {} 6618 6619 void Sema::ActOnStartOfFunctionDefinitionInOpenMPDeclareVariantScope( 6620 Scope *S, Declarator &D, MultiTemplateParamsArg TemplateParamLists, 6621 SmallVectorImpl<FunctionDecl *> &Bases) { 6622 if (!D.getIdentifier()) 6623 return; 6624 6625 OMPDeclareVariantScope &DVScope = OMPDeclareVariantScopes.back(); 6626 6627 // Template specialization is an extension, check if we do it. 6628 bool IsTemplated = !TemplateParamLists.empty(); 6629 if (IsTemplated & 6630 !DVScope.TI->isExtensionActive( 6631 llvm::omp::TraitProperty::implementation_extension_allow_templates)) 6632 return; 6633 6634 IdentifierInfo *BaseII = D.getIdentifier(); 6635 LookupResult Lookup(*this, DeclarationName(BaseII), D.getIdentifierLoc(), 6636 LookupOrdinaryName); 6637 LookupParsedName(Lookup, S, &D.getCXXScopeSpec()); 6638 6639 TypeSourceInfo *TInfo = GetTypeForDeclarator(D, S); 6640 QualType FType = TInfo->getType(); 6641 6642 bool IsConstexpr = 6643 D.getDeclSpec().getConstexprSpecifier() == ConstexprSpecKind::Constexpr; 6644 bool IsConsteval = 6645 D.getDeclSpec().getConstexprSpecifier() == ConstexprSpecKind::Consteval; 6646 6647 for (auto *Candidate : Lookup) { 6648 auto *CandidateDecl = Candidate->getUnderlyingDecl(); 6649 FunctionDecl *UDecl = nullptr; 6650 if (IsTemplated && isa<FunctionTemplateDecl>(CandidateDecl)) 6651 UDecl = cast<FunctionTemplateDecl>(CandidateDecl)->getTemplatedDecl(); 6652 else if (!IsTemplated) 6653 UDecl = dyn_cast<FunctionDecl>(CandidateDecl); 6654 if (!UDecl) 6655 continue; 6656 6657 // Don't specialize constexpr/consteval functions with 6658 // non-constexpr/consteval functions. 6659 if (UDecl->isConstexpr() && !IsConstexpr) 6660 continue; 6661 if (UDecl->isConsteval() && !IsConsteval) 6662 continue; 6663 6664 QualType UDeclTy = UDecl->getType(); 6665 if (!UDeclTy->isDependentType()) { 6666 QualType NewType = Context.mergeFunctionTypes( 6667 FType, UDeclTy, /* OfBlockPointer */ false, 6668 /* Unqualified */ false, /* AllowCXX */ true); 6669 if (NewType.isNull()) 6670 continue; 6671 } 6672 6673 // Found a base! 6674 Bases.push_back(UDecl); 6675 } 6676 6677 bool UseImplicitBase = !DVScope.TI->isExtensionActive( 6678 llvm::omp::TraitProperty::implementation_extension_disable_implicit_base); 6679 // If no base was found we create a declaration that we use as base. 6680 if (Bases.empty() && UseImplicitBase) { 6681 D.setFunctionDefinitionKind(FunctionDefinitionKind::Declaration); 6682 Decl *BaseD = HandleDeclarator(S, D, TemplateParamLists); 6683 BaseD->setImplicit(true); 6684 if (auto *BaseTemplD = dyn_cast<FunctionTemplateDecl>(BaseD)) 6685 Bases.push_back(BaseTemplD->getTemplatedDecl()); 6686 else 6687 Bases.push_back(cast<FunctionDecl>(BaseD)); 6688 } 6689 6690 std::string MangledName; 6691 MangledName += D.getIdentifier()->getName(); 6692 MangledName += getOpenMPVariantManglingSeparatorStr(); 6693 MangledName += DVScope.NameSuffix; 6694 IdentifierInfo &VariantII = Context.Idents.get(MangledName); 6695 6696 VariantII.setMangledOpenMPVariantName(true); 6697 D.SetIdentifier(&VariantII, D.getBeginLoc()); 6698 } 6699 6700 void Sema::ActOnFinishedFunctionDefinitionInOpenMPDeclareVariantScope( 6701 Decl *D, SmallVectorImpl<FunctionDecl *> &Bases) { 6702 // Do not mark function as is used to prevent its emission if this is the 6703 // only place where it is used. 6704 EnterExpressionEvaluationContext Unevaluated( 6705 *this, Sema::ExpressionEvaluationContext::Unevaluated); 6706 6707 FunctionDecl *FD = nullptr; 6708 if (auto *UTemplDecl = dyn_cast<FunctionTemplateDecl>(D)) 6709 FD = UTemplDecl->getTemplatedDecl(); 6710 else 6711 FD = cast<FunctionDecl>(D); 6712 auto *VariantFuncRef = DeclRefExpr::Create( 6713 Context, NestedNameSpecifierLoc(), SourceLocation(), FD, 6714 /* RefersToEnclosingVariableOrCapture */ false, 6715 /* NameLoc */ FD->getLocation(), FD->getType(), ExprValueKind::VK_RValue); 6716 6717 OMPDeclareVariantScope &DVScope = OMPDeclareVariantScopes.back(); 6718 auto *OMPDeclareVariantA = OMPDeclareVariantAttr::CreateImplicit( 6719 Context, VariantFuncRef, DVScope.TI); 6720 for (FunctionDecl *BaseFD : Bases) 6721 BaseFD->addAttr(OMPDeclareVariantA); 6722 } 6723 6724 ExprResult Sema::ActOnOpenMPCall(ExprResult Call, Scope *Scope, 6725 SourceLocation LParenLoc, 6726 MultiExprArg ArgExprs, 6727 SourceLocation RParenLoc, Expr *ExecConfig) { 6728 // The common case is a regular call we do not want to specialize at all. Try 6729 // to make that case fast by bailing early. 6730 CallExpr *CE = dyn_cast<CallExpr>(Call.get()); 6731 if (!CE) 6732 return Call; 6733 6734 FunctionDecl *CalleeFnDecl = CE->getDirectCallee(); 6735 if (!CalleeFnDecl) 6736 return Call; 6737 6738 if (!CalleeFnDecl->hasAttr<OMPDeclareVariantAttr>()) 6739 return Call; 6740 6741 ASTContext &Context = getASTContext(); 6742 std::function<void(StringRef)> DiagUnknownTrait = [this, 6743 CE](StringRef ISATrait) { 6744 // TODO Track the selector locations in a way that is accessible here to 6745 // improve the diagnostic location. 6746 Diag(CE->getBeginLoc(), diag::warn_unknown_declare_variant_isa_trait) 6747 << ISATrait; 6748 }; 6749 TargetOMPContext OMPCtx(Context, std::move(DiagUnknownTrait), 6750 getCurFunctionDecl()); 6751 6752 QualType CalleeFnType = CalleeFnDecl->getType(); 6753 6754 SmallVector<Expr *, 4> Exprs; 6755 SmallVector<VariantMatchInfo, 4> VMIs; 6756 while (CalleeFnDecl) { 6757 for (OMPDeclareVariantAttr *A : 6758 CalleeFnDecl->specific_attrs<OMPDeclareVariantAttr>()) { 6759 Expr *VariantRef = A->getVariantFuncRef(); 6760 6761 VariantMatchInfo VMI; 6762 OMPTraitInfo &TI = A->getTraitInfo(); 6763 TI.getAsVariantMatchInfo(Context, VMI); 6764 if (!isVariantApplicableInContext(VMI, OMPCtx, 6765 /* DeviceSetOnly */ false)) 6766 continue; 6767 6768 VMIs.push_back(VMI); 6769 Exprs.push_back(VariantRef); 6770 } 6771 6772 CalleeFnDecl = CalleeFnDecl->getPreviousDecl(); 6773 } 6774 6775 ExprResult NewCall; 6776 do { 6777 int BestIdx = getBestVariantMatchForContext(VMIs, OMPCtx); 6778 if (BestIdx < 0) 6779 return Call; 6780 Expr *BestExpr = cast<DeclRefExpr>(Exprs[BestIdx]); 6781 Decl *BestDecl = cast<DeclRefExpr>(BestExpr)->getDecl(); 6782 6783 { 6784 // Try to build a (member) call expression for the current best applicable 6785 // variant expression. We allow this to fail in which case we continue 6786 // with the next best variant expression. The fail case is part of the 6787 // implementation defined behavior in the OpenMP standard when it talks 6788 // about what differences in the function prototypes: "Any differences 6789 // that the specific OpenMP context requires in the prototype of the 6790 // variant from the base function prototype are implementation defined." 6791 // This wording is there to allow the specialized variant to have a 6792 // different type than the base function. This is intended and OK but if 6793 // we cannot create a call the difference is not in the "implementation 6794 // defined range" we allow. 6795 Sema::TentativeAnalysisScope Trap(*this); 6796 6797 if (auto *SpecializedMethod = dyn_cast<CXXMethodDecl>(BestDecl)) { 6798 auto *MemberCall = dyn_cast<CXXMemberCallExpr>(CE); 6799 BestExpr = MemberExpr::CreateImplicit( 6800 Context, MemberCall->getImplicitObjectArgument(), 6801 /* IsArrow */ false, SpecializedMethod, Context.BoundMemberTy, 6802 MemberCall->getValueKind(), MemberCall->getObjectKind()); 6803 } 6804 NewCall = BuildCallExpr(Scope, BestExpr, LParenLoc, ArgExprs, RParenLoc, 6805 ExecConfig); 6806 if (NewCall.isUsable()) { 6807 if (CallExpr *NCE = dyn_cast<CallExpr>(NewCall.get())) { 6808 FunctionDecl *NewCalleeFnDecl = NCE->getDirectCallee(); 6809 QualType NewType = Context.mergeFunctionTypes( 6810 CalleeFnType, NewCalleeFnDecl->getType(), 6811 /* OfBlockPointer */ false, 6812 /* Unqualified */ false, /* AllowCXX */ true); 6813 if (!NewType.isNull()) 6814 break; 6815 // Don't use the call if the function type was not compatible. 6816 NewCall = nullptr; 6817 } 6818 } 6819 } 6820 6821 VMIs.erase(VMIs.begin() + BestIdx); 6822 Exprs.erase(Exprs.begin() + BestIdx); 6823 } while (!VMIs.empty()); 6824 6825 if (!NewCall.isUsable()) 6826 return Call; 6827 return PseudoObjectExpr::Create(Context, CE, {NewCall.get()}, 0); 6828 } 6829 6830 Optional<std::pair<FunctionDecl *, Expr *>> 6831 Sema::checkOpenMPDeclareVariantFunction(Sema::DeclGroupPtrTy DG, 6832 Expr *VariantRef, OMPTraitInfo &TI, 6833 SourceRange SR) { 6834 if (!DG || DG.get().isNull()) 6835 return None; 6836 6837 const int VariantId = 1; 6838 // Must be applied only to single decl. 6839 if (!DG.get().isSingleDecl()) { 6840 Diag(SR.getBegin(), diag::err_omp_single_decl_in_declare_simd_variant) 6841 << VariantId << SR; 6842 return None; 6843 } 6844 Decl *ADecl = DG.get().getSingleDecl(); 6845 if (auto *FTD = dyn_cast<FunctionTemplateDecl>(ADecl)) 6846 ADecl = FTD->getTemplatedDecl(); 6847 6848 // Decl must be a function. 6849 auto *FD = dyn_cast<FunctionDecl>(ADecl); 6850 if (!FD) { 6851 Diag(ADecl->getLocation(), diag::err_omp_function_expected) 6852 << VariantId << SR; 6853 return None; 6854 } 6855 6856 auto &&HasMultiVersionAttributes = [](const FunctionDecl *FD) { 6857 return FD->hasAttrs() && 6858 (FD->hasAttr<CPUDispatchAttr>() || FD->hasAttr<CPUSpecificAttr>() || 6859 FD->hasAttr<TargetAttr>()); 6860 }; 6861 // OpenMP is not compatible with CPU-specific attributes. 6862 if (HasMultiVersionAttributes(FD)) { 6863 Diag(FD->getLocation(), diag::err_omp_declare_variant_incompat_attributes) 6864 << SR; 6865 return None; 6866 } 6867 6868 // Allow #pragma omp declare variant only if the function is not used. 6869 if (FD->isUsed(false)) 6870 Diag(SR.getBegin(), diag::warn_omp_declare_variant_after_used) 6871 << FD->getLocation(); 6872 6873 // Check if the function was emitted already. 6874 const FunctionDecl *Definition; 6875 if (!FD->isThisDeclarationADefinition() && FD->isDefined(Definition) && 6876 (LangOpts.EmitAllDecls || Context.DeclMustBeEmitted(Definition))) 6877 Diag(SR.getBegin(), diag::warn_omp_declare_variant_after_emitted) 6878 << FD->getLocation(); 6879 6880 // The VariantRef must point to function. 6881 if (!VariantRef) { 6882 Diag(SR.getBegin(), diag::err_omp_function_expected) << VariantId; 6883 return None; 6884 } 6885 6886 auto ShouldDelayChecks = [](Expr *&E, bool) { 6887 return E && (E->isTypeDependent() || E->isValueDependent() || 6888 E->containsUnexpandedParameterPack() || 6889 E->isInstantiationDependent()); 6890 }; 6891 // Do not check templates, wait until instantiation. 6892 if (FD->isDependentContext() || ShouldDelayChecks(VariantRef, false) || 6893 TI.anyScoreOrCondition(ShouldDelayChecks)) 6894 return std::make_pair(FD, VariantRef); 6895 6896 // Deal with non-constant score and user condition expressions. 6897 auto HandleNonConstantScoresAndConditions = [this](Expr *&E, 6898 bool IsScore) -> bool { 6899 if (!E || E->isIntegerConstantExpr(Context)) 6900 return false; 6901 6902 if (IsScore) { 6903 // We warn on non-constant scores and pretend they were not present. 6904 Diag(E->getExprLoc(), diag::warn_omp_declare_variant_score_not_constant) 6905 << E; 6906 E = nullptr; 6907 } else { 6908 // We could replace a non-constant user condition with "false" but we 6909 // will soon need to handle these anyway for the dynamic version of 6910 // OpenMP context selectors. 6911 Diag(E->getExprLoc(), 6912 diag::err_omp_declare_variant_user_condition_not_constant) 6913 << E; 6914 } 6915 return true; 6916 }; 6917 if (TI.anyScoreOrCondition(HandleNonConstantScoresAndConditions)) 6918 return None; 6919 6920 // Convert VariantRef expression to the type of the original function to 6921 // resolve possible conflicts. 6922 ExprResult VariantRefCast = VariantRef; 6923 if (LangOpts.CPlusPlus) { 6924 QualType FnPtrType; 6925 auto *Method = dyn_cast<CXXMethodDecl>(FD); 6926 if (Method && !Method->isStatic()) { 6927 const Type *ClassType = 6928 Context.getTypeDeclType(Method->getParent()).getTypePtr(); 6929 FnPtrType = Context.getMemberPointerType(FD->getType(), ClassType); 6930 ExprResult ER; 6931 { 6932 // Build adrr_of unary op to correctly handle type checks for member 6933 // functions. 6934 Sema::TentativeAnalysisScope Trap(*this); 6935 ER = CreateBuiltinUnaryOp(VariantRef->getBeginLoc(), UO_AddrOf, 6936 VariantRef); 6937 } 6938 if (!ER.isUsable()) { 6939 Diag(VariantRef->getExprLoc(), diag::err_omp_function_expected) 6940 << VariantId << VariantRef->getSourceRange(); 6941 return None; 6942 } 6943 VariantRef = ER.get(); 6944 } else { 6945 FnPtrType = Context.getPointerType(FD->getType()); 6946 } 6947 QualType VarianPtrType = Context.getPointerType(VariantRef->getType()); 6948 if (VarianPtrType.getUnqualifiedType() != FnPtrType.getUnqualifiedType()) { 6949 ImplicitConversionSequence ICS = TryImplicitConversion( 6950 VariantRef, FnPtrType.getUnqualifiedType(), 6951 /*SuppressUserConversions=*/false, AllowedExplicit::None, 6952 /*InOverloadResolution=*/false, 6953 /*CStyle=*/false, 6954 /*AllowObjCWritebackConversion=*/false); 6955 if (ICS.isFailure()) { 6956 Diag(VariantRef->getExprLoc(), 6957 diag::err_omp_declare_variant_incompat_types) 6958 << VariantRef->getType() 6959 << ((Method && !Method->isStatic()) ? FnPtrType : FD->getType()) 6960 << VariantRef->getSourceRange(); 6961 return None; 6962 } 6963 VariantRefCast = PerformImplicitConversion( 6964 VariantRef, FnPtrType.getUnqualifiedType(), AA_Converting); 6965 if (!VariantRefCast.isUsable()) 6966 return None; 6967 } 6968 // Drop previously built artificial addr_of unary op for member functions. 6969 if (Method && !Method->isStatic()) { 6970 Expr *PossibleAddrOfVariantRef = VariantRefCast.get(); 6971 if (auto *UO = dyn_cast<UnaryOperator>( 6972 PossibleAddrOfVariantRef->IgnoreImplicit())) 6973 VariantRefCast = UO->getSubExpr(); 6974 } 6975 } 6976 6977 ExprResult ER = CheckPlaceholderExpr(VariantRefCast.get()); 6978 if (!ER.isUsable() || 6979 !ER.get()->IgnoreParenImpCasts()->getType()->isFunctionType()) { 6980 Diag(VariantRef->getExprLoc(), diag::err_omp_function_expected) 6981 << VariantId << VariantRef->getSourceRange(); 6982 return None; 6983 } 6984 6985 // The VariantRef must point to function. 6986 auto *DRE = dyn_cast<DeclRefExpr>(ER.get()->IgnoreParenImpCasts()); 6987 if (!DRE) { 6988 Diag(VariantRef->getExprLoc(), diag::err_omp_function_expected) 6989 << VariantId << VariantRef->getSourceRange(); 6990 return None; 6991 } 6992 auto *NewFD = dyn_cast_or_null<FunctionDecl>(DRE->getDecl()); 6993 if (!NewFD) { 6994 Diag(VariantRef->getExprLoc(), diag::err_omp_function_expected) 6995 << VariantId << VariantRef->getSourceRange(); 6996 return None; 6997 } 6998 6999 // Check if function types are compatible in C. 7000 if (!LangOpts.CPlusPlus) { 7001 QualType NewType = 7002 Context.mergeFunctionTypes(FD->getType(), NewFD->getType()); 7003 if (NewType.isNull()) { 7004 Diag(VariantRef->getExprLoc(), 7005 diag::err_omp_declare_variant_incompat_types) 7006 << NewFD->getType() << FD->getType() << VariantRef->getSourceRange(); 7007 return None; 7008 } 7009 if (NewType->isFunctionProtoType()) { 7010 if (FD->getType()->isFunctionNoProtoType()) 7011 setPrototype(*this, FD, NewFD, NewType); 7012 else if (NewFD->getType()->isFunctionNoProtoType()) 7013 setPrototype(*this, NewFD, FD, NewType); 7014 } 7015 } 7016 7017 // Check if variant function is not marked with declare variant directive. 7018 if (NewFD->hasAttrs() && NewFD->hasAttr<OMPDeclareVariantAttr>()) { 7019 Diag(VariantRef->getExprLoc(), 7020 diag::warn_omp_declare_variant_marked_as_declare_variant) 7021 << VariantRef->getSourceRange(); 7022 SourceRange SR = 7023 NewFD->specific_attr_begin<OMPDeclareVariantAttr>()->getRange(); 7024 Diag(SR.getBegin(), diag::note_omp_marked_declare_variant_here) << SR; 7025 return None; 7026 } 7027 7028 enum DoesntSupport { 7029 VirtFuncs = 1, 7030 Constructors = 3, 7031 Destructors = 4, 7032 DeletedFuncs = 5, 7033 DefaultedFuncs = 6, 7034 ConstexprFuncs = 7, 7035 ConstevalFuncs = 8, 7036 }; 7037 if (const auto *CXXFD = dyn_cast<CXXMethodDecl>(FD)) { 7038 if (CXXFD->isVirtual()) { 7039 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support) 7040 << VirtFuncs; 7041 return None; 7042 } 7043 7044 if (isa<CXXConstructorDecl>(FD)) { 7045 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support) 7046 << Constructors; 7047 return None; 7048 } 7049 7050 if (isa<CXXDestructorDecl>(FD)) { 7051 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support) 7052 << Destructors; 7053 return None; 7054 } 7055 } 7056 7057 if (FD->isDeleted()) { 7058 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support) 7059 << DeletedFuncs; 7060 return None; 7061 } 7062 7063 if (FD->isDefaulted()) { 7064 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support) 7065 << DefaultedFuncs; 7066 return None; 7067 } 7068 7069 if (FD->isConstexpr()) { 7070 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support) 7071 << (NewFD->isConsteval() ? ConstevalFuncs : ConstexprFuncs); 7072 return None; 7073 } 7074 7075 // Check general compatibility. 7076 if (areMultiversionVariantFunctionsCompatible( 7077 FD, NewFD, PartialDiagnostic::NullDiagnostic(), 7078 PartialDiagnosticAt(SourceLocation(), 7079 PartialDiagnostic::NullDiagnostic()), 7080 PartialDiagnosticAt( 7081 VariantRef->getExprLoc(), 7082 PDiag(diag::err_omp_declare_variant_doesnt_support)), 7083 PartialDiagnosticAt(VariantRef->getExprLoc(), 7084 PDiag(diag::err_omp_declare_variant_diff) 7085 << FD->getLocation()), 7086 /*TemplatesSupported=*/true, /*ConstexprSupported=*/false, 7087 /*CLinkageMayDiffer=*/true)) 7088 return None; 7089 return std::make_pair(FD, cast<Expr>(DRE)); 7090 } 7091 7092 void Sema::ActOnOpenMPDeclareVariantDirective(FunctionDecl *FD, 7093 Expr *VariantRef, 7094 OMPTraitInfo &TI, 7095 SourceRange SR) { 7096 auto *NewAttr = 7097 OMPDeclareVariantAttr::CreateImplicit(Context, VariantRef, &TI, SR); 7098 FD->addAttr(NewAttr); 7099 } 7100 7101 StmtResult Sema::ActOnOpenMPParallelDirective(ArrayRef<OMPClause *> Clauses, 7102 Stmt *AStmt, 7103 SourceLocation StartLoc, 7104 SourceLocation EndLoc) { 7105 if (!AStmt) 7106 return StmtError(); 7107 7108 auto *CS = cast<CapturedStmt>(AStmt); 7109 // 1.2.2 OpenMP Language Terminology 7110 // Structured block - An executable statement with a single entry at the 7111 // top and a single exit at the bottom. 7112 // The point of exit cannot be a branch out of the structured block. 7113 // longjmp() and throw() must not violate the entry/exit criteria. 7114 CS->getCapturedDecl()->setNothrow(); 7115 7116 setFunctionHasBranchProtectedScope(); 7117 7118 return OMPParallelDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt, 7119 DSAStack->getTaskgroupReductionRef(), 7120 DSAStack->isCancelRegion()); 7121 } 7122 7123 namespace { 7124 /// Iteration space of a single for loop. 7125 struct LoopIterationSpace final { 7126 /// True if the condition operator is the strict compare operator (<, > or 7127 /// !=). 7128 bool IsStrictCompare = false; 7129 /// Condition of the loop. 7130 Expr *PreCond = nullptr; 7131 /// This expression calculates the number of iterations in the loop. 7132 /// It is always possible to calculate it before starting the loop. 7133 Expr *NumIterations = nullptr; 7134 /// The loop counter variable. 7135 Expr *CounterVar = nullptr; 7136 /// Private loop counter variable. 7137 Expr *PrivateCounterVar = nullptr; 7138 /// This is initializer for the initial value of #CounterVar. 7139 Expr *CounterInit = nullptr; 7140 /// This is step for the #CounterVar used to generate its update: 7141 /// #CounterVar = #CounterInit + #CounterStep * CurrentIteration. 7142 Expr *CounterStep = nullptr; 7143 /// Should step be subtracted? 7144 bool Subtract = false; 7145 /// Source range of the loop init. 7146 SourceRange InitSrcRange; 7147 /// Source range of the loop condition. 7148 SourceRange CondSrcRange; 7149 /// Source range of the loop increment. 7150 SourceRange IncSrcRange; 7151 /// Minimum value that can have the loop control variable. Used to support 7152 /// non-rectangular loops. Applied only for LCV with the non-iterator types, 7153 /// since only such variables can be used in non-loop invariant expressions. 7154 Expr *MinValue = nullptr; 7155 /// Maximum value that can have the loop control variable. Used to support 7156 /// non-rectangular loops. Applied only for LCV with the non-iterator type, 7157 /// since only such variables can be used in non-loop invariant expressions. 7158 Expr *MaxValue = nullptr; 7159 /// true, if the lower bound depends on the outer loop control var. 7160 bool IsNonRectangularLB = false; 7161 /// true, if the upper bound depends on the outer loop control var. 7162 bool IsNonRectangularUB = false; 7163 /// Index of the loop this loop depends on and forms non-rectangular loop 7164 /// nest. 7165 unsigned LoopDependentIdx = 0; 7166 /// Final condition for the non-rectangular loop nest support. It is used to 7167 /// check that the number of iterations for this particular counter must be 7168 /// finished. 7169 Expr *FinalCondition = nullptr; 7170 }; 7171 7172 /// Helper class for checking canonical form of the OpenMP loops and 7173 /// extracting iteration space of each loop in the loop nest, that will be used 7174 /// for IR generation. 7175 class OpenMPIterationSpaceChecker { 7176 /// Reference to Sema. 7177 Sema &SemaRef; 7178 /// Does the loop associated directive support non-rectangular loops? 7179 bool SupportsNonRectangular; 7180 /// Data-sharing stack. 7181 DSAStackTy &Stack; 7182 /// A location for diagnostics (when there is no some better location). 7183 SourceLocation DefaultLoc; 7184 /// A location for diagnostics (when increment is not compatible). 7185 SourceLocation ConditionLoc; 7186 /// A source location for referring to loop init later. 7187 SourceRange InitSrcRange; 7188 /// A source location for referring to condition later. 7189 SourceRange ConditionSrcRange; 7190 /// A source location for referring to increment later. 7191 SourceRange IncrementSrcRange; 7192 /// Loop variable. 7193 ValueDecl *LCDecl = nullptr; 7194 /// Reference to loop variable. 7195 Expr *LCRef = nullptr; 7196 /// Lower bound (initializer for the var). 7197 Expr *LB = nullptr; 7198 /// Upper bound. 7199 Expr *UB = nullptr; 7200 /// Loop step (increment). 7201 Expr *Step = nullptr; 7202 /// This flag is true when condition is one of: 7203 /// Var < UB 7204 /// Var <= UB 7205 /// UB > Var 7206 /// UB >= Var 7207 /// This will have no value when the condition is != 7208 llvm::Optional<bool> TestIsLessOp; 7209 /// This flag is true when condition is strict ( < or > ). 7210 bool TestIsStrictOp = false; 7211 /// This flag is true when step is subtracted on each iteration. 7212 bool SubtractStep = false; 7213 /// The outer loop counter this loop depends on (if any). 7214 const ValueDecl *DepDecl = nullptr; 7215 /// Contains number of loop (starts from 1) on which loop counter init 7216 /// expression of this loop depends on. 7217 Optional<unsigned> InitDependOnLC; 7218 /// Contains number of loop (starts from 1) on which loop counter condition 7219 /// expression of this loop depends on. 7220 Optional<unsigned> CondDependOnLC; 7221 /// Checks if the provide statement depends on the loop counter. 7222 Optional<unsigned> doesDependOnLoopCounter(const Stmt *S, bool IsInitializer); 7223 /// Original condition required for checking of the exit condition for 7224 /// non-rectangular loop. 7225 Expr *Condition = nullptr; 7226 7227 public: 7228 OpenMPIterationSpaceChecker(Sema &SemaRef, bool SupportsNonRectangular, 7229 DSAStackTy &Stack, SourceLocation DefaultLoc) 7230 : SemaRef(SemaRef), SupportsNonRectangular(SupportsNonRectangular), 7231 Stack(Stack), DefaultLoc(DefaultLoc), ConditionLoc(DefaultLoc) {} 7232 /// Check init-expr for canonical loop form and save loop counter 7233 /// variable - #Var and its initialization value - #LB. 7234 bool checkAndSetInit(Stmt *S, bool EmitDiags = true); 7235 /// Check test-expr for canonical form, save upper-bound (#UB), flags 7236 /// for less/greater and for strict/non-strict comparison. 7237 bool checkAndSetCond(Expr *S); 7238 /// Check incr-expr for canonical loop form and return true if it 7239 /// does not conform, otherwise save loop step (#Step). 7240 bool checkAndSetInc(Expr *S); 7241 /// Return the loop counter variable. 7242 ValueDecl *getLoopDecl() const { return LCDecl; } 7243 /// Return the reference expression to loop counter variable. 7244 Expr *getLoopDeclRefExpr() const { return LCRef; } 7245 /// Source range of the loop init. 7246 SourceRange getInitSrcRange() const { return InitSrcRange; } 7247 /// Source range of the loop condition. 7248 SourceRange getConditionSrcRange() const { return ConditionSrcRange; } 7249 /// Source range of the loop increment. 7250 SourceRange getIncrementSrcRange() const { return IncrementSrcRange; } 7251 /// True if the step should be subtracted. 7252 bool shouldSubtractStep() const { return SubtractStep; } 7253 /// True, if the compare operator is strict (<, > or !=). 7254 bool isStrictTestOp() const { return TestIsStrictOp; } 7255 /// Build the expression to calculate the number of iterations. 7256 Expr *buildNumIterations( 7257 Scope *S, ArrayRef<LoopIterationSpace> ResultIterSpaces, bool LimitedType, 7258 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const; 7259 /// Build the precondition expression for the loops. 7260 Expr * 7261 buildPreCond(Scope *S, Expr *Cond, 7262 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const; 7263 /// Build reference expression to the counter be used for codegen. 7264 DeclRefExpr * 7265 buildCounterVar(llvm::MapVector<const Expr *, DeclRefExpr *> &Captures, 7266 DSAStackTy &DSA) const; 7267 /// Build reference expression to the private counter be used for 7268 /// codegen. 7269 Expr *buildPrivateCounterVar() const; 7270 /// Build initialization of the counter be used for codegen. 7271 Expr *buildCounterInit() const; 7272 /// Build step of the counter be used for codegen. 7273 Expr *buildCounterStep() const; 7274 /// Build loop data with counter value for depend clauses in ordered 7275 /// directives. 7276 Expr * 7277 buildOrderedLoopData(Scope *S, Expr *Counter, 7278 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures, 7279 SourceLocation Loc, Expr *Inc = nullptr, 7280 OverloadedOperatorKind OOK = OO_Amp); 7281 /// Builds the minimum value for the loop counter. 7282 std::pair<Expr *, Expr *> buildMinMaxValues( 7283 Scope *S, llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const; 7284 /// Builds final condition for the non-rectangular loops. 7285 Expr *buildFinalCondition(Scope *S) const; 7286 /// Return true if any expression is dependent. 7287 bool dependent() const; 7288 /// Returns true if the initializer forms non-rectangular loop. 7289 bool doesInitDependOnLC() const { return InitDependOnLC.hasValue(); } 7290 /// Returns true if the condition forms non-rectangular loop. 7291 bool doesCondDependOnLC() const { return CondDependOnLC.hasValue(); } 7292 /// Returns index of the loop we depend on (starting from 1), or 0 otherwise. 7293 unsigned getLoopDependentIdx() const { 7294 return InitDependOnLC.getValueOr(CondDependOnLC.getValueOr(0)); 7295 } 7296 7297 private: 7298 /// Check the right-hand side of an assignment in the increment 7299 /// expression. 7300 bool checkAndSetIncRHS(Expr *RHS); 7301 /// Helper to set loop counter variable and its initializer. 7302 bool setLCDeclAndLB(ValueDecl *NewLCDecl, Expr *NewDeclRefExpr, Expr *NewLB, 7303 bool EmitDiags); 7304 /// Helper to set upper bound. 7305 bool setUB(Expr *NewUB, llvm::Optional<bool> LessOp, bool StrictOp, 7306 SourceRange SR, SourceLocation SL); 7307 /// Helper to set loop increment. 7308 bool setStep(Expr *NewStep, bool Subtract); 7309 }; 7310 7311 bool OpenMPIterationSpaceChecker::dependent() const { 7312 if (!LCDecl) { 7313 assert(!LB && !UB && !Step); 7314 return false; 7315 } 7316 return LCDecl->getType()->isDependentType() || 7317 (LB && LB->isValueDependent()) || (UB && UB->isValueDependent()) || 7318 (Step && Step->isValueDependent()); 7319 } 7320 7321 bool OpenMPIterationSpaceChecker::setLCDeclAndLB(ValueDecl *NewLCDecl, 7322 Expr *NewLCRefExpr, 7323 Expr *NewLB, bool EmitDiags) { 7324 // State consistency checking to ensure correct usage. 7325 assert(LCDecl == nullptr && LB == nullptr && LCRef == nullptr && 7326 UB == nullptr && Step == nullptr && !TestIsLessOp && !TestIsStrictOp); 7327 if (!NewLCDecl || !NewLB) 7328 return true; 7329 LCDecl = getCanonicalDecl(NewLCDecl); 7330 LCRef = NewLCRefExpr; 7331 if (auto *CE = dyn_cast_or_null<CXXConstructExpr>(NewLB)) 7332 if (const CXXConstructorDecl *Ctor = CE->getConstructor()) 7333 if ((Ctor->isCopyOrMoveConstructor() || 7334 Ctor->isConvertingConstructor(/*AllowExplicit=*/false)) && 7335 CE->getNumArgs() > 0 && CE->getArg(0) != nullptr) 7336 NewLB = CE->getArg(0)->IgnoreParenImpCasts(); 7337 LB = NewLB; 7338 if (EmitDiags) 7339 InitDependOnLC = doesDependOnLoopCounter(LB, /*IsInitializer=*/true); 7340 return false; 7341 } 7342 7343 bool OpenMPIterationSpaceChecker::setUB(Expr *NewUB, 7344 llvm::Optional<bool> LessOp, 7345 bool StrictOp, SourceRange SR, 7346 SourceLocation SL) { 7347 // State consistency checking to ensure correct usage. 7348 assert(LCDecl != nullptr && LB != nullptr && UB == nullptr && 7349 Step == nullptr && !TestIsLessOp && !TestIsStrictOp); 7350 if (!NewUB) 7351 return true; 7352 UB = NewUB; 7353 if (LessOp) 7354 TestIsLessOp = LessOp; 7355 TestIsStrictOp = StrictOp; 7356 ConditionSrcRange = SR; 7357 ConditionLoc = SL; 7358 CondDependOnLC = doesDependOnLoopCounter(UB, /*IsInitializer=*/false); 7359 return false; 7360 } 7361 7362 bool OpenMPIterationSpaceChecker::setStep(Expr *NewStep, bool Subtract) { 7363 // State consistency checking to ensure correct usage. 7364 assert(LCDecl != nullptr && LB != nullptr && Step == nullptr); 7365 if (!NewStep) 7366 return true; 7367 if (!NewStep->isValueDependent()) { 7368 // Check that the step is integer expression. 7369 SourceLocation StepLoc = NewStep->getBeginLoc(); 7370 ExprResult Val = SemaRef.PerformOpenMPImplicitIntegerConversion( 7371 StepLoc, getExprAsWritten(NewStep)); 7372 if (Val.isInvalid()) 7373 return true; 7374 NewStep = Val.get(); 7375 7376 // OpenMP [2.6, Canonical Loop Form, Restrictions] 7377 // If test-expr is of form var relational-op b and relational-op is < or 7378 // <= then incr-expr must cause var to increase on each iteration of the 7379 // loop. If test-expr is of form var relational-op b and relational-op is 7380 // > or >= then incr-expr must cause var to decrease on each iteration of 7381 // the loop. 7382 // If test-expr is of form b relational-op var and relational-op is < or 7383 // <= then incr-expr must cause var to decrease on each iteration of the 7384 // loop. If test-expr is of form b relational-op var and relational-op is 7385 // > or >= then incr-expr must cause var to increase on each iteration of 7386 // the loop. 7387 Optional<llvm::APSInt> Result = 7388 NewStep->getIntegerConstantExpr(SemaRef.Context); 7389 bool IsUnsigned = !NewStep->getType()->hasSignedIntegerRepresentation(); 7390 bool IsConstNeg = 7391 Result && Result->isSigned() && (Subtract != Result->isNegative()); 7392 bool IsConstPos = 7393 Result && Result->isSigned() && (Subtract == Result->isNegative()); 7394 bool IsConstZero = Result && !Result->getBoolValue(); 7395 7396 // != with increment is treated as <; != with decrement is treated as > 7397 if (!TestIsLessOp.hasValue()) 7398 TestIsLessOp = IsConstPos || (IsUnsigned && !Subtract); 7399 if (UB && (IsConstZero || 7400 (TestIsLessOp.getValue() ? 7401 (IsConstNeg || (IsUnsigned && Subtract)) : 7402 (IsConstPos || (IsUnsigned && !Subtract))))) { 7403 SemaRef.Diag(NewStep->getExprLoc(), 7404 diag::err_omp_loop_incr_not_compatible) 7405 << LCDecl << TestIsLessOp.getValue() << NewStep->getSourceRange(); 7406 SemaRef.Diag(ConditionLoc, 7407 diag::note_omp_loop_cond_requres_compatible_incr) 7408 << TestIsLessOp.getValue() << ConditionSrcRange; 7409 return true; 7410 } 7411 if (TestIsLessOp.getValue() == Subtract) { 7412 NewStep = 7413 SemaRef.CreateBuiltinUnaryOp(NewStep->getExprLoc(), UO_Minus, NewStep) 7414 .get(); 7415 Subtract = !Subtract; 7416 } 7417 } 7418 7419 Step = NewStep; 7420 SubtractStep = Subtract; 7421 return false; 7422 } 7423 7424 namespace { 7425 /// Checker for the non-rectangular loops. Checks if the initializer or 7426 /// condition expression references loop counter variable. 7427 class LoopCounterRefChecker final 7428 : public ConstStmtVisitor<LoopCounterRefChecker, bool> { 7429 Sema &SemaRef; 7430 DSAStackTy &Stack; 7431 const ValueDecl *CurLCDecl = nullptr; 7432 const ValueDecl *DepDecl = nullptr; 7433 const ValueDecl *PrevDepDecl = nullptr; 7434 bool IsInitializer = true; 7435 bool SupportsNonRectangular; 7436 unsigned BaseLoopId = 0; 7437 bool checkDecl(const Expr *E, const ValueDecl *VD) { 7438 if (getCanonicalDecl(VD) == getCanonicalDecl(CurLCDecl)) { 7439 SemaRef.Diag(E->getExprLoc(), diag::err_omp_stmt_depends_on_loop_counter) 7440 << (IsInitializer ? 0 : 1); 7441 return false; 7442 } 7443 const auto &&Data = Stack.isLoopControlVariable(VD); 7444 // OpenMP, 2.9.1 Canonical Loop Form, Restrictions. 7445 // The type of the loop iterator on which we depend may not have a random 7446 // access iterator type. 7447 if (Data.first && VD->getType()->isRecordType()) { 7448 SmallString<128> Name; 7449 llvm::raw_svector_ostream OS(Name); 7450 VD->getNameForDiagnostic(OS, SemaRef.getPrintingPolicy(), 7451 /*Qualified=*/true); 7452 SemaRef.Diag(E->getExprLoc(), 7453 diag::err_omp_wrong_dependency_iterator_type) 7454 << OS.str(); 7455 SemaRef.Diag(VD->getLocation(), diag::note_previous_decl) << VD; 7456 return false; 7457 } 7458 if (Data.first && !SupportsNonRectangular) { 7459 SemaRef.Diag(E->getExprLoc(), diag::err_omp_invariant_dependency); 7460 return false; 7461 } 7462 if (Data.first && 7463 (DepDecl || (PrevDepDecl && 7464 getCanonicalDecl(VD) != getCanonicalDecl(PrevDepDecl)))) { 7465 if (!DepDecl && PrevDepDecl) 7466 DepDecl = PrevDepDecl; 7467 SmallString<128> Name; 7468 llvm::raw_svector_ostream OS(Name); 7469 DepDecl->getNameForDiagnostic(OS, SemaRef.getPrintingPolicy(), 7470 /*Qualified=*/true); 7471 SemaRef.Diag(E->getExprLoc(), 7472 diag::err_omp_invariant_or_linear_dependency) 7473 << OS.str(); 7474 return false; 7475 } 7476 if (Data.first) { 7477 DepDecl = VD; 7478 BaseLoopId = Data.first; 7479 } 7480 return Data.first; 7481 } 7482 7483 public: 7484 bool VisitDeclRefExpr(const DeclRefExpr *E) { 7485 const ValueDecl *VD = E->getDecl(); 7486 if (isa<VarDecl>(VD)) 7487 return checkDecl(E, VD); 7488 return false; 7489 } 7490 bool VisitMemberExpr(const MemberExpr *E) { 7491 if (isa<CXXThisExpr>(E->getBase()->IgnoreParens())) { 7492 const ValueDecl *VD = E->getMemberDecl(); 7493 if (isa<VarDecl>(VD) || isa<FieldDecl>(VD)) 7494 return checkDecl(E, VD); 7495 } 7496 return false; 7497 } 7498 bool VisitStmt(const Stmt *S) { 7499 bool Res = false; 7500 for (const Stmt *Child : S->children()) 7501 Res = (Child && Visit(Child)) || Res; 7502 return Res; 7503 } 7504 explicit LoopCounterRefChecker(Sema &SemaRef, DSAStackTy &Stack, 7505 const ValueDecl *CurLCDecl, bool IsInitializer, 7506 const ValueDecl *PrevDepDecl = nullptr, 7507 bool SupportsNonRectangular = true) 7508 : SemaRef(SemaRef), Stack(Stack), CurLCDecl(CurLCDecl), 7509 PrevDepDecl(PrevDepDecl), IsInitializer(IsInitializer), 7510 SupportsNonRectangular(SupportsNonRectangular) {} 7511 unsigned getBaseLoopId() const { 7512 assert(CurLCDecl && "Expected loop dependency."); 7513 return BaseLoopId; 7514 } 7515 const ValueDecl *getDepDecl() const { 7516 assert(CurLCDecl && "Expected loop dependency."); 7517 return DepDecl; 7518 } 7519 }; 7520 } // namespace 7521 7522 Optional<unsigned> 7523 OpenMPIterationSpaceChecker::doesDependOnLoopCounter(const Stmt *S, 7524 bool IsInitializer) { 7525 // Check for the non-rectangular loops. 7526 LoopCounterRefChecker LoopStmtChecker(SemaRef, Stack, LCDecl, IsInitializer, 7527 DepDecl, SupportsNonRectangular); 7528 if (LoopStmtChecker.Visit(S)) { 7529 DepDecl = LoopStmtChecker.getDepDecl(); 7530 return LoopStmtChecker.getBaseLoopId(); 7531 } 7532 return llvm::None; 7533 } 7534 7535 bool OpenMPIterationSpaceChecker::checkAndSetInit(Stmt *S, bool EmitDiags) { 7536 // Check init-expr for canonical loop form and save loop counter 7537 // variable - #Var and its initialization value - #LB. 7538 // OpenMP [2.6] Canonical loop form. init-expr may be one of the following: 7539 // var = lb 7540 // integer-type var = lb 7541 // random-access-iterator-type var = lb 7542 // pointer-type var = lb 7543 // 7544 if (!S) { 7545 if (EmitDiags) { 7546 SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_init); 7547 } 7548 return true; 7549 } 7550 if (auto *ExprTemp = dyn_cast<ExprWithCleanups>(S)) 7551 if (!ExprTemp->cleanupsHaveSideEffects()) 7552 S = ExprTemp->getSubExpr(); 7553 7554 InitSrcRange = S->getSourceRange(); 7555 if (Expr *E = dyn_cast<Expr>(S)) 7556 S = E->IgnoreParens(); 7557 if (auto *BO = dyn_cast<BinaryOperator>(S)) { 7558 if (BO->getOpcode() == BO_Assign) { 7559 Expr *LHS = BO->getLHS()->IgnoreParens(); 7560 if (auto *DRE = dyn_cast<DeclRefExpr>(LHS)) { 7561 if (auto *CED = dyn_cast<OMPCapturedExprDecl>(DRE->getDecl())) 7562 if (auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit()))) 7563 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(), 7564 EmitDiags); 7565 return setLCDeclAndLB(DRE->getDecl(), DRE, BO->getRHS(), EmitDiags); 7566 } 7567 if (auto *ME = dyn_cast<MemberExpr>(LHS)) { 7568 if (ME->isArrow() && 7569 isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts())) 7570 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(), 7571 EmitDiags); 7572 } 7573 } 7574 } else if (auto *DS = dyn_cast<DeclStmt>(S)) { 7575 if (DS->isSingleDecl()) { 7576 if (auto *Var = dyn_cast_or_null<VarDecl>(DS->getSingleDecl())) { 7577 if (Var->hasInit() && !Var->getType()->isReferenceType()) { 7578 // Accept non-canonical init form here but emit ext. warning. 7579 if (Var->getInitStyle() != VarDecl::CInit && EmitDiags) 7580 SemaRef.Diag(S->getBeginLoc(), 7581 diag::ext_omp_loop_not_canonical_init) 7582 << S->getSourceRange(); 7583 return setLCDeclAndLB( 7584 Var, 7585 buildDeclRefExpr(SemaRef, Var, 7586 Var->getType().getNonReferenceType(), 7587 DS->getBeginLoc()), 7588 Var->getInit(), EmitDiags); 7589 } 7590 } 7591 } 7592 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) { 7593 if (CE->getOperator() == OO_Equal) { 7594 Expr *LHS = CE->getArg(0); 7595 if (auto *DRE = dyn_cast<DeclRefExpr>(LHS)) { 7596 if (auto *CED = dyn_cast<OMPCapturedExprDecl>(DRE->getDecl())) 7597 if (auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit()))) 7598 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(), 7599 EmitDiags); 7600 return setLCDeclAndLB(DRE->getDecl(), DRE, CE->getArg(1), EmitDiags); 7601 } 7602 if (auto *ME = dyn_cast<MemberExpr>(LHS)) { 7603 if (ME->isArrow() && 7604 isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts())) 7605 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(), 7606 EmitDiags); 7607 } 7608 } 7609 } 7610 7611 if (dependent() || SemaRef.CurContext->isDependentContext()) 7612 return false; 7613 if (EmitDiags) { 7614 SemaRef.Diag(S->getBeginLoc(), diag::err_omp_loop_not_canonical_init) 7615 << S->getSourceRange(); 7616 } 7617 return true; 7618 } 7619 7620 /// Ignore parenthesizes, implicit casts, copy constructor and return the 7621 /// variable (which may be the loop variable) if possible. 7622 static const ValueDecl *getInitLCDecl(const Expr *E) { 7623 if (!E) 7624 return nullptr; 7625 E = getExprAsWritten(E); 7626 if (const auto *CE = dyn_cast_or_null<CXXConstructExpr>(E)) 7627 if (const CXXConstructorDecl *Ctor = CE->getConstructor()) 7628 if ((Ctor->isCopyOrMoveConstructor() || 7629 Ctor->isConvertingConstructor(/*AllowExplicit=*/false)) && 7630 CE->getNumArgs() > 0 && CE->getArg(0) != nullptr) 7631 E = CE->getArg(0)->IgnoreParenImpCasts(); 7632 if (const auto *DRE = dyn_cast_or_null<DeclRefExpr>(E)) { 7633 if (const auto *VD = dyn_cast<VarDecl>(DRE->getDecl())) 7634 return getCanonicalDecl(VD); 7635 } 7636 if (const auto *ME = dyn_cast_or_null<MemberExpr>(E)) 7637 if (ME->isArrow() && isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts())) 7638 return getCanonicalDecl(ME->getMemberDecl()); 7639 return nullptr; 7640 } 7641 7642 bool OpenMPIterationSpaceChecker::checkAndSetCond(Expr *S) { 7643 // Check test-expr for canonical form, save upper-bound UB, flags for 7644 // less/greater and for strict/non-strict comparison. 7645 // OpenMP [2.9] Canonical loop form. Test-expr may be one of the following: 7646 // var relational-op b 7647 // b relational-op var 7648 // 7649 bool IneqCondIsCanonical = SemaRef.getLangOpts().OpenMP >= 50; 7650 if (!S) { 7651 SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_cond) 7652 << (IneqCondIsCanonical ? 1 : 0) << LCDecl; 7653 return true; 7654 } 7655 Condition = S; 7656 S = getExprAsWritten(S); 7657 SourceLocation CondLoc = S->getBeginLoc(); 7658 if (auto *BO = dyn_cast<BinaryOperator>(S)) { 7659 if (BO->isRelationalOp()) { 7660 if (getInitLCDecl(BO->getLHS()) == LCDecl) 7661 return setUB(BO->getRHS(), 7662 (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_LE), 7663 (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_GT), 7664 BO->getSourceRange(), BO->getOperatorLoc()); 7665 if (getInitLCDecl(BO->getRHS()) == LCDecl) 7666 return setUB(BO->getLHS(), 7667 (BO->getOpcode() == BO_GT || BO->getOpcode() == BO_GE), 7668 (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_GT), 7669 BO->getSourceRange(), BO->getOperatorLoc()); 7670 } else if (IneqCondIsCanonical && BO->getOpcode() == BO_NE) 7671 return setUB( 7672 getInitLCDecl(BO->getLHS()) == LCDecl ? BO->getRHS() : BO->getLHS(), 7673 /*LessOp=*/llvm::None, 7674 /*StrictOp=*/true, BO->getSourceRange(), BO->getOperatorLoc()); 7675 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) { 7676 if (CE->getNumArgs() == 2) { 7677 auto Op = CE->getOperator(); 7678 switch (Op) { 7679 case OO_Greater: 7680 case OO_GreaterEqual: 7681 case OO_Less: 7682 case OO_LessEqual: 7683 if (getInitLCDecl(CE->getArg(0)) == LCDecl) 7684 return setUB(CE->getArg(1), Op == OO_Less || Op == OO_LessEqual, 7685 Op == OO_Less || Op == OO_Greater, CE->getSourceRange(), 7686 CE->getOperatorLoc()); 7687 if (getInitLCDecl(CE->getArg(1)) == LCDecl) 7688 return setUB(CE->getArg(0), Op == OO_Greater || Op == OO_GreaterEqual, 7689 Op == OO_Less || Op == OO_Greater, CE->getSourceRange(), 7690 CE->getOperatorLoc()); 7691 break; 7692 case OO_ExclaimEqual: 7693 if (IneqCondIsCanonical) 7694 return setUB(getInitLCDecl(CE->getArg(0)) == LCDecl ? CE->getArg(1) 7695 : CE->getArg(0), 7696 /*LessOp=*/llvm::None, 7697 /*StrictOp=*/true, CE->getSourceRange(), 7698 CE->getOperatorLoc()); 7699 break; 7700 default: 7701 break; 7702 } 7703 } 7704 } 7705 if (dependent() || SemaRef.CurContext->isDependentContext()) 7706 return false; 7707 SemaRef.Diag(CondLoc, diag::err_omp_loop_not_canonical_cond) 7708 << (IneqCondIsCanonical ? 1 : 0) << S->getSourceRange() << LCDecl; 7709 return true; 7710 } 7711 7712 bool OpenMPIterationSpaceChecker::checkAndSetIncRHS(Expr *RHS) { 7713 // RHS of canonical loop form increment can be: 7714 // var + incr 7715 // incr + var 7716 // var - incr 7717 // 7718 RHS = RHS->IgnoreParenImpCasts(); 7719 if (auto *BO = dyn_cast<BinaryOperator>(RHS)) { 7720 if (BO->isAdditiveOp()) { 7721 bool IsAdd = BO->getOpcode() == BO_Add; 7722 if (getInitLCDecl(BO->getLHS()) == LCDecl) 7723 return setStep(BO->getRHS(), !IsAdd); 7724 if (IsAdd && getInitLCDecl(BO->getRHS()) == LCDecl) 7725 return setStep(BO->getLHS(), /*Subtract=*/false); 7726 } 7727 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(RHS)) { 7728 bool IsAdd = CE->getOperator() == OO_Plus; 7729 if ((IsAdd || CE->getOperator() == OO_Minus) && CE->getNumArgs() == 2) { 7730 if (getInitLCDecl(CE->getArg(0)) == LCDecl) 7731 return setStep(CE->getArg(1), !IsAdd); 7732 if (IsAdd && getInitLCDecl(CE->getArg(1)) == LCDecl) 7733 return setStep(CE->getArg(0), /*Subtract=*/false); 7734 } 7735 } 7736 if (dependent() || SemaRef.CurContext->isDependentContext()) 7737 return false; 7738 SemaRef.Diag(RHS->getBeginLoc(), diag::err_omp_loop_not_canonical_incr) 7739 << RHS->getSourceRange() << LCDecl; 7740 return true; 7741 } 7742 7743 bool OpenMPIterationSpaceChecker::checkAndSetInc(Expr *S) { 7744 // Check incr-expr for canonical loop form and return true if it 7745 // does not conform. 7746 // OpenMP [2.6] Canonical loop form. Test-expr may be one of the following: 7747 // ++var 7748 // var++ 7749 // --var 7750 // var-- 7751 // var += incr 7752 // var -= incr 7753 // var = var + incr 7754 // var = incr + var 7755 // var = var - incr 7756 // 7757 if (!S) { 7758 SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_incr) << LCDecl; 7759 return true; 7760 } 7761 if (auto *ExprTemp = dyn_cast<ExprWithCleanups>(S)) 7762 if (!ExprTemp->cleanupsHaveSideEffects()) 7763 S = ExprTemp->getSubExpr(); 7764 7765 IncrementSrcRange = S->getSourceRange(); 7766 S = S->IgnoreParens(); 7767 if (auto *UO = dyn_cast<UnaryOperator>(S)) { 7768 if (UO->isIncrementDecrementOp() && 7769 getInitLCDecl(UO->getSubExpr()) == LCDecl) 7770 return setStep(SemaRef 7771 .ActOnIntegerConstant(UO->getBeginLoc(), 7772 (UO->isDecrementOp() ? -1 : 1)) 7773 .get(), 7774 /*Subtract=*/false); 7775 } else if (auto *BO = dyn_cast<BinaryOperator>(S)) { 7776 switch (BO->getOpcode()) { 7777 case BO_AddAssign: 7778 case BO_SubAssign: 7779 if (getInitLCDecl(BO->getLHS()) == LCDecl) 7780 return setStep(BO->getRHS(), BO->getOpcode() == BO_SubAssign); 7781 break; 7782 case BO_Assign: 7783 if (getInitLCDecl(BO->getLHS()) == LCDecl) 7784 return checkAndSetIncRHS(BO->getRHS()); 7785 break; 7786 default: 7787 break; 7788 } 7789 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) { 7790 switch (CE->getOperator()) { 7791 case OO_PlusPlus: 7792 case OO_MinusMinus: 7793 if (getInitLCDecl(CE->getArg(0)) == LCDecl) 7794 return setStep(SemaRef 7795 .ActOnIntegerConstant( 7796 CE->getBeginLoc(), 7797 ((CE->getOperator() == OO_MinusMinus) ? -1 : 1)) 7798 .get(), 7799 /*Subtract=*/false); 7800 break; 7801 case OO_PlusEqual: 7802 case OO_MinusEqual: 7803 if (getInitLCDecl(CE->getArg(0)) == LCDecl) 7804 return setStep(CE->getArg(1), CE->getOperator() == OO_MinusEqual); 7805 break; 7806 case OO_Equal: 7807 if (getInitLCDecl(CE->getArg(0)) == LCDecl) 7808 return checkAndSetIncRHS(CE->getArg(1)); 7809 break; 7810 default: 7811 break; 7812 } 7813 } 7814 if (dependent() || SemaRef.CurContext->isDependentContext()) 7815 return false; 7816 SemaRef.Diag(S->getBeginLoc(), diag::err_omp_loop_not_canonical_incr) 7817 << S->getSourceRange() << LCDecl; 7818 return true; 7819 } 7820 7821 static ExprResult 7822 tryBuildCapture(Sema &SemaRef, Expr *Capture, 7823 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) { 7824 if (SemaRef.CurContext->isDependentContext() || Capture->containsErrors()) 7825 return Capture; 7826 if (Capture->isEvaluatable(SemaRef.Context, Expr::SE_AllowSideEffects)) 7827 return SemaRef.PerformImplicitConversion( 7828 Capture->IgnoreImpCasts(), Capture->getType(), Sema::AA_Converting, 7829 /*AllowExplicit=*/true); 7830 auto I = Captures.find(Capture); 7831 if (I != Captures.end()) 7832 return buildCapture(SemaRef, Capture, I->second); 7833 DeclRefExpr *Ref = nullptr; 7834 ExprResult Res = buildCapture(SemaRef, Capture, Ref); 7835 Captures[Capture] = Ref; 7836 return Res; 7837 } 7838 7839 /// Calculate number of iterations, transforming to unsigned, if number of 7840 /// iterations may be larger than the original type. 7841 static Expr * 7842 calculateNumIters(Sema &SemaRef, Scope *S, SourceLocation DefaultLoc, 7843 Expr *Lower, Expr *Upper, Expr *Step, QualType LCTy, 7844 bool TestIsStrictOp, bool RoundToStep, 7845 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) { 7846 ExprResult NewStep = tryBuildCapture(SemaRef, Step, Captures); 7847 if (!NewStep.isUsable()) 7848 return nullptr; 7849 llvm::APSInt LRes, SRes; 7850 bool IsLowerConst = false, IsStepConst = false; 7851 if (Optional<llvm::APSInt> Res = Lower->getIntegerConstantExpr(SemaRef.Context)) { 7852 LRes = *Res; 7853 IsLowerConst = true; 7854 } 7855 if (Optional<llvm::APSInt> Res = Step->getIntegerConstantExpr(SemaRef.Context)) { 7856 SRes = *Res; 7857 IsStepConst = true; 7858 } 7859 bool NoNeedToConvert = IsLowerConst && !RoundToStep && 7860 ((!TestIsStrictOp && LRes.isNonNegative()) || 7861 (TestIsStrictOp && LRes.isStrictlyPositive())); 7862 bool NeedToReorganize = false; 7863 // Check if any subexpressions in Lower -Step [+ 1] lead to overflow. 7864 if (!NoNeedToConvert && IsLowerConst && 7865 (TestIsStrictOp || (RoundToStep && IsStepConst))) { 7866 NoNeedToConvert = true; 7867 if (RoundToStep) { 7868 unsigned BW = LRes.getBitWidth() > SRes.getBitWidth() 7869 ? LRes.getBitWidth() 7870 : SRes.getBitWidth(); 7871 LRes = LRes.extend(BW + 1); 7872 LRes.setIsSigned(true); 7873 SRes = SRes.extend(BW + 1); 7874 SRes.setIsSigned(true); 7875 LRes -= SRes; 7876 NoNeedToConvert = LRes.trunc(BW).extend(BW + 1) == LRes; 7877 LRes = LRes.trunc(BW); 7878 } 7879 if (TestIsStrictOp) { 7880 unsigned BW = LRes.getBitWidth(); 7881 LRes = LRes.extend(BW + 1); 7882 LRes.setIsSigned(true); 7883 ++LRes; 7884 NoNeedToConvert = 7885 NoNeedToConvert && LRes.trunc(BW).extend(BW + 1) == LRes; 7886 // truncate to the original bitwidth. 7887 LRes = LRes.trunc(BW); 7888 } 7889 NeedToReorganize = NoNeedToConvert; 7890 } 7891 llvm::APSInt URes; 7892 bool IsUpperConst = false; 7893 if (Optional<llvm::APSInt> Res = Upper->getIntegerConstantExpr(SemaRef.Context)) { 7894 URes = *Res; 7895 IsUpperConst = true; 7896 } 7897 if (NoNeedToConvert && IsLowerConst && IsUpperConst && 7898 (!RoundToStep || IsStepConst)) { 7899 unsigned BW = LRes.getBitWidth() > URes.getBitWidth() ? LRes.getBitWidth() 7900 : URes.getBitWidth(); 7901 LRes = LRes.extend(BW + 1); 7902 LRes.setIsSigned(true); 7903 URes = URes.extend(BW + 1); 7904 URes.setIsSigned(true); 7905 URes -= LRes; 7906 NoNeedToConvert = URes.trunc(BW).extend(BW + 1) == URes; 7907 NeedToReorganize = NoNeedToConvert; 7908 } 7909 // If the boundaries are not constant or (Lower - Step [+ 1]) is not constant 7910 // or less than zero (Upper - (Lower - Step [+ 1]) may overflow) - promote to 7911 // unsigned. 7912 if ((!NoNeedToConvert || (LRes.isNegative() && !IsUpperConst)) && 7913 !LCTy->isDependentType() && LCTy->isIntegerType()) { 7914 QualType LowerTy = Lower->getType(); 7915 QualType UpperTy = Upper->getType(); 7916 uint64_t LowerSize = SemaRef.Context.getTypeSize(LowerTy); 7917 uint64_t UpperSize = SemaRef.Context.getTypeSize(UpperTy); 7918 if ((LowerSize <= UpperSize && UpperTy->hasSignedIntegerRepresentation()) || 7919 (LowerSize > UpperSize && LowerTy->hasSignedIntegerRepresentation())) { 7920 QualType CastType = SemaRef.Context.getIntTypeForBitwidth( 7921 LowerSize > UpperSize ? LowerSize : UpperSize, /*Signed=*/0); 7922 Upper = 7923 SemaRef 7924 .PerformImplicitConversion( 7925 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Upper).get(), 7926 CastType, Sema::AA_Converting) 7927 .get(); 7928 Lower = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Lower).get(); 7929 NewStep = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, NewStep.get()); 7930 } 7931 } 7932 if (!Lower || !Upper || NewStep.isInvalid()) 7933 return nullptr; 7934 7935 ExprResult Diff; 7936 // If need to reorganize, then calculate the form as Upper - (Lower - Step [+ 7937 // 1]). 7938 if (NeedToReorganize) { 7939 Diff = Lower; 7940 7941 if (RoundToStep) { 7942 // Lower - Step 7943 Diff = 7944 SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Diff.get(), NewStep.get()); 7945 if (!Diff.isUsable()) 7946 return nullptr; 7947 } 7948 7949 // Lower - Step [+ 1] 7950 if (TestIsStrictOp) 7951 Diff = SemaRef.BuildBinOp( 7952 S, DefaultLoc, BO_Add, Diff.get(), 7953 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()); 7954 if (!Diff.isUsable()) 7955 return nullptr; 7956 7957 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get()); 7958 if (!Diff.isUsable()) 7959 return nullptr; 7960 7961 // Upper - (Lower - Step [+ 1]). 7962 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Diff.get()); 7963 if (!Diff.isUsable()) 7964 return nullptr; 7965 } else { 7966 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Lower); 7967 7968 if (!Diff.isUsable() && LCTy->getAsCXXRecordDecl()) { 7969 // BuildBinOp already emitted error, this one is to point user to upper 7970 // and lower bound, and to tell what is passed to 'operator-'. 7971 SemaRef.Diag(Upper->getBeginLoc(), diag::err_omp_loop_diff_cxx) 7972 << Upper->getSourceRange() << Lower->getSourceRange(); 7973 return nullptr; 7974 } 7975 7976 if (!Diff.isUsable()) 7977 return nullptr; 7978 7979 // Upper - Lower [- 1] 7980 if (TestIsStrictOp) 7981 Diff = SemaRef.BuildBinOp( 7982 S, DefaultLoc, BO_Sub, Diff.get(), 7983 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()); 7984 if (!Diff.isUsable()) 7985 return nullptr; 7986 7987 if (RoundToStep) { 7988 // Upper - Lower [- 1] + Step 7989 Diff = 7990 SemaRef.BuildBinOp(S, DefaultLoc, BO_Add, Diff.get(), NewStep.get()); 7991 if (!Diff.isUsable()) 7992 return nullptr; 7993 } 7994 } 7995 7996 // Parentheses (for dumping/debugging purposes only). 7997 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get()); 7998 if (!Diff.isUsable()) 7999 return nullptr; 8000 8001 // (Upper - Lower [- 1] + Step) / Step or (Upper - Lower) / Step 8002 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Div, Diff.get(), NewStep.get()); 8003 if (!Diff.isUsable()) 8004 return nullptr; 8005 8006 return Diff.get(); 8007 } 8008 8009 /// Build the expression to calculate the number of iterations. 8010 Expr *OpenMPIterationSpaceChecker::buildNumIterations( 8011 Scope *S, ArrayRef<LoopIterationSpace> ResultIterSpaces, bool LimitedType, 8012 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const { 8013 QualType VarType = LCDecl->getType().getNonReferenceType(); 8014 if (!VarType->isIntegerType() && !VarType->isPointerType() && 8015 !SemaRef.getLangOpts().CPlusPlus) 8016 return nullptr; 8017 Expr *LBVal = LB; 8018 Expr *UBVal = UB; 8019 // LB = TestIsLessOp.getValue() ? min(LB(MinVal), LB(MaxVal)) : 8020 // max(LB(MinVal), LB(MaxVal)) 8021 if (InitDependOnLC) { 8022 const LoopIterationSpace &IS = ResultIterSpaces[*InitDependOnLC - 1]; 8023 if (!IS.MinValue || !IS.MaxValue) 8024 return nullptr; 8025 // OuterVar = Min 8026 ExprResult MinValue = 8027 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MinValue); 8028 if (!MinValue.isUsable()) 8029 return nullptr; 8030 8031 ExprResult LBMinVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign, 8032 IS.CounterVar, MinValue.get()); 8033 if (!LBMinVal.isUsable()) 8034 return nullptr; 8035 // OuterVar = Min, LBVal 8036 LBMinVal = 8037 SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, LBMinVal.get(), LBVal); 8038 if (!LBMinVal.isUsable()) 8039 return nullptr; 8040 // (OuterVar = Min, LBVal) 8041 LBMinVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, LBMinVal.get()); 8042 if (!LBMinVal.isUsable()) 8043 return nullptr; 8044 8045 // OuterVar = Max 8046 ExprResult MaxValue = 8047 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MaxValue); 8048 if (!MaxValue.isUsable()) 8049 return nullptr; 8050 8051 ExprResult LBMaxVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign, 8052 IS.CounterVar, MaxValue.get()); 8053 if (!LBMaxVal.isUsable()) 8054 return nullptr; 8055 // OuterVar = Max, LBVal 8056 LBMaxVal = 8057 SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, LBMaxVal.get(), LBVal); 8058 if (!LBMaxVal.isUsable()) 8059 return nullptr; 8060 // (OuterVar = Max, LBVal) 8061 LBMaxVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, LBMaxVal.get()); 8062 if (!LBMaxVal.isUsable()) 8063 return nullptr; 8064 8065 Expr *LBMin = tryBuildCapture(SemaRef, LBMinVal.get(), Captures).get(); 8066 Expr *LBMax = tryBuildCapture(SemaRef, LBMaxVal.get(), Captures).get(); 8067 if (!LBMin || !LBMax) 8068 return nullptr; 8069 // LB(MinVal) < LB(MaxVal) 8070 ExprResult MinLessMaxRes = 8071 SemaRef.BuildBinOp(S, DefaultLoc, BO_LT, LBMin, LBMax); 8072 if (!MinLessMaxRes.isUsable()) 8073 return nullptr; 8074 Expr *MinLessMax = 8075 tryBuildCapture(SemaRef, MinLessMaxRes.get(), Captures).get(); 8076 if (!MinLessMax) 8077 return nullptr; 8078 if (TestIsLessOp.getValue()) { 8079 // LB(MinVal) < LB(MaxVal) ? LB(MinVal) : LB(MaxVal) - min(LB(MinVal), 8080 // LB(MaxVal)) 8081 ExprResult MinLB = SemaRef.ActOnConditionalOp(DefaultLoc, DefaultLoc, 8082 MinLessMax, LBMin, LBMax); 8083 if (!MinLB.isUsable()) 8084 return nullptr; 8085 LBVal = MinLB.get(); 8086 } else { 8087 // LB(MinVal) < LB(MaxVal) ? LB(MaxVal) : LB(MinVal) - max(LB(MinVal), 8088 // LB(MaxVal)) 8089 ExprResult MaxLB = SemaRef.ActOnConditionalOp(DefaultLoc, DefaultLoc, 8090 MinLessMax, LBMax, LBMin); 8091 if (!MaxLB.isUsable()) 8092 return nullptr; 8093 LBVal = MaxLB.get(); 8094 } 8095 } 8096 // UB = TestIsLessOp.getValue() ? max(UB(MinVal), UB(MaxVal)) : 8097 // min(UB(MinVal), UB(MaxVal)) 8098 if (CondDependOnLC) { 8099 const LoopIterationSpace &IS = ResultIterSpaces[*CondDependOnLC - 1]; 8100 if (!IS.MinValue || !IS.MaxValue) 8101 return nullptr; 8102 // OuterVar = Min 8103 ExprResult MinValue = 8104 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MinValue); 8105 if (!MinValue.isUsable()) 8106 return nullptr; 8107 8108 ExprResult UBMinVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign, 8109 IS.CounterVar, MinValue.get()); 8110 if (!UBMinVal.isUsable()) 8111 return nullptr; 8112 // OuterVar = Min, UBVal 8113 UBMinVal = 8114 SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, UBMinVal.get(), UBVal); 8115 if (!UBMinVal.isUsable()) 8116 return nullptr; 8117 // (OuterVar = Min, UBVal) 8118 UBMinVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, UBMinVal.get()); 8119 if (!UBMinVal.isUsable()) 8120 return nullptr; 8121 8122 // OuterVar = Max 8123 ExprResult MaxValue = 8124 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MaxValue); 8125 if (!MaxValue.isUsable()) 8126 return nullptr; 8127 8128 ExprResult UBMaxVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign, 8129 IS.CounterVar, MaxValue.get()); 8130 if (!UBMaxVal.isUsable()) 8131 return nullptr; 8132 // OuterVar = Max, UBVal 8133 UBMaxVal = 8134 SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, UBMaxVal.get(), UBVal); 8135 if (!UBMaxVal.isUsable()) 8136 return nullptr; 8137 // (OuterVar = Max, UBVal) 8138 UBMaxVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, UBMaxVal.get()); 8139 if (!UBMaxVal.isUsable()) 8140 return nullptr; 8141 8142 Expr *UBMin = tryBuildCapture(SemaRef, UBMinVal.get(), Captures).get(); 8143 Expr *UBMax = tryBuildCapture(SemaRef, UBMaxVal.get(), Captures).get(); 8144 if (!UBMin || !UBMax) 8145 return nullptr; 8146 // UB(MinVal) > UB(MaxVal) 8147 ExprResult MinGreaterMaxRes = 8148 SemaRef.BuildBinOp(S, DefaultLoc, BO_GT, UBMin, UBMax); 8149 if (!MinGreaterMaxRes.isUsable()) 8150 return nullptr; 8151 Expr *MinGreaterMax = 8152 tryBuildCapture(SemaRef, MinGreaterMaxRes.get(), Captures).get(); 8153 if (!MinGreaterMax) 8154 return nullptr; 8155 if (TestIsLessOp.getValue()) { 8156 // UB(MinVal) > UB(MaxVal) ? UB(MinVal) : UB(MaxVal) - max(UB(MinVal), 8157 // UB(MaxVal)) 8158 ExprResult MaxUB = SemaRef.ActOnConditionalOp( 8159 DefaultLoc, DefaultLoc, MinGreaterMax, UBMin, UBMax); 8160 if (!MaxUB.isUsable()) 8161 return nullptr; 8162 UBVal = MaxUB.get(); 8163 } else { 8164 // UB(MinVal) > UB(MaxVal) ? UB(MaxVal) : UB(MinVal) - min(UB(MinVal), 8165 // UB(MaxVal)) 8166 ExprResult MinUB = SemaRef.ActOnConditionalOp( 8167 DefaultLoc, DefaultLoc, MinGreaterMax, UBMax, UBMin); 8168 if (!MinUB.isUsable()) 8169 return nullptr; 8170 UBVal = MinUB.get(); 8171 } 8172 } 8173 Expr *UBExpr = TestIsLessOp.getValue() ? UBVal : LBVal; 8174 Expr *LBExpr = TestIsLessOp.getValue() ? LBVal : UBVal; 8175 Expr *Upper = tryBuildCapture(SemaRef, UBExpr, Captures).get(); 8176 Expr *Lower = tryBuildCapture(SemaRef, LBExpr, Captures).get(); 8177 if (!Upper || !Lower) 8178 return nullptr; 8179 8180 ExprResult Diff = calculateNumIters(SemaRef, S, DefaultLoc, Lower, Upper, 8181 Step, VarType, TestIsStrictOp, 8182 /*RoundToStep=*/true, Captures); 8183 if (!Diff.isUsable()) 8184 return nullptr; 8185 8186 // OpenMP runtime requires 32-bit or 64-bit loop variables. 8187 QualType Type = Diff.get()->getType(); 8188 ASTContext &C = SemaRef.Context; 8189 bool UseVarType = VarType->hasIntegerRepresentation() && 8190 C.getTypeSize(Type) > C.getTypeSize(VarType); 8191 if (!Type->isIntegerType() || UseVarType) { 8192 unsigned NewSize = 8193 UseVarType ? C.getTypeSize(VarType) : C.getTypeSize(Type); 8194 bool IsSigned = UseVarType ? VarType->hasSignedIntegerRepresentation() 8195 : Type->hasSignedIntegerRepresentation(); 8196 Type = C.getIntTypeForBitwidth(NewSize, IsSigned); 8197 if (!SemaRef.Context.hasSameType(Diff.get()->getType(), Type)) { 8198 Diff = SemaRef.PerformImplicitConversion( 8199 Diff.get(), Type, Sema::AA_Converting, /*AllowExplicit=*/true); 8200 if (!Diff.isUsable()) 8201 return nullptr; 8202 } 8203 } 8204 if (LimitedType) { 8205 unsigned NewSize = (C.getTypeSize(Type) > 32) ? 64 : 32; 8206 if (NewSize != C.getTypeSize(Type)) { 8207 if (NewSize < C.getTypeSize(Type)) { 8208 assert(NewSize == 64 && "incorrect loop var size"); 8209 SemaRef.Diag(DefaultLoc, diag::warn_omp_loop_64_bit_var) 8210 << InitSrcRange << ConditionSrcRange; 8211 } 8212 QualType NewType = C.getIntTypeForBitwidth( 8213 NewSize, Type->hasSignedIntegerRepresentation() || 8214 C.getTypeSize(Type) < NewSize); 8215 if (!SemaRef.Context.hasSameType(Diff.get()->getType(), NewType)) { 8216 Diff = SemaRef.PerformImplicitConversion(Diff.get(), NewType, 8217 Sema::AA_Converting, true); 8218 if (!Diff.isUsable()) 8219 return nullptr; 8220 } 8221 } 8222 } 8223 8224 return Diff.get(); 8225 } 8226 8227 std::pair<Expr *, Expr *> OpenMPIterationSpaceChecker::buildMinMaxValues( 8228 Scope *S, llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const { 8229 // Do not build for iterators, they cannot be used in non-rectangular loop 8230 // nests. 8231 if (LCDecl->getType()->isRecordType()) 8232 return std::make_pair(nullptr, nullptr); 8233 // If we subtract, the min is in the condition, otherwise the min is in the 8234 // init value. 8235 Expr *MinExpr = nullptr; 8236 Expr *MaxExpr = nullptr; 8237 Expr *LBExpr = TestIsLessOp.getValue() ? LB : UB; 8238 Expr *UBExpr = TestIsLessOp.getValue() ? UB : LB; 8239 bool LBNonRect = TestIsLessOp.getValue() ? InitDependOnLC.hasValue() 8240 : CondDependOnLC.hasValue(); 8241 bool UBNonRect = TestIsLessOp.getValue() ? CondDependOnLC.hasValue() 8242 : InitDependOnLC.hasValue(); 8243 Expr *Lower = 8244 LBNonRect ? LBExpr : tryBuildCapture(SemaRef, LBExpr, Captures).get(); 8245 Expr *Upper = 8246 UBNonRect ? UBExpr : tryBuildCapture(SemaRef, UBExpr, Captures).get(); 8247 if (!Upper || !Lower) 8248 return std::make_pair(nullptr, nullptr); 8249 8250 if (TestIsLessOp.getValue()) 8251 MinExpr = Lower; 8252 else 8253 MaxExpr = Upper; 8254 8255 // Build minimum/maximum value based on number of iterations. 8256 QualType VarType = LCDecl->getType().getNonReferenceType(); 8257 8258 ExprResult Diff = calculateNumIters(SemaRef, S, DefaultLoc, Lower, Upper, 8259 Step, VarType, TestIsStrictOp, 8260 /*RoundToStep=*/false, Captures); 8261 if (!Diff.isUsable()) 8262 return std::make_pair(nullptr, nullptr); 8263 8264 // ((Upper - Lower [- 1]) / Step) * Step 8265 // Parentheses (for dumping/debugging purposes only). 8266 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get()); 8267 if (!Diff.isUsable()) 8268 return std::make_pair(nullptr, nullptr); 8269 8270 ExprResult NewStep = tryBuildCapture(SemaRef, Step, Captures); 8271 if (!NewStep.isUsable()) 8272 return std::make_pair(nullptr, nullptr); 8273 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Mul, Diff.get(), NewStep.get()); 8274 if (!Diff.isUsable()) 8275 return std::make_pair(nullptr, nullptr); 8276 8277 // Parentheses (for dumping/debugging purposes only). 8278 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get()); 8279 if (!Diff.isUsable()) 8280 return std::make_pair(nullptr, nullptr); 8281 8282 // Convert to the ptrdiff_t, if original type is pointer. 8283 if (VarType->isAnyPointerType() && 8284 !SemaRef.Context.hasSameType( 8285 Diff.get()->getType(), 8286 SemaRef.Context.getUnsignedPointerDiffType())) { 8287 Diff = SemaRef.PerformImplicitConversion( 8288 Diff.get(), SemaRef.Context.getUnsignedPointerDiffType(), 8289 Sema::AA_Converting, /*AllowExplicit=*/true); 8290 } 8291 if (!Diff.isUsable()) 8292 return std::make_pair(nullptr, nullptr); 8293 8294 if (TestIsLessOp.getValue()) { 8295 // MinExpr = Lower; 8296 // MaxExpr = Lower + (((Upper - Lower [- 1]) / Step) * Step) 8297 Diff = SemaRef.BuildBinOp( 8298 S, DefaultLoc, BO_Add, 8299 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Lower).get(), 8300 Diff.get()); 8301 if (!Diff.isUsable()) 8302 return std::make_pair(nullptr, nullptr); 8303 } else { 8304 // MaxExpr = Upper; 8305 // MinExpr = Upper - (((Upper - Lower [- 1]) / Step) * Step) 8306 Diff = SemaRef.BuildBinOp( 8307 S, DefaultLoc, BO_Sub, 8308 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Upper).get(), 8309 Diff.get()); 8310 if (!Diff.isUsable()) 8311 return std::make_pair(nullptr, nullptr); 8312 } 8313 8314 // Convert to the original type. 8315 if (SemaRef.Context.hasSameType(Diff.get()->getType(), VarType)) 8316 Diff = SemaRef.PerformImplicitConversion(Diff.get(), VarType, 8317 Sema::AA_Converting, 8318 /*AllowExplicit=*/true); 8319 if (!Diff.isUsable()) 8320 return std::make_pair(nullptr, nullptr); 8321 8322 Sema::TentativeAnalysisScope Trap(SemaRef); 8323 Diff = SemaRef.ActOnFinishFullExpr(Diff.get(), /*DiscardedValue=*/false); 8324 if (!Diff.isUsable()) 8325 return std::make_pair(nullptr, nullptr); 8326 8327 if (TestIsLessOp.getValue()) 8328 MaxExpr = Diff.get(); 8329 else 8330 MinExpr = Diff.get(); 8331 8332 return std::make_pair(MinExpr, MaxExpr); 8333 } 8334 8335 Expr *OpenMPIterationSpaceChecker::buildFinalCondition(Scope *S) const { 8336 if (InitDependOnLC || CondDependOnLC) 8337 return Condition; 8338 return nullptr; 8339 } 8340 8341 Expr *OpenMPIterationSpaceChecker::buildPreCond( 8342 Scope *S, Expr *Cond, 8343 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const { 8344 // Do not build a precondition when the condition/initialization is dependent 8345 // to prevent pessimistic early loop exit. 8346 // TODO: this can be improved by calculating min/max values but not sure that 8347 // it will be very effective. 8348 if (CondDependOnLC || InitDependOnLC) 8349 return SemaRef.PerformImplicitConversion( 8350 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get(), 8351 SemaRef.Context.BoolTy, /*Action=*/Sema::AA_Casting, 8352 /*AllowExplicit=*/true).get(); 8353 8354 // Try to build LB <op> UB, where <op> is <, >, <=, or >=. 8355 Sema::TentativeAnalysisScope Trap(SemaRef); 8356 8357 ExprResult NewLB = tryBuildCapture(SemaRef, LB, Captures); 8358 ExprResult NewUB = tryBuildCapture(SemaRef, UB, Captures); 8359 if (!NewLB.isUsable() || !NewUB.isUsable()) 8360 return nullptr; 8361 8362 ExprResult CondExpr = 8363 SemaRef.BuildBinOp(S, DefaultLoc, 8364 TestIsLessOp.getValue() ? 8365 (TestIsStrictOp ? BO_LT : BO_LE) : 8366 (TestIsStrictOp ? BO_GT : BO_GE), 8367 NewLB.get(), NewUB.get()); 8368 if (CondExpr.isUsable()) { 8369 if (!SemaRef.Context.hasSameUnqualifiedType(CondExpr.get()->getType(), 8370 SemaRef.Context.BoolTy)) 8371 CondExpr = SemaRef.PerformImplicitConversion( 8372 CondExpr.get(), SemaRef.Context.BoolTy, /*Action=*/Sema::AA_Casting, 8373 /*AllowExplicit=*/true); 8374 } 8375 8376 // Otherwise use original loop condition and evaluate it in runtime. 8377 return CondExpr.isUsable() ? CondExpr.get() : Cond; 8378 } 8379 8380 /// Build reference expression to the counter be used for codegen. 8381 DeclRefExpr *OpenMPIterationSpaceChecker::buildCounterVar( 8382 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures, 8383 DSAStackTy &DSA) const { 8384 auto *VD = dyn_cast<VarDecl>(LCDecl); 8385 if (!VD) { 8386 VD = SemaRef.isOpenMPCapturedDecl(LCDecl); 8387 DeclRefExpr *Ref = buildDeclRefExpr( 8388 SemaRef, VD, VD->getType().getNonReferenceType(), DefaultLoc); 8389 const DSAStackTy::DSAVarData Data = 8390 DSA.getTopDSA(LCDecl, /*FromParent=*/false); 8391 // If the loop control decl is explicitly marked as private, do not mark it 8392 // as captured again. 8393 if (!isOpenMPPrivate(Data.CKind) || !Data.RefExpr) 8394 Captures.insert(std::make_pair(LCRef, Ref)); 8395 return Ref; 8396 } 8397 return cast<DeclRefExpr>(LCRef); 8398 } 8399 8400 Expr *OpenMPIterationSpaceChecker::buildPrivateCounterVar() const { 8401 if (LCDecl && !LCDecl->isInvalidDecl()) { 8402 QualType Type = LCDecl->getType().getNonReferenceType(); 8403 VarDecl *PrivateVar = buildVarDecl( 8404 SemaRef, DefaultLoc, Type, LCDecl->getName(), 8405 LCDecl->hasAttrs() ? &LCDecl->getAttrs() : nullptr, 8406 isa<VarDecl>(LCDecl) 8407 ? buildDeclRefExpr(SemaRef, cast<VarDecl>(LCDecl), Type, DefaultLoc) 8408 : nullptr); 8409 if (PrivateVar->isInvalidDecl()) 8410 return nullptr; 8411 return buildDeclRefExpr(SemaRef, PrivateVar, Type, DefaultLoc); 8412 } 8413 return nullptr; 8414 } 8415 8416 /// Build initialization of the counter to be used for codegen. 8417 Expr *OpenMPIterationSpaceChecker::buildCounterInit() const { return LB; } 8418 8419 /// Build step of the counter be used for codegen. 8420 Expr *OpenMPIterationSpaceChecker::buildCounterStep() const { return Step; } 8421 8422 Expr *OpenMPIterationSpaceChecker::buildOrderedLoopData( 8423 Scope *S, Expr *Counter, 8424 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures, SourceLocation Loc, 8425 Expr *Inc, OverloadedOperatorKind OOK) { 8426 Expr *Cnt = SemaRef.DefaultLvalueConversion(Counter).get(); 8427 if (!Cnt) 8428 return nullptr; 8429 if (Inc) { 8430 assert((OOK == OO_Plus || OOK == OO_Minus) && 8431 "Expected only + or - operations for depend clauses."); 8432 BinaryOperatorKind BOK = (OOK == OO_Plus) ? BO_Add : BO_Sub; 8433 Cnt = SemaRef.BuildBinOp(S, Loc, BOK, Cnt, Inc).get(); 8434 if (!Cnt) 8435 return nullptr; 8436 } 8437 QualType VarType = LCDecl->getType().getNonReferenceType(); 8438 if (!VarType->isIntegerType() && !VarType->isPointerType() && 8439 !SemaRef.getLangOpts().CPlusPlus) 8440 return nullptr; 8441 // Upper - Lower 8442 Expr *Upper = TestIsLessOp.getValue() 8443 ? Cnt 8444 : tryBuildCapture(SemaRef, LB, Captures).get(); 8445 Expr *Lower = TestIsLessOp.getValue() 8446 ? tryBuildCapture(SemaRef, LB, Captures).get() 8447 : Cnt; 8448 if (!Upper || !Lower) 8449 return nullptr; 8450 8451 ExprResult Diff = calculateNumIters( 8452 SemaRef, S, DefaultLoc, Lower, Upper, Step, VarType, 8453 /*TestIsStrictOp=*/false, /*RoundToStep=*/false, Captures); 8454 if (!Diff.isUsable()) 8455 return nullptr; 8456 8457 return Diff.get(); 8458 } 8459 } // namespace 8460 8461 void Sema::ActOnOpenMPLoopInitialization(SourceLocation ForLoc, Stmt *Init) { 8462 assert(getLangOpts().OpenMP && "OpenMP is not active."); 8463 assert(Init && "Expected loop in canonical form."); 8464 unsigned AssociatedLoops = DSAStack->getAssociatedLoops(); 8465 if (AssociatedLoops > 0 && 8466 isOpenMPLoopDirective(DSAStack->getCurrentDirective())) { 8467 DSAStack->loopStart(); 8468 OpenMPIterationSpaceChecker ISC(*this, /*SupportsNonRectangular=*/true, 8469 *DSAStack, ForLoc); 8470 if (!ISC.checkAndSetInit(Init, /*EmitDiags=*/false)) { 8471 if (ValueDecl *D = ISC.getLoopDecl()) { 8472 auto *VD = dyn_cast<VarDecl>(D); 8473 DeclRefExpr *PrivateRef = nullptr; 8474 if (!VD) { 8475 if (VarDecl *Private = isOpenMPCapturedDecl(D)) { 8476 VD = Private; 8477 } else { 8478 PrivateRef = buildCapture(*this, D, ISC.getLoopDeclRefExpr(), 8479 /*WithInit=*/false); 8480 VD = cast<VarDecl>(PrivateRef->getDecl()); 8481 } 8482 } 8483 DSAStack->addLoopControlVariable(D, VD); 8484 const Decl *LD = DSAStack->getPossiblyLoopCunter(); 8485 if (LD != D->getCanonicalDecl()) { 8486 DSAStack->resetPossibleLoopCounter(); 8487 if (auto *Var = dyn_cast_or_null<VarDecl>(LD)) 8488 MarkDeclarationsReferencedInExpr( 8489 buildDeclRefExpr(*this, const_cast<VarDecl *>(Var), 8490 Var->getType().getNonLValueExprType(Context), 8491 ForLoc, /*RefersToCapture=*/true)); 8492 } 8493 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 8494 // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables 8495 // Referenced in a Construct, C/C++]. The loop iteration variable in the 8496 // associated for-loop of a simd construct with just one associated 8497 // for-loop may be listed in a linear clause with a constant-linear-step 8498 // that is the increment of the associated for-loop. The loop iteration 8499 // variable(s) in the associated for-loop(s) of a for or parallel for 8500 // construct may be listed in a private or lastprivate clause. 8501 DSAStackTy::DSAVarData DVar = 8502 DSAStack->getTopDSA(D, /*FromParent=*/false); 8503 // If LoopVarRefExpr is nullptr it means the corresponding loop variable 8504 // is declared in the loop and it is predetermined as a private. 8505 Expr *LoopDeclRefExpr = ISC.getLoopDeclRefExpr(); 8506 OpenMPClauseKind PredeterminedCKind = 8507 isOpenMPSimdDirective(DKind) 8508 ? (DSAStack->hasMutipleLoops() ? OMPC_lastprivate : OMPC_linear) 8509 : OMPC_private; 8510 if (((isOpenMPSimdDirective(DKind) && DVar.CKind != OMPC_unknown && 8511 DVar.CKind != PredeterminedCKind && DVar.RefExpr && 8512 (LangOpts.OpenMP <= 45 || (DVar.CKind != OMPC_lastprivate && 8513 DVar.CKind != OMPC_private))) || 8514 ((isOpenMPWorksharingDirective(DKind) || DKind == OMPD_taskloop || 8515 DKind == OMPD_master_taskloop || 8516 DKind == OMPD_parallel_master_taskloop || 8517 isOpenMPDistributeDirective(DKind)) && 8518 !isOpenMPSimdDirective(DKind) && DVar.CKind != OMPC_unknown && 8519 DVar.CKind != OMPC_private && DVar.CKind != OMPC_lastprivate)) && 8520 (DVar.CKind != OMPC_private || DVar.RefExpr)) { 8521 Diag(Init->getBeginLoc(), diag::err_omp_loop_var_dsa) 8522 << getOpenMPClauseName(DVar.CKind) 8523 << getOpenMPDirectiveName(DKind) 8524 << getOpenMPClauseName(PredeterminedCKind); 8525 if (DVar.RefExpr == nullptr) 8526 DVar.CKind = PredeterminedCKind; 8527 reportOriginalDsa(*this, DSAStack, D, DVar, 8528 /*IsLoopIterVar=*/true); 8529 } else if (LoopDeclRefExpr) { 8530 // Make the loop iteration variable private (for worksharing 8531 // constructs), linear (for simd directives with the only one 8532 // associated loop) or lastprivate (for simd directives with several 8533 // collapsed or ordered loops). 8534 if (DVar.CKind == OMPC_unknown) 8535 DSAStack->addDSA(D, LoopDeclRefExpr, PredeterminedCKind, 8536 PrivateRef); 8537 } 8538 } 8539 } 8540 DSAStack->setAssociatedLoops(AssociatedLoops - 1); 8541 } 8542 } 8543 8544 /// Called on a for stmt to check and extract its iteration space 8545 /// for further processing (such as collapsing). 8546 static bool checkOpenMPIterationSpace( 8547 OpenMPDirectiveKind DKind, Stmt *S, Sema &SemaRef, DSAStackTy &DSA, 8548 unsigned CurrentNestedLoopCount, unsigned NestedLoopCount, 8549 unsigned TotalNestedLoopCount, Expr *CollapseLoopCountExpr, 8550 Expr *OrderedLoopCountExpr, 8551 Sema::VarsWithInheritedDSAType &VarsWithImplicitDSA, 8552 llvm::MutableArrayRef<LoopIterationSpace> ResultIterSpaces, 8553 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) { 8554 bool SupportsNonRectangular = !isOpenMPLoopTransformationDirective(DKind); 8555 // OpenMP [2.9.1, Canonical Loop Form] 8556 // for (init-expr; test-expr; incr-expr) structured-block 8557 // for (range-decl: range-expr) structured-block 8558 if (auto *CanonLoop = dyn_cast_or_null<OMPCanonicalLoop>(S)) 8559 S = CanonLoop->getLoopStmt(); 8560 auto *For = dyn_cast_or_null<ForStmt>(S); 8561 auto *CXXFor = dyn_cast_or_null<CXXForRangeStmt>(S); 8562 // Ranged for is supported only in OpenMP 5.0. 8563 if (!For && (SemaRef.LangOpts.OpenMP <= 45 || !CXXFor)) { 8564 SemaRef.Diag(S->getBeginLoc(), diag::err_omp_not_for) 8565 << (CollapseLoopCountExpr != nullptr || OrderedLoopCountExpr != nullptr) 8566 << getOpenMPDirectiveName(DKind) << TotalNestedLoopCount 8567 << (CurrentNestedLoopCount > 0) << CurrentNestedLoopCount; 8568 if (TotalNestedLoopCount > 1) { 8569 if (CollapseLoopCountExpr && OrderedLoopCountExpr) 8570 SemaRef.Diag(DSA.getConstructLoc(), 8571 diag::note_omp_collapse_ordered_expr) 8572 << 2 << CollapseLoopCountExpr->getSourceRange() 8573 << OrderedLoopCountExpr->getSourceRange(); 8574 else if (CollapseLoopCountExpr) 8575 SemaRef.Diag(CollapseLoopCountExpr->getExprLoc(), 8576 diag::note_omp_collapse_ordered_expr) 8577 << 0 << CollapseLoopCountExpr->getSourceRange(); 8578 else 8579 SemaRef.Diag(OrderedLoopCountExpr->getExprLoc(), 8580 diag::note_omp_collapse_ordered_expr) 8581 << 1 << OrderedLoopCountExpr->getSourceRange(); 8582 } 8583 return true; 8584 } 8585 assert(((For && For->getBody()) || (CXXFor && CXXFor->getBody())) && 8586 "No loop body."); 8587 8588 OpenMPIterationSpaceChecker ISC(SemaRef, SupportsNonRectangular, DSA, 8589 For ? For->getForLoc() : CXXFor->getForLoc()); 8590 8591 // Check init. 8592 Stmt *Init = For ? For->getInit() : CXXFor->getBeginStmt(); 8593 if (ISC.checkAndSetInit(Init)) 8594 return true; 8595 8596 bool HasErrors = false; 8597 8598 // Check loop variable's type. 8599 if (ValueDecl *LCDecl = ISC.getLoopDecl()) { 8600 // OpenMP [2.6, Canonical Loop Form] 8601 // Var is one of the following: 8602 // A variable of signed or unsigned integer type. 8603 // For C++, a variable of a random access iterator type. 8604 // For C, a variable of a pointer type. 8605 QualType VarType = LCDecl->getType().getNonReferenceType(); 8606 if (!VarType->isDependentType() && !VarType->isIntegerType() && 8607 !VarType->isPointerType() && 8608 !(SemaRef.getLangOpts().CPlusPlus && VarType->isOverloadableType())) { 8609 SemaRef.Diag(Init->getBeginLoc(), diag::err_omp_loop_variable_type) 8610 << SemaRef.getLangOpts().CPlusPlus; 8611 HasErrors = true; 8612 } 8613 8614 // OpenMP, 2.14.1.1 Data-sharing Attribute Rules for Variables Referenced in 8615 // a Construct 8616 // The loop iteration variable(s) in the associated for-loop(s) of a for or 8617 // parallel for construct is (are) private. 8618 // The loop iteration variable in the associated for-loop of a simd 8619 // construct with just one associated for-loop is linear with a 8620 // constant-linear-step that is the increment of the associated for-loop. 8621 // Exclude loop var from the list of variables with implicitly defined data 8622 // sharing attributes. 8623 VarsWithImplicitDSA.erase(LCDecl); 8624 8625 assert(isOpenMPLoopDirective(DKind) && "DSA for non-loop vars"); 8626 8627 // Check test-expr. 8628 HasErrors |= ISC.checkAndSetCond(For ? For->getCond() : CXXFor->getCond()); 8629 8630 // Check incr-expr. 8631 HasErrors |= ISC.checkAndSetInc(For ? For->getInc() : CXXFor->getInc()); 8632 } 8633 8634 if (ISC.dependent() || SemaRef.CurContext->isDependentContext() || HasErrors) 8635 return HasErrors; 8636 8637 // Build the loop's iteration space representation. 8638 ResultIterSpaces[CurrentNestedLoopCount].PreCond = ISC.buildPreCond( 8639 DSA.getCurScope(), For ? For->getCond() : CXXFor->getCond(), Captures); 8640 ResultIterSpaces[CurrentNestedLoopCount].NumIterations = 8641 ISC.buildNumIterations(DSA.getCurScope(), ResultIterSpaces, 8642 (isOpenMPWorksharingDirective(DKind) || 8643 isOpenMPTaskLoopDirective(DKind) || 8644 isOpenMPDistributeDirective(DKind) || 8645 isOpenMPLoopTransformationDirective(DKind)), 8646 Captures); 8647 ResultIterSpaces[CurrentNestedLoopCount].CounterVar = 8648 ISC.buildCounterVar(Captures, DSA); 8649 ResultIterSpaces[CurrentNestedLoopCount].PrivateCounterVar = 8650 ISC.buildPrivateCounterVar(); 8651 ResultIterSpaces[CurrentNestedLoopCount].CounterInit = ISC.buildCounterInit(); 8652 ResultIterSpaces[CurrentNestedLoopCount].CounterStep = ISC.buildCounterStep(); 8653 ResultIterSpaces[CurrentNestedLoopCount].InitSrcRange = ISC.getInitSrcRange(); 8654 ResultIterSpaces[CurrentNestedLoopCount].CondSrcRange = 8655 ISC.getConditionSrcRange(); 8656 ResultIterSpaces[CurrentNestedLoopCount].IncSrcRange = 8657 ISC.getIncrementSrcRange(); 8658 ResultIterSpaces[CurrentNestedLoopCount].Subtract = ISC.shouldSubtractStep(); 8659 ResultIterSpaces[CurrentNestedLoopCount].IsStrictCompare = 8660 ISC.isStrictTestOp(); 8661 std::tie(ResultIterSpaces[CurrentNestedLoopCount].MinValue, 8662 ResultIterSpaces[CurrentNestedLoopCount].MaxValue) = 8663 ISC.buildMinMaxValues(DSA.getCurScope(), Captures); 8664 ResultIterSpaces[CurrentNestedLoopCount].FinalCondition = 8665 ISC.buildFinalCondition(DSA.getCurScope()); 8666 ResultIterSpaces[CurrentNestedLoopCount].IsNonRectangularLB = 8667 ISC.doesInitDependOnLC(); 8668 ResultIterSpaces[CurrentNestedLoopCount].IsNonRectangularUB = 8669 ISC.doesCondDependOnLC(); 8670 ResultIterSpaces[CurrentNestedLoopCount].LoopDependentIdx = 8671 ISC.getLoopDependentIdx(); 8672 8673 HasErrors |= 8674 (ResultIterSpaces[CurrentNestedLoopCount].PreCond == nullptr || 8675 ResultIterSpaces[CurrentNestedLoopCount].NumIterations == nullptr || 8676 ResultIterSpaces[CurrentNestedLoopCount].CounterVar == nullptr || 8677 ResultIterSpaces[CurrentNestedLoopCount].PrivateCounterVar == nullptr || 8678 ResultIterSpaces[CurrentNestedLoopCount].CounterInit == nullptr || 8679 ResultIterSpaces[CurrentNestedLoopCount].CounterStep == nullptr); 8680 if (!HasErrors && DSA.isOrderedRegion()) { 8681 if (DSA.getOrderedRegionParam().second->getNumForLoops()) { 8682 if (CurrentNestedLoopCount < 8683 DSA.getOrderedRegionParam().second->getLoopNumIterations().size()) { 8684 DSA.getOrderedRegionParam().second->setLoopNumIterations( 8685 CurrentNestedLoopCount, 8686 ResultIterSpaces[CurrentNestedLoopCount].NumIterations); 8687 DSA.getOrderedRegionParam().second->setLoopCounter( 8688 CurrentNestedLoopCount, 8689 ResultIterSpaces[CurrentNestedLoopCount].CounterVar); 8690 } 8691 } 8692 for (auto &Pair : DSA.getDoacrossDependClauses()) { 8693 if (CurrentNestedLoopCount >= Pair.first->getNumLoops()) { 8694 // Erroneous case - clause has some problems. 8695 continue; 8696 } 8697 if (Pair.first->getDependencyKind() == OMPC_DEPEND_sink && 8698 Pair.second.size() <= CurrentNestedLoopCount) { 8699 // Erroneous case - clause has some problems. 8700 Pair.first->setLoopData(CurrentNestedLoopCount, nullptr); 8701 continue; 8702 } 8703 Expr *CntValue; 8704 if (Pair.first->getDependencyKind() == OMPC_DEPEND_source) 8705 CntValue = ISC.buildOrderedLoopData( 8706 DSA.getCurScope(), 8707 ResultIterSpaces[CurrentNestedLoopCount].CounterVar, Captures, 8708 Pair.first->getDependencyLoc()); 8709 else 8710 CntValue = ISC.buildOrderedLoopData( 8711 DSA.getCurScope(), 8712 ResultIterSpaces[CurrentNestedLoopCount].CounterVar, Captures, 8713 Pair.first->getDependencyLoc(), 8714 Pair.second[CurrentNestedLoopCount].first, 8715 Pair.second[CurrentNestedLoopCount].second); 8716 Pair.first->setLoopData(CurrentNestedLoopCount, CntValue); 8717 } 8718 } 8719 8720 return HasErrors; 8721 } 8722 8723 /// Build 'VarRef = Start. 8724 static ExprResult 8725 buildCounterInit(Sema &SemaRef, Scope *S, SourceLocation Loc, ExprResult VarRef, 8726 ExprResult Start, bool IsNonRectangularLB, 8727 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) { 8728 // Build 'VarRef = Start. 8729 ExprResult NewStart = IsNonRectangularLB 8730 ? Start.get() 8731 : tryBuildCapture(SemaRef, Start.get(), Captures); 8732 if (!NewStart.isUsable()) 8733 return ExprError(); 8734 if (!SemaRef.Context.hasSameType(NewStart.get()->getType(), 8735 VarRef.get()->getType())) { 8736 NewStart = SemaRef.PerformImplicitConversion( 8737 NewStart.get(), VarRef.get()->getType(), Sema::AA_Converting, 8738 /*AllowExplicit=*/true); 8739 if (!NewStart.isUsable()) 8740 return ExprError(); 8741 } 8742 8743 ExprResult Init = 8744 SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), NewStart.get()); 8745 return Init; 8746 } 8747 8748 /// Build 'VarRef = Start + Iter * Step'. 8749 static ExprResult buildCounterUpdate( 8750 Sema &SemaRef, Scope *S, SourceLocation Loc, ExprResult VarRef, 8751 ExprResult Start, ExprResult Iter, ExprResult Step, bool Subtract, 8752 bool IsNonRectangularLB, 8753 llvm::MapVector<const Expr *, DeclRefExpr *> *Captures = nullptr) { 8754 // Add parentheses (for debugging purposes only). 8755 Iter = SemaRef.ActOnParenExpr(Loc, Loc, Iter.get()); 8756 if (!VarRef.isUsable() || !Start.isUsable() || !Iter.isUsable() || 8757 !Step.isUsable()) 8758 return ExprError(); 8759 8760 ExprResult NewStep = Step; 8761 if (Captures) 8762 NewStep = tryBuildCapture(SemaRef, Step.get(), *Captures); 8763 if (NewStep.isInvalid()) 8764 return ExprError(); 8765 ExprResult Update = 8766 SemaRef.BuildBinOp(S, Loc, BO_Mul, Iter.get(), NewStep.get()); 8767 if (!Update.isUsable()) 8768 return ExprError(); 8769 8770 // Try to build 'VarRef = Start, VarRef (+|-)= Iter * Step' or 8771 // 'VarRef = Start (+|-) Iter * Step'. 8772 if (!Start.isUsable()) 8773 return ExprError(); 8774 ExprResult NewStart = SemaRef.ActOnParenExpr(Loc, Loc, Start.get()); 8775 if (!NewStart.isUsable()) 8776 return ExprError(); 8777 if (Captures && !IsNonRectangularLB) 8778 NewStart = tryBuildCapture(SemaRef, Start.get(), *Captures); 8779 if (NewStart.isInvalid()) 8780 return ExprError(); 8781 8782 // First attempt: try to build 'VarRef = Start, VarRef += Iter * Step'. 8783 ExprResult SavedUpdate = Update; 8784 ExprResult UpdateVal; 8785 if (VarRef.get()->getType()->isOverloadableType() || 8786 NewStart.get()->getType()->isOverloadableType() || 8787 Update.get()->getType()->isOverloadableType()) { 8788 Sema::TentativeAnalysisScope Trap(SemaRef); 8789 8790 Update = 8791 SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), NewStart.get()); 8792 if (Update.isUsable()) { 8793 UpdateVal = 8794 SemaRef.BuildBinOp(S, Loc, Subtract ? BO_SubAssign : BO_AddAssign, 8795 VarRef.get(), SavedUpdate.get()); 8796 if (UpdateVal.isUsable()) { 8797 Update = SemaRef.CreateBuiltinBinOp(Loc, BO_Comma, Update.get(), 8798 UpdateVal.get()); 8799 } 8800 } 8801 } 8802 8803 // Second attempt: try to build 'VarRef = Start (+|-) Iter * Step'. 8804 if (!Update.isUsable() || !UpdateVal.isUsable()) { 8805 Update = SemaRef.BuildBinOp(S, Loc, Subtract ? BO_Sub : BO_Add, 8806 NewStart.get(), SavedUpdate.get()); 8807 if (!Update.isUsable()) 8808 return ExprError(); 8809 8810 if (!SemaRef.Context.hasSameType(Update.get()->getType(), 8811 VarRef.get()->getType())) { 8812 Update = SemaRef.PerformImplicitConversion( 8813 Update.get(), VarRef.get()->getType(), Sema::AA_Converting, true); 8814 if (!Update.isUsable()) 8815 return ExprError(); 8816 } 8817 8818 Update = SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), Update.get()); 8819 } 8820 return Update; 8821 } 8822 8823 /// Convert integer expression \a E to make it have at least \a Bits 8824 /// bits. 8825 static ExprResult widenIterationCount(unsigned Bits, Expr *E, Sema &SemaRef) { 8826 if (E == nullptr) 8827 return ExprError(); 8828 ASTContext &C = SemaRef.Context; 8829 QualType OldType = E->getType(); 8830 unsigned HasBits = C.getTypeSize(OldType); 8831 if (HasBits >= Bits) 8832 return ExprResult(E); 8833 // OK to convert to signed, because new type has more bits than old. 8834 QualType NewType = C.getIntTypeForBitwidth(Bits, /* Signed */ true); 8835 return SemaRef.PerformImplicitConversion(E, NewType, Sema::AA_Converting, 8836 true); 8837 } 8838 8839 /// Check if the given expression \a E is a constant integer that fits 8840 /// into \a Bits bits. 8841 static bool fitsInto(unsigned Bits, bool Signed, const Expr *E, Sema &SemaRef) { 8842 if (E == nullptr) 8843 return false; 8844 if (Optional<llvm::APSInt> Result = 8845 E->getIntegerConstantExpr(SemaRef.Context)) 8846 return Signed ? Result->isSignedIntN(Bits) : Result->isIntN(Bits); 8847 return false; 8848 } 8849 8850 /// Build preinits statement for the given declarations. 8851 static Stmt *buildPreInits(ASTContext &Context, 8852 MutableArrayRef<Decl *> PreInits) { 8853 if (!PreInits.empty()) { 8854 return new (Context) DeclStmt( 8855 DeclGroupRef::Create(Context, PreInits.begin(), PreInits.size()), 8856 SourceLocation(), SourceLocation()); 8857 } 8858 return nullptr; 8859 } 8860 8861 /// Build preinits statement for the given declarations. 8862 static Stmt * 8863 buildPreInits(ASTContext &Context, 8864 const llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) { 8865 if (!Captures.empty()) { 8866 SmallVector<Decl *, 16> PreInits; 8867 for (const auto &Pair : Captures) 8868 PreInits.push_back(Pair.second->getDecl()); 8869 return buildPreInits(Context, PreInits); 8870 } 8871 return nullptr; 8872 } 8873 8874 /// Build postupdate expression for the given list of postupdates expressions. 8875 static Expr *buildPostUpdate(Sema &S, ArrayRef<Expr *> PostUpdates) { 8876 Expr *PostUpdate = nullptr; 8877 if (!PostUpdates.empty()) { 8878 for (Expr *E : PostUpdates) { 8879 Expr *ConvE = S.BuildCStyleCastExpr( 8880 E->getExprLoc(), 8881 S.Context.getTrivialTypeSourceInfo(S.Context.VoidTy), 8882 E->getExprLoc(), E) 8883 .get(); 8884 PostUpdate = PostUpdate 8885 ? S.CreateBuiltinBinOp(ConvE->getExprLoc(), BO_Comma, 8886 PostUpdate, ConvE) 8887 .get() 8888 : ConvE; 8889 } 8890 } 8891 return PostUpdate; 8892 } 8893 8894 /// Called on a for stmt to check itself and nested loops (if any). 8895 /// \return Returns 0 if one of the collapsed stmts is not canonical for loop, 8896 /// number of collapsed loops otherwise. 8897 static unsigned 8898 checkOpenMPLoop(OpenMPDirectiveKind DKind, Expr *CollapseLoopCountExpr, 8899 Expr *OrderedLoopCountExpr, Stmt *AStmt, Sema &SemaRef, 8900 DSAStackTy &DSA, 8901 Sema::VarsWithInheritedDSAType &VarsWithImplicitDSA, 8902 OMPLoopBasedDirective::HelperExprs &Built) { 8903 unsigned NestedLoopCount = 1; 8904 bool SupportsNonPerfectlyNested = (SemaRef.LangOpts.OpenMP >= 50) && 8905 !isOpenMPLoopTransformationDirective(DKind); 8906 8907 if (CollapseLoopCountExpr) { 8908 // Found 'collapse' clause - calculate collapse number. 8909 Expr::EvalResult Result; 8910 if (!CollapseLoopCountExpr->isValueDependent() && 8911 CollapseLoopCountExpr->EvaluateAsInt(Result, SemaRef.getASTContext())) { 8912 NestedLoopCount = Result.Val.getInt().getLimitedValue(); 8913 } else { 8914 Built.clear(/*Size=*/1); 8915 return 1; 8916 } 8917 } 8918 unsigned OrderedLoopCount = 1; 8919 if (OrderedLoopCountExpr) { 8920 // Found 'ordered' clause - calculate collapse number. 8921 Expr::EvalResult EVResult; 8922 if (!OrderedLoopCountExpr->isValueDependent() && 8923 OrderedLoopCountExpr->EvaluateAsInt(EVResult, 8924 SemaRef.getASTContext())) { 8925 llvm::APSInt Result = EVResult.Val.getInt(); 8926 if (Result.getLimitedValue() < NestedLoopCount) { 8927 SemaRef.Diag(OrderedLoopCountExpr->getExprLoc(), 8928 diag::err_omp_wrong_ordered_loop_count) 8929 << OrderedLoopCountExpr->getSourceRange(); 8930 SemaRef.Diag(CollapseLoopCountExpr->getExprLoc(), 8931 diag::note_collapse_loop_count) 8932 << CollapseLoopCountExpr->getSourceRange(); 8933 } 8934 OrderedLoopCount = Result.getLimitedValue(); 8935 } else { 8936 Built.clear(/*Size=*/1); 8937 return 1; 8938 } 8939 } 8940 // This is helper routine for loop directives (e.g., 'for', 'simd', 8941 // 'for simd', etc.). 8942 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 8943 unsigned NumLoops = std::max(OrderedLoopCount, NestedLoopCount); 8944 SmallVector<LoopIterationSpace, 4> IterSpaces(NumLoops); 8945 if (!OMPLoopBasedDirective::doForAllLoops( 8946 AStmt->IgnoreContainers(!isOpenMPLoopTransformationDirective(DKind)), 8947 SupportsNonPerfectlyNested, NumLoops, 8948 [DKind, &SemaRef, &DSA, NumLoops, NestedLoopCount, 8949 CollapseLoopCountExpr, OrderedLoopCountExpr, &VarsWithImplicitDSA, 8950 &IterSpaces, &Captures](unsigned Cnt, Stmt *CurStmt) { 8951 if (checkOpenMPIterationSpace( 8952 DKind, CurStmt, SemaRef, DSA, Cnt, NestedLoopCount, 8953 NumLoops, CollapseLoopCountExpr, OrderedLoopCountExpr, 8954 VarsWithImplicitDSA, IterSpaces, Captures)) 8955 return true; 8956 if (Cnt > 0 && Cnt >= NestedLoopCount && 8957 IterSpaces[Cnt].CounterVar) { 8958 // Handle initialization of captured loop iterator variables. 8959 auto *DRE = cast<DeclRefExpr>(IterSpaces[Cnt].CounterVar); 8960 if (isa<OMPCapturedExprDecl>(DRE->getDecl())) { 8961 Captures[DRE] = DRE; 8962 } 8963 } 8964 return false; 8965 })) 8966 return 0; 8967 8968 Built.clear(/* size */ NestedLoopCount); 8969 8970 if (SemaRef.CurContext->isDependentContext()) 8971 return NestedLoopCount; 8972 8973 // An example of what is generated for the following code: 8974 // 8975 // #pragma omp simd collapse(2) ordered(2) 8976 // for (i = 0; i < NI; ++i) 8977 // for (k = 0; k < NK; ++k) 8978 // for (j = J0; j < NJ; j+=2) { 8979 // <loop body> 8980 // } 8981 // 8982 // We generate the code below. 8983 // Note: the loop body may be outlined in CodeGen. 8984 // Note: some counters may be C++ classes, operator- is used to find number of 8985 // iterations and operator+= to calculate counter value. 8986 // Note: decltype(NumIterations) must be integer type (in 'omp for', only i32 8987 // or i64 is currently supported). 8988 // 8989 // #define NumIterations (NI * ((NJ - J0 - 1 + 2) / 2)) 8990 // for (int[32|64]_t IV = 0; IV < NumIterations; ++IV ) { 8991 // .local.i = IV / ((NJ - J0 - 1 + 2) / 2); 8992 // .local.j = J0 + (IV % ((NJ - J0 - 1 + 2) / 2)) * 2; 8993 // // similar updates for vars in clauses (e.g. 'linear') 8994 // <loop body (using local i and j)> 8995 // } 8996 // i = NI; // assign final values of counters 8997 // j = NJ; 8998 // 8999 9000 // Last iteration number is (I1 * I2 * ... In) - 1, where I1, I2 ... In are 9001 // the iteration counts of the collapsed for loops. 9002 // Precondition tests if there is at least one iteration (all conditions are 9003 // true). 9004 auto PreCond = ExprResult(IterSpaces[0].PreCond); 9005 Expr *N0 = IterSpaces[0].NumIterations; 9006 ExprResult LastIteration32 = 9007 widenIterationCount(/*Bits=*/32, 9008 SemaRef 9009 .PerformImplicitConversion( 9010 N0->IgnoreImpCasts(), N0->getType(), 9011 Sema::AA_Converting, /*AllowExplicit=*/true) 9012 .get(), 9013 SemaRef); 9014 ExprResult LastIteration64 = widenIterationCount( 9015 /*Bits=*/64, 9016 SemaRef 9017 .PerformImplicitConversion(N0->IgnoreImpCasts(), N0->getType(), 9018 Sema::AA_Converting, 9019 /*AllowExplicit=*/true) 9020 .get(), 9021 SemaRef); 9022 9023 if (!LastIteration32.isUsable() || !LastIteration64.isUsable()) 9024 return NestedLoopCount; 9025 9026 ASTContext &C = SemaRef.Context; 9027 bool AllCountsNeedLessThan32Bits = C.getTypeSize(N0->getType()) < 32; 9028 9029 Scope *CurScope = DSA.getCurScope(); 9030 for (unsigned Cnt = 1; Cnt < NestedLoopCount; ++Cnt) { 9031 if (PreCond.isUsable()) { 9032 PreCond = 9033 SemaRef.BuildBinOp(CurScope, PreCond.get()->getExprLoc(), BO_LAnd, 9034 PreCond.get(), IterSpaces[Cnt].PreCond); 9035 } 9036 Expr *N = IterSpaces[Cnt].NumIterations; 9037 SourceLocation Loc = N->getExprLoc(); 9038 AllCountsNeedLessThan32Bits &= C.getTypeSize(N->getType()) < 32; 9039 if (LastIteration32.isUsable()) 9040 LastIteration32 = SemaRef.BuildBinOp( 9041 CurScope, Loc, BO_Mul, LastIteration32.get(), 9042 SemaRef 9043 .PerformImplicitConversion(N->IgnoreImpCasts(), N->getType(), 9044 Sema::AA_Converting, 9045 /*AllowExplicit=*/true) 9046 .get()); 9047 if (LastIteration64.isUsable()) 9048 LastIteration64 = SemaRef.BuildBinOp( 9049 CurScope, Loc, BO_Mul, LastIteration64.get(), 9050 SemaRef 9051 .PerformImplicitConversion(N->IgnoreImpCasts(), N->getType(), 9052 Sema::AA_Converting, 9053 /*AllowExplicit=*/true) 9054 .get()); 9055 } 9056 9057 // Choose either the 32-bit or 64-bit version. 9058 ExprResult LastIteration = LastIteration64; 9059 if (SemaRef.getLangOpts().OpenMPOptimisticCollapse || 9060 (LastIteration32.isUsable() && 9061 C.getTypeSize(LastIteration32.get()->getType()) == 32 && 9062 (AllCountsNeedLessThan32Bits || NestedLoopCount == 1 || 9063 fitsInto( 9064 /*Bits=*/32, 9065 LastIteration32.get()->getType()->hasSignedIntegerRepresentation(), 9066 LastIteration64.get(), SemaRef)))) 9067 LastIteration = LastIteration32; 9068 QualType VType = LastIteration.get()->getType(); 9069 QualType RealVType = VType; 9070 QualType StrideVType = VType; 9071 if (isOpenMPTaskLoopDirective(DKind)) { 9072 VType = 9073 SemaRef.Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/0); 9074 StrideVType = 9075 SemaRef.Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/1); 9076 } 9077 9078 if (!LastIteration.isUsable()) 9079 return 0; 9080 9081 // Save the number of iterations. 9082 ExprResult NumIterations = LastIteration; 9083 { 9084 LastIteration = SemaRef.BuildBinOp( 9085 CurScope, LastIteration.get()->getExprLoc(), BO_Sub, 9086 LastIteration.get(), 9087 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()); 9088 if (!LastIteration.isUsable()) 9089 return 0; 9090 } 9091 9092 // Calculate the last iteration number beforehand instead of doing this on 9093 // each iteration. Do not do this if the number of iterations may be kfold-ed. 9094 bool IsConstant = LastIteration.get()->isIntegerConstantExpr(SemaRef.Context); 9095 ExprResult CalcLastIteration; 9096 if (!IsConstant) { 9097 ExprResult SaveRef = 9098 tryBuildCapture(SemaRef, LastIteration.get(), Captures); 9099 LastIteration = SaveRef; 9100 9101 // Prepare SaveRef + 1. 9102 NumIterations = SemaRef.BuildBinOp( 9103 CurScope, SaveRef.get()->getExprLoc(), BO_Add, SaveRef.get(), 9104 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()); 9105 if (!NumIterations.isUsable()) 9106 return 0; 9107 } 9108 9109 SourceLocation InitLoc = IterSpaces[0].InitSrcRange.getBegin(); 9110 9111 // Build variables passed into runtime, necessary for worksharing directives. 9112 ExprResult LB, UB, IL, ST, EUB, CombLB, CombUB, PrevLB, PrevUB, CombEUB; 9113 if (isOpenMPWorksharingDirective(DKind) || isOpenMPTaskLoopDirective(DKind) || 9114 isOpenMPDistributeDirective(DKind) || 9115 isOpenMPLoopTransformationDirective(DKind)) { 9116 // Lower bound variable, initialized with zero. 9117 VarDecl *LBDecl = buildVarDecl(SemaRef, InitLoc, VType, ".omp.lb"); 9118 LB = buildDeclRefExpr(SemaRef, LBDecl, VType, InitLoc); 9119 SemaRef.AddInitializerToDecl(LBDecl, 9120 SemaRef.ActOnIntegerConstant(InitLoc, 0).get(), 9121 /*DirectInit*/ false); 9122 9123 // Upper bound variable, initialized with last iteration number. 9124 VarDecl *UBDecl = buildVarDecl(SemaRef, InitLoc, VType, ".omp.ub"); 9125 UB = buildDeclRefExpr(SemaRef, UBDecl, VType, InitLoc); 9126 SemaRef.AddInitializerToDecl(UBDecl, LastIteration.get(), 9127 /*DirectInit*/ false); 9128 9129 // A 32-bit variable-flag where runtime returns 1 for the last iteration. 9130 // This will be used to implement clause 'lastprivate'. 9131 QualType Int32Ty = SemaRef.Context.getIntTypeForBitwidth(32, true); 9132 VarDecl *ILDecl = buildVarDecl(SemaRef, InitLoc, Int32Ty, ".omp.is_last"); 9133 IL = buildDeclRefExpr(SemaRef, ILDecl, Int32Ty, InitLoc); 9134 SemaRef.AddInitializerToDecl(ILDecl, 9135 SemaRef.ActOnIntegerConstant(InitLoc, 0).get(), 9136 /*DirectInit*/ false); 9137 9138 // Stride variable returned by runtime (we initialize it to 1 by default). 9139 VarDecl *STDecl = 9140 buildVarDecl(SemaRef, InitLoc, StrideVType, ".omp.stride"); 9141 ST = buildDeclRefExpr(SemaRef, STDecl, StrideVType, InitLoc); 9142 SemaRef.AddInitializerToDecl(STDecl, 9143 SemaRef.ActOnIntegerConstant(InitLoc, 1).get(), 9144 /*DirectInit*/ false); 9145 9146 // Build expression: UB = min(UB, LastIteration) 9147 // It is necessary for CodeGen of directives with static scheduling. 9148 ExprResult IsUBGreater = SemaRef.BuildBinOp(CurScope, InitLoc, BO_GT, 9149 UB.get(), LastIteration.get()); 9150 ExprResult CondOp = SemaRef.ActOnConditionalOp( 9151 LastIteration.get()->getExprLoc(), InitLoc, IsUBGreater.get(), 9152 LastIteration.get(), UB.get()); 9153 EUB = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, UB.get(), 9154 CondOp.get()); 9155 EUB = SemaRef.ActOnFinishFullExpr(EUB.get(), /*DiscardedValue*/ false); 9156 9157 // If we have a combined directive that combines 'distribute', 'for' or 9158 // 'simd' we need to be able to access the bounds of the schedule of the 9159 // enclosing region. E.g. in 'distribute parallel for' the bounds obtained 9160 // by scheduling 'distribute' have to be passed to the schedule of 'for'. 9161 if (isOpenMPLoopBoundSharingDirective(DKind)) { 9162 // Lower bound variable, initialized with zero. 9163 VarDecl *CombLBDecl = 9164 buildVarDecl(SemaRef, InitLoc, VType, ".omp.comb.lb"); 9165 CombLB = buildDeclRefExpr(SemaRef, CombLBDecl, VType, InitLoc); 9166 SemaRef.AddInitializerToDecl( 9167 CombLBDecl, SemaRef.ActOnIntegerConstant(InitLoc, 0).get(), 9168 /*DirectInit*/ false); 9169 9170 // Upper bound variable, initialized with last iteration number. 9171 VarDecl *CombUBDecl = 9172 buildVarDecl(SemaRef, InitLoc, VType, ".omp.comb.ub"); 9173 CombUB = buildDeclRefExpr(SemaRef, CombUBDecl, VType, InitLoc); 9174 SemaRef.AddInitializerToDecl(CombUBDecl, LastIteration.get(), 9175 /*DirectInit*/ false); 9176 9177 ExprResult CombIsUBGreater = SemaRef.BuildBinOp( 9178 CurScope, InitLoc, BO_GT, CombUB.get(), LastIteration.get()); 9179 ExprResult CombCondOp = 9180 SemaRef.ActOnConditionalOp(InitLoc, InitLoc, CombIsUBGreater.get(), 9181 LastIteration.get(), CombUB.get()); 9182 CombEUB = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, CombUB.get(), 9183 CombCondOp.get()); 9184 CombEUB = 9185 SemaRef.ActOnFinishFullExpr(CombEUB.get(), /*DiscardedValue*/ false); 9186 9187 const CapturedDecl *CD = cast<CapturedStmt>(AStmt)->getCapturedDecl(); 9188 // We expect to have at least 2 more parameters than the 'parallel' 9189 // directive does - the lower and upper bounds of the previous schedule. 9190 assert(CD->getNumParams() >= 4 && 9191 "Unexpected number of parameters in loop combined directive"); 9192 9193 // Set the proper type for the bounds given what we learned from the 9194 // enclosed loops. 9195 ImplicitParamDecl *PrevLBDecl = CD->getParam(/*PrevLB=*/2); 9196 ImplicitParamDecl *PrevUBDecl = CD->getParam(/*PrevUB=*/3); 9197 9198 // Previous lower and upper bounds are obtained from the region 9199 // parameters. 9200 PrevLB = 9201 buildDeclRefExpr(SemaRef, PrevLBDecl, PrevLBDecl->getType(), InitLoc); 9202 PrevUB = 9203 buildDeclRefExpr(SemaRef, PrevUBDecl, PrevUBDecl->getType(), InitLoc); 9204 } 9205 } 9206 9207 // Build the iteration variable and its initialization before loop. 9208 ExprResult IV; 9209 ExprResult Init, CombInit; 9210 { 9211 VarDecl *IVDecl = buildVarDecl(SemaRef, InitLoc, RealVType, ".omp.iv"); 9212 IV = buildDeclRefExpr(SemaRef, IVDecl, RealVType, InitLoc); 9213 Expr *RHS = (isOpenMPWorksharingDirective(DKind) || 9214 isOpenMPTaskLoopDirective(DKind) || 9215 isOpenMPDistributeDirective(DKind) || 9216 isOpenMPLoopTransformationDirective(DKind)) 9217 ? LB.get() 9218 : SemaRef.ActOnIntegerConstant(SourceLocation(), 0).get(); 9219 Init = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, IV.get(), RHS); 9220 Init = SemaRef.ActOnFinishFullExpr(Init.get(), /*DiscardedValue*/ false); 9221 9222 if (isOpenMPLoopBoundSharingDirective(DKind)) { 9223 Expr *CombRHS = 9224 (isOpenMPWorksharingDirective(DKind) || 9225 isOpenMPTaskLoopDirective(DKind) || 9226 isOpenMPDistributeDirective(DKind)) 9227 ? CombLB.get() 9228 : SemaRef.ActOnIntegerConstant(SourceLocation(), 0).get(); 9229 CombInit = 9230 SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, IV.get(), CombRHS); 9231 CombInit = 9232 SemaRef.ActOnFinishFullExpr(CombInit.get(), /*DiscardedValue*/ false); 9233 } 9234 } 9235 9236 bool UseStrictCompare = 9237 RealVType->hasUnsignedIntegerRepresentation() && 9238 llvm::all_of(IterSpaces, [](const LoopIterationSpace &LIS) { 9239 return LIS.IsStrictCompare; 9240 }); 9241 // Loop condition (IV < NumIterations) or (IV <= UB or IV < UB + 1 (for 9242 // unsigned IV)) for worksharing loops. 9243 SourceLocation CondLoc = AStmt->getBeginLoc(); 9244 Expr *BoundUB = UB.get(); 9245 if (UseStrictCompare) { 9246 BoundUB = 9247 SemaRef 9248 .BuildBinOp(CurScope, CondLoc, BO_Add, BoundUB, 9249 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()) 9250 .get(); 9251 BoundUB = 9252 SemaRef.ActOnFinishFullExpr(BoundUB, /*DiscardedValue*/ false).get(); 9253 } 9254 ExprResult Cond = 9255 (isOpenMPWorksharingDirective(DKind) || 9256 isOpenMPTaskLoopDirective(DKind) || isOpenMPDistributeDirective(DKind) || 9257 isOpenMPLoopTransformationDirective(DKind)) 9258 ? SemaRef.BuildBinOp(CurScope, CondLoc, 9259 UseStrictCompare ? BO_LT : BO_LE, IV.get(), 9260 BoundUB) 9261 : SemaRef.BuildBinOp(CurScope, CondLoc, BO_LT, IV.get(), 9262 NumIterations.get()); 9263 ExprResult CombDistCond; 9264 if (isOpenMPLoopBoundSharingDirective(DKind)) { 9265 CombDistCond = SemaRef.BuildBinOp(CurScope, CondLoc, BO_LT, IV.get(), 9266 NumIterations.get()); 9267 } 9268 9269 ExprResult CombCond; 9270 if (isOpenMPLoopBoundSharingDirective(DKind)) { 9271 Expr *BoundCombUB = CombUB.get(); 9272 if (UseStrictCompare) { 9273 BoundCombUB = 9274 SemaRef 9275 .BuildBinOp( 9276 CurScope, CondLoc, BO_Add, BoundCombUB, 9277 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()) 9278 .get(); 9279 BoundCombUB = 9280 SemaRef.ActOnFinishFullExpr(BoundCombUB, /*DiscardedValue*/ false) 9281 .get(); 9282 } 9283 CombCond = 9284 SemaRef.BuildBinOp(CurScope, CondLoc, UseStrictCompare ? BO_LT : BO_LE, 9285 IV.get(), BoundCombUB); 9286 } 9287 // Loop increment (IV = IV + 1) 9288 SourceLocation IncLoc = AStmt->getBeginLoc(); 9289 ExprResult Inc = 9290 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, IV.get(), 9291 SemaRef.ActOnIntegerConstant(IncLoc, 1).get()); 9292 if (!Inc.isUsable()) 9293 return 0; 9294 Inc = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, IV.get(), Inc.get()); 9295 Inc = SemaRef.ActOnFinishFullExpr(Inc.get(), /*DiscardedValue*/ false); 9296 if (!Inc.isUsable()) 9297 return 0; 9298 9299 // Increments for worksharing loops (LB = LB + ST; UB = UB + ST). 9300 // Used for directives with static scheduling. 9301 // In combined construct, add combined version that use CombLB and CombUB 9302 // base variables for the update 9303 ExprResult NextLB, NextUB, CombNextLB, CombNextUB; 9304 if (isOpenMPWorksharingDirective(DKind) || isOpenMPTaskLoopDirective(DKind) || 9305 isOpenMPDistributeDirective(DKind) || 9306 isOpenMPLoopTransformationDirective(DKind)) { 9307 // LB + ST 9308 NextLB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, LB.get(), ST.get()); 9309 if (!NextLB.isUsable()) 9310 return 0; 9311 // LB = LB + ST 9312 NextLB = 9313 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, LB.get(), NextLB.get()); 9314 NextLB = 9315 SemaRef.ActOnFinishFullExpr(NextLB.get(), /*DiscardedValue*/ false); 9316 if (!NextLB.isUsable()) 9317 return 0; 9318 // UB + ST 9319 NextUB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, UB.get(), ST.get()); 9320 if (!NextUB.isUsable()) 9321 return 0; 9322 // UB = UB + ST 9323 NextUB = 9324 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, UB.get(), NextUB.get()); 9325 NextUB = 9326 SemaRef.ActOnFinishFullExpr(NextUB.get(), /*DiscardedValue*/ false); 9327 if (!NextUB.isUsable()) 9328 return 0; 9329 if (isOpenMPLoopBoundSharingDirective(DKind)) { 9330 CombNextLB = 9331 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, CombLB.get(), ST.get()); 9332 if (!NextLB.isUsable()) 9333 return 0; 9334 // LB = LB + ST 9335 CombNextLB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, CombLB.get(), 9336 CombNextLB.get()); 9337 CombNextLB = SemaRef.ActOnFinishFullExpr(CombNextLB.get(), 9338 /*DiscardedValue*/ false); 9339 if (!CombNextLB.isUsable()) 9340 return 0; 9341 // UB + ST 9342 CombNextUB = 9343 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, CombUB.get(), ST.get()); 9344 if (!CombNextUB.isUsable()) 9345 return 0; 9346 // UB = UB + ST 9347 CombNextUB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, CombUB.get(), 9348 CombNextUB.get()); 9349 CombNextUB = SemaRef.ActOnFinishFullExpr(CombNextUB.get(), 9350 /*DiscardedValue*/ false); 9351 if (!CombNextUB.isUsable()) 9352 return 0; 9353 } 9354 } 9355 9356 // Create increment expression for distribute loop when combined in a same 9357 // directive with for as IV = IV + ST; ensure upper bound expression based 9358 // on PrevUB instead of NumIterations - used to implement 'for' when found 9359 // in combination with 'distribute', like in 'distribute parallel for' 9360 SourceLocation DistIncLoc = AStmt->getBeginLoc(); 9361 ExprResult DistCond, DistInc, PrevEUB, ParForInDistCond; 9362 if (isOpenMPLoopBoundSharingDirective(DKind)) { 9363 DistCond = SemaRef.BuildBinOp( 9364 CurScope, CondLoc, UseStrictCompare ? BO_LT : BO_LE, IV.get(), BoundUB); 9365 assert(DistCond.isUsable() && "distribute cond expr was not built"); 9366 9367 DistInc = 9368 SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Add, IV.get(), ST.get()); 9369 assert(DistInc.isUsable() && "distribute inc expr was not built"); 9370 DistInc = SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Assign, IV.get(), 9371 DistInc.get()); 9372 DistInc = 9373 SemaRef.ActOnFinishFullExpr(DistInc.get(), /*DiscardedValue*/ false); 9374 assert(DistInc.isUsable() && "distribute inc expr was not built"); 9375 9376 // Build expression: UB = min(UB, prevUB) for #for in composite or combined 9377 // construct 9378 SourceLocation DistEUBLoc = AStmt->getBeginLoc(); 9379 ExprResult IsUBGreater = 9380 SemaRef.BuildBinOp(CurScope, DistEUBLoc, BO_GT, UB.get(), PrevUB.get()); 9381 ExprResult CondOp = SemaRef.ActOnConditionalOp( 9382 DistEUBLoc, DistEUBLoc, IsUBGreater.get(), PrevUB.get(), UB.get()); 9383 PrevEUB = SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Assign, UB.get(), 9384 CondOp.get()); 9385 PrevEUB = 9386 SemaRef.ActOnFinishFullExpr(PrevEUB.get(), /*DiscardedValue*/ false); 9387 9388 // Build IV <= PrevUB or IV < PrevUB + 1 for unsigned IV to be used in 9389 // parallel for is in combination with a distribute directive with 9390 // schedule(static, 1) 9391 Expr *BoundPrevUB = PrevUB.get(); 9392 if (UseStrictCompare) { 9393 BoundPrevUB = 9394 SemaRef 9395 .BuildBinOp( 9396 CurScope, CondLoc, BO_Add, BoundPrevUB, 9397 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()) 9398 .get(); 9399 BoundPrevUB = 9400 SemaRef.ActOnFinishFullExpr(BoundPrevUB, /*DiscardedValue*/ false) 9401 .get(); 9402 } 9403 ParForInDistCond = 9404 SemaRef.BuildBinOp(CurScope, CondLoc, UseStrictCompare ? BO_LT : BO_LE, 9405 IV.get(), BoundPrevUB); 9406 } 9407 9408 // Build updates and final values of the loop counters. 9409 bool HasErrors = false; 9410 Built.Counters.resize(NestedLoopCount); 9411 Built.Inits.resize(NestedLoopCount); 9412 Built.Updates.resize(NestedLoopCount); 9413 Built.Finals.resize(NestedLoopCount); 9414 Built.DependentCounters.resize(NestedLoopCount); 9415 Built.DependentInits.resize(NestedLoopCount); 9416 Built.FinalsConditions.resize(NestedLoopCount); 9417 { 9418 // We implement the following algorithm for obtaining the 9419 // original loop iteration variable values based on the 9420 // value of the collapsed loop iteration variable IV. 9421 // 9422 // Let n+1 be the number of collapsed loops in the nest. 9423 // Iteration variables (I0, I1, .... In) 9424 // Iteration counts (N0, N1, ... Nn) 9425 // 9426 // Acc = IV; 9427 // 9428 // To compute Ik for loop k, 0 <= k <= n, generate: 9429 // Prod = N(k+1) * N(k+2) * ... * Nn; 9430 // Ik = Acc / Prod; 9431 // Acc -= Ik * Prod; 9432 // 9433 ExprResult Acc = IV; 9434 for (unsigned int Cnt = 0; Cnt < NestedLoopCount; ++Cnt) { 9435 LoopIterationSpace &IS = IterSpaces[Cnt]; 9436 SourceLocation UpdLoc = IS.IncSrcRange.getBegin(); 9437 ExprResult Iter; 9438 9439 // Compute prod 9440 ExprResult Prod = 9441 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get(); 9442 for (unsigned int K = Cnt+1; K < NestedLoopCount; ++K) 9443 Prod = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Mul, Prod.get(), 9444 IterSpaces[K].NumIterations); 9445 9446 // Iter = Acc / Prod 9447 // If there is at least one more inner loop to avoid 9448 // multiplication by 1. 9449 if (Cnt + 1 < NestedLoopCount) 9450 Iter = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Div, 9451 Acc.get(), Prod.get()); 9452 else 9453 Iter = Acc; 9454 if (!Iter.isUsable()) { 9455 HasErrors = true; 9456 break; 9457 } 9458 9459 // Update Acc: 9460 // Acc -= Iter * Prod 9461 // Check if there is at least one more inner loop to avoid 9462 // multiplication by 1. 9463 if (Cnt + 1 < NestedLoopCount) 9464 Prod = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Mul, 9465 Iter.get(), Prod.get()); 9466 else 9467 Prod = Iter; 9468 Acc = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Sub, 9469 Acc.get(), Prod.get()); 9470 9471 // Build update: IS.CounterVar(Private) = IS.Start + Iter * IS.Step 9472 auto *VD = cast<VarDecl>(cast<DeclRefExpr>(IS.CounterVar)->getDecl()); 9473 DeclRefExpr *CounterVar = buildDeclRefExpr( 9474 SemaRef, VD, IS.CounterVar->getType(), IS.CounterVar->getExprLoc(), 9475 /*RefersToCapture=*/true); 9476 ExprResult Init = 9477 buildCounterInit(SemaRef, CurScope, UpdLoc, CounterVar, 9478 IS.CounterInit, IS.IsNonRectangularLB, Captures); 9479 if (!Init.isUsable()) { 9480 HasErrors = true; 9481 break; 9482 } 9483 ExprResult Update = buildCounterUpdate( 9484 SemaRef, CurScope, UpdLoc, CounterVar, IS.CounterInit, Iter, 9485 IS.CounterStep, IS.Subtract, IS.IsNonRectangularLB, &Captures); 9486 if (!Update.isUsable()) { 9487 HasErrors = true; 9488 break; 9489 } 9490 9491 // Build final: IS.CounterVar = IS.Start + IS.NumIters * IS.Step 9492 ExprResult Final = 9493 buildCounterUpdate(SemaRef, CurScope, UpdLoc, CounterVar, 9494 IS.CounterInit, IS.NumIterations, IS.CounterStep, 9495 IS.Subtract, IS.IsNonRectangularLB, &Captures); 9496 if (!Final.isUsable()) { 9497 HasErrors = true; 9498 break; 9499 } 9500 9501 if (!Update.isUsable() || !Final.isUsable()) { 9502 HasErrors = true; 9503 break; 9504 } 9505 // Save results 9506 Built.Counters[Cnt] = IS.CounterVar; 9507 Built.PrivateCounters[Cnt] = IS.PrivateCounterVar; 9508 Built.Inits[Cnt] = Init.get(); 9509 Built.Updates[Cnt] = Update.get(); 9510 Built.Finals[Cnt] = Final.get(); 9511 Built.DependentCounters[Cnt] = nullptr; 9512 Built.DependentInits[Cnt] = nullptr; 9513 Built.FinalsConditions[Cnt] = nullptr; 9514 if (IS.IsNonRectangularLB || IS.IsNonRectangularUB) { 9515 Built.DependentCounters[Cnt] = 9516 Built.Counters[NestedLoopCount - 1 - IS.LoopDependentIdx]; 9517 Built.DependentInits[Cnt] = 9518 Built.Inits[NestedLoopCount - 1 - IS.LoopDependentIdx]; 9519 Built.FinalsConditions[Cnt] = IS.FinalCondition; 9520 } 9521 } 9522 } 9523 9524 if (HasErrors) 9525 return 0; 9526 9527 // Save results 9528 Built.IterationVarRef = IV.get(); 9529 Built.LastIteration = LastIteration.get(); 9530 Built.NumIterations = NumIterations.get(); 9531 Built.CalcLastIteration = SemaRef 9532 .ActOnFinishFullExpr(CalcLastIteration.get(), 9533 /*DiscardedValue=*/false) 9534 .get(); 9535 Built.PreCond = PreCond.get(); 9536 Built.PreInits = buildPreInits(C, Captures); 9537 Built.Cond = Cond.get(); 9538 Built.Init = Init.get(); 9539 Built.Inc = Inc.get(); 9540 Built.LB = LB.get(); 9541 Built.UB = UB.get(); 9542 Built.IL = IL.get(); 9543 Built.ST = ST.get(); 9544 Built.EUB = EUB.get(); 9545 Built.NLB = NextLB.get(); 9546 Built.NUB = NextUB.get(); 9547 Built.PrevLB = PrevLB.get(); 9548 Built.PrevUB = PrevUB.get(); 9549 Built.DistInc = DistInc.get(); 9550 Built.PrevEUB = PrevEUB.get(); 9551 Built.DistCombinedFields.LB = CombLB.get(); 9552 Built.DistCombinedFields.UB = CombUB.get(); 9553 Built.DistCombinedFields.EUB = CombEUB.get(); 9554 Built.DistCombinedFields.Init = CombInit.get(); 9555 Built.DistCombinedFields.Cond = CombCond.get(); 9556 Built.DistCombinedFields.NLB = CombNextLB.get(); 9557 Built.DistCombinedFields.NUB = CombNextUB.get(); 9558 Built.DistCombinedFields.DistCond = CombDistCond.get(); 9559 Built.DistCombinedFields.ParForInDistCond = ParForInDistCond.get(); 9560 9561 return NestedLoopCount; 9562 } 9563 9564 static Expr *getCollapseNumberExpr(ArrayRef<OMPClause *> Clauses) { 9565 auto CollapseClauses = 9566 OMPExecutableDirective::getClausesOfKind<OMPCollapseClause>(Clauses); 9567 if (CollapseClauses.begin() != CollapseClauses.end()) 9568 return (*CollapseClauses.begin())->getNumForLoops(); 9569 return nullptr; 9570 } 9571 9572 static Expr *getOrderedNumberExpr(ArrayRef<OMPClause *> Clauses) { 9573 auto OrderedClauses = 9574 OMPExecutableDirective::getClausesOfKind<OMPOrderedClause>(Clauses); 9575 if (OrderedClauses.begin() != OrderedClauses.end()) 9576 return (*OrderedClauses.begin())->getNumForLoops(); 9577 return nullptr; 9578 } 9579 9580 static bool checkSimdlenSafelenSpecified(Sema &S, 9581 const ArrayRef<OMPClause *> Clauses) { 9582 const OMPSafelenClause *Safelen = nullptr; 9583 const OMPSimdlenClause *Simdlen = nullptr; 9584 9585 for (const OMPClause *Clause : Clauses) { 9586 if (Clause->getClauseKind() == OMPC_safelen) 9587 Safelen = cast<OMPSafelenClause>(Clause); 9588 else if (Clause->getClauseKind() == OMPC_simdlen) 9589 Simdlen = cast<OMPSimdlenClause>(Clause); 9590 if (Safelen && Simdlen) 9591 break; 9592 } 9593 9594 if (Simdlen && Safelen) { 9595 const Expr *SimdlenLength = Simdlen->getSimdlen(); 9596 const Expr *SafelenLength = Safelen->getSafelen(); 9597 if (SimdlenLength->isValueDependent() || SimdlenLength->isTypeDependent() || 9598 SimdlenLength->isInstantiationDependent() || 9599 SimdlenLength->containsUnexpandedParameterPack()) 9600 return false; 9601 if (SafelenLength->isValueDependent() || SafelenLength->isTypeDependent() || 9602 SafelenLength->isInstantiationDependent() || 9603 SafelenLength->containsUnexpandedParameterPack()) 9604 return false; 9605 Expr::EvalResult SimdlenResult, SafelenResult; 9606 SimdlenLength->EvaluateAsInt(SimdlenResult, S.Context); 9607 SafelenLength->EvaluateAsInt(SafelenResult, S.Context); 9608 llvm::APSInt SimdlenRes = SimdlenResult.Val.getInt(); 9609 llvm::APSInt SafelenRes = SafelenResult.Val.getInt(); 9610 // OpenMP 4.5 [2.8.1, simd Construct, Restrictions] 9611 // If both simdlen and safelen clauses are specified, the value of the 9612 // simdlen parameter must be less than or equal to the value of the safelen 9613 // parameter. 9614 if (SimdlenRes > SafelenRes) { 9615 S.Diag(SimdlenLength->getExprLoc(), 9616 diag::err_omp_wrong_simdlen_safelen_values) 9617 << SimdlenLength->getSourceRange() << SafelenLength->getSourceRange(); 9618 return true; 9619 } 9620 } 9621 return false; 9622 } 9623 9624 StmtResult 9625 Sema::ActOnOpenMPSimdDirective(ArrayRef<OMPClause *> Clauses, Stmt *AStmt, 9626 SourceLocation StartLoc, SourceLocation EndLoc, 9627 VarsWithInheritedDSAType &VarsWithImplicitDSA) { 9628 if (!AStmt) 9629 return StmtError(); 9630 9631 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 9632 OMPLoopBasedDirective::HelperExprs B; 9633 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 9634 // define the nested loops number. 9635 unsigned NestedLoopCount = checkOpenMPLoop( 9636 OMPD_simd, getCollapseNumberExpr(Clauses), getOrderedNumberExpr(Clauses), 9637 AStmt, *this, *DSAStack, VarsWithImplicitDSA, B); 9638 if (NestedLoopCount == 0) 9639 return StmtError(); 9640 9641 assert((CurContext->isDependentContext() || B.builtAll()) && 9642 "omp simd loop exprs were not built"); 9643 9644 if (!CurContext->isDependentContext()) { 9645 // Finalize the clauses that need pre-built expressions for CodeGen. 9646 for (OMPClause *C : Clauses) { 9647 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 9648 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 9649 B.NumIterations, *this, CurScope, 9650 DSAStack)) 9651 return StmtError(); 9652 } 9653 } 9654 9655 if (checkSimdlenSafelenSpecified(*this, Clauses)) 9656 return StmtError(); 9657 9658 setFunctionHasBranchProtectedScope(); 9659 return OMPSimdDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount, 9660 Clauses, AStmt, B); 9661 } 9662 9663 StmtResult 9664 Sema::ActOnOpenMPForDirective(ArrayRef<OMPClause *> Clauses, Stmt *AStmt, 9665 SourceLocation StartLoc, SourceLocation EndLoc, 9666 VarsWithInheritedDSAType &VarsWithImplicitDSA) { 9667 if (!AStmt) 9668 return StmtError(); 9669 9670 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 9671 OMPLoopBasedDirective::HelperExprs B; 9672 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 9673 // define the nested loops number. 9674 unsigned NestedLoopCount = checkOpenMPLoop( 9675 OMPD_for, getCollapseNumberExpr(Clauses), getOrderedNumberExpr(Clauses), 9676 AStmt, *this, *DSAStack, VarsWithImplicitDSA, B); 9677 if (NestedLoopCount == 0) 9678 return StmtError(); 9679 9680 assert((CurContext->isDependentContext() || B.builtAll()) && 9681 "omp for loop exprs were not built"); 9682 9683 if (!CurContext->isDependentContext()) { 9684 // Finalize the clauses that need pre-built expressions for CodeGen. 9685 for (OMPClause *C : Clauses) { 9686 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 9687 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 9688 B.NumIterations, *this, CurScope, 9689 DSAStack)) 9690 return StmtError(); 9691 } 9692 } 9693 9694 setFunctionHasBranchProtectedScope(); 9695 return OMPForDirective::Create( 9696 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B, 9697 DSAStack->getTaskgroupReductionRef(), DSAStack->isCancelRegion()); 9698 } 9699 9700 StmtResult Sema::ActOnOpenMPForSimdDirective( 9701 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 9702 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 9703 if (!AStmt) 9704 return StmtError(); 9705 9706 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 9707 OMPLoopBasedDirective::HelperExprs B; 9708 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 9709 // define the nested loops number. 9710 unsigned NestedLoopCount = 9711 checkOpenMPLoop(OMPD_for_simd, getCollapseNumberExpr(Clauses), 9712 getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack, 9713 VarsWithImplicitDSA, B); 9714 if (NestedLoopCount == 0) 9715 return StmtError(); 9716 9717 assert((CurContext->isDependentContext() || B.builtAll()) && 9718 "omp for simd loop exprs were not built"); 9719 9720 if (!CurContext->isDependentContext()) { 9721 // Finalize the clauses that need pre-built expressions for CodeGen. 9722 for (OMPClause *C : Clauses) { 9723 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 9724 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 9725 B.NumIterations, *this, CurScope, 9726 DSAStack)) 9727 return StmtError(); 9728 } 9729 } 9730 9731 if (checkSimdlenSafelenSpecified(*this, Clauses)) 9732 return StmtError(); 9733 9734 setFunctionHasBranchProtectedScope(); 9735 return OMPForSimdDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount, 9736 Clauses, AStmt, B); 9737 } 9738 9739 StmtResult Sema::ActOnOpenMPSectionsDirective(ArrayRef<OMPClause *> Clauses, 9740 Stmt *AStmt, 9741 SourceLocation StartLoc, 9742 SourceLocation EndLoc) { 9743 if (!AStmt) 9744 return StmtError(); 9745 9746 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 9747 auto BaseStmt = AStmt; 9748 while (auto *CS = dyn_cast_or_null<CapturedStmt>(BaseStmt)) 9749 BaseStmt = CS->getCapturedStmt(); 9750 if (auto *C = dyn_cast_or_null<CompoundStmt>(BaseStmt)) { 9751 auto S = C->children(); 9752 if (S.begin() == S.end()) 9753 return StmtError(); 9754 // All associated statements must be '#pragma omp section' except for 9755 // the first one. 9756 for (Stmt *SectionStmt : llvm::make_range(std::next(S.begin()), S.end())) { 9757 if (!SectionStmt || !isa<OMPSectionDirective>(SectionStmt)) { 9758 if (SectionStmt) 9759 Diag(SectionStmt->getBeginLoc(), 9760 diag::err_omp_sections_substmt_not_section); 9761 return StmtError(); 9762 } 9763 cast<OMPSectionDirective>(SectionStmt) 9764 ->setHasCancel(DSAStack->isCancelRegion()); 9765 } 9766 } else { 9767 Diag(AStmt->getBeginLoc(), diag::err_omp_sections_not_compound_stmt); 9768 return StmtError(); 9769 } 9770 9771 setFunctionHasBranchProtectedScope(); 9772 9773 return OMPSectionsDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt, 9774 DSAStack->getTaskgroupReductionRef(), 9775 DSAStack->isCancelRegion()); 9776 } 9777 9778 StmtResult Sema::ActOnOpenMPSectionDirective(Stmt *AStmt, 9779 SourceLocation StartLoc, 9780 SourceLocation EndLoc) { 9781 if (!AStmt) 9782 return StmtError(); 9783 9784 setFunctionHasBranchProtectedScope(); 9785 DSAStack->setParentCancelRegion(DSAStack->isCancelRegion()); 9786 9787 return OMPSectionDirective::Create(Context, StartLoc, EndLoc, AStmt, 9788 DSAStack->isCancelRegion()); 9789 } 9790 9791 static Expr *getDirectCallExpr(Expr *E) { 9792 E = E->IgnoreParenCasts()->IgnoreImplicit(); 9793 if (auto *CE = dyn_cast<CallExpr>(E)) 9794 if (CE->getDirectCallee()) 9795 return E; 9796 return nullptr; 9797 } 9798 9799 StmtResult Sema::ActOnOpenMPDispatchDirective(ArrayRef<OMPClause *> Clauses, 9800 Stmt *AStmt, 9801 SourceLocation StartLoc, 9802 SourceLocation EndLoc) { 9803 if (!AStmt) 9804 return StmtError(); 9805 9806 Stmt *S = cast<CapturedStmt>(AStmt)->getCapturedStmt(); 9807 9808 // 5.1 OpenMP 9809 // expression-stmt : an expression statement with one of the following forms: 9810 // expression = target-call ( [expression-list] ); 9811 // target-call ( [expression-list] ); 9812 9813 SourceLocation TargetCallLoc; 9814 9815 if (!CurContext->isDependentContext()) { 9816 Expr *TargetCall = nullptr; 9817 9818 auto *E = dyn_cast<Expr>(S); 9819 if (!E) { 9820 Diag(S->getBeginLoc(), diag::err_omp_dispatch_statement_call); 9821 return StmtError(); 9822 } 9823 9824 E = E->IgnoreParenCasts()->IgnoreImplicit(); 9825 9826 if (auto *BO = dyn_cast<BinaryOperator>(E)) { 9827 if (BO->getOpcode() == BO_Assign) 9828 TargetCall = getDirectCallExpr(BO->getRHS()); 9829 } else { 9830 if (auto *COCE = dyn_cast<CXXOperatorCallExpr>(E)) 9831 if (COCE->getOperator() == OO_Equal) 9832 TargetCall = getDirectCallExpr(COCE->getArg(1)); 9833 if (!TargetCall) 9834 TargetCall = getDirectCallExpr(E); 9835 } 9836 if (!TargetCall) { 9837 Diag(E->getBeginLoc(), diag::err_omp_dispatch_statement_call); 9838 return StmtError(); 9839 } 9840 TargetCallLoc = TargetCall->getExprLoc(); 9841 } 9842 9843 setFunctionHasBranchProtectedScope(); 9844 9845 return OMPDispatchDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt, 9846 TargetCallLoc); 9847 } 9848 9849 StmtResult Sema::ActOnOpenMPSingleDirective(ArrayRef<OMPClause *> Clauses, 9850 Stmt *AStmt, 9851 SourceLocation StartLoc, 9852 SourceLocation EndLoc) { 9853 if (!AStmt) 9854 return StmtError(); 9855 9856 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 9857 9858 setFunctionHasBranchProtectedScope(); 9859 9860 // OpenMP [2.7.3, single Construct, Restrictions] 9861 // The copyprivate clause must not be used with the nowait clause. 9862 const OMPClause *Nowait = nullptr; 9863 const OMPClause *Copyprivate = nullptr; 9864 for (const OMPClause *Clause : Clauses) { 9865 if (Clause->getClauseKind() == OMPC_nowait) 9866 Nowait = Clause; 9867 else if (Clause->getClauseKind() == OMPC_copyprivate) 9868 Copyprivate = Clause; 9869 if (Copyprivate && Nowait) { 9870 Diag(Copyprivate->getBeginLoc(), 9871 diag::err_omp_single_copyprivate_with_nowait); 9872 Diag(Nowait->getBeginLoc(), diag::note_omp_nowait_clause_here); 9873 return StmtError(); 9874 } 9875 } 9876 9877 return OMPSingleDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt); 9878 } 9879 9880 StmtResult Sema::ActOnOpenMPMasterDirective(Stmt *AStmt, 9881 SourceLocation StartLoc, 9882 SourceLocation EndLoc) { 9883 if (!AStmt) 9884 return StmtError(); 9885 9886 setFunctionHasBranchProtectedScope(); 9887 9888 return OMPMasterDirective::Create(Context, StartLoc, EndLoc, AStmt); 9889 } 9890 9891 StmtResult Sema::ActOnOpenMPMaskedDirective(ArrayRef<OMPClause *> Clauses, 9892 Stmt *AStmt, 9893 SourceLocation StartLoc, 9894 SourceLocation EndLoc) { 9895 if (!AStmt) 9896 return StmtError(); 9897 9898 setFunctionHasBranchProtectedScope(); 9899 9900 return OMPMaskedDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt); 9901 } 9902 9903 StmtResult Sema::ActOnOpenMPCriticalDirective( 9904 const DeclarationNameInfo &DirName, ArrayRef<OMPClause *> Clauses, 9905 Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc) { 9906 if (!AStmt) 9907 return StmtError(); 9908 9909 bool ErrorFound = false; 9910 llvm::APSInt Hint; 9911 SourceLocation HintLoc; 9912 bool DependentHint = false; 9913 for (const OMPClause *C : Clauses) { 9914 if (C->getClauseKind() == OMPC_hint) { 9915 if (!DirName.getName()) { 9916 Diag(C->getBeginLoc(), diag::err_omp_hint_clause_no_name); 9917 ErrorFound = true; 9918 } 9919 Expr *E = cast<OMPHintClause>(C)->getHint(); 9920 if (E->isTypeDependent() || E->isValueDependent() || 9921 E->isInstantiationDependent()) { 9922 DependentHint = true; 9923 } else { 9924 Hint = E->EvaluateKnownConstInt(Context); 9925 HintLoc = C->getBeginLoc(); 9926 } 9927 } 9928 } 9929 if (ErrorFound) 9930 return StmtError(); 9931 const auto Pair = DSAStack->getCriticalWithHint(DirName); 9932 if (Pair.first && DirName.getName() && !DependentHint) { 9933 if (llvm::APSInt::compareValues(Hint, Pair.second) != 0) { 9934 Diag(StartLoc, diag::err_omp_critical_with_hint); 9935 if (HintLoc.isValid()) 9936 Diag(HintLoc, diag::note_omp_critical_hint_here) 9937 << 0 << Hint.toString(/*Radix=*/10, /*Signed=*/false); 9938 else 9939 Diag(StartLoc, diag::note_omp_critical_no_hint) << 0; 9940 if (const auto *C = Pair.first->getSingleClause<OMPHintClause>()) { 9941 Diag(C->getBeginLoc(), diag::note_omp_critical_hint_here) 9942 << 1 9943 << C->getHint()->EvaluateKnownConstInt(Context).toString( 9944 /*Radix=*/10, /*Signed=*/false); 9945 } else { 9946 Diag(Pair.first->getBeginLoc(), diag::note_omp_critical_no_hint) << 1; 9947 } 9948 } 9949 } 9950 9951 setFunctionHasBranchProtectedScope(); 9952 9953 auto *Dir = OMPCriticalDirective::Create(Context, DirName, StartLoc, EndLoc, 9954 Clauses, AStmt); 9955 if (!Pair.first && DirName.getName() && !DependentHint) 9956 DSAStack->addCriticalWithHint(Dir, Hint); 9957 return Dir; 9958 } 9959 9960 StmtResult Sema::ActOnOpenMPParallelForDirective( 9961 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 9962 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 9963 if (!AStmt) 9964 return StmtError(); 9965 9966 auto *CS = cast<CapturedStmt>(AStmt); 9967 // 1.2.2 OpenMP Language Terminology 9968 // Structured block - An executable statement with a single entry at the 9969 // top and a single exit at the bottom. 9970 // The point of exit cannot be a branch out of the structured block. 9971 // longjmp() and throw() must not violate the entry/exit criteria. 9972 CS->getCapturedDecl()->setNothrow(); 9973 9974 OMPLoopBasedDirective::HelperExprs B; 9975 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 9976 // define the nested loops number. 9977 unsigned NestedLoopCount = 9978 checkOpenMPLoop(OMPD_parallel_for, getCollapseNumberExpr(Clauses), 9979 getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack, 9980 VarsWithImplicitDSA, B); 9981 if (NestedLoopCount == 0) 9982 return StmtError(); 9983 9984 assert((CurContext->isDependentContext() || B.builtAll()) && 9985 "omp parallel for loop exprs were not built"); 9986 9987 if (!CurContext->isDependentContext()) { 9988 // Finalize the clauses that need pre-built expressions for CodeGen. 9989 for (OMPClause *C : Clauses) { 9990 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 9991 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 9992 B.NumIterations, *this, CurScope, 9993 DSAStack)) 9994 return StmtError(); 9995 } 9996 } 9997 9998 setFunctionHasBranchProtectedScope(); 9999 return OMPParallelForDirective::Create( 10000 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B, 10001 DSAStack->getTaskgroupReductionRef(), DSAStack->isCancelRegion()); 10002 } 10003 10004 StmtResult Sema::ActOnOpenMPParallelForSimdDirective( 10005 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10006 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10007 if (!AStmt) 10008 return StmtError(); 10009 10010 auto *CS = cast<CapturedStmt>(AStmt); 10011 // 1.2.2 OpenMP Language Terminology 10012 // Structured block - An executable statement with a single entry at the 10013 // top and a single exit at the bottom. 10014 // The point of exit cannot be a branch out of the structured block. 10015 // longjmp() and throw() must not violate the entry/exit criteria. 10016 CS->getCapturedDecl()->setNothrow(); 10017 10018 OMPLoopBasedDirective::HelperExprs B; 10019 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 10020 // define the nested loops number. 10021 unsigned NestedLoopCount = 10022 checkOpenMPLoop(OMPD_parallel_for_simd, getCollapseNumberExpr(Clauses), 10023 getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack, 10024 VarsWithImplicitDSA, B); 10025 if (NestedLoopCount == 0) 10026 return StmtError(); 10027 10028 if (!CurContext->isDependentContext()) { 10029 // Finalize the clauses that need pre-built expressions for CodeGen. 10030 for (OMPClause *C : Clauses) { 10031 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 10032 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 10033 B.NumIterations, *this, CurScope, 10034 DSAStack)) 10035 return StmtError(); 10036 } 10037 } 10038 10039 if (checkSimdlenSafelenSpecified(*this, Clauses)) 10040 return StmtError(); 10041 10042 setFunctionHasBranchProtectedScope(); 10043 return OMPParallelForSimdDirective::Create( 10044 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 10045 } 10046 10047 StmtResult 10048 Sema::ActOnOpenMPParallelMasterDirective(ArrayRef<OMPClause *> Clauses, 10049 Stmt *AStmt, SourceLocation StartLoc, 10050 SourceLocation EndLoc) { 10051 if (!AStmt) 10052 return StmtError(); 10053 10054 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 10055 auto *CS = cast<CapturedStmt>(AStmt); 10056 // 1.2.2 OpenMP Language Terminology 10057 // Structured block - An executable statement with a single entry at the 10058 // top and a single exit at the bottom. 10059 // The point of exit cannot be a branch out of the structured block. 10060 // longjmp() and throw() must not violate the entry/exit criteria. 10061 CS->getCapturedDecl()->setNothrow(); 10062 10063 setFunctionHasBranchProtectedScope(); 10064 10065 return OMPParallelMasterDirective::Create( 10066 Context, StartLoc, EndLoc, Clauses, AStmt, 10067 DSAStack->getTaskgroupReductionRef()); 10068 } 10069 10070 StmtResult 10071 Sema::ActOnOpenMPParallelSectionsDirective(ArrayRef<OMPClause *> Clauses, 10072 Stmt *AStmt, SourceLocation StartLoc, 10073 SourceLocation EndLoc) { 10074 if (!AStmt) 10075 return StmtError(); 10076 10077 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 10078 auto BaseStmt = AStmt; 10079 while (auto *CS = dyn_cast_or_null<CapturedStmt>(BaseStmt)) 10080 BaseStmt = CS->getCapturedStmt(); 10081 if (auto *C = dyn_cast_or_null<CompoundStmt>(BaseStmt)) { 10082 auto S = C->children(); 10083 if (S.begin() == S.end()) 10084 return StmtError(); 10085 // All associated statements must be '#pragma omp section' except for 10086 // the first one. 10087 for (Stmt *SectionStmt : llvm::make_range(std::next(S.begin()), S.end())) { 10088 if (!SectionStmt || !isa<OMPSectionDirective>(SectionStmt)) { 10089 if (SectionStmt) 10090 Diag(SectionStmt->getBeginLoc(), 10091 diag::err_omp_parallel_sections_substmt_not_section); 10092 return StmtError(); 10093 } 10094 cast<OMPSectionDirective>(SectionStmt) 10095 ->setHasCancel(DSAStack->isCancelRegion()); 10096 } 10097 } else { 10098 Diag(AStmt->getBeginLoc(), 10099 diag::err_omp_parallel_sections_not_compound_stmt); 10100 return StmtError(); 10101 } 10102 10103 setFunctionHasBranchProtectedScope(); 10104 10105 return OMPParallelSectionsDirective::Create( 10106 Context, StartLoc, EndLoc, Clauses, AStmt, 10107 DSAStack->getTaskgroupReductionRef(), DSAStack->isCancelRegion()); 10108 } 10109 10110 /// detach and mergeable clauses are mutially exclusive, check for it. 10111 static bool checkDetachMergeableClauses(Sema &S, 10112 ArrayRef<OMPClause *> Clauses) { 10113 const OMPClause *PrevClause = nullptr; 10114 bool ErrorFound = false; 10115 for (const OMPClause *C : Clauses) { 10116 if (C->getClauseKind() == OMPC_detach || 10117 C->getClauseKind() == OMPC_mergeable) { 10118 if (!PrevClause) { 10119 PrevClause = C; 10120 } else if (PrevClause->getClauseKind() != C->getClauseKind()) { 10121 S.Diag(C->getBeginLoc(), diag::err_omp_clauses_mutually_exclusive) 10122 << getOpenMPClauseName(C->getClauseKind()) 10123 << getOpenMPClauseName(PrevClause->getClauseKind()); 10124 S.Diag(PrevClause->getBeginLoc(), diag::note_omp_previous_clause) 10125 << getOpenMPClauseName(PrevClause->getClauseKind()); 10126 ErrorFound = true; 10127 } 10128 } 10129 } 10130 return ErrorFound; 10131 } 10132 10133 StmtResult Sema::ActOnOpenMPTaskDirective(ArrayRef<OMPClause *> Clauses, 10134 Stmt *AStmt, SourceLocation StartLoc, 10135 SourceLocation EndLoc) { 10136 if (!AStmt) 10137 return StmtError(); 10138 10139 // OpenMP 5.0, 2.10.1 task Construct 10140 // If a detach clause appears on the directive, then a mergeable clause cannot 10141 // appear on the same directive. 10142 if (checkDetachMergeableClauses(*this, Clauses)) 10143 return StmtError(); 10144 10145 auto *CS = cast<CapturedStmt>(AStmt); 10146 // 1.2.2 OpenMP Language Terminology 10147 // Structured block - An executable statement with a single entry at the 10148 // top and a single exit at the bottom. 10149 // The point of exit cannot be a branch out of the structured block. 10150 // longjmp() and throw() must not violate the entry/exit criteria. 10151 CS->getCapturedDecl()->setNothrow(); 10152 10153 setFunctionHasBranchProtectedScope(); 10154 10155 return OMPTaskDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt, 10156 DSAStack->isCancelRegion()); 10157 } 10158 10159 StmtResult Sema::ActOnOpenMPTaskyieldDirective(SourceLocation StartLoc, 10160 SourceLocation EndLoc) { 10161 return OMPTaskyieldDirective::Create(Context, StartLoc, EndLoc); 10162 } 10163 10164 StmtResult Sema::ActOnOpenMPBarrierDirective(SourceLocation StartLoc, 10165 SourceLocation EndLoc) { 10166 return OMPBarrierDirective::Create(Context, StartLoc, EndLoc); 10167 } 10168 10169 StmtResult Sema::ActOnOpenMPTaskwaitDirective(SourceLocation StartLoc, 10170 SourceLocation EndLoc) { 10171 return OMPTaskwaitDirective::Create(Context, StartLoc, EndLoc); 10172 } 10173 10174 StmtResult Sema::ActOnOpenMPTaskgroupDirective(ArrayRef<OMPClause *> Clauses, 10175 Stmt *AStmt, 10176 SourceLocation StartLoc, 10177 SourceLocation EndLoc) { 10178 if (!AStmt) 10179 return StmtError(); 10180 10181 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 10182 10183 setFunctionHasBranchProtectedScope(); 10184 10185 return OMPTaskgroupDirective::Create(Context, StartLoc, EndLoc, Clauses, 10186 AStmt, 10187 DSAStack->getTaskgroupReductionRef()); 10188 } 10189 10190 StmtResult Sema::ActOnOpenMPFlushDirective(ArrayRef<OMPClause *> Clauses, 10191 SourceLocation StartLoc, 10192 SourceLocation EndLoc) { 10193 OMPFlushClause *FC = nullptr; 10194 OMPClause *OrderClause = nullptr; 10195 for (OMPClause *C : Clauses) { 10196 if (C->getClauseKind() == OMPC_flush) 10197 FC = cast<OMPFlushClause>(C); 10198 else 10199 OrderClause = C; 10200 } 10201 OpenMPClauseKind MemOrderKind = OMPC_unknown; 10202 SourceLocation MemOrderLoc; 10203 for (const OMPClause *C : Clauses) { 10204 if (C->getClauseKind() == OMPC_acq_rel || 10205 C->getClauseKind() == OMPC_acquire || 10206 C->getClauseKind() == OMPC_release) { 10207 if (MemOrderKind != OMPC_unknown) { 10208 Diag(C->getBeginLoc(), diag::err_omp_several_mem_order_clauses) 10209 << getOpenMPDirectiveName(OMPD_flush) << 1 10210 << SourceRange(C->getBeginLoc(), C->getEndLoc()); 10211 Diag(MemOrderLoc, diag::note_omp_previous_mem_order_clause) 10212 << getOpenMPClauseName(MemOrderKind); 10213 } else { 10214 MemOrderKind = C->getClauseKind(); 10215 MemOrderLoc = C->getBeginLoc(); 10216 } 10217 } 10218 } 10219 if (FC && OrderClause) { 10220 Diag(FC->getLParenLoc(), diag::err_omp_flush_order_clause_and_list) 10221 << getOpenMPClauseName(OrderClause->getClauseKind()); 10222 Diag(OrderClause->getBeginLoc(), diag::note_omp_flush_order_clause_here) 10223 << getOpenMPClauseName(OrderClause->getClauseKind()); 10224 return StmtError(); 10225 } 10226 return OMPFlushDirective::Create(Context, StartLoc, EndLoc, Clauses); 10227 } 10228 10229 StmtResult Sema::ActOnOpenMPDepobjDirective(ArrayRef<OMPClause *> Clauses, 10230 SourceLocation StartLoc, 10231 SourceLocation EndLoc) { 10232 if (Clauses.empty()) { 10233 Diag(StartLoc, diag::err_omp_depobj_expected); 10234 return StmtError(); 10235 } else if (Clauses[0]->getClauseKind() != OMPC_depobj) { 10236 Diag(Clauses[0]->getBeginLoc(), diag::err_omp_depobj_expected); 10237 return StmtError(); 10238 } 10239 // Only depobj expression and another single clause is allowed. 10240 if (Clauses.size() > 2) { 10241 Diag(Clauses[2]->getBeginLoc(), 10242 diag::err_omp_depobj_single_clause_expected); 10243 return StmtError(); 10244 } else if (Clauses.size() < 1) { 10245 Diag(Clauses[0]->getEndLoc(), diag::err_omp_depobj_single_clause_expected); 10246 return StmtError(); 10247 } 10248 return OMPDepobjDirective::Create(Context, StartLoc, EndLoc, Clauses); 10249 } 10250 10251 StmtResult Sema::ActOnOpenMPScanDirective(ArrayRef<OMPClause *> Clauses, 10252 SourceLocation StartLoc, 10253 SourceLocation EndLoc) { 10254 // Check that exactly one clause is specified. 10255 if (Clauses.size() != 1) { 10256 Diag(Clauses.empty() ? EndLoc : Clauses[1]->getBeginLoc(), 10257 diag::err_omp_scan_single_clause_expected); 10258 return StmtError(); 10259 } 10260 // Check that scan directive is used in the scopeof the OpenMP loop body. 10261 if (Scope *S = DSAStack->getCurScope()) { 10262 Scope *ParentS = S->getParent(); 10263 if (!ParentS || ParentS->getParent() != ParentS->getBreakParent() || 10264 !ParentS->getBreakParent()->isOpenMPLoopScope()) 10265 return StmtError(Diag(StartLoc, diag::err_omp_orphaned_device_directive) 10266 << getOpenMPDirectiveName(OMPD_scan) << 5); 10267 } 10268 // Check that only one instance of scan directives is used in the same outer 10269 // region. 10270 if (DSAStack->doesParentHasScanDirective()) { 10271 Diag(StartLoc, diag::err_omp_several_directives_in_region) << "scan"; 10272 Diag(DSAStack->getParentScanDirectiveLoc(), 10273 diag::note_omp_previous_directive) 10274 << "scan"; 10275 return StmtError(); 10276 } 10277 DSAStack->setParentHasScanDirective(StartLoc); 10278 return OMPScanDirective::Create(Context, StartLoc, EndLoc, Clauses); 10279 } 10280 10281 StmtResult Sema::ActOnOpenMPOrderedDirective(ArrayRef<OMPClause *> Clauses, 10282 Stmt *AStmt, 10283 SourceLocation StartLoc, 10284 SourceLocation EndLoc) { 10285 const OMPClause *DependFound = nullptr; 10286 const OMPClause *DependSourceClause = nullptr; 10287 const OMPClause *DependSinkClause = nullptr; 10288 bool ErrorFound = false; 10289 const OMPThreadsClause *TC = nullptr; 10290 const OMPSIMDClause *SC = nullptr; 10291 for (const OMPClause *C : Clauses) { 10292 if (auto *DC = dyn_cast<OMPDependClause>(C)) { 10293 DependFound = C; 10294 if (DC->getDependencyKind() == OMPC_DEPEND_source) { 10295 if (DependSourceClause) { 10296 Diag(C->getBeginLoc(), diag::err_omp_more_one_clause) 10297 << getOpenMPDirectiveName(OMPD_ordered) 10298 << getOpenMPClauseName(OMPC_depend) << 2; 10299 ErrorFound = true; 10300 } else { 10301 DependSourceClause = C; 10302 } 10303 if (DependSinkClause) { 10304 Diag(C->getBeginLoc(), diag::err_omp_depend_sink_source_not_allowed) 10305 << 0; 10306 ErrorFound = true; 10307 } 10308 } else if (DC->getDependencyKind() == OMPC_DEPEND_sink) { 10309 if (DependSourceClause) { 10310 Diag(C->getBeginLoc(), diag::err_omp_depend_sink_source_not_allowed) 10311 << 1; 10312 ErrorFound = true; 10313 } 10314 DependSinkClause = C; 10315 } 10316 } else if (C->getClauseKind() == OMPC_threads) { 10317 TC = cast<OMPThreadsClause>(C); 10318 } else if (C->getClauseKind() == OMPC_simd) { 10319 SC = cast<OMPSIMDClause>(C); 10320 } 10321 } 10322 if (!ErrorFound && !SC && 10323 isOpenMPSimdDirective(DSAStack->getParentDirective())) { 10324 // OpenMP [2.8.1,simd Construct, Restrictions] 10325 // An ordered construct with the simd clause is the only OpenMP construct 10326 // that can appear in the simd region. 10327 Diag(StartLoc, diag::err_omp_prohibited_region_simd) 10328 << (LangOpts.OpenMP >= 50 ? 1 : 0); 10329 ErrorFound = true; 10330 } else if (DependFound && (TC || SC)) { 10331 Diag(DependFound->getBeginLoc(), diag::err_omp_depend_clause_thread_simd) 10332 << getOpenMPClauseName(TC ? TC->getClauseKind() : SC->getClauseKind()); 10333 ErrorFound = true; 10334 } else if (DependFound && !DSAStack->getParentOrderedRegionParam().first) { 10335 Diag(DependFound->getBeginLoc(), 10336 diag::err_omp_ordered_directive_without_param); 10337 ErrorFound = true; 10338 } else if (TC || Clauses.empty()) { 10339 if (const Expr *Param = DSAStack->getParentOrderedRegionParam().first) { 10340 SourceLocation ErrLoc = TC ? TC->getBeginLoc() : StartLoc; 10341 Diag(ErrLoc, diag::err_omp_ordered_directive_with_param) 10342 << (TC != nullptr); 10343 Diag(Param->getBeginLoc(), diag::note_omp_ordered_param) << 1; 10344 ErrorFound = true; 10345 } 10346 } 10347 if ((!AStmt && !DependFound) || ErrorFound) 10348 return StmtError(); 10349 10350 // OpenMP 5.0, 2.17.9, ordered Construct, Restrictions. 10351 // During execution of an iteration of a worksharing-loop or a loop nest 10352 // within a worksharing-loop, simd, or worksharing-loop SIMD region, a thread 10353 // must not execute more than one ordered region corresponding to an ordered 10354 // construct without a depend clause. 10355 if (!DependFound) { 10356 if (DSAStack->doesParentHasOrderedDirective()) { 10357 Diag(StartLoc, diag::err_omp_several_directives_in_region) << "ordered"; 10358 Diag(DSAStack->getParentOrderedDirectiveLoc(), 10359 diag::note_omp_previous_directive) 10360 << "ordered"; 10361 return StmtError(); 10362 } 10363 DSAStack->setParentHasOrderedDirective(StartLoc); 10364 } 10365 10366 if (AStmt) { 10367 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 10368 10369 setFunctionHasBranchProtectedScope(); 10370 } 10371 10372 return OMPOrderedDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt); 10373 } 10374 10375 namespace { 10376 /// Helper class for checking expression in 'omp atomic [update]' 10377 /// construct. 10378 class OpenMPAtomicUpdateChecker { 10379 /// Error results for atomic update expressions. 10380 enum ExprAnalysisErrorCode { 10381 /// A statement is not an expression statement. 10382 NotAnExpression, 10383 /// Expression is not builtin binary or unary operation. 10384 NotABinaryOrUnaryExpression, 10385 /// Unary operation is not post-/pre- increment/decrement operation. 10386 NotAnUnaryIncDecExpression, 10387 /// An expression is not of scalar type. 10388 NotAScalarType, 10389 /// A binary operation is not an assignment operation. 10390 NotAnAssignmentOp, 10391 /// RHS part of the binary operation is not a binary expression. 10392 NotABinaryExpression, 10393 /// RHS part is not additive/multiplicative/shift/biwise binary 10394 /// expression. 10395 NotABinaryOperator, 10396 /// RHS binary operation does not have reference to the updated LHS 10397 /// part. 10398 NotAnUpdateExpression, 10399 /// No errors is found. 10400 NoError 10401 }; 10402 /// Reference to Sema. 10403 Sema &SemaRef; 10404 /// A location for note diagnostics (when error is found). 10405 SourceLocation NoteLoc; 10406 /// 'x' lvalue part of the source atomic expression. 10407 Expr *X; 10408 /// 'expr' rvalue part of the source atomic expression. 10409 Expr *E; 10410 /// Helper expression of the form 10411 /// 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or 10412 /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'. 10413 Expr *UpdateExpr; 10414 /// Is 'x' a LHS in a RHS part of full update expression. It is 10415 /// important for non-associative operations. 10416 bool IsXLHSInRHSPart; 10417 BinaryOperatorKind Op; 10418 SourceLocation OpLoc; 10419 /// true if the source expression is a postfix unary operation, false 10420 /// if it is a prefix unary operation. 10421 bool IsPostfixUpdate; 10422 10423 public: 10424 OpenMPAtomicUpdateChecker(Sema &SemaRef) 10425 : SemaRef(SemaRef), X(nullptr), E(nullptr), UpdateExpr(nullptr), 10426 IsXLHSInRHSPart(false), Op(BO_PtrMemD), IsPostfixUpdate(false) {} 10427 /// Check specified statement that it is suitable for 'atomic update' 10428 /// constructs and extract 'x', 'expr' and Operation from the original 10429 /// expression. If DiagId and NoteId == 0, then only check is performed 10430 /// without error notification. 10431 /// \param DiagId Diagnostic which should be emitted if error is found. 10432 /// \param NoteId Diagnostic note for the main error message. 10433 /// \return true if statement is not an update expression, false otherwise. 10434 bool checkStatement(Stmt *S, unsigned DiagId = 0, unsigned NoteId = 0); 10435 /// Return the 'x' lvalue part of the source atomic expression. 10436 Expr *getX() const { return X; } 10437 /// Return the 'expr' rvalue part of the source atomic expression. 10438 Expr *getExpr() const { return E; } 10439 /// Return the update expression used in calculation of the updated 10440 /// value. Always has form 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or 10441 /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'. 10442 Expr *getUpdateExpr() const { return UpdateExpr; } 10443 /// Return true if 'x' is LHS in RHS part of full update expression, 10444 /// false otherwise. 10445 bool isXLHSInRHSPart() const { return IsXLHSInRHSPart; } 10446 10447 /// true if the source expression is a postfix unary operation, false 10448 /// if it is a prefix unary operation. 10449 bool isPostfixUpdate() const { return IsPostfixUpdate; } 10450 10451 private: 10452 bool checkBinaryOperation(BinaryOperator *AtomicBinOp, unsigned DiagId = 0, 10453 unsigned NoteId = 0); 10454 }; 10455 } // namespace 10456 10457 bool OpenMPAtomicUpdateChecker::checkBinaryOperation( 10458 BinaryOperator *AtomicBinOp, unsigned DiagId, unsigned NoteId) { 10459 ExprAnalysisErrorCode ErrorFound = NoError; 10460 SourceLocation ErrorLoc, NoteLoc; 10461 SourceRange ErrorRange, NoteRange; 10462 // Allowed constructs are: 10463 // x = x binop expr; 10464 // x = expr binop x; 10465 if (AtomicBinOp->getOpcode() == BO_Assign) { 10466 X = AtomicBinOp->getLHS(); 10467 if (const auto *AtomicInnerBinOp = dyn_cast<BinaryOperator>( 10468 AtomicBinOp->getRHS()->IgnoreParenImpCasts())) { 10469 if (AtomicInnerBinOp->isMultiplicativeOp() || 10470 AtomicInnerBinOp->isAdditiveOp() || AtomicInnerBinOp->isShiftOp() || 10471 AtomicInnerBinOp->isBitwiseOp()) { 10472 Op = AtomicInnerBinOp->getOpcode(); 10473 OpLoc = AtomicInnerBinOp->getOperatorLoc(); 10474 Expr *LHS = AtomicInnerBinOp->getLHS(); 10475 Expr *RHS = AtomicInnerBinOp->getRHS(); 10476 llvm::FoldingSetNodeID XId, LHSId, RHSId; 10477 X->IgnoreParenImpCasts()->Profile(XId, SemaRef.getASTContext(), 10478 /*Canonical=*/true); 10479 LHS->IgnoreParenImpCasts()->Profile(LHSId, SemaRef.getASTContext(), 10480 /*Canonical=*/true); 10481 RHS->IgnoreParenImpCasts()->Profile(RHSId, SemaRef.getASTContext(), 10482 /*Canonical=*/true); 10483 if (XId == LHSId) { 10484 E = RHS; 10485 IsXLHSInRHSPart = true; 10486 } else if (XId == RHSId) { 10487 E = LHS; 10488 IsXLHSInRHSPart = false; 10489 } else { 10490 ErrorLoc = AtomicInnerBinOp->getExprLoc(); 10491 ErrorRange = AtomicInnerBinOp->getSourceRange(); 10492 NoteLoc = X->getExprLoc(); 10493 NoteRange = X->getSourceRange(); 10494 ErrorFound = NotAnUpdateExpression; 10495 } 10496 } else { 10497 ErrorLoc = AtomicInnerBinOp->getExprLoc(); 10498 ErrorRange = AtomicInnerBinOp->getSourceRange(); 10499 NoteLoc = AtomicInnerBinOp->getOperatorLoc(); 10500 NoteRange = SourceRange(NoteLoc, NoteLoc); 10501 ErrorFound = NotABinaryOperator; 10502 } 10503 } else { 10504 NoteLoc = ErrorLoc = AtomicBinOp->getRHS()->getExprLoc(); 10505 NoteRange = ErrorRange = AtomicBinOp->getRHS()->getSourceRange(); 10506 ErrorFound = NotABinaryExpression; 10507 } 10508 } else { 10509 ErrorLoc = AtomicBinOp->getExprLoc(); 10510 ErrorRange = AtomicBinOp->getSourceRange(); 10511 NoteLoc = AtomicBinOp->getOperatorLoc(); 10512 NoteRange = SourceRange(NoteLoc, NoteLoc); 10513 ErrorFound = NotAnAssignmentOp; 10514 } 10515 if (ErrorFound != NoError && DiagId != 0 && NoteId != 0) { 10516 SemaRef.Diag(ErrorLoc, DiagId) << ErrorRange; 10517 SemaRef.Diag(NoteLoc, NoteId) << ErrorFound << NoteRange; 10518 return true; 10519 } 10520 if (SemaRef.CurContext->isDependentContext()) 10521 E = X = UpdateExpr = nullptr; 10522 return ErrorFound != NoError; 10523 } 10524 10525 bool OpenMPAtomicUpdateChecker::checkStatement(Stmt *S, unsigned DiagId, 10526 unsigned NoteId) { 10527 ExprAnalysisErrorCode ErrorFound = NoError; 10528 SourceLocation ErrorLoc, NoteLoc; 10529 SourceRange ErrorRange, NoteRange; 10530 // Allowed constructs are: 10531 // x++; 10532 // x--; 10533 // ++x; 10534 // --x; 10535 // x binop= expr; 10536 // x = x binop expr; 10537 // x = expr binop x; 10538 if (auto *AtomicBody = dyn_cast<Expr>(S)) { 10539 AtomicBody = AtomicBody->IgnoreParenImpCasts(); 10540 if (AtomicBody->getType()->isScalarType() || 10541 AtomicBody->isInstantiationDependent()) { 10542 if (const auto *AtomicCompAssignOp = dyn_cast<CompoundAssignOperator>( 10543 AtomicBody->IgnoreParenImpCasts())) { 10544 // Check for Compound Assignment Operation 10545 Op = BinaryOperator::getOpForCompoundAssignment( 10546 AtomicCompAssignOp->getOpcode()); 10547 OpLoc = AtomicCompAssignOp->getOperatorLoc(); 10548 E = AtomicCompAssignOp->getRHS(); 10549 X = AtomicCompAssignOp->getLHS()->IgnoreParens(); 10550 IsXLHSInRHSPart = true; 10551 } else if (auto *AtomicBinOp = dyn_cast<BinaryOperator>( 10552 AtomicBody->IgnoreParenImpCasts())) { 10553 // Check for Binary Operation 10554 if (checkBinaryOperation(AtomicBinOp, DiagId, NoteId)) 10555 return true; 10556 } else if (const auto *AtomicUnaryOp = dyn_cast<UnaryOperator>( 10557 AtomicBody->IgnoreParenImpCasts())) { 10558 // Check for Unary Operation 10559 if (AtomicUnaryOp->isIncrementDecrementOp()) { 10560 IsPostfixUpdate = AtomicUnaryOp->isPostfix(); 10561 Op = AtomicUnaryOp->isIncrementOp() ? BO_Add : BO_Sub; 10562 OpLoc = AtomicUnaryOp->getOperatorLoc(); 10563 X = AtomicUnaryOp->getSubExpr()->IgnoreParens(); 10564 E = SemaRef.ActOnIntegerConstant(OpLoc, /*uint64_t Val=*/1).get(); 10565 IsXLHSInRHSPart = true; 10566 } else { 10567 ErrorFound = NotAnUnaryIncDecExpression; 10568 ErrorLoc = AtomicUnaryOp->getExprLoc(); 10569 ErrorRange = AtomicUnaryOp->getSourceRange(); 10570 NoteLoc = AtomicUnaryOp->getOperatorLoc(); 10571 NoteRange = SourceRange(NoteLoc, NoteLoc); 10572 } 10573 } else if (!AtomicBody->isInstantiationDependent()) { 10574 ErrorFound = NotABinaryOrUnaryExpression; 10575 NoteLoc = ErrorLoc = AtomicBody->getExprLoc(); 10576 NoteRange = ErrorRange = AtomicBody->getSourceRange(); 10577 } 10578 } else { 10579 ErrorFound = NotAScalarType; 10580 NoteLoc = ErrorLoc = AtomicBody->getBeginLoc(); 10581 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc); 10582 } 10583 } else { 10584 ErrorFound = NotAnExpression; 10585 NoteLoc = ErrorLoc = S->getBeginLoc(); 10586 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc); 10587 } 10588 if (ErrorFound != NoError && DiagId != 0 && NoteId != 0) { 10589 SemaRef.Diag(ErrorLoc, DiagId) << ErrorRange; 10590 SemaRef.Diag(NoteLoc, NoteId) << ErrorFound << NoteRange; 10591 return true; 10592 } 10593 if (SemaRef.CurContext->isDependentContext()) 10594 E = X = UpdateExpr = nullptr; 10595 if (ErrorFound == NoError && E && X) { 10596 // Build an update expression of form 'OpaqueValueExpr(x) binop 10597 // OpaqueValueExpr(expr)' or 'OpaqueValueExpr(expr) binop 10598 // OpaqueValueExpr(x)' and then cast it to the type of the 'x' expression. 10599 auto *OVEX = new (SemaRef.getASTContext()) 10600 OpaqueValueExpr(X->getExprLoc(), X->getType(), VK_RValue); 10601 auto *OVEExpr = new (SemaRef.getASTContext()) 10602 OpaqueValueExpr(E->getExprLoc(), E->getType(), VK_RValue); 10603 ExprResult Update = 10604 SemaRef.CreateBuiltinBinOp(OpLoc, Op, IsXLHSInRHSPart ? OVEX : OVEExpr, 10605 IsXLHSInRHSPart ? OVEExpr : OVEX); 10606 if (Update.isInvalid()) 10607 return true; 10608 Update = SemaRef.PerformImplicitConversion(Update.get(), X->getType(), 10609 Sema::AA_Casting); 10610 if (Update.isInvalid()) 10611 return true; 10612 UpdateExpr = Update.get(); 10613 } 10614 return ErrorFound != NoError; 10615 } 10616 10617 StmtResult Sema::ActOnOpenMPAtomicDirective(ArrayRef<OMPClause *> Clauses, 10618 Stmt *AStmt, 10619 SourceLocation StartLoc, 10620 SourceLocation EndLoc) { 10621 // Register location of the first atomic directive. 10622 DSAStack->addAtomicDirectiveLoc(StartLoc); 10623 if (!AStmt) 10624 return StmtError(); 10625 10626 // 1.2.2 OpenMP Language Terminology 10627 // Structured block - An executable statement with a single entry at the 10628 // top and a single exit at the bottom. 10629 // The point of exit cannot be a branch out of the structured block. 10630 // longjmp() and throw() must not violate the entry/exit criteria. 10631 OpenMPClauseKind AtomicKind = OMPC_unknown; 10632 SourceLocation AtomicKindLoc; 10633 OpenMPClauseKind MemOrderKind = OMPC_unknown; 10634 SourceLocation MemOrderLoc; 10635 for (const OMPClause *C : Clauses) { 10636 if (C->getClauseKind() == OMPC_read || C->getClauseKind() == OMPC_write || 10637 C->getClauseKind() == OMPC_update || 10638 C->getClauseKind() == OMPC_capture) { 10639 if (AtomicKind != OMPC_unknown) { 10640 Diag(C->getBeginLoc(), diag::err_omp_atomic_several_clauses) 10641 << SourceRange(C->getBeginLoc(), C->getEndLoc()); 10642 Diag(AtomicKindLoc, diag::note_omp_previous_mem_order_clause) 10643 << getOpenMPClauseName(AtomicKind); 10644 } else { 10645 AtomicKind = C->getClauseKind(); 10646 AtomicKindLoc = C->getBeginLoc(); 10647 } 10648 } 10649 if (C->getClauseKind() == OMPC_seq_cst || 10650 C->getClauseKind() == OMPC_acq_rel || 10651 C->getClauseKind() == OMPC_acquire || 10652 C->getClauseKind() == OMPC_release || 10653 C->getClauseKind() == OMPC_relaxed) { 10654 if (MemOrderKind != OMPC_unknown) { 10655 Diag(C->getBeginLoc(), diag::err_omp_several_mem_order_clauses) 10656 << getOpenMPDirectiveName(OMPD_atomic) << 0 10657 << SourceRange(C->getBeginLoc(), C->getEndLoc()); 10658 Diag(MemOrderLoc, diag::note_omp_previous_mem_order_clause) 10659 << getOpenMPClauseName(MemOrderKind); 10660 } else { 10661 MemOrderKind = C->getClauseKind(); 10662 MemOrderLoc = C->getBeginLoc(); 10663 } 10664 } 10665 } 10666 // OpenMP 5.0, 2.17.7 atomic Construct, Restrictions 10667 // If atomic-clause is read then memory-order-clause must not be acq_rel or 10668 // release. 10669 // If atomic-clause is write then memory-order-clause must not be acq_rel or 10670 // acquire. 10671 // If atomic-clause is update or not present then memory-order-clause must not 10672 // be acq_rel or acquire. 10673 if ((AtomicKind == OMPC_read && 10674 (MemOrderKind == OMPC_acq_rel || MemOrderKind == OMPC_release)) || 10675 ((AtomicKind == OMPC_write || AtomicKind == OMPC_update || 10676 AtomicKind == OMPC_unknown) && 10677 (MemOrderKind == OMPC_acq_rel || MemOrderKind == OMPC_acquire))) { 10678 SourceLocation Loc = AtomicKindLoc; 10679 if (AtomicKind == OMPC_unknown) 10680 Loc = StartLoc; 10681 Diag(Loc, diag::err_omp_atomic_incompatible_mem_order_clause) 10682 << getOpenMPClauseName(AtomicKind) 10683 << (AtomicKind == OMPC_unknown ? 1 : 0) 10684 << getOpenMPClauseName(MemOrderKind); 10685 Diag(MemOrderLoc, diag::note_omp_previous_mem_order_clause) 10686 << getOpenMPClauseName(MemOrderKind); 10687 } 10688 10689 Stmt *Body = AStmt; 10690 if (auto *EWC = dyn_cast<ExprWithCleanups>(Body)) 10691 Body = EWC->getSubExpr(); 10692 10693 Expr *X = nullptr; 10694 Expr *V = nullptr; 10695 Expr *E = nullptr; 10696 Expr *UE = nullptr; 10697 bool IsXLHSInRHSPart = false; 10698 bool IsPostfixUpdate = false; 10699 // OpenMP [2.12.6, atomic Construct] 10700 // In the next expressions: 10701 // * x and v (as applicable) are both l-value expressions with scalar type. 10702 // * During the execution of an atomic region, multiple syntactic 10703 // occurrences of x must designate the same storage location. 10704 // * Neither of v and expr (as applicable) may access the storage location 10705 // designated by x. 10706 // * Neither of x and expr (as applicable) may access the storage location 10707 // designated by v. 10708 // * expr is an expression with scalar type. 10709 // * binop is one of +, *, -, /, &, ^, |, <<, or >>. 10710 // * binop, binop=, ++, and -- are not overloaded operators. 10711 // * The expression x binop expr must be numerically equivalent to x binop 10712 // (expr). This requirement is satisfied if the operators in expr have 10713 // precedence greater than binop, or by using parentheses around expr or 10714 // subexpressions of expr. 10715 // * The expression expr binop x must be numerically equivalent to (expr) 10716 // binop x. This requirement is satisfied if the operators in expr have 10717 // precedence equal to or greater than binop, or by using parentheses around 10718 // expr or subexpressions of expr. 10719 // * For forms that allow multiple occurrences of x, the number of times 10720 // that x is evaluated is unspecified. 10721 if (AtomicKind == OMPC_read) { 10722 enum { 10723 NotAnExpression, 10724 NotAnAssignmentOp, 10725 NotAScalarType, 10726 NotAnLValue, 10727 NoError 10728 } ErrorFound = NoError; 10729 SourceLocation ErrorLoc, NoteLoc; 10730 SourceRange ErrorRange, NoteRange; 10731 // If clause is read: 10732 // v = x; 10733 if (const auto *AtomicBody = dyn_cast<Expr>(Body)) { 10734 const auto *AtomicBinOp = 10735 dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts()); 10736 if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) { 10737 X = AtomicBinOp->getRHS()->IgnoreParenImpCasts(); 10738 V = AtomicBinOp->getLHS()->IgnoreParenImpCasts(); 10739 if ((X->isInstantiationDependent() || X->getType()->isScalarType()) && 10740 (V->isInstantiationDependent() || V->getType()->isScalarType())) { 10741 if (!X->isLValue() || !V->isLValue()) { 10742 const Expr *NotLValueExpr = X->isLValue() ? V : X; 10743 ErrorFound = NotAnLValue; 10744 ErrorLoc = AtomicBinOp->getExprLoc(); 10745 ErrorRange = AtomicBinOp->getSourceRange(); 10746 NoteLoc = NotLValueExpr->getExprLoc(); 10747 NoteRange = NotLValueExpr->getSourceRange(); 10748 } 10749 } else if (!X->isInstantiationDependent() || 10750 !V->isInstantiationDependent()) { 10751 const Expr *NotScalarExpr = 10752 (X->isInstantiationDependent() || X->getType()->isScalarType()) 10753 ? V 10754 : X; 10755 ErrorFound = NotAScalarType; 10756 ErrorLoc = AtomicBinOp->getExprLoc(); 10757 ErrorRange = AtomicBinOp->getSourceRange(); 10758 NoteLoc = NotScalarExpr->getExprLoc(); 10759 NoteRange = NotScalarExpr->getSourceRange(); 10760 } 10761 } else if (!AtomicBody->isInstantiationDependent()) { 10762 ErrorFound = NotAnAssignmentOp; 10763 ErrorLoc = AtomicBody->getExprLoc(); 10764 ErrorRange = AtomicBody->getSourceRange(); 10765 NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc() 10766 : AtomicBody->getExprLoc(); 10767 NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange() 10768 : AtomicBody->getSourceRange(); 10769 } 10770 } else { 10771 ErrorFound = NotAnExpression; 10772 NoteLoc = ErrorLoc = Body->getBeginLoc(); 10773 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc); 10774 } 10775 if (ErrorFound != NoError) { 10776 Diag(ErrorLoc, diag::err_omp_atomic_read_not_expression_statement) 10777 << ErrorRange; 10778 Diag(NoteLoc, diag::note_omp_atomic_read_write) << ErrorFound 10779 << NoteRange; 10780 return StmtError(); 10781 } 10782 if (CurContext->isDependentContext()) 10783 V = X = nullptr; 10784 } else if (AtomicKind == OMPC_write) { 10785 enum { 10786 NotAnExpression, 10787 NotAnAssignmentOp, 10788 NotAScalarType, 10789 NotAnLValue, 10790 NoError 10791 } ErrorFound = NoError; 10792 SourceLocation ErrorLoc, NoteLoc; 10793 SourceRange ErrorRange, NoteRange; 10794 // If clause is write: 10795 // x = expr; 10796 if (const auto *AtomicBody = dyn_cast<Expr>(Body)) { 10797 const auto *AtomicBinOp = 10798 dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts()); 10799 if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) { 10800 X = AtomicBinOp->getLHS(); 10801 E = AtomicBinOp->getRHS(); 10802 if ((X->isInstantiationDependent() || X->getType()->isScalarType()) && 10803 (E->isInstantiationDependent() || E->getType()->isScalarType())) { 10804 if (!X->isLValue()) { 10805 ErrorFound = NotAnLValue; 10806 ErrorLoc = AtomicBinOp->getExprLoc(); 10807 ErrorRange = AtomicBinOp->getSourceRange(); 10808 NoteLoc = X->getExprLoc(); 10809 NoteRange = X->getSourceRange(); 10810 } 10811 } else if (!X->isInstantiationDependent() || 10812 !E->isInstantiationDependent()) { 10813 const Expr *NotScalarExpr = 10814 (X->isInstantiationDependent() || X->getType()->isScalarType()) 10815 ? E 10816 : X; 10817 ErrorFound = NotAScalarType; 10818 ErrorLoc = AtomicBinOp->getExprLoc(); 10819 ErrorRange = AtomicBinOp->getSourceRange(); 10820 NoteLoc = NotScalarExpr->getExprLoc(); 10821 NoteRange = NotScalarExpr->getSourceRange(); 10822 } 10823 } else if (!AtomicBody->isInstantiationDependent()) { 10824 ErrorFound = NotAnAssignmentOp; 10825 ErrorLoc = AtomicBody->getExprLoc(); 10826 ErrorRange = AtomicBody->getSourceRange(); 10827 NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc() 10828 : AtomicBody->getExprLoc(); 10829 NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange() 10830 : AtomicBody->getSourceRange(); 10831 } 10832 } else { 10833 ErrorFound = NotAnExpression; 10834 NoteLoc = ErrorLoc = Body->getBeginLoc(); 10835 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc); 10836 } 10837 if (ErrorFound != NoError) { 10838 Diag(ErrorLoc, diag::err_omp_atomic_write_not_expression_statement) 10839 << ErrorRange; 10840 Diag(NoteLoc, diag::note_omp_atomic_read_write) << ErrorFound 10841 << NoteRange; 10842 return StmtError(); 10843 } 10844 if (CurContext->isDependentContext()) 10845 E = X = nullptr; 10846 } else if (AtomicKind == OMPC_update || AtomicKind == OMPC_unknown) { 10847 // If clause is update: 10848 // x++; 10849 // x--; 10850 // ++x; 10851 // --x; 10852 // x binop= expr; 10853 // x = x binop expr; 10854 // x = expr binop x; 10855 OpenMPAtomicUpdateChecker Checker(*this); 10856 if (Checker.checkStatement( 10857 Body, (AtomicKind == OMPC_update) 10858 ? diag::err_omp_atomic_update_not_expression_statement 10859 : diag::err_omp_atomic_not_expression_statement, 10860 diag::note_omp_atomic_update)) 10861 return StmtError(); 10862 if (!CurContext->isDependentContext()) { 10863 E = Checker.getExpr(); 10864 X = Checker.getX(); 10865 UE = Checker.getUpdateExpr(); 10866 IsXLHSInRHSPart = Checker.isXLHSInRHSPart(); 10867 } 10868 } else if (AtomicKind == OMPC_capture) { 10869 enum { 10870 NotAnAssignmentOp, 10871 NotACompoundStatement, 10872 NotTwoSubstatements, 10873 NotASpecificExpression, 10874 NoError 10875 } ErrorFound = NoError; 10876 SourceLocation ErrorLoc, NoteLoc; 10877 SourceRange ErrorRange, NoteRange; 10878 if (const auto *AtomicBody = dyn_cast<Expr>(Body)) { 10879 // If clause is a capture: 10880 // v = x++; 10881 // v = x--; 10882 // v = ++x; 10883 // v = --x; 10884 // v = x binop= expr; 10885 // v = x = x binop expr; 10886 // v = x = expr binop x; 10887 const auto *AtomicBinOp = 10888 dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts()); 10889 if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) { 10890 V = AtomicBinOp->getLHS(); 10891 Body = AtomicBinOp->getRHS()->IgnoreParenImpCasts(); 10892 OpenMPAtomicUpdateChecker Checker(*this); 10893 if (Checker.checkStatement( 10894 Body, diag::err_omp_atomic_capture_not_expression_statement, 10895 diag::note_omp_atomic_update)) 10896 return StmtError(); 10897 E = Checker.getExpr(); 10898 X = Checker.getX(); 10899 UE = Checker.getUpdateExpr(); 10900 IsXLHSInRHSPart = Checker.isXLHSInRHSPart(); 10901 IsPostfixUpdate = Checker.isPostfixUpdate(); 10902 } else if (!AtomicBody->isInstantiationDependent()) { 10903 ErrorLoc = AtomicBody->getExprLoc(); 10904 ErrorRange = AtomicBody->getSourceRange(); 10905 NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc() 10906 : AtomicBody->getExprLoc(); 10907 NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange() 10908 : AtomicBody->getSourceRange(); 10909 ErrorFound = NotAnAssignmentOp; 10910 } 10911 if (ErrorFound != NoError) { 10912 Diag(ErrorLoc, diag::err_omp_atomic_capture_not_expression_statement) 10913 << ErrorRange; 10914 Diag(NoteLoc, diag::note_omp_atomic_capture) << ErrorFound << NoteRange; 10915 return StmtError(); 10916 } 10917 if (CurContext->isDependentContext()) 10918 UE = V = E = X = nullptr; 10919 } else { 10920 // If clause is a capture: 10921 // { v = x; x = expr; } 10922 // { v = x; x++; } 10923 // { v = x; x--; } 10924 // { v = x; ++x; } 10925 // { v = x; --x; } 10926 // { v = x; x binop= expr; } 10927 // { v = x; x = x binop expr; } 10928 // { v = x; x = expr binop x; } 10929 // { x++; v = x; } 10930 // { x--; v = x; } 10931 // { ++x; v = x; } 10932 // { --x; v = x; } 10933 // { x binop= expr; v = x; } 10934 // { x = x binop expr; v = x; } 10935 // { x = expr binop x; v = x; } 10936 if (auto *CS = dyn_cast<CompoundStmt>(Body)) { 10937 // Check that this is { expr1; expr2; } 10938 if (CS->size() == 2) { 10939 Stmt *First = CS->body_front(); 10940 Stmt *Second = CS->body_back(); 10941 if (auto *EWC = dyn_cast<ExprWithCleanups>(First)) 10942 First = EWC->getSubExpr()->IgnoreParenImpCasts(); 10943 if (auto *EWC = dyn_cast<ExprWithCleanups>(Second)) 10944 Second = EWC->getSubExpr()->IgnoreParenImpCasts(); 10945 // Need to find what subexpression is 'v' and what is 'x'. 10946 OpenMPAtomicUpdateChecker Checker(*this); 10947 bool IsUpdateExprFound = !Checker.checkStatement(Second); 10948 BinaryOperator *BinOp = nullptr; 10949 if (IsUpdateExprFound) { 10950 BinOp = dyn_cast<BinaryOperator>(First); 10951 IsUpdateExprFound = BinOp && BinOp->getOpcode() == BO_Assign; 10952 } 10953 if (IsUpdateExprFound && !CurContext->isDependentContext()) { 10954 // { v = x; x++; } 10955 // { v = x; x--; } 10956 // { v = x; ++x; } 10957 // { v = x; --x; } 10958 // { v = x; x binop= expr; } 10959 // { v = x; x = x binop expr; } 10960 // { v = x; x = expr binop x; } 10961 // Check that the first expression has form v = x. 10962 Expr *PossibleX = BinOp->getRHS()->IgnoreParenImpCasts(); 10963 llvm::FoldingSetNodeID XId, PossibleXId; 10964 Checker.getX()->Profile(XId, Context, /*Canonical=*/true); 10965 PossibleX->Profile(PossibleXId, Context, /*Canonical=*/true); 10966 IsUpdateExprFound = XId == PossibleXId; 10967 if (IsUpdateExprFound) { 10968 V = BinOp->getLHS(); 10969 X = Checker.getX(); 10970 E = Checker.getExpr(); 10971 UE = Checker.getUpdateExpr(); 10972 IsXLHSInRHSPart = Checker.isXLHSInRHSPart(); 10973 IsPostfixUpdate = true; 10974 } 10975 } 10976 if (!IsUpdateExprFound) { 10977 IsUpdateExprFound = !Checker.checkStatement(First); 10978 BinOp = nullptr; 10979 if (IsUpdateExprFound) { 10980 BinOp = dyn_cast<BinaryOperator>(Second); 10981 IsUpdateExprFound = BinOp && BinOp->getOpcode() == BO_Assign; 10982 } 10983 if (IsUpdateExprFound && !CurContext->isDependentContext()) { 10984 // { x++; v = x; } 10985 // { x--; v = x; } 10986 // { ++x; v = x; } 10987 // { --x; v = x; } 10988 // { x binop= expr; v = x; } 10989 // { x = x binop expr; v = x; } 10990 // { x = expr binop x; v = x; } 10991 // Check that the second expression has form v = x. 10992 Expr *PossibleX = BinOp->getRHS()->IgnoreParenImpCasts(); 10993 llvm::FoldingSetNodeID XId, PossibleXId; 10994 Checker.getX()->Profile(XId, Context, /*Canonical=*/true); 10995 PossibleX->Profile(PossibleXId, Context, /*Canonical=*/true); 10996 IsUpdateExprFound = XId == PossibleXId; 10997 if (IsUpdateExprFound) { 10998 V = BinOp->getLHS(); 10999 X = Checker.getX(); 11000 E = Checker.getExpr(); 11001 UE = Checker.getUpdateExpr(); 11002 IsXLHSInRHSPart = Checker.isXLHSInRHSPart(); 11003 IsPostfixUpdate = false; 11004 } 11005 } 11006 } 11007 if (!IsUpdateExprFound) { 11008 // { v = x; x = expr; } 11009 auto *FirstExpr = dyn_cast<Expr>(First); 11010 auto *SecondExpr = dyn_cast<Expr>(Second); 11011 if (!FirstExpr || !SecondExpr || 11012 !(FirstExpr->isInstantiationDependent() || 11013 SecondExpr->isInstantiationDependent())) { 11014 auto *FirstBinOp = dyn_cast<BinaryOperator>(First); 11015 if (!FirstBinOp || FirstBinOp->getOpcode() != BO_Assign) { 11016 ErrorFound = NotAnAssignmentOp; 11017 NoteLoc = ErrorLoc = FirstBinOp ? FirstBinOp->getOperatorLoc() 11018 : First->getBeginLoc(); 11019 NoteRange = ErrorRange = FirstBinOp 11020 ? FirstBinOp->getSourceRange() 11021 : SourceRange(ErrorLoc, ErrorLoc); 11022 } else { 11023 auto *SecondBinOp = dyn_cast<BinaryOperator>(Second); 11024 if (!SecondBinOp || SecondBinOp->getOpcode() != BO_Assign) { 11025 ErrorFound = NotAnAssignmentOp; 11026 NoteLoc = ErrorLoc = SecondBinOp 11027 ? SecondBinOp->getOperatorLoc() 11028 : Second->getBeginLoc(); 11029 NoteRange = ErrorRange = 11030 SecondBinOp ? SecondBinOp->getSourceRange() 11031 : SourceRange(ErrorLoc, ErrorLoc); 11032 } else { 11033 Expr *PossibleXRHSInFirst = 11034 FirstBinOp->getRHS()->IgnoreParenImpCasts(); 11035 Expr *PossibleXLHSInSecond = 11036 SecondBinOp->getLHS()->IgnoreParenImpCasts(); 11037 llvm::FoldingSetNodeID X1Id, X2Id; 11038 PossibleXRHSInFirst->Profile(X1Id, Context, 11039 /*Canonical=*/true); 11040 PossibleXLHSInSecond->Profile(X2Id, Context, 11041 /*Canonical=*/true); 11042 IsUpdateExprFound = X1Id == X2Id; 11043 if (IsUpdateExprFound) { 11044 V = FirstBinOp->getLHS(); 11045 X = SecondBinOp->getLHS(); 11046 E = SecondBinOp->getRHS(); 11047 UE = nullptr; 11048 IsXLHSInRHSPart = false; 11049 IsPostfixUpdate = true; 11050 } else { 11051 ErrorFound = NotASpecificExpression; 11052 ErrorLoc = FirstBinOp->getExprLoc(); 11053 ErrorRange = FirstBinOp->getSourceRange(); 11054 NoteLoc = SecondBinOp->getLHS()->getExprLoc(); 11055 NoteRange = SecondBinOp->getRHS()->getSourceRange(); 11056 } 11057 } 11058 } 11059 } 11060 } 11061 } else { 11062 NoteLoc = ErrorLoc = Body->getBeginLoc(); 11063 NoteRange = ErrorRange = 11064 SourceRange(Body->getBeginLoc(), Body->getBeginLoc()); 11065 ErrorFound = NotTwoSubstatements; 11066 } 11067 } else { 11068 NoteLoc = ErrorLoc = Body->getBeginLoc(); 11069 NoteRange = ErrorRange = 11070 SourceRange(Body->getBeginLoc(), Body->getBeginLoc()); 11071 ErrorFound = NotACompoundStatement; 11072 } 11073 if (ErrorFound != NoError) { 11074 Diag(ErrorLoc, diag::err_omp_atomic_capture_not_compound_statement) 11075 << ErrorRange; 11076 Diag(NoteLoc, diag::note_omp_atomic_capture) << ErrorFound << NoteRange; 11077 return StmtError(); 11078 } 11079 if (CurContext->isDependentContext()) 11080 UE = V = E = X = nullptr; 11081 } 11082 } 11083 11084 setFunctionHasBranchProtectedScope(); 11085 11086 return OMPAtomicDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt, 11087 X, V, E, UE, IsXLHSInRHSPart, 11088 IsPostfixUpdate); 11089 } 11090 11091 StmtResult Sema::ActOnOpenMPTargetDirective(ArrayRef<OMPClause *> Clauses, 11092 Stmt *AStmt, 11093 SourceLocation StartLoc, 11094 SourceLocation EndLoc) { 11095 if (!AStmt) 11096 return StmtError(); 11097 11098 auto *CS = cast<CapturedStmt>(AStmt); 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 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target); 11106 ThisCaptureLevel > 1; --ThisCaptureLevel) { 11107 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 11108 // 1.2.2 OpenMP Language Terminology 11109 // Structured block - An executable statement with a single entry at the 11110 // top and a single exit at the bottom. 11111 // The point of exit cannot be a branch out of the structured block. 11112 // longjmp() and throw() must not violate the entry/exit criteria. 11113 CS->getCapturedDecl()->setNothrow(); 11114 } 11115 11116 // OpenMP [2.16, Nesting of Regions] 11117 // If specified, a teams construct must be contained within a target 11118 // construct. That target construct must contain no statements or directives 11119 // outside of the teams construct. 11120 if (DSAStack->hasInnerTeamsRegion()) { 11121 const Stmt *S = CS->IgnoreContainers(/*IgnoreCaptured=*/true); 11122 bool OMPTeamsFound = true; 11123 if (const auto *CS = dyn_cast<CompoundStmt>(S)) { 11124 auto I = CS->body_begin(); 11125 while (I != CS->body_end()) { 11126 const auto *OED = dyn_cast<OMPExecutableDirective>(*I); 11127 if (!OED || !isOpenMPTeamsDirective(OED->getDirectiveKind()) || 11128 OMPTeamsFound) { 11129 11130 OMPTeamsFound = false; 11131 break; 11132 } 11133 ++I; 11134 } 11135 assert(I != CS->body_end() && "Not found statement"); 11136 S = *I; 11137 } else { 11138 const auto *OED = dyn_cast<OMPExecutableDirective>(S); 11139 OMPTeamsFound = OED && isOpenMPTeamsDirective(OED->getDirectiveKind()); 11140 } 11141 if (!OMPTeamsFound) { 11142 Diag(StartLoc, diag::err_omp_target_contains_not_only_teams); 11143 Diag(DSAStack->getInnerTeamsRegionLoc(), 11144 diag::note_omp_nested_teams_construct_here); 11145 Diag(S->getBeginLoc(), diag::note_omp_nested_statement_here) 11146 << isa<OMPExecutableDirective>(S); 11147 return StmtError(); 11148 } 11149 } 11150 11151 setFunctionHasBranchProtectedScope(); 11152 11153 return OMPTargetDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt); 11154 } 11155 11156 StmtResult 11157 Sema::ActOnOpenMPTargetParallelDirective(ArrayRef<OMPClause *> Clauses, 11158 Stmt *AStmt, SourceLocation StartLoc, 11159 SourceLocation EndLoc) { 11160 if (!AStmt) 11161 return StmtError(); 11162 11163 auto *CS = cast<CapturedStmt>(AStmt); 11164 // 1.2.2 OpenMP Language Terminology 11165 // Structured block - An executable statement with a single entry at the 11166 // top and a single exit at the bottom. 11167 // The point of exit cannot be a branch out of the structured block. 11168 // longjmp() and throw() must not violate the entry/exit criteria. 11169 CS->getCapturedDecl()->setNothrow(); 11170 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel); 11171 ThisCaptureLevel > 1; --ThisCaptureLevel) { 11172 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 11173 // 1.2.2 OpenMP Language Terminology 11174 // Structured block - An executable statement with a single entry at the 11175 // top and a single exit at the bottom. 11176 // The point of exit cannot be a branch out of the structured block. 11177 // longjmp() and throw() must not violate the entry/exit criteria. 11178 CS->getCapturedDecl()->setNothrow(); 11179 } 11180 11181 setFunctionHasBranchProtectedScope(); 11182 11183 return OMPTargetParallelDirective::Create( 11184 Context, StartLoc, EndLoc, Clauses, AStmt, 11185 DSAStack->getTaskgroupReductionRef(), DSAStack->isCancelRegion()); 11186 } 11187 11188 StmtResult Sema::ActOnOpenMPTargetParallelForDirective( 11189 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 11190 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 11191 if (!AStmt) 11192 return StmtError(); 11193 11194 auto *CS = cast<CapturedStmt>(AStmt); 11195 // 1.2.2 OpenMP Language Terminology 11196 // Structured block - An executable statement with a single entry at the 11197 // top and a single exit at the bottom. 11198 // The point of exit cannot be a branch out of the structured block. 11199 // longjmp() and throw() must not violate the entry/exit criteria. 11200 CS->getCapturedDecl()->setNothrow(); 11201 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel_for); 11202 ThisCaptureLevel > 1; --ThisCaptureLevel) { 11203 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 11204 // 1.2.2 OpenMP Language Terminology 11205 // Structured block - An executable statement with a single entry at the 11206 // top and a single exit at the bottom. 11207 // The point of exit cannot be a branch out of the structured block. 11208 // longjmp() and throw() must not violate the entry/exit criteria. 11209 CS->getCapturedDecl()->setNothrow(); 11210 } 11211 11212 OMPLoopBasedDirective::HelperExprs B; 11213 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 11214 // define the nested loops number. 11215 unsigned NestedLoopCount = 11216 checkOpenMPLoop(OMPD_target_parallel_for, getCollapseNumberExpr(Clauses), 11217 getOrderedNumberExpr(Clauses), CS, *this, *DSAStack, 11218 VarsWithImplicitDSA, B); 11219 if (NestedLoopCount == 0) 11220 return StmtError(); 11221 11222 assert((CurContext->isDependentContext() || B.builtAll()) && 11223 "omp target parallel for loop exprs were not built"); 11224 11225 if (!CurContext->isDependentContext()) { 11226 // Finalize the clauses that need pre-built expressions for CodeGen. 11227 for (OMPClause *C : Clauses) { 11228 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 11229 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 11230 B.NumIterations, *this, CurScope, 11231 DSAStack)) 11232 return StmtError(); 11233 } 11234 } 11235 11236 setFunctionHasBranchProtectedScope(); 11237 return OMPTargetParallelForDirective::Create( 11238 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B, 11239 DSAStack->getTaskgroupReductionRef(), DSAStack->isCancelRegion()); 11240 } 11241 11242 /// Check for existence of a map clause in the list of clauses. 11243 static bool hasClauses(ArrayRef<OMPClause *> Clauses, 11244 const OpenMPClauseKind K) { 11245 return llvm::any_of( 11246 Clauses, [K](const OMPClause *C) { return C->getClauseKind() == K; }); 11247 } 11248 11249 template <typename... Params> 11250 static bool hasClauses(ArrayRef<OMPClause *> Clauses, const OpenMPClauseKind K, 11251 const Params... ClauseTypes) { 11252 return hasClauses(Clauses, K) || hasClauses(Clauses, ClauseTypes...); 11253 } 11254 11255 StmtResult Sema::ActOnOpenMPTargetDataDirective(ArrayRef<OMPClause *> Clauses, 11256 Stmt *AStmt, 11257 SourceLocation StartLoc, 11258 SourceLocation EndLoc) { 11259 if (!AStmt) 11260 return StmtError(); 11261 11262 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 11263 11264 // OpenMP [2.12.2, target data Construct, Restrictions] 11265 // At least one map, use_device_addr or use_device_ptr clause must appear on 11266 // the directive. 11267 if (!hasClauses(Clauses, OMPC_map, OMPC_use_device_ptr) && 11268 (LangOpts.OpenMP < 50 || !hasClauses(Clauses, OMPC_use_device_addr))) { 11269 StringRef Expected; 11270 if (LangOpts.OpenMP < 50) 11271 Expected = "'map' or 'use_device_ptr'"; 11272 else 11273 Expected = "'map', 'use_device_ptr', or 'use_device_addr'"; 11274 Diag(StartLoc, diag::err_omp_no_clause_for_directive) 11275 << Expected << getOpenMPDirectiveName(OMPD_target_data); 11276 return StmtError(); 11277 } 11278 11279 setFunctionHasBranchProtectedScope(); 11280 11281 return OMPTargetDataDirective::Create(Context, StartLoc, EndLoc, Clauses, 11282 AStmt); 11283 } 11284 11285 StmtResult 11286 Sema::ActOnOpenMPTargetEnterDataDirective(ArrayRef<OMPClause *> Clauses, 11287 SourceLocation StartLoc, 11288 SourceLocation EndLoc, Stmt *AStmt) { 11289 if (!AStmt) 11290 return StmtError(); 11291 11292 auto *CS = cast<CapturedStmt>(AStmt); 11293 // 1.2.2 OpenMP Language Terminology 11294 // Structured block - An executable statement with a single entry at the 11295 // top and a single exit at the bottom. 11296 // The point of exit cannot be a branch out of the structured block. 11297 // longjmp() and throw() must not violate the entry/exit criteria. 11298 CS->getCapturedDecl()->setNothrow(); 11299 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_enter_data); 11300 ThisCaptureLevel > 1; --ThisCaptureLevel) { 11301 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 11302 // 1.2.2 OpenMP Language Terminology 11303 // Structured block - An executable statement with a single entry at the 11304 // top and a single exit at the bottom. 11305 // The point of exit cannot be a branch out of the structured block. 11306 // longjmp() and throw() must not violate the entry/exit criteria. 11307 CS->getCapturedDecl()->setNothrow(); 11308 } 11309 11310 // OpenMP [2.10.2, Restrictions, p. 99] 11311 // At least one map clause must appear on the directive. 11312 if (!hasClauses(Clauses, OMPC_map)) { 11313 Diag(StartLoc, diag::err_omp_no_clause_for_directive) 11314 << "'map'" << getOpenMPDirectiveName(OMPD_target_enter_data); 11315 return StmtError(); 11316 } 11317 11318 return OMPTargetEnterDataDirective::Create(Context, StartLoc, EndLoc, Clauses, 11319 AStmt); 11320 } 11321 11322 StmtResult 11323 Sema::ActOnOpenMPTargetExitDataDirective(ArrayRef<OMPClause *> Clauses, 11324 SourceLocation StartLoc, 11325 SourceLocation EndLoc, Stmt *AStmt) { 11326 if (!AStmt) 11327 return StmtError(); 11328 11329 auto *CS = cast<CapturedStmt>(AStmt); 11330 // 1.2.2 OpenMP Language Terminology 11331 // Structured block - An executable statement with a single entry at the 11332 // top and a single exit at the bottom. 11333 // The point of exit cannot be a branch out of the structured block. 11334 // longjmp() and throw() must not violate the entry/exit criteria. 11335 CS->getCapturedDecl()->setNothrow(); 11336 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_exit_data); 11337 ThisCaptureLevel > 1; --ThisCaptureLevel) { 11338 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 11339 // 1.2.2 OpenMP Language Terminology 11340 // Structured block - An executable statement with a single entry at the 11341 // top and a single exit at the bottom. 11342 // The point of exit cannot be a branch out of the structured block. 11343 // longjmp() and throw() must not violate the entry/exit criteria. 11344 CS->getCapturedDecl()->setNothrow(); 11345 } 11346 11347 // OpenMP [2.10.3, Restrictions, p. 102] 11348 // At least one map clause must appear on the directive. 11349 if (!hasClauses(Clauses, OMPC_map)) { 11350 Diag(StartLoc, diag::err_omp_no_clause_for_directive) 11351 << "'map'" << getOpenMPDirectiveName(OMPD_target_exit_data); 11352 return StmtError(); 11353 } 11354 11355 return OMPTargetExitDataDirective::Create(Context, StartLoc, EndLoc, Clauses, 11356 AStmt); 11357 } 11358 11359 StmtResult Sema::ActOnOpenMPTargetUpdateDirective(ArrayRef<OMPClause *> Clauses, 11360 SourceLocation StartLoc, 11361 SourceLocation EndLoc, 11362 Stmt *AStmt) { 11363 if (!AStmt) 11364 return StmtError(); 11365 11366 auto *CS = cast<CapturedStmt>(AStmt); 11367 // 1.2.2 OpenMP Language Terminology 11368 // Structured block - An executable statement with a single entry at the 11369 // top and a single exit at the bottom. 11370 // The point of exit cannot be a branch out of the structured block. 11371 // longjmp() and throw() must not violate the entry/exit criteria. 11372 CS->getCapturedDecl()->setNothrow(); 11373 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_update); 11374 ThisCaptureLevel > 1; --ThisCaptureLevel) { 11375 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 11376 // 1.2.2 OpenMP Language Terminology 11377 // Structured block - An executable statement with a single entry at the 11378 // top and a single exit at the bottom. 11379 // The point of exit cannot be a branch out of the structured block. 11380 // longjmp() and throw() must not violate the entry/exit criteria. 11381 CS->getCapturedDecl()->setNothrow(); 11382 } 11383 11384 if (!hasClauses(Clauses, OMPC_to, OMPC_from)) { 11385 Diag(StartLoc, diag::err_omp_at_least_one_motion_clause_required); 11386 return StmtError(); 11387 } 11388 return OMPTargetUpdateDirective::Create(Context, StartLoc, EndLoc, Clauses, 11389 AStmt); 11390 } 11391 11392 StmtResult Sema::ActOnOpenMPTeamsDirective(ArrayRef<OMPClause *> Clauses, 11393 Stmt *AStmt, SourceLocation StartLoc, 11394 SourceLocation EndLoc) { 11395 if (!AStmt) 11396 return StmtError(); 11397 11398 auto *CS = cast<CapturedStmt>(AStmt); 11399 // 1.2.2 OpenMP Language Terminology 11400 // Structured block - An executable statement with a single entry at the 11401 // top and a single exit at the bottom. 11402 // The point of exit cannot be a branch out of the structured block. 11403 // longjmp() and throw() must not violate the entry/exit criteria. 11404 CS->getCapturedDecl()->setNothrow(); 11405 11406 setFunctionHasBranchProtectedScope(); 11407 11408 DSAStack->setParentTeamsRegionLoc(StartLoc); 11409 11410 return OMPTeamsDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt); 11411 } 11412 11413 StmtResult 11414 Sema::ActOnOpenMPCancellationPointDirective(SourceLocation StartLoc, 11415 SourceLocation EndLoc, 11416 OpenMPDirectiveKind CancelRegion) { 11417 if (DSAStack->isParentNowaitRegion()) { 11418 Diag(StartLoc, diag::err_omp_parent_cancel_region_nowait) << 0; 11419 return StmtError(); 11420 } 11421 if (DSAStack->isParentOrderedRegion()) { 11422 Diag(StartLoc, diag::err_omp_parent_cancel_region_ordered) << 0; 11423 return StmtError(); 11424 } 11425 return OMPCancellationPointDirective::Create(Context, StartLoc, EndLoc, 11426 CancelRegion); 11427 } 11428 11429 StmtResult Sema::ActOnOpenMPCancelDirective(ArrayRef<OMPClause *> Clauses, 11430 SourceLocation StartLoc, 11431 SourceLocation EndLoc, 11432 OpenMPDirectiveKind CancelRegion) { 11433 if (DSAStack->isParentNowaitRegion()) { 11434 Diag(StartLoc, diag::err_omp_parent_cancel_region_nowait) << 1; 11435 return StmtError(); 11436 } 11437 if (DSAStack->isParentOrderedRegion()) { 11438 Diag(StartLoc, diag::err_omp_parent_cancel_region_ordered) << 1; 11439 return StmtError(); 11440 } 11441 DSAStack->setParentCancelRegion(/*Cancel=*/true); 11442 return OMPCancelDirective::Create(Context, StartLoc, EndLoc, Clauses, 11443 CancelRegion); 11444 } 11445 11446 static bool checkGrainsizeNumTasksClauses(Sema &S, 11447 ArrayRef<OMPClause *> Clauses) { 11448 const OMPClause *PrevClause = nullptr; 11449 bool ErrorFound = false; 11450 for (const OMPClause *C : Clauses) { 11451 if (C->getClauseKind() == OMPC_grainsize || 11452 C->getClauseKind() == OMPC_num_tasks) { 11453 if (!PrevClause) 11454 PrevClause = C; 11455 else if (PrevClause->getClauseKind() != C->getClauseKind()) { 11456 S.Diag(C->getBeginLoc(), diag::err_omp_clauses_mutually_exclusive) 11457 << getOpenMPClauseName(C->getClauseKind()) 11458 << getOpenMPClauseName(PrevClause->getClauseKind()); 11459 S.Diag(PrevClause->getBeginLoc(), diag::note_omp_previous_clause) 11460 << getOpenMPClauseName(PrevClause->getClauseKind()); 11461 ErrorFound = true; 11462 } 11463 } 11464 } 11465 return ErrorFound; 11466 } 11467 11468 static bool checkReductionClauseWithNogroup(Sema &S, 11469 ArrayRef<OMPClause *> Clauses) { 11470 const OMPClause *ReductionClause = nullptr; 11471 const OMPClause *NogroupClause = nullptr; 11472 for (const OMPClause *C : Clauses) { 11473 if (C->getClauseKind() == OMPC_reduction) { 11474 ReductionClause = C; 11475 if (NogroupClause) 11476 break; 11477 continue; 11478 } 11479 if (C->getClauseKind() == OMPC_nogroup) { 11480 NogroupClause = C; 11481 if (ReductionClause) 11482 break; 11483 continue; 11484 } 11485 } 11486 if (ReductionClause && NogroupClause) { 11487 S.Diag(ReductionClause->getBeginLoc(), diag::err_omp_reduction_with_nogroup) 11488 << SourceRange(NogroupClause->getBeginLoc(), 11489 NogroupClause->getEndLoc()); 11490 return true; 11491 } 11492 return false; 11493 } 11494 11495 StmtResult Sema::ActOnOpenMPTaskLoopDirective( 11496 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 11497 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 11498 if (!AStmt) 11499 return StmtError(); 11500 11501 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 11502 OMPLoopBasedDirective::HelperExprs B; 11503 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 11504 // define the nested loops number. 11505 unsigned NestedLoopCount = 11506 checkOpenMPLoop(OMPD_taskloop, getCollapseNumberExpr(Clauses), 11507 /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack, 11508 VarsWithImplicitDSA, B); 11509 if (NestedLoopCount == 0) 11510 return StmtError(); 11511 11512 assert((CurContext->isDependentContext() || B.builtAll()) && 11513 "omp for loop exprs were not built"); 11514 11515 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 11516 // The grainsize clause and num_tasks clause are mutually exclusive and may 11517 // not appear on the same taskloop directive. 11518 if (checkGrainsizeNumTasksClauses(*this, Clauses)) 11519 return StmtError(); 11520 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 11521 // If a reduction clause is present on the taskloop directive, the nogroup 11522 // clause must not be specified. 11523 if (checkReductionClauseWithNogroup(*this, Clauses)) 11524 return StmtError(); 11525 11526 setFunctionHasBranchProtectedScope(); 11527 return OMPTaskLoopDirective::Create(Context, StartLoc, EndLoc, 11528 NestedLoopCount, Clauses, AStmt, B, 11529 DSAStack->isCancelRegion()); 11530 } 11531 11532 StmtResult Sema::ActOnOpenMPTaskLoopSimdDirective( 11533 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 11534 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 11535 if (!AStmt) 11536 return StmtError(); 11537 11538 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 11539 OMPLoopBasedDirective::HelperExprs B; 11540 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 11541 // define the nested loops number. 11542 unsigned NestedLoopCount = 11543 checkOpenMPLoop(OMPD_taskloop_simd, getCollapseNumberExpr(Clauses), 11544 /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack, 11545 VarsWithImplicitDSA, B); 11546 if (NestedLoopCount == 0) 11547 return StmtError(); 11548 11549 assert((CurContext->isDependentContext() || B.builtAll()) && 11550 "omp for loop exprs were not built"); 11551 11552 if (!CurContext->isDependentContext()) { 11553 // Finalize the clauses that need pre-built expressions for CodeGen. 11554 for (OMPClause *C : Clauses) { 11555 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 11556 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 11557 B.NumIterations, *this, CurScope, 11558 DSAStack)) 11559 return StmtError(); 11560 } 11561 } 11562 11563 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 11564 // The grainsize clause and num_tasks clause are mutually exclusive and may 11565 // not appear on the same taskloop directive. 11566 if (checkGrainsizeNumTasksClauses(*this, Clauses)) 11567 return StmtError(); 11568 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 11569 // If a reduction clause is present on the taskloop directive, the nogroup 11570 // clause must not be specified. 11571 if (checkReductionClauseWithNogroup(*this, Clauses)) 11572 return StmtError(); 11573 if (checkSimdlenSafelenSpecified(*this, Clauses)) 11574 return StmtError(); 11575 11576 setFunctionHasBranchProtectedScope(); 11577 return OMPTaskLoopSimdDirective::Create(Context, StartLoc, EndLoc, 11578 NestedLoopCount, Clauses, AStmt, B); 11579 } 11580 11581 StmtResult Sema::ActOnOpenMPMasterTaskLoopDirective( 11582 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 11583 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 11584 if (!AStmt) 11585 return StmtError(); 11586 11587 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 11588 OMPLoopBasedDirective::HelperExprs B; 11589 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 11590 // define the nested loops number. 11591 unsigned NestedLoopCount = 11592 checkOpenMPLoop(OMPD_master_taskloop, getCollapseNumberExpr(Clauses), 11593 /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack, 11594 VarsWithImplicitDSA, B); 11595 if (NestedLoopCount == 0) 11596 return StmtError(); 11597 11598 assert((CurContext->isDependentContext() || B.builtAll()) && 11599 "omp for loop exprs were not built"); 11600 11601 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 11602 // The grainsize clause and num_tasks clause are mutually exclusive and may 11603 // not appear on the same taskloop directive. 11604 if (checkGrainsizeNumTasksClauses(*this, Clauses)) 11605 return StmtError(); 11606 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 11607 // If a reduction clause is present on the taskloop directive, the nogroup 11608 // clause must not be specified. 11609 if (checkReductionClauseWithNogroup(*this, Clauses)) 11610 return StmtError(); 11611 11612 setFunctionHasBranchProtectedScope(); 11613 return OMPMasterTaskLoopDirective::Create(Context, StartLoc, EndLoc, 11614 NestedLoopCount, Clauses, AStmt, B, 11615 DSAStack->isCancelRegion()); 11616 } 11617 11618 StmtResult Sema::ActOnOpenMPMasterTaskLoopSimdDirective( 11619 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 11620 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 11621 if (!AStmt) 11622 return StmtError(); 11623 11624 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 11625 OMPLoopBasedDirective::HelperExprs B; 11626 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 11627 // define the nested loops number. 11628 unsigned NestedLoopCount = 11629 checkOpenMPLoop(OMPD_master_taskloop_simd, getCollapseNumberExpr(Clauses), 11630 /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack, 11631 VarsWithImplicitDSA, B); 11632 if (NestedLoopCount == 0) 11633 return StmtError(); 11634 11635 assert((CurContext->isDependentContext() || B.builtAll()) && 11636 "omp for loop exprs were not built"); 11637 11638 if (!CurContext->isDependentContext()) { 11639 // Finalize the clauses that need pre-built expressions for CodeGen. 11640 for (OMPClause *C : Clauses) { 11641 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 11642 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 11643 B.NumIterations, *this, CurScope, 11644 DSAStack)) 11645 return StmtError(); 11646 } 11647 } 11648 11649 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 11650 // The grainsize clause and num_tasks clause are mutually exclusive and may 11651 // not appear on the same taskloop directive. 11652 if (checkGrainsizeNumTasksClauses(*this, Clauses)) 11653 return StmtError(); 11654 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 11655 // If a reduction clause is present on the taskloop directive, the nogroup 11656 // clause must not be specified. 11657 if (checkReductionClauseWithNogroup(*this, Clauses)) 11658 return StmtError(); 11659 if (checkSimdlenSafelenSpecified(*this, Clauses)) 11660 return StmtError(); 11661 11662 setFunctionHasBranchProtectedScope(); 11663 return OMPMasterTaskLoopSimdDirective::Create( 11664 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 11665 } 11666 11667 StmtResult Sema::ActOnOpenMPParallelMasterTaskLoopDirective( 11668 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 11669 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 11670 if (!AStmt) 11671 return StmtError(); 11672 11673 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 11674 auto *CS = cast<CapturedStmt>(AStmt); 11675 // 1.2.2 OpenMP Language Terminology 11676 // Structured block - An executable statement with a single entry at the 11677 // top and a single exit at the bottom. 11678 // The point of exit cannot be a branch out of the structured block. 11679 // longjmp() and throw() must not violate the entry/exit criteria. 11680 CS->getCapturedDecl()->setNothrow(); 11681 for (int ThisCaptureLevel = 11682 getOpenMPCaptureLevels(OMPD_parallel_master_taskloop); 11683 ThisCaptureLevel > 1; --ThisCaptureLevel) { 11684 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 11685 // 1.2.2 OpenMP Language Terminology 11686 // Structured block - An executable statement with a single entry at the 11687 // top and a single exit at the bottom. 11688 // The point of exit cannot be a branch out of the structured block. 11689 // longjmp() and throw() must not violate the entry/exit criteria. 11690 CS->getCapturedDecl()->setNothrow(); 11691 } 11692 11693 OMPLoopBasedDirective::HelperExprs B; 11694 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 11695 // define the nested loops number. 11696 unsigned NestedLoopCount = checkOpenMPLoop( 11697 OMPD_parallel_master_taskloop, getCollapseNumberExpr(Clauses), 11698 /*OrderedLoopCountExpr=*/nullptr, CS, *this, *DSAStack, 11699 VarsWithImplicitDSA, B); 11700 if (NestedLoopCount == 0) 11701 return StmtError(); 11702 11703 assert((CurContext->isDependentContext() || B.builtAll()) && 11704 "omp for loop exprs were not built"); 11705 11706 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 11707 // The grainsize clause and num_tasks clause are mutually exclusive and may 11708 // not appear on the same taskloop directive. 11709 if (checkGrainsizeNumTasksClauses(*this, Clauses)) 11710 return StmtError(); 11711 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 11712 // If a reduction clause is present on the taskloop directive, the nogroup 11713 // clause must not be specified. 11714 if (checkReductionClauseWithNogroup(*this, Clauses)) 11715 return StmtError(); 11716 11717 setFunctionHasBranchProtectedScope(); 11718 return OMPParallelMasterTaskLoopDirective::Create( 11719 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B, 11720 DSAStack->isCancelRegion()); 11721 } 11722 11723 StmtResult Sema::ActOnOpenMPParallelMasterTaskLoopSimdDirective( 11724 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 11725 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 11726 if (!AStmt) 11727 return StmtError(); 11728 11729 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 11730 auto *CS = cast<CapturedStmt>(AStmt); 11731 // 1.2.2 OpenMP Language Terminology 11732 // Structured block - An executable statement with a single entry at the 11733 // top and a single exit at the bottom. 11734 // The point of exit cannot be a branch out of the structured block. 11735 // longjmp() and throw() must not violate the entry/exit criteria. 11736 CS->getCapturedDecl()->setNothrow(); 11737 for (int ThisCaptureLevel = 11738 getOpenMPCaptureLevels(OMPD_parallel_master_taskloop_simd); 11739 ThisCaptureLevel > 1; --ThisCaptureLevel) { 11740 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 11741 // 1.2.2 OpenMP Language Terminology 11742 // Structured block - An executable statement with a single entry at the 11743 // top and a single exit at the bottom. 11744 // The point of exit cannot be a branch out of the structured block. 11745 // longjmp() and throw() must not violate the entry/exit criteria. 11746 CS->getCapturedDecl()->setNothrow(); 11747 } 11748 11749 OMPLoopBasedDirective::HelperExprs B; 11750 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 11751 // define the nested loops number. 11752 unsigned NestedLoopCount = checkOpenMPLoop( 11753 OMPD_parallel_master_taskloop_simd, getCollapseNumberExpr(Clauses), 11754 /*OrderedLoopCountExpr=*/nullptr, CS, *this, *DSAStack, 11755 VarsWithImplicitDSA, B); 11756 if (NestedLoopCount == 0) 11757 return StmtError(); 11758 11759 assert((CurContext->isDependentContext() || B.builtAll()) && 11760 "omp for loop exprs were not built"); 11761 11762 if (!CurContext->isDependentContext()) { 11763 // Finalize the clauses that need pre-built expressions for CodeGen. 11764 for (OMPClause *C : Clauses) { 11765 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 11766 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 11767 B.NumIterations, *this, CurScope, 11768 DSAStack)) 11769 return StmtError(); 11770 } 11771 } 11772 11773 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 11774 // The grainsize clause and num_tasks clause are mutually exclusive and may 11775 // not appear on the same taskloop directive. 11776 if (checkGrainsizeNumTasksClauses(*this, Clauses)) 11777 return StmtError(); 11778 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 11779 // If a reduction clause is present on the taskloop directive, the nogroup 11780 // clause must not be specified. 11781 if (checkReductionClauseWithNogroup(*this, Clauses)) 11782 return StmtError(); 11783 if (checkSimdlenSafelenSpecified(*this, Clauses)) 11784 return StmtError(); 11785 11786 setFunctionHasBranchProtectedScope(); 11787 return OMPParallelMasterTaskLoopSimdDirective::Create( 11788 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 11789 } 11790 11791 StmtResult Sema::ActOnOpenMPDistributeDirective( 11792 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 11793 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 11794 if (!AStmt) 11795 return StmtError(); 11796 11797 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 11798 OMPLoopBasedDirective::HelperExprs B; 11799 // In presence of clause 'collapse' with number of loops, it will 11800 // define the nested loops number. 11801 unsigned NestedLoopCount = 11802 checkOpenMPLoop(OMPD_distribute, getCollapseNumberExpr(Clauses), 11803 nullptr /*ordered not a clause on distribute*/, AStmt, 11804 *this, *DSAStack, VarsWithImplicitDSA, B); 11805 if (NestedLoopCount == 0) 11806 return StmtError(); 11807 11808 assert((CurContext->isDependentContext() || B.builtAll()) && 11809 "omp for loop exprs were not built"); 11810 11811 setFunctionHasBranchProtectedScope(); 11812 return OMPDistributeDirective::Create(Context, StartLoc, EndLoc, 11813 NestedLoopCount, Clauses, AStmt, B); 11814 } 11815 11816 StmtResult Sema::ActOnOpenMPDistributeParallelForDirective( 11817 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 11818 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 11819 if (!AStmt) 11820 return StmtError(); 11821 11822 auto *CS = cast<CapturedStmt>(AStmt); 11823 // 1.2.2 OpenMP Language Terminology 11824 // Structured block - An executable statement with a single entry at the 11825 // top and a single exit at the bottom. 11826 // The point of exit cannot be a branch out of the structured block. 11827 // longjmp() and throw() must not violate the entry/exit criteria. 11828 CS->getCapturedDecl()->setNothrow(); 11829 for (int ThisCaptureLevel = 11830 getOpenMPCaptureLevels(OMPD_distribute_parallel_for); 11831 ThisCaptureLevel > 1; --ThisCaptureLevel) { 11832 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 11833 // 1.2.2 OpenMP Language Terminology 11834 // Structured block - An executable statement with a single entry at the 11835 // top and a single exit at the bottom. 11836 // The point of exit cannot be a branch out of the structured block. 11837 // longjmp() and throw() must not violate the entry/exit criteria. 11838 CS->getCapturedDecl()->setNothrow(); 11839 } 11840 11841 OMPLoopBasedDirective::HelperExprs B; 11842 // In presence of clause 'collapse' with number of loops, it will 11843 // define the nested loops number. 11844 unsigned NestedLoopCount = checkOpenMPLoop( 11845 OMPD_distribute_parallel_for, getCollapseNumberExpr(Clauses), 11846 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 11847 VarsWithImplicitDSA, B); 11848 if (NestedLoopCount == 0) 11849 return StmtError(); 11850 11851 assert((CurContext->isDependentContext() || B.builtAll()) && 11852 "omp for loop exprs were not built"); 11853 11854 setFunctionHasBranchProtectedScope(); 11855 return OMPDistributeParallelForDirective::Create( 11856 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B, 11857 DSAStack->getTaskgroupReductionRef(), DSAStack->isCancelRegion()); 11858 } 11859 11860 StmtResult Sema::ActOnOpenMPDistributeParallelForSimdDirective( 11861 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 11862 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 11863 if (!AStmt) 11864 return StmtError(); 11865 11866 auto *CS = cast<CapturedStmt>(AStmt); 11867 // 1.2.2 OpenMP Language Terminology 11868 // Structured block - An executable statement with a single entry at the 11869 // top and a single exit at the bottom. 11870 // The point of exit cannot be a branch out of the structured block. 11871 // longjmp() and throw() must not violate the entry/exit criteria. 11872 CS->getCapturedDecl()->setNothrow(); 11873 for (int ThisCaptureLevel = 11874 getOpenMPCaptureLevels(OMPD_distribute_parallel_for_simd); 11875 ThisCaptureLevel > 1; --ThisCaptureLevel) { 11876 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 11877 // 1.2.2 OpenMP Language Terminology 11878 // Structured block - An executable statement with a single entry at the 11879 // top and a single exit at the bottom. 11880 // The point of exit cannot be a branch out of the structured block. 11881 // longjmp() and throw() must not violate the entry/exit criteria. 11882 CS->getCapturedDecl()->setNothrow(); 11883 } 11884 11885 OMPLoopBasedDirective::HelperExprs B; 11886 // In presence of clause 'collapse' with number of loops, it will 11887 // define the nested loops number. 11888 unsigned NestedLoopCount = checkOpenMPLoop( 11889 OMPD_distribute_parallel_for_simd, getCollapseNumberExpr(Clauses), 11890 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 11891 VarsWithImplicitDSA, B); 11892 if (NestedLoopCount == 0) 11893 return StmtError(); 11894 11895 assert((CurContext->isDependentContext() || B.builtAll()) && 11896 "omp for loop exprs were not built"); 11897 11898 if (!CurContext->isDependentContext()) { 11899 // Finalize the clauses that need pre-built expressions for CodeGen. 11900 for (OMPClause *C : Clauses) { 11901 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 11902 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 11903 B.NumIterations, *this, CurScope, 11904 DSAStack)) 11905 return StmtError(); 11906 } 11907 } 11908 11909 if (checkSimdlenSafelenSpecified(*this, Clauses)) 11910 return StmtError(); 11911 11912 setFunctionHasBranchProtectedScope(); 11913 return OMPDistributeParallelForSimdDirective::Create( 11914 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 11915 } 11916 11917 StmtResult Sema::ActOnOpenMPDistributeSimdDirective( 11918 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 11919 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 11920 if (!AStmt) 11921 return StmtError(); 11922 11923 auto *CS = cast<CapturedStmt>(AStmt); 11924 // 1.2.2 OpenMP Language Terminology 11925 // Structured block - An executable statement with a single entry at the 11926 // top and a single exit at the bottom. 11927 // The point of exit cannot be a branch out of the structured block. 11928 // longjmp() and throw() must not violate the entry/exit criteria. 11929 CS->getCapturedDecl()->setNothrow(); 11930 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_distribute_simd); 11931 ThisCaptureLevel > 1; --ThisCaptureLevel) { 11932 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 11933 // 1.2.2 OpenMP Language Terminology 11934 // Structured block - An executable statement with a single entry at the 11935 // top and a single exit at the bottom. 11936 // The point of exit cannot be a branch out of the structured block. 11937 // longjmp() and throw() must not violate the entry/exit criteria. 11938 CS->getCapturedDecl()->setNothrow(); 11939 } 11940 11941 OMPLoopBasedDirective::HelperExprs B; 11942 // In presence of clause 'collapse' with number of loops, it will 11943 // define the nested loops number. 11944 unsigned NestedLoopCount = 11945 checkOpenMPLoop(OMPD_distribute_simd, getCollapseNumberExpr(Clauses), 11946 nullptr /*ordered not a clause on distribute*/, CS, *this, 11947 *DSAStack, VarsWithImplicitDSA, B); 11948 if (NestedLoopCount == 0) 11949 return StmtError(); 11950 11951 assert((CurContext->isDependentContext() || B.builtAll()) && 11952 "omp for loop exprs were not built"); 11953 11954 if (!CurContext->isDependentContext()) { 11955 // Finalize the clauses that need pre-built expressions for CodeGen. 11956 for (OMPClause *C : Clauses) { 11957 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 11958 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 11959 B.NumIterations, *this, CurScope, 11960 DSAStack)) 11961 return StmtError(); 11962 } 11963 } 11964 11965 if (checkSimdlenSafelenSpecified(*this, Clauses)) 11966 return StmtError(); 11967 11968 setFunctionHasBranchProtectedScope(); 11969 return OMPDistributeSimdDirective::Create(Context, StartLoc, EndLoc, 11970 NestedLoopCount, Clauses, AStmt, B); 11971 } 11972 11973 StmtResult Sema::ActOnOpenMPTargetParallelForSimdDirective( 11974 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 11975 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 11976 if (!AStmt) 11977 return StmtError(); 11978 11979 auto *CS = cast<CapturedStmt>(AStmt); 11980 // 1.2.2 OpenMP Language Terminology 11981 // Structured block - An executable statement with a single entry at the 11982 // top and a single exit at the bottom. 11983 // The point of exit cannot be a branch out of the structured block. 11984 // longjmp() and throw() must not violate the entry/exit criteria. 11985 CS->getCapturedDecl()->setNothrow(); 11986 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel_for); 11987 ThisCaptureLevel > 1; --ThisCaptureLevel) { 11988 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 11989 // 1.2.2 OpenMP Language Terminology 11990 // Structured block - An executable statement with a single entry at the 11991 // top and a single exit at the bottom. 11992 // The point of exit cannot be a branch out of the structured block. 11993 // longjmp() and throw() must not violate the entry/exit criteria. 11994 CS->getCapturedDecl()->setNothrow(); 11995 } 11996 11997 OMPLoopBasedDirective::HelperExprs B; 11998 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 11999 // define the nested loops number. 12000 unsigned NestedLoopCount = checkOpenMPLoop( 12001 OMPD_target_parallel_for_simd, getCollapseNumberExpr(Clauses), 12002 getOrderedNumberExpr(Clauses), CS, *this, *DSAStack, 12003 VarsWithImplicitDSA, B); 12004 if (NestedLoopCount == 0) 12005 return StmtError(); 12006 12007 assert((CurContext->isDependentContext() || B.builtAll()) && 12008 "omp target parallel for simd loop exprs were not built"); 12009 12010 if (!CurContext->isDependentContext()) { 12011 // Finalize the clauses that need pre-built expressions for CodeGen. 12012 for (OMPClause *C : Clauses) { 12013 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 12014 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 12015 B.NumIterations, *this, CurScope, 12016 DSAStack)) 12017 return StmtError(); 12018 } 12019 } 12020 if (checkSimdlenSafelenSpecified(*this, Clauses)) 12021 return StmtError(); 12022 12023 setFunctionHasBranchProtectedScope(); 12024 return OMPTargetParallelForSimdDirective::Create( 12025 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 12026 } 12027 12028 StmtResult Sema::ActOnOpenMPTargetSimdDirective( 12029 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 12030 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 12031 if (!AStmt) 12032 return StmtError(); 12033 12034 auto *CS = cast<CapturedStmt>(AStmt); 12035 // 1.2.2 OpenMP Language Terminology 12036 // Structured block - An executable statement with a single entry at the 12037 // top and a single exit at the bottom. 12038 // The point of exit cannot be a branch out of the structured block. 12039 // longjmp() and throw() must not violate the entry/exit criteria. 12040 CS->getCapturedDecl()->setNothrow(); 12041 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_simd); 12042 ThisCaptureLevel > 1; --ThisCaptureLevel) { 12043 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 12044 // 1.2.2 OpenMP Language Terminology 12045 // Structured block - An executable statement with a single entry at the 12046 // top and a single exit at the bottom. 12047 // The point of exit cannot be a branch out of the structured block. 12048 // longjmp() and throw() must not violate the entry/exit criteria. 12049 CS->getCapturedDecl()->setNothrow(); 12050 } 12051 12052 OMPLoopBasedDirective::HelperExprs B; 12053 // In presence of clause 'collapse' with number of loops, it will define the 12054 // nested loops number. 12055 unsigned NestedLoopCount = 12056 checkOpenMPLoop(OMPD_target_simd, getCollapseNumberExpr(Clauses), 12057 getOrderedNumberExpr(Clauses), CS, *this, *DSAStack, 12058 VarsWithImplicitDSA, B); 12059 if (NestedLoopCount == 0) 12060 return StmtError(); 12061 12062 assert((CurContext->isDependentContext() || B.builtAll()) && 12063 "omp target simd loop exprs were not built"); 12064 12065 if (!CurContext->isDependentContext()) { 12066 // Finalize the clauses that need pre-built expressions for CodeGen. 12067 for (OMPClause *C : Clauses) { 12068 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 12069 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 12070 B.NumIterations, *this, CurScope, 12071 DSAStack)) 12072 return StmtError(); 12073 } 12074 } 12075 12076 if (checkSimdlenSafelenSpecified(*this, Clauses)) 12077 return StmtError(); 12078 12079 setFunctionHasBranchProtectedScope(); 12080 return OMPTargetSimdDirective::Create(Context, StartLoc, EndLoc, 12081 NestedLoopCount, Clauses, AStmt, B); 12082 } 12083 12084 StmtResult Sema::ActOnOpenMPTeamsDistributeDirective( 12085 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 12086 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 12087 if (!AStmt) 12088 return StmtError(); 12089 12090 auto *CS = cast<CapturedStmt>(AStmt); 12091 // 1.2.2 OpenMP Language Terminology 12092 // Structured block - An executable statement with a single entry at the 12093 // top and a single exit at the bottom. 12094 // The point of exit cannot be a branch out of the structured block. 12095 // longjmp() and throw() must not violate the entry/exit criteria. 12096 CS->getCapturedDecl()->setNothrow(); 12097 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_teams_distribute); 12098 ThisCaptureLevel > 1; --ThisCaptureLevel) { 12099 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 12100 // 1.2.2 OpenMP Language Terminology 12101 // Structured block - An executable statement with a single entry at the 12102 // top and a single exit at the bottom. 12103 // The point of exit cannot be a branch out of the structured block. 12104 // longjmp() and throw() must not violate the entry/exit criteria. 12105 CS->getCapturedDecl()->setNothrow(); 12106 } 12107 12108 OMPLoopBasedDirective::HelperExprs B; 12109 // In presence of clause 'collapse' with number of loops, it will 12110 // define the nested loops number. 12111 unsigned NestedLoopCount = 12112 checkOpenMPLoop(OMPD_teams_distribute, getCollapseNumberExpr(Clauses), 12113 nullptr /*ordered not a clause on distribute*/, CS, *this, 12114 *DSAStack, VarsWithImplicitDSA, B); 12115 if (NestedLoopCount == 0) 12116 return StmtError(); 12117 12118 assert((CurContext->isDependentContext() || B.builtAll()) && 12119 "omp teams distribute loop exprs were not built"); 12120 12121 setFunctionHasBranchProtectedScope(); 12122 12123 DSAStack->setParentTeamsRegionLoc(StartLoc); 12124 12125 return OMPTeamsDistributeDirective::Create( 12126 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 12127 } 12128 12129 StmtResult Sema::ActOnOpenMPTeamsDistributeSimdDirective( 12130 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 12131 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 12132 if (!AStmt) 12133 return StmtError(); 12134 12135 auto *CS = cast<CapturedStmt>(AStmt); 12136 // 1.2.2 OpenMP Language Terminology 12137 // Structured block - An executable statement with a single entry at the 12138 // top and a single exit at the bottom. 12139 // The point of exit cannot be a branch out of the structured block. 12140 // longjmp() and throw() must not violate the entry/exit criteria. 12141 CS->getCapturedDecl()->setNothrow(); 12142 for (int ThisCaptureLevel = 12143 getOpenMPCaptureLevels(OMPD_teams_distribute_simd); 12144 ThisCaptureLevel > 1; --ThisCaptureLevel) { 12145 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 12146 // 1.2.2 OpenMP Language Terminology 12147 // Structured block - An executable statement with a single entry at the 12148 // top and a single exit at the bottom. 12149 // The point of exit cannot be a branch out of the structured block. 12150 // longjmp() and throw() must not violate the entry/exit criteria. 12151 CS->getCapturedDecl()->setNothrow(); 12152 } 12153 12154 OMPLoopBasedDirective::HelperExprs B; 12155 // In presence of clause 'collapse' with number of loops, it will 12156 // define the nested loops number. 12157 unsigned NestedLoopCount = checkOpenMPLoop( 12158 OMPD_teams_distribute_simd, getCollapseNumberExpr(Clauses), 12159 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 12160 VarsWithImplicitDSA, B); 12161 12162 if (NestedLoopCount == 0) 12163 return StmtError(); 12164 12165 assert((CurContext->isDependentContext() || B.builtAll()) && 12166 "omp teams distribute simd loop exprs were not built"); 12167 12168 if (!CurContext->isDependentContext()) { 12169 // Finalize the clauses that need pre-built expressions for CodeGen. 12170 for (OMPClause *C : Clauses) { 12171 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 12172 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 12173 B.NumIterations, *this, CurScope, 12174 DSAStack)) 12175 return StmtError(); 12176 } 12177 } 12178 12179 if (checkSimdlenSafelenSpecified(*this, Clauses)) 12180 return StmtError(); 12181 12182 setFunctionHasBranchProtectedScope(); 12183 12184 DSAStack->setParentTeamsRegionLoc(StartLoc); 12185 12186 return OMPTeamsDistributeSimdDirective::Create( 12187 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 12188 } 12189 12190 StmtResult Sema::ActOnOpenMPTeamsDistributeParallelForSimdDirective( 12191 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 12192 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 12193 if (!AStmt) 12194 return StmtError(); 12195 12196 auto *CS = cast<CapturedStmt>(AStmt); 12197 // 1.2.2 OpenMP Language Terminology 12198 // Structured block - An executable statement with a single entry at the 12199 // top and a single exit at the bottom. 12200 // The point of exit cannot be a branch out of the structured block. 12201 // longjmp() and throw() must not violate the entry/exit criteria. 12202 CS->getCapturedDecl()->setNothrow(); 12203 12204 for (int ThisCaptureLevel = 12205 getOpenMPCaptureLevels(OMPD_teams_distribute_parallel_for_simd); 12206 ThisCaptureLevel > 1; --ThisCaptureLevel) { 12207 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 12208 // 1.2.2 OpenMP Language Terminology 12209 // Structured block - An executable statement with a single entry at the 12210 // top and a single exit at the bottom. 12211 // The point of exit cannot be a branch out of the structured block. 12212 // longjmp() and throw() must not violate the entry/exit criteria. 12213 CS->getCapturedDecl()->setNothrow(); 12214 } 12215 12216 OMPLoopBasedDirective::HelperExprs B; 12217 // In presence of clause 'collapse' with number of loops, it will 12218 // define the nested loops number. 12219 unsigned NestedLoopCount = checkOpenMPLoop( 12220 OMPD_teams_distribute_parallel_for_simd, getCollapseNumberExpr(Clauses), 12221 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 12222 VarsWithImplicitDSA, B); 12223 12224 if (NestedLoopCount == 0) 12225 return StmtError(); 12226 12227 assert((CurContext->isDependentContext() || B.builtAll()) && 12228 "omp for loop exprs were not built"); 12229 12230 if (!CurContext->isDependentContext()) { 12231 // Finalize the clauses that need pre-built expressions for CodeGen. 12232 for (OMPClause *C : Clauses) { 12233 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 12234 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 12235 B.NumIterations, *this, CurScope, 12236 DSAStack)) 12237 return StmtError(); 12238 } 12239 } 12240 12241 if (checkSimdlenSafelenSpecified(*this, Clauses)) 12242 return StmtError(); 12243 12244 setFunctionHasBranchProtectedScope(); 12245 12246 DSAStack->setParentTeamsRegionLoc(StartLoc); 12247 12248 return OMPTeamsDistributeParallelForSimdDirective::Create( 12249 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 12250 } 12251 12252 StmtResult Sema::ActOnOpenMPTeamsDistributeParallelForDirective( 12253 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 12254 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 12255 if (!AStmt) 12256 return StmtError(); 12257 12258 auto *CS = cast<CapturedStmt>(AStmt); 12259 // 1.2.2 OpenMP Language Terminology 12260 // Structured block - An executable statement with a single entry at the 12261 // top and a single exit at the bottom. 12262 // The point of exit cannot be a branch out of the structured block. 12263 // longjmp() and throw() must not violate the entry/exit criteria. 12264 CS->getCapturedDecl()->setNothrow(); 12265 12266 for (int ThisCaptureLevel = 12267 getOpenMPCaptureLevels(OMPD_teams_distribute_parallel_for); 12268 ThisCaptureLevel > 1; --ThisCaptureLevel) { 12269 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 12270 // 1.2.2 OpenMP Language Terminology 12271 // Structured block - An executable statement with a single entry at the 12272 // top and a single exit at the bottom. 12273 // The point of exit cannot be a branch out of the structured block. 12274 // longjmp() and throw() must not violate the entry/exit criteria. 12275 CS->getCapturedDecl()->setNothrow(); 12276 } 12277 12278 OMPLoopBasedDirective::HelperExprs B; 12279 // In presence of clause 'collapse' with number of loops, it will 12280 // define the nested loops number. 12281 unsigned NestedLoopCount = checkOpenMPLoop( 12282 OMPD_teams_distribute_parallel_for, getCollapseNumberExpr(Clauses), 12283 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 12284 VarsWithImplicitDSA, B); 12285 12286 if (NestedLoopCount == 0) 12287 return StmtError(); 12288 12289 assert((CurContext->isDependentContext() || B.builtAll()) && 12290 "omp for loop exprs were not built"); 12291 12292 setFunctionHasBranchProtectedScope(); 12293 12294 DSAStack->setParentTeamsRegionLoc(StartLoc); 12295 12296 return OMPTeamsDistributeParallelForDirective::Create( 12297 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B, 12298 DSAStack->getTaskgroupReductionRef(), DSAStack->isCancelRegion()); 12299 } 12300 12301 StmtResult Sema::ActOnOpenMPTargetTeamsDirective(ArrayRef<OMPClause *> Clauses, 12302 Stmt *AStmt, 12303 SourceLocation StartLoc, 12304 SourceLocation EndLoc) { 12305 if (!AStmt) 12306 return StmtError(); 12307 12308 auto *CS = cast<CapturedStmt>(AStmt); 12309 // 1.2.2 OpenMP Language Terminology 12310 // Structured block - An executable statement with a single entry at the 12311 // top and a single exit at the bottom. 12312 // The point of exit cannot be a branch out of the structured block. 12313 // longjmp() and throw() must not violate the entry/exit criteria. 12314 CS->getCapturedDecl()->setNothrow(); 12315 12316 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_teams); 12317 ThisCaptureLevel > 1; --ThisCaptureLevel) { 12318 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 12319 // 1.2.2 OpenMP Language Terminology 12320 // Structured block - An executable statement with a single entry at the 12321 // top and a single exit at the bottom. 12322 // The point of exit cannot be a branch out of the structured block. 12323 // longjmp() and throw() must not violate the entry/exit criteria. 12324 CS->getCapturedDecl()->setNothrow(); 12325 } 12326 setFunctionHasBranchProtectedScope(); 12327 12328 return OMPTargetTeamsDirective::Create(Context, StartLoc, EndLoc, Clauses, 12329 AStmt); 12330 } 12331 12332 StmtResult Sema::ActOnOpenMPTargetTeamsDistributeDirective( 12333 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 12334 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 12335 if (!AStmt) 12336 return StmtError(); 12337 12338 auto *CS = cast<CapturedStmt>(AStmt); 12339 // 1.2.2 OpenMP Language Terminology 12340 // Structured block - An executable statement with a single entry at the 12341 // top and a single exit at the bottom. 12342 // The point of exit cannot be a branch out of the structured block. 12343 // longjmp() and throw() must not violate the entry/exit criteria. 12344 CS->getCapturedDecl()->setNothrow(); 12345 for (int ThisCaptureLevel = 12346 getOpenMPCaptureLevels(OMPD_target_teams_distribute); 12347 ThisCaptureLevel > 1; --ThisCaptureLevel) { 12348 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 12349 // 1.2.2 OpenMP Language Terminology 12350 // Structured block - An executable statement with a single entry at the 12351 // top and a single exit at the bottom. 12352 // The point of exit cannot be a branch out of the structured block. 12353 // longjmp() and throw() must not violate the entry/exit criteria. 12354 CS->getCapturedDecl()->setNothrow(); 12355 } 12356 12357 OMPLoopBasedDirective::HelperExprs B; 12358 // In presence of clause 'collapse' with number of loops, it will 12359 // define the nested loops number. 12360 unsigned NestedLoopCount = checkOpenMPLoop( 12361 OMPD_target_teams_distribute, getCollapseNumberExpr(Clauses), 12362 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 12363 VarsWithImplicitDSA, B); 12364 if (NestedLoopCount == 0) 12365 return StmtError(); 12366 12367 assert((CurContext->isDependentContext() || B.builtAll()) && 12368 "omp target teams distribute loop exprs were not built"); 12369 12370 setFunctionHasBranchProtectedScope(); 12371 return OMPTargetTeamsDistributeDirective::Create( 12372 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 12373 } 12374 12375 StmtResult Sema::ActOnOpenMPTargetTeamsDistributeParallelForDirective( 12376 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 12377 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 12378 if (!AStmt) 12379 return StmtError(); 12380 12381 auto *CS = cast<CapturedStmt>(AStmt); 12382 // 1.2.2 OpenMP Language Terminology 12383 // Structured block - An executable statement with a single entry at the 12384 // top and a single exit at the bottom. 12385 // The point of exit cannot be a branch out of the structured block. 12386 // longjmp() and throw() must not violate the entry/exit criteria. 12387 CS->getCapturedDecl()->setNothrow(); 12388 for (int ThisCaptureLevel = 12389 getOpenMPCaptureLevels(OMPD_target_teams_distribute_parallel_for); 12390 ThisCaptureLevel > 1; --ThisCaptureLevel) { 12391 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 12392 // 1.2.2 OpenMP Language Terminology 12393 // Structured block - An executable statement with a single entry at the 12394 // top and a single exit at the bottom. 12395 // The point of exit cannot be a branch out of the structured block. 12396 // longjmp() and throw() must not violate the entry/exit criteria. 12397 CS->getCapturedDecl()->setNothrow(); 12398 } 12399 12400 OMPLoopBasedDirective::HelperExprs B; 12401 // In presence of clause 'collapse' with number of loops, it will 12402 // define the nested loops number. 12403 unsigned NestedLoopCount = checkOpenMPLoop( 12404 OMPD_target_teams_distribute_parallel_for, getCollapseNumberExpr(Clauses), 12405 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 12406 VarsWithImplicitDSA, B); 12407 if (NestedLoopCount == 0) 12408 return StmtError(); 12409 12410 assert((CurContext->isDependentContext() || B.builtAll()) && 12411 "omp target teams distribute parallel for loop exprs were not built"); 12412 12413 if (!CurContext->isDependentContext()) { 12414 // Finalize the clauses that need pre-built expressions for CodeGen. 12415 for (OMPClause *C : Clauses) { 12416 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 12417 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 12418 B.NumIterations, *this, CurScope, 12419 DSAStack)) 12420 return StmtError(); 12421 } 12422 } 12423 12424 setFunctionHasBranchProtectedScope(); 12425 return OMPTargetTeamsDistributeParallelForDirective::Create( 12426 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B, 12427 DSAStack->getTaskgroupReductionRef(), DSAStack->isCancelRegion()); 12428 } 12429 12430 StmtResult Sema::ActOnOpenMPTargetTeamsDistributeParallelForSimdDirective( 12431 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 12432 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 12433 if (!AStmt) 12434 return StmtError(); 12435 12436 auto *CS = cast<CapturedStmt>(AStmt); 12437 // 1.2.2 OpenMP Language Terminology 12438 // Structured block - An executable statement with a single entry at the 12439 // top and a single exit at the bottom. 12440 // The point of exit cannot be a branch out of the structured block. 12441 // longjmp() and throw() must not violate the entry/exit criteria. 12442 CS->getCapturedDecl()->setNothrow(); 12443 for (int ThisCaptureLevel = getOpenMPCaptureLevels( 12444 OMPD_target_teams_distribute_parallel_for_simd); 12445 ThisCaptureLevel > 1; --ThisCaptureLevel) { 12446 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 12447 // 1.2.2 OpenMP Language Terminology 12448 // Structured block - An executable statement with a single entry at the 12449 // top and a single exit at the bottom. 12450 // The point of exit cannot be a branch out of the structured block. 12451 // longjmp() and throw() must not violate the entry/exit criteria. 12452 CS->getCapturedDecl()->setNothrow(); 12453 } 12454 12455 OMPLoopBasedDirective::HelperExprs B; 12456 // In presence of clause 'collapse' with number of loops, it will 12457 // define the nested loops number. 12458 unsigned NestedLoopCount = 12459 checkOpenMPLoop(OMPD_target_teams_distribute_parallel_for_simd, 12460 getCollapseNumberExpr(Clauses), 12461 nullptr /*ordered not a clause on distribute*/, CS, *this, 12462 *DSAStack, VarsWithImplicitDSA, B); 12463 if (NestedLoopCount == 0) 12464 return StmtError(); 12465 12466 assert((CurContext->isDependentContext() || B.builtAll()) && 12467 "omp target teams distribute parallel for simd loop exprs were not " 12468 "built"); 12469 12470 if (!CurContext->isDependentContext()) { 12471 // Finalize the clauses that need pre-built expressions for CodeGen. 12472 for (OMPClause *C : Clauses) { 12473 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 12474 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 12475 B.NumIterations, *this, CurScope, 12476 DSAStack)) 12477 return StmtError(); 12478 } 12479 } 12480 12481 if (checkSimdlenSafelenSpecified(*this, Clauses)) 12482 return StmtError(); 12483 12484 setFunctionHasBranchProtectedScope(); 12485 return OMPTargetTeamsDistributeParallelForSimdDirective::Create( 12486 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 12487 } 12488 12489 StmtResult Sema::ActOnOpenMPTargetTeamsDistributeSimdDirective( 12490 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 12491 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 12492 if (!AStmt) 12493 return StmtError(); 12494 12495 auto *CS = cast<CapturedStmt>(AStmt); 12496 // 1.2.2 OpenMP Language Terminology 12497 // Structured block - An executable statement with a single entry at the 12498 // top and a single exit at the bottom. 12499 // The point of exit cannot be a branch out of the structured block. 12500 // longjmp() and throw() must not violate the entry/exit criteria. 12501 CS->getCapturedDecl()->setNothrow(); 12502 for (int ThisCaptureLevel = 12503 getOpenMPCaptureLevels(OMPD_target_teams_distribute_simd); 12504 ThisCaptureLevel > 1; --ThisCaptureLevel) { 12505 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 12506 // 1.2.2 OpenMP Language Terminology 12507 // Structured block - An executable statement with a single entry at the 12508 // top and a single exit at the bottom. 12509 // The point of exit cannot be a branch out of the structured block. 12510 // longjmp() and throw() must not violate the entry/exit criteria. 12511 CS->getCapturedDecl()->setNothrow(); 12512 } 12513 12514 OMPLoopBasedDirective::HelperExprs B; 12515 // In presence of clause 'collapse' with number of loops, it will 12516 // define the nested loops number. 12517 unsigned NestedLoopCount = checkOpenMPLoop( 12518 OMPD_target_teams_distribute_simd, getCollapseNumberExpr(Clauses), 12519 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 12520 VarsWithImplicitDSA, B); 12521 if (NestedLoopCount == 0) 12522 return StmtError(); 12523 12524 assert((CurContext->isDependentContext() || B.builtAll()) && 12525 "omp target teams distribute simd loop exprs were not built"); 12526 12527 if (!CurContext->isDependentContext()) { 12528 // Finalize the clauses that need pre-built expressions for CodeGen. 12529 for (OMPClause *C : Clauses) { 12530 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 12531 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 12532 B.NumIterations, *this, CurScope, 12533 DSAStack)) 12534 return StmtError(); 12535 } 12536 } 12537 12538 if (checkSimdlenSafelenSpecified(*this, Clauses)) 12539 return StmtError(); 12540 12541 setFunctionHasBranchProtectedScope(); 12542 return OMPTargetTeamsDistributeSimdDirective::Create( 12543 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 12544 } 12545 12546 StmtResult Sema::ActOnOpenMPTileDirective(ArrayRef<OMPClause *> Clauses, 12547 Stmt *AStmt, SourceLocation StartLoc, 12548 SourceLocation EndLoc) { 12549 auto SizesClauses = 12550 OMPExecutableDirective::getClausesOfKind<OMPSizesClause>(Clauses); 12551 if (SizesClauses.empty()) { 12552 // A missing 'sizes' clause is already reported by the parser. 12553 return StmtError(); 12554 } 12555 const OMPSizesClause *SizesClause = *SizesClauses.begin(); 12556 unsigned NumLoops = SizesClause->getNumSizes(); 12557 12558 // Empty statement should only be possible if there already was an error. 12559 if (!AStmt) 12560 return StmtError(); 12561 12562 // Verify and diagnose loop nest. 12563 SmallVector<OMPLoopBasedDirective::HelperExprs, 4> LoopHelpers(NumLoops); 12564 Stmt *Body = nullptr; 12565 SmallVector<Stmt *, 4> OriginalInits; 12566 if (!OMPLoopBasedDirective::doForAllLoops( 12567 AStmt->IgnoreContainers(), /*TryImperfectlyNestedLoops=*/false, 12568 NumLoops, 12569 [this, &LoopHelpers, &Body, &OriginalInits](unsigned Cnt, 12570 Stmt *CurStmt) { 12571 VarsWithInheritedDSAType TmpDSA; 12572 unsigned SingleNumLoops = 12573 checkOpenMPLoop(OMPD_tile, nullptr, nullptr, CurStmt, *this, 12574 *DSAStack, TmpDSA, LoopHelpers[Cnt]); 12575 if (SingleNumLoops == 0) 12576 return true; 12577 assert(SingleNumLoops == 1 && "Expect single loop iteration space"); 12578 if (auto *For = dyn_cast<ForStmt>(CurStmt)) { 12579 OriginalInits.push_back(For->getInit()); 12580 Body = For->getBody(); 12581 } else { 12582 assert(isa<CXXForRangeStmt>(CurStmt) && 12583 "Expected canonical for or range-based for loops."); 12584 auto *CXXFor = cast<CXXForRangeStmt>(CurStmt); 12585 OriginalInits.push_back(CXXFor->getBeginStmt()); 12586 Body = CXXFor->getBody(); 12587 } 12588 return false; 12589 })) 12590 return StmtError(); 12591 12592 // Delay tiling to when template is completely instantiated. 12593 if (CurContext->isDependentContext()) 12594 return OMPTileDirective::Create(Context, StartLoc, EndLoc, Clauses, 12595 NumLoops, AStmt, nullptr, nullptr); 12596 12597 // Collection of generated variable declaration. 12598 SmallVector<Decl *, 4> PreInits; 12599 12600 // Create iteration variables for the generated loops. 12601 SmallVector<VarDecl *, 4> FloorIndVars; 12602 SmallVector<VarDecl *, 4> TileIndVars; 12603 FloorIndVars.resize(NumLoops); 12604 TileIndVars.resize(NumLoops); 12605 for (unsigned I = 0; I < NumLoops; ++I) { 12606 OMPLoopBasedDirective::HelperExprs &LoopHelper = LoopHelpers[I]; 12607 if (auto *PI = cast_or_null<DeclStmt>(LoopHelper.PreInits)) 12608 PreInits.append(PI->decl_begin(), PI->decl_end()); 12609 assert(LoopHelper.Counters.size() == 1 && 12610 "Expect single-dimensional loop iteration space"); 12611 auto *OrigCntVar = cast<DeclRefExpr>(LoopHelper.Counters.front()); 12612 std::string OrigVarName = OrigCntVar->getNameInfo().getAsString(); 12613 DeclRefExpr *IterVarRef = cast<DeclRefExpr>(LoopHelper.IterationVarRef); 12614 QualType CntTy = IterVarRef->getType(); 12615 12616 // Iteration variable for the floor (i.e. outer) loop. 12617 { 12618 std::string FloorCntName = 12619 (Twine(".floor_") + llvm::utostr(I) + ".iv." + OrigVarName).str(); 12620 VarDecl *FloorCntDecl = 12621 buildVarDecl(*this, {}, CntTy, FloorCntName, nullptr, OrigCntVar); 12622 FloorIndVars[I] = FloorCntDecl; 12623 } 12624 12625 // Iteration variable for the tile (i.e. inner) loop. 12626 { 12627 std::string TileCntName = 12628 (Twine(".tile_") + llvm::utostr(I) + ".iv." + OrigVarName).str(); 12629 12630 // Reuse the iteration variable created by checkOpenMPLoop. It is also 12631 // used by the expressions to derive the original iteration variable's 12632 // value from the logical iteration number. 12633 auto *TileCntDecl = cast<VarDecl>(IterVarRef->getDecl()); 12634 TileCntDecl->setDeclName(&PP.getIdentifierTable().get(TileCntName)); 12635 TileIndVars[I] = TileCntDecl; 12636 } 12637 if (auto *PI = dyn_cast_or_null<DeclStmt>(OriginalInits[I])) 12638 PreInits.append(PI->decl_begin(), PI->decl_end()); 12639 // Gather declarations for the data members used as counters. 12640 for (Expr *CounterRef : LoopHelper.Counters) { 12641 auto *CounterDecl = cast<DeclRefExpr>(CounterRef)->getDecl(); 12642 if (isa<OMPCapturedExprDecl>(CounterDecl)) 12643 PreInits.push_back(CounterDecl); 12644 } 12645 } 12646 12647 // Once the original iteration values are set, append the innermost body. 12648 Stmt *Inner = Body; 12649 12650 // Create tile loops from the inside to the outside. 12651 for (int I = NumLoops - 1; I >= 0; --I) { 12652 OMPLoopBasedDirective::HelperExprs &LoopHelper = LoopHelpers[I]; 12653 Expr *NumIterations = LoopHelper.NumIterations; 12654 auto *OrigCntVar = cast<DeclRefExpr>(LoopHelper.Counters[0]); 12655 QualType CntTy = OrigCntVar->getType(); 12656 Expr *DimTileSize = SizesClause->getSizesRefs()[I]; 12657 Scope *CurScope = getCurScope(); 12658 12659 // Commonly used variables. 12660 DeclRefExpr *TileIV = buildDeclRefExpr(*this, TileIndVars[I], CntTy, 12661 OrigCntVar->getExprLoc()); 12662 DeclRefExpr *FloorIV = buildDeclRefExpr(*this, FloorIndVars[I], CntTy, 12663 OrigCntVar->getExprLoc()); 12664 12665 // For init-statement: auto .tile.iv = .floor.iv 12666 AddInitializerToDecl(TileIndVars[I], DefaultLvalueConversion(FloorIV).get(), 12667 /*DirectInit=*/false); 12668 Decl *CounterDecl = TileIndVars[I]; 12669 StmtResult InitStmt = new (Context) 12670 DeclStmt(DeclGroupRef::Create(Context, &CounterDecl, 1), 12671 OrigCntVar->getBeginLoc(), OrigCntVar->getEndLoc()); 12672 if (!InitStmt.isUsable()) 12673 return StmtError(); 12674 12675 // For cond-expression: .tile.iv < min(.floor.iv + DimTileSize, 12676 // NumIterations) 12677 ExprResult EndOfTile = BuildBinOp(CurScope, LoopHelper.Cond->getExprLoc(), 12678 BO_Add, FloorIV, DimTileSize); 12679 if (!EndOfTile.isUsable()) 12680 return StmtError(); 12681 ExprResult IsPartialTile = 12682 BuildBinOp(CurScope, LoopHelper.Cond->getExprLoc(), BO_LT, 12683 NumIterations, EndOfTile.get()); 12684 if (!IsPartialTile.isUsable()) 12685 return StmtError(); 12686 ExprResult MinTileAndIterSpace = ActOnConditionalOp( 12687 LoopHelper.Cond->getBeginLoc(), LoopHelper.Cond->getEndLoc(), 12688 IsPartialTile.get(), NumIterations, EndOfTile.get()); 12689 if (!MinTileAndIterSpace.isUsable()) 12690 return StmtError(); 12691 ExprResult CondExpr = BuildBinOp(CurScope, LoopHelper.Cond->getExprLoc(), 12692 BO_LT, TileIV, MinTileAndIterSpace.get()); 12693 if (!CondExpr.isUsable()) 12694 return StmtError(); 12695 12696 // For incr-statement: ++.tile.iv 12697 ExprResult IncrStmt = 12698 BuildUnaryOp(CurScope, LoopHelper.Inc->getExprLoc(), UO_PreInc, TileIV); 12699 if (!IncrStmt.isUsable()) 12700 return StmtError(); 12701 12702 // Statements to set the original iteration variable's value from the 12703 // logical iteration number. 12704 // Generated for loop is: 12705 // Original_for_init; 12706 // for (auto .tile.iv = .floor.iv; .tile.iv < min(.floor.iv + DimTileSize, 12707 // NumIterations); ++.tile.iv) { 12708 // Original_Body; 12709 // Original_counter_update; 12710 // } 12711 // FIXME: If the innermost body is an loop itself, inserting these 12712 // statements stops it being recognized as a perfectly nested loop (e.g. 12713 // for applying tiling again). If this is the case, sink the expressions 12714 // further into the inner loop. 12715 SmallVector<Stmt *, 4> BodyParts; 12716 BodyParts.append(LoopHelper.Updates.begin(), LoopHelper.Updates.end()); 12717 BodyParts.push_back(Inner); 12718 Inner = CompoundStmt::Create(Context, BodyParts, Inner->getBeginLoc(), 12719 Inner->getEndLoc()); 12720 Inner = new (Context) 12721 ForStmt(Context, InitStmt.get(), CondExpr.get(), nullptr, 12722 IncrStmt.get(), Inner, LoopHelper.Init->getBeginLoc(), 12723 LoopHelper.Init->getBeginLoc(), LoopHelper.Inc->getEndLoc()); 12724 } 12725 12726 // Create floor loops from the inside to the outside. 12727 for (int I = NumLoops - 1; I >= 0; --I) { 12728 auto &LoopHelper = LoopHelpers[I]; 12729 Expr *NumIterations = LoopHelper.NumIterations; 12730 DeclRefExpr *OrigCntVar = cast<DeclRefExpr>(LoopHelper.Counters[0]); 12731 QualType CntTy = OrigCntVar->getType(); 12732 Expr *DimTileSize = SizesClause->getSizesRefs()[I]; 12733 Scope *CurScope = getCurScope(); 12734 12735 // Commonly used variables. 12736 DeclRefExpr *FloorIV = buildDeclRefExpr(*this, FloorIndVars[I], CntTy, 12737 OrigCntVar->getExprLoc()); 12738 12739 // For init-statement: auto .floor.iv = 0 12740 AddInitializerToDecl( 12741 FloorIndVars[I], 12742 ActOnIntegerConstant(LoopHelper.Init->getExprLoc(), 0).get(), 12743 /*DirectInit=*/false); 12744 Decl *CounterDecl = FloorIndVars[I]; 12745 StmtResult InitStmt = new (Context) 12746 DeclStmt(DeclGroupRef::Create(Context, &CounterDecl, 1), 12747 OrigCntVar->getBeginLoc(), OrigCntVar->getEndLoc()); 12748 if (!InitStmt.isUsable()) 12749 return StmtError(); 12750 12751 // For cond-expression: .floor.iv < NumIterations 12752 ExprResult CondExpr = BuildBinOp(CurScope, LoopHelper.Cond->getExprLoc(), 12753 BO_LT, FloorIV, NumIterations); 12754 if (!CondExpr.isUsable()) 12755 return StmtError(); 12756 12757 // For incr-statement: .floor.iv += DimTileSize 12758 ExprResult IncrStmt = BuildBinOp(CurScope, LoopHelper.Inc->getExprLoc(), 12759 BO_AddAssign, FloorIV, DimTileSize); 12760 if (!IncrStmt.isUsable()) 12761 return StmtError(); 12762 12763 Inner = new (Context) 12764 ForStmt(Context, InitStmt.get(), CondExpr.get(), nullptr, 12765 IncrStmt.get(), Inner, LoopHelper.Init->getBeginLoc(), 12766 LoopHelper.Init->getBeginLoc(), LoopHelper.Inc->getEndLoc()); 12767 } 12768 12769 return OMPTileDirective::Create(Context, StartLoc, EndLoc, Clauses, NumLoops, 12770 AStmt, Inner, 12771 buildPreInits(Context, PreInits)); 12772 } 12773 12774 OMPClause *Sema::ActOnOpenMPSingleExprClause(OpenMPClauseKind Kind, Expr *Expr, 12775 SourceLocation StartLoc, 12776 SourceLocation LParenLoc, 12777 SourceLocation EndLoc) { 12778 OMPClause *Res = nullptr; 12779 switch (Kind) { 12780 case OMPC_final: 12781 Res = ActOnOpenMPFinalClause(Expr, StartLoc, LParenLoc, EndLoc); 12782 break; 12783 case OMPC_num_threads: 12784 Res = ActOnOpenMPNumThreadsClause(Expr, StartLoc, LParenLoc, EndLoc); 12785 break; 12786 case OMPC_safelen: 12787 Res = ActOnOpenMPSafelenClause(Expr, StartLoc, LParenLoc, EndLoc); 12788 break; 12789 case OMPC_simdlen: 12790 Res = ActOnOpenMPSimdlenClause(Expr, StartLoc, LParenLoc, EndLoc); 12791 break; 12792 case OMPC_allocator: 12793 Res = ActOnOpenMPAllocatorClause(Expr, StartLoc, LParenLoc, EndLoc); 12794 break; 12795 case OMPC_collapse: 12796 Res = ActOnOpenMPCollapseClause(Expr, StartLoc, LParenLoc, EndLoc); 12797 break; 12798 case OMPC_ordered: 12799 Res = ActOnOpenMPOrderedClause(StartLoc, EndLoc, LParenLoc, Expr); 12800 break; 12801 case OMPC_num_teams: 12802 Res = ActOnOpenMPNumTeamsClause(Expr, StartLoc, LParenLoc, EndLoc); 12803 break; 12804 case OMPC_thread_limit: 12805 Res = ActOnOpenMPThreadLimitClause(Expr, StartLoc, LParenLoc, EndLoc); 12806 break; 12807 case OMPC_priority: 12808 Res = ActOnOpenMPPriorityClause(Expr, StartLoc, LParenLoc, EndLoc); 12809 break; 12810 case OMPC_grainsize: 12811 Res = ActOnOpenMPGrainsizeClause(Expr, StartLoc, LParenLoc, EndLoc); 12812 break; 12813 case OMPC_num_tasks: 12814 Res = ActOnOpenMPNumTasksClause(Expr, StartLoc, LParenLoc, EndLoc); 12815 break; 12816 case OMPC_hint: 12817 Res = ActOnOpenMPHintClause(Expr, StartLoc, LParenLoc, EndLoc); 12818 break; 12819 case OMPC_depobj: 12820 Res = ActOnOpenMPDepobjClause(Expr, StartLoc, LParenLoc, EndLoc); 12821 break; 12822 case OMPC_detach: 12823 Res = ActOnOpenMPDetachClause(Expr, StartLoc, LParenLoc, EndLoc); 12824 break; 12825 case OMPC_novariants: 12826 Res = ActOnOpenMPNovariantsClause(Expr, StartLoc, LParenLoc, EndLoc); 12827 break; 12828 case OMPC_nocontext: 12829 Res = ActOnOpenMPNocontextClause(Expr, StartLoc, LParenLoc, EndLoc); 12830 break; 12831 case OMPC_filter: 12832 Res = ActOnOpenMPFilterClause(Expr, StartLoc, LParenLoc, EndLoc); 12833 break; 12834 case OMPC_device: 12835 case OMPC_if: 12836 case OMPC_default: 12837 case OMPC_proc_bind: 12838 case OMPC_schedule: 12839 case OMPC_private: 12840 case OMPC_firstprivate: 12841 case OMPC_lastprivate: 12842 case OMPC_shared: 12843 case OMPC_reduction: 12844 case OMPC_task_reduction: 12845 case OMPC_in_reduction: 12846 case OMPC_linear: 12847 case OMPC_aligned: 12848 case OMPC_copyin: 12849 case OMPC_copyprivate: 12850 case OMPC_nowait: 12851 case OMPC_untied: 12852 case OMPC_mergeable: 12853 case OMPC_threadprivate: 12854 case OMPC_sizes: 12855 case OMPC_allocate: 12856 case OMPC_flush: 12857 case OMPC_read: 12858 case OMPC_write: 12859 case OMPC_update: 12860 case OMPC_capture: 12861 case OMPC_seq_cst: 12862 case OMPC_acq_rel: 12863 case OMPC_acquire: 12864 case OMPC_release: 12865 case OMPC_relaxed: 12866 case OMPC_depend: 12867 case OMPC_threads: 12868 case OMPC_simd: 12869 case OMPC_map: 12870 case OMPC_nogroup: 12871 case OMPC_dist_schedule: 12872 case OMPC_defaultmap: 12873 case OMPC_unknown: 12874 case OMPC_uniform: 12875 case OMPC_to: 12876 case OMPC_from: 12877 case OMPC_use_device_ptr: 12878 case OMPC_use_device_addr: 12879 case OMPC_is_device_ptr: 12880 case OMPC_unified_address: 12881 case OMPC_unified_shared_memory: 12882 case OMPC_reverse_offload: 12883 case OMPC_dynamic_allocators: 12884 case OMPC_atomic_default_mem_order: 12885 case OMPC_device_type: 12886 case OMPC_match: 12887 case OMPC_nontemporal: 12888 case OMPC_order: 12889 case OMPC_destroy: 12890 case OMPC_inclusive: 12891 case OMPC_exclusive: 12892 case OMPC_uses_allocators: 12893 case OMPC_affinity: 12894 default: 12895 llvm_unreachable("Clause is not allowed."); 12896 } 12897 return Res; 12898 } 12899 12900 // An OpenMP directive such as 'target parallel' has two captured regions: 12901 // for the 'target' and 'parallel' respectively. This function returns 12902 // the region in which to capture expressions associated with a clause. 12903 // A return value of OMPD_unknown signifies that the expression should not 12904 // be captured. 12905 static OpenMPDirectiveKind getOpenMPCaptureRegionForClause( 12906 OpenMPDirectiveKind DKind, OpenMPClauseKind CKind, unsigned OpenMPVersion, 12907 OpenMPDirectiveKind NameModifier = OMPD_unknown) { 12908 OpenMPDirectiveKind CaptureRegion = OMPD_unknown; 12909 switch (CKind) { 12910 case OMPC_if: 12911 switch (DKind) { 12912 case OMPD_target_parallel_for_simd: 12913 if (OpenMPVersion >= 50 && 12914 (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)) { 12915 CaptureRegion = OMPD_parallel; 12916 break; 12917 } 12918 LLVM_FALLTHROUGH; 12919 case OMPD_target_parallel: 12920 case OMPD_target_parallel_for: 12921 // If this clause applies to the nested 'parallel' region, capture within 12922 // the 'target' region, otherwise do not capture. 12923 if (NameModifier == OMPD_unknown || NameModifier == OMPD_parallel) 12924 CaptureRegion = OMPD_target; 12925 break; 12926 case OMPD_target_teams_distribute_parallel_for_simd: 12927 if (OpenMPVersion >= 50 && 12928 (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)) { 12929 CaptureRegion = OMPD_parallel; 12930 break; 12931 } 12932 LLVM_FALLTHROUGH; 12933 case OMPD_target_teams_distribute_parallel_for: 12934 // If this clause applies to the nested 'parallel' region, capture within 12935 // the 'teams' region, otherwise do not capture. 12936 if (NameModifier == OMPD_unknown || NameModifier == OMPD_parallel) 12937 CaptureRegion = OMPD_teams; 12938 break; 12939 case OMPD_teams_distribute_parallel_for_simd: 12940 if (OpenMPVersion >= 50 && 12941 (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)) { 12942 CaptureRegion = OMPD_parallel; 12943 break; 12944 } 12945 LLVM_FALLTHROUGH; 12946 case OMPD_teams_distribute_parallel_for: 12947 CaptureRegion = OMPD_teams; 12948 break; 12949 case OMPD_target_update: 12950 case OMPD_target_enter_data: 12951 case OMPD_target_exit_data: 12952 CaptureRegion = OMPD_task; 12953 break; 12954 case OMPD_parallel_master_taskloop: 12955 if (NameModifier == OMPD_unknown || NameModifier == OMPD_taskloop) 12956 CaptureRegion = OMPD_parallel; 12957 break; 12958 case OMPD_parallel_master_taskloop_simd: 12959 if ((OpenMPVersion <= 45 && NameModifier == OMPD_unknown) || 12960 NameModifier == OMPD_taskloop) { 12961 CaptureRegion = OMPD_parallel; 12962 break; 12963 } 12964 if (OpenMPVersion <= 45) 12965 break; 12966 if (NameModifier == OMPD_unknown || NameModifier == OMPD_simd) 12967 CaptureRegion = OMPD_taskloop; 12968 break; 12969 case OMPD_parallel_for_simd: 12970 if (OpenMPVersion <= 45) 12971 break; 12972 if (NameModifier == OMPD_unknown || NameModifier == OMPD_simd) 12973 CaptureRegion = OMPD_parallel; 12974 break; 12975 case OMPD_taskloop_simd: 12976 case OMPD_master_taskloop_simd: 12977 if (OpenMPVersion <= 45) 12978 break; 12979 if (NameModifier == OMPD_unknown || NameModifier == OMPD_simd) 12980 CaptureRegion = OMPD_taskloop; 12981 break; 12982 case OMPD_distribute_parallel_for_simd: 12983 if (OpenMPVersion <= 45) 12984 break; 12985 if (NameModifier == OMPD_unknown || NameModifier == OMPD_simd) 12986 CaptureRegion = OMPD_parallel; 12987 break; 12988 case OMPD_target_simd: 12989 if (OpenMPVersion >= 50 && 12990 (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)) 12991 CaptureRegion = OMPD_target; 12992 break; 12993 case OMPD_teams_distribute_simd: 12994 case OMPD_target_teams_distribute_simd: 12995 if (OpenMPVersion >= 50 && 12996 (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)) 12997 CaptureRegion = OMPD_teams; 12998 break; 12999 case OMPD_cancel: 13000 case OMPD_parallel: 13001 case OMPD_parallel_master: 13002 case OMPD_parallel_sections: 13003 case OMPD_parallel_for: 13004 case OMPD_target: 13005 case OMPD_target_teams: 13006 case OMPD_target_teams_distribute: 13007 case OMPD_distribute_parallel_for: 13008 case OMPD_task: 13009 case OMPD_taskloop: 13010 case OMPD_master_taskloop: 13011 case OMPD_target_data: 13012 case OMPD_simd: 13013 case OMPD_for_simd: 13014 case OMPD_distribute_simd: 13015 // Do not capture if-clause expressions. 13016 break; 13017 case OMPD_threadprivate: 13018 case OMPD_allocate: 13019 case OMPD_taskyield: 13020 case OMPD_barrier: 13021 case OMPD_taskwait: 13022 case OMPD_cancellation_point: 13023 case OMPD_flush: 13024 case OMPD_depobj: 13025 case OMPD_scan: 13026 case OMPD_declare_reduction: 13027 case OMPD_declare_mapper: 13028 case OMPD_declare_simd: 13029 case OMPD_declare_variant: 13030 case OMPD_begin_declare_variant: 13031 case OMPD_end_declare_variant: 13032 case OMPD_declare_target: 13033 case OMPD_end_declare_target: 13034 case OMPD_teams: 13035 case OMPD_tile: 13036 case OMPD_for: 13037 case OMPD_sections: 13038 case OMPD_section: 13039 case OMPD_single: 13040 case OMPD_master: 13041 case OMPD_masked: 13042 case OMPD_critical: 13043 case OMPD_taskgroup: 13044 case OMPD_distribute: 13045 case OMPD_ordered: 13046 case OMPD_atomic: 13047 case OMPD_teams_distribute: 13048 case OMPD_requires: 13049 llvm_unreachable("Unexpected OpenMP directive with if-clause"); 13050 case OMPD_unknown: 13051 default: 13052 llvm_unreachable("Unknown OpenMP directive"); 13053 } 13054 break; 13055 case OMPC_num_threads: 13056 switch (DKind) { 13057 case OMPD_target_parallel: 13058 case OMPD_target_parallel_for: 13059 case OMPD_target_parallel_for_simd: 13060 CaptureRegion = OMPD_target; 13061 break; 13062 case OMPD_teams_distribute_parallel_for: 13063 case OMPD_teams_distribute_parallel_for_simd: 13064 case OMPD_target_teams_distribute_parallel_for: 13065 case OMPD_target_teams_distribute_parallel_for_simd: 13066 CaptureRegion = OMPD_teams; 13067 break; 13068 case OMPD_parallel: 13069 case OMPD_parallel_master: 13070 case OMPD_parallel_sections: 13071 case OMPD_parallel_for: 13072 case OMPD_parallel_for_simd: 13073 case OMPD_distribute_parallel_for: 13074 case OMPD_distribute_parallel_for_simd: 13075 case OMPD_parallel_master_taskloop: 13076 case OMPD_parallel_master_taskloop_simd: 13077 // Do not capture num_threads-clause expressions. 13078 break; 13079 case OMPD_target_data: 13080 case OMPD_target_enter_data: 13081 case OMPD_target_exit_data: 13082 case OMPD_target_update: 13083 case OMPD_target: 13084 case OMPD_target_simd: 13085 case OMPD_target_teams: 13086 case OMPD_target_teams_distribute: 13087 case OMPD_target_teams_distribute_simd: 13088 case OMPD_cancel: 13089 case OMPD_task: 13090 case OMPD_taskloop: 13091 case OMPD_taskloop_simd: 13092 case OMPD_master_taskloop: 13093 case OMPD_master_taskloop_simd: 13094 case OMPD_threadprivate: 13095 case OMPD_allocate: 13096 case OMPD_taskyield: 13097 case OMPD_barrier: 13098 case OMPD_taskwait: 13099 case OMPD_cancellation_point: 13100 case OMPD_flush: 13101 case OMPD_depobj: 13102 case OMPD_scan: 13103 case OMPD_declare_reduction: 13104 case OMPD_declare_mapper: 13105 case OMPD_declare_simd: 13106 case OMPD_declare_variant: 13107 case OMPD_begin_declare_variant: 13108 case OMPD_end_declare_variant: 13109 case OMPD_declare_target: 13110 case OMPD_end_declare_target: 13111 case OMPD_teams: 13112 case OMPD_simd: 13113 case OMPD_tile: 13114 case OMPD_for: 13115 case OMPD_for_simd: 13116 case OMPD_sections: 13117 case OMPD_section: 13118 case OMPD_single: 13119 case OMPD_master: 13120 case OMPD_masked: 13121 case OMPD_critical: 13122 case OMPD_taskgroup: 13123 case OMPD_distribute: 13124 case OMPD_ordered: 13125 case OMPD_atomic: 13126 case OMPD_distribute_simd: 13127 case OMPD_teams_distribute: 13128 case OMPD_teams_distribute_simd: 13129 case OMPD_requires: 13130 llvm_unreachable("Unexpected OpenMP directive with num_threads-clause"); 13131 case OMPD_unknown: 13132 default: 13133 llvm_unreachable("Unknown OpenMP directive"); 13134 } 13135 break; 13136 case OMPC_num_teams: 13137 switch (DKind) { 13138 case OMPD_target_teams: 13139 case OMPD_target_teams_distribute: 13140 case OMPD_target_teams_distribute_simd: 13141 case OMPD_target_teams_distribute_parallel_for: 13142 case OMPD_target_teams_distribute_parallel_for_simd: 13143 CaptureRegion = OMPD_target; 13144 break; 13145 case OMPD_teams_distribute_parallel_for: 13146 case OMPD_teams_distribute_parallel_for_simd: 13147 case OMPD_teams: 13148 case OMPD_teams_distribute: 13149 case OMPD_teams_distribute_simd: 13150 // Do not capture num_teams-clause expressions. 13151 break; 13152 case OMPD_distribute_parallel_for: 13153 case OMPD_distribute_parallel_for_simd: 13154 case OMPD_task: 13155 case OMPD_taskloop: 13156 case OMPD_taskloop_simd: 13157 case OMPD_master_taskloop: 13158 case OMPD_master_taskloop_simd: 13159 case OMPD_parallel_master_taskloop: 13160 case OMPD_parallel_master_taskloop_simd: 13161 case OMPD_target_data: 13162 case OMPD_target_enter_data: 13163 case OMPD_target_exit_data: 13164 case OMPD_target_update: 13165 case OMPD_cancel: 13166 case OMPD_parallel: 13167 case OMPD_parallel_master: 13168 case OMPD_parallel_sections: 13169 case OMPD_parallel_for: 13170 case OMPD_parallel_for_simd: 13171 case OMPD_target: 13172 case OMPD_target_simd: 13173 case OMPD_target_parallel: 13174 case OMPD_target_parallel_for: 13175 case OMPD_target_parallel_for_simd: 13176 case OMPD_threadprivate: 13177 case OMPD_allocate: 13178 case OMPD_taskyield: 13179 case OMPD_barrier: 13180 case OMPD_taskwait: 13181 case OMPD_cancellation_point: 13182 case OMPD_flush: 13183 case OMPD_depobj: 13184 case OMPD_scan: 13185 case OMPD_declare_reduction: 13186 case OMPD_declare_mapper: 13187 case OMPD_declare_simd: 13188 case OMPD_declare_variant: 13189 case OMPD_begin_declare_variant: 13190 case OMPD_end_declare_variant: 13191 case OMPD_declare_target: 13192 case OMPD_end_declare_target: 13193 case OMPD_simd: 13194 case OMPD_tile: 13195 case OMPD_for: 13196 case OMPD_for_simd: 13197 case OMPD_sections: 13198 case OMPD_section: 13199 case OMPD_single: 13200 case OMPD_master: 13201 case OMPD_masked: 13202 case OMPD_critical: 13203 case OMPD_taskgroup: 13204 case OMPD_distribute: 13205 case OMPD_ordered: 13206 case OMPD_atomic: 13207 case OMPD_distribute_simd: 13208 case OMPD_requires: 13209 llvm_unreachable("Unexpected OpenMP directive with num_teams-clause"); 13210 case OMPD_unknown: 13211 default: 13212 llvm_unreachable("Unknown OpenMP directive"); 13213 } 13214 break; 13215 case OMPC_thread_limit: 13216 switch (DKind) { 13217 case OMPD_target_teams: 13218 case OMPD_target_teams_distribute: 13219 case OMPD_target_teams_distribute_simd: 13220 case OMPD_target_teams_distribute_parallel_for: 13221 case OMPD_target_teams_distribute_parallel_for_simd: 13222 CaptureRegion = OMPD_target; 13223 break; 13224 case OMPD_teams_distribute_parallel_for: 13225 case OMPD_teams_distribute_parallel_for_simd: 13226 case OMPD_teams: 13227 case OMPD_teams_distribute: 13228 case OMPD_teams_distribute_simd: 13229 // Do not capture thread_limit-clause expressions. 13230 break; 13231 case OMPD_distribute_parallel_for: 13232 case OMPD_distribute_parallel_for_simd: 13233 case OMPD_task: 13234 case OMPD_taskloop: 13235 case OMPD_taskloop_simd: 13236 case OMPD_master_taskloop: 13237 case OMPD_master_taskloop_simd: 13238 case OMPD_parallel_master_taskloop: 13239 case OMPD_parallel_master_taskloop_simd: 13240 case OMPD_target_data: 13241 case OMPD_target_enter_data: 13242 case OMPD_target_exit_data: 13243 case OMPD_target_update: 13244 case OMPD_cancel: 13245 case OMPD_parallel: 13246 case OMPD_parallel_master: 13247 case OMPD_parallel_sections: 13248 case OMPD_parallel_for: 13249 case OMPD_parallel_for_simd: 13250 case OMPD_target: 13251 case OMPD_target_simd: 13252 case OMPD_target_parallel: 13253 case OMPD_target_parallel_for: 13254 case OMPD_target_parallel_for_simd: 13255 case OMPD_threadprivate: 13256 case OMPD_allocate: 13257 case OMPD_taskyield: 13258 case OMPD_barrier: 13259 case OMPD_taskwait: 13260 case OMPD_cancellation_point: 13261 case OMPD_flush: 13262 case OMPD_depobj: 13263 case OMPD_scan: 13264 case OMPD_declare_reduction: 13265 case OMPD_declare_mapper: 13266 case OMPD_declare_simd: 13267 case OMPD_declare_variant: 13268 case OMPD_begin_declare_variant: 13269 case OMPD_end_declare_variant: 13270 case OMPD_declare_target: 13271 case OMPD_end_declare_target: 13272 case OMPD_simd: 13273 case OMPD_tile: 13274 case OMPD_for: 13275 case OMPD_for_simd: 13276 case OMPD_sections: 13277 case OMPD_section: 13278 case OMPD_single: 13279 case OMPD_master: 13280 case OMPD_masked: 13281 case OMPD_critical: 13282 case OMPD_taskgroup: 13283 case OMPD_distribute: 13284 case OMPD_ordered: 13285 case OMPD_atomic: 13286 case OMPD_distribute_simd: 13287 case OMPD_requires: 13288 llvm_unreachable("Unexpected OpenMP directive with thread_limit-clause"); 13289 case OMPD_unknown: 13290 default: 13291 llvm_unreachable("Unknown OpenMP directive"); 13292 } 13293 break; 13294 case OMPC_schedule: 13295 switch (DKind) { 13296 case OMPD_parallel_for: 13297 case OMPD_parallel_for_simd: 13298 case OMPD_distribute_parallel_for: 13299 case OMPD_distribute_parallel_for_simd: 13300 case OMPD_teams_distribute_parallel_for: 13301 case OMPD_teams_distribute_parallel_for_simd: 13302 case OMPD_target_parallel_for: 13303 case OMPD_target_parallel_for_simd: 13304 case OMPD_target_teams_distribute_parallel_for: 13305 case OMPD_target_teams_distribute_parallel_for_simd: 13306 CaptureRegion = OMPD_parallel; 13307 break; 13308 case OMPD_for: 13309 case OMPD_for_simd: 13310 // Do not capture schedule-clause expressions. 13311 break; 13312 case OMPD_task: 13313 case OMPD_taskloop: 13314 case OMPD_taskloop_simd: 13315 case OMPD_master_taskloop: 13316 case OMPD_master_taskloop_simd: 13317 case OMPD_parallel_master_taskloop: 13318 case OMPD_parallel_master_taskloop_simd: 13319 case OMPD_target_data: 13320 case OMPD_target_enter_data: 13321 case OMPD_target_exit_data: 13322 case OMPD_target_update: 13323 case OMPD_teams: 13324 case OMPD_teams_distribute: 13325 case OMPD_teams_distribute_simd: 13326 case OMPD_target_teams_distribute: 13327 case OMPD_target_teams_distribute_simd: 13328 case OMPD_target: 13329 case OMPD_target_simd: 13330 case OMPD_target_parallel: 13331 case OMPD_cancel: 13332 case OMPD_parallel: 13333 case OMPD_parallel_master: 13334 case OMPD_parallel_sections: 13335 case OMPD_threadprivate: 13336 case OMPD_allocate: 13337 case OMPD_taskyield: 13338 case OMPD_barrier: 13339 case OMPD_taskwait: 13340 case OMPD_cancellation_point: 13341 case OMPD_flush: 13342 case OMPD_depobj: 13343 case OMPD_scan: 13344 case OMPD_declare_reduction: 13345 case OMPD_declare_mapper: 13346 case OMPD_declare_simd: 13347 case OMPD_declare_variant: 13348 case OMPD_begin_declare_variant: 13349 case OMPD_end_declare_variant: 13350 case OMPD_declare_target: 13351 case OMPD_end_declare_target: 13352 case OMPD_simd: 13353 case OMPD_tile: 13354 case OMPD_sections: 13355 case OMPD_section: 13356 case OMPD_single: 13357 case OMPD_master: 13358 case OMPD_masked: 13359 case OMPD_critical: 13360 case OMPD_taskgroup: 13361 case OMPD_distribute: 13362 case OMPD_ordered: 13363 case OMPD_atomic: 13364 case OMPD_distribute_simd: 13365 case OMPD_target_teams: 13366 case OMPD_requires: 13367 llvm_unreachable("Unexpected OpenMP directive with schedule clause"); 13368 case OMPD_unknown: 13369 default: 13370 llvm_unreachable("Unknown OpenMP directive"); 13371 } 13372 break; 13373 case OMPC_dist_schedule: 13374 switch (DKind) { 13375 case OMPD_teams_distribute_parallel_for: 13376 case OMPD_teams_distribute_parallel_for_simd: 13377 case OMPD_teams_distribute: 13378 case OMPD_teams_distribute_simd: 13379 case OMPD_target_teams_distribute_parallel_for: 13380 case OMPD_target_teams_distribute_parallel_for_simd: 13381 case OMPD_target_teams_distribute: 13382 case OMPD_target_teams_distribute_simd: 13383 CaptureRegion = OMPD_teams; 13384 break; 13385 case OMPD_distribute_parallel_for: 13386 case OMPD_distribute_parallel_for_simd: 13387 case OMPD_distribute: 13388 case OMPD_distribute_simd: 13389 // Do not capture dist_schedule-clause expressions. 13390 break; 13391 case OMPD_parallel_for: 13392 case OMPD_parallel_for_simd: 13393 case OMPD_target_parallel_for_simd: 13394 case OMPD_target_parallel_for: 13395 case OMPD_task: 13396 case OMPD_taskloop: 13397 case OMPD_taskloop_simd: 13398 case OMPD_master_taskloop: 13399 case OMPD_master_taskloop_simd: 13400 case OMPD_parallel_master_taskloop: 13401 case OMPD_parallel_master_taskloop_simd: 13402 case OMPD_target_data: 13403 case OMPD_target_enter_data: 13404 case OMPD_target_exit_data: 13405 case OMPD_target_update: 13406 case OMPD_teams: 13407 case OMPD_target: 13408 case OMPD_target_simd: 13409 case OMPD_target_parallel: 13410 case OMPD_cancel: 13411 case OMPD_parallel: 13412 case OMPD_parallel_master: 13413 case OMPD_parallel_sections: 13414 case OMPD_threadprivate: 13415 case OMPD_allocate: 13416 case OMPD_taskyield: 13417 case OMPD_barrier: 13418 case OMPD_taskwait: 13419 case OMPD_cancellation_point: 13420 case OMPD_flush: 13421 case OMPD_depobj: 13422 case OMPD_scan: 13423 case OMPD_declare_reduction: 13424 case OMPD_declare_mapper: 13425 case OMPD_declare_simd: 13426 case OMPD_declare_variant: 13427 case OMPD_begin_declare_variant: 13428 case OMPD_end_declare_variant: 13429 case OMPD_declare_target: 13430 case OMPD_end_declare_target: 13431 case OMPD_simd: 13432 case OMPD_tile: 13433 case OMPD_for: 13434 case OMPD_for_simd: 13435 case OMPD_sections: 13436 case OMPD_section: 13437 case OMPD_single: 13438 case OMPD_master: 13439 case OMPD_masked: 13440 case OMPD_critical: 13441 case OMPD_taskgroup: 13442 case OMPD_ordered: 13443 case OMPD_atomic: 13444 case OMPD_target_teams: 13445 case OMPD_requires: 13446 llvm_unreachable("Unexpected OpenMP directive with dist_schedule clause"); 13447 case OMPD_unknown: 13448 default: 13449 llvm_unreachable("Unknown OpenMP directive"); 13450 } 13451 break; 13452 case OMPC_device: 13453 switch (DKind) { 13454 case OMPD_target_update: 13455 case OMPD_target_enter_data: 13456 case OMPD_target_exit_data: 13457 case OMPD_target: 13458 case OMPD_target_simd: 13459 case OMPD_target_teams: 13460 case OMPD_target_parallel: 13461 case OMPD_target_teams_distribute: 13462 case OMPD_target_teams_distribute_simd: 13463 case OMPD_target_parallel_for: 13464 case OMPD_target_parallel_for_simd: 13465 case OMPD_target_teams_distribute_parallel_for: 13466 case OMPD_target_teams_distribute_parallel_for_simd: 13467 case OMPD_dispatch: 13468 CaptureRegion = OMPD_task; 13469 break; 13470 case OMPD_target_data: 13471 case OMPD_interop: 13472 // Do not capture device-clause expressions. 13473 break; 13474 case OMPD_teams_distribute_parallel_for: 13475 case OMPD_teams_distribute_parallel_for_simd: 13476 case OMPD_teams: 13477 case OMPD_teams_distribute: 13478 case OMPD_teams_distribute_simd: 13479 case OMPD_distribute_parallel_for: 13480 case OMPD_distribute_parallel_for_simd: 13481 case OMPD_task: 13482 case OMPD_taskloop: 13483 case OMPD_taskloop_simd: 13484 case OMPD_master_taskloop: 13485 case OMPD_master_taskloop_simd: 13486 case OMPD_parallel_master_taskloop: 13487 case OMPD_parallel_master_taskloop_simd: 13488 case OMPD_cancel: 13489 case OMPD_parallel: 13490 case OMPD_parallel_master: 13491 case OMPD_parallel_sections: 13492 case OMPD_parallel_for: 13493 case OMPD_parallel_for_simd: 13494 case OMPD_threadprivate: 13495 case OMPD_allocate: 13496 case OMPD_taskyield: 13497 case OMPD_barrier: 13498 case OMPD_taskwait: 13499 case OMPD_cancellation_point: 13500 case OMPD_flush: 13501 case OMPD_depobj: 13502 case OMPD_scan: 13503 case OMPD_declare_reduction: 13504 case OMPD_declare_mapper: 13505 case OMPD_declare_simd: 13506 case OMPD_declare_variant: 13507 case OMPD_begin_declare_variant: 13508 case OMPD_end_declare_variant: 13509 case OMPD_declare_target: 13510 case OMPD_end_declare_target: 13511 case OMPD_simd: 13512 case OMPD_tile: 13513 case OMPD_for: 13514 case OMPD_for_simd: 13515 case OMPD_sections: 13516 case OMPD_section: 13517 case OMPD_single: 13518 case OMPD_master: 13519 case OMPD_masked: 13520 case OMPD_critical: 13521 case OMPD_taskgroup: 13522 case OMPD_distribute: 13523 case OMPD_ordered: 13524 case OMPD_atomic: 13525 case OMPD_distribute_simd: 13526 case OMPD_requires: 13527 llvm_unreachable("Unexpected OpenMP directive with device-clause"); 13528 case OMPD_unknown: 13529 default: 13530 llvm_unreachable("Unknown OpenMP directive"); 13531 } 13532 break; 13533 case OMPC_grainsize: 13534 case OMPC_num_tasks: 13535 case OMPC_final: 13536 case OMPC_priority: 13537 switch (DKind) { 13538 case OMPD_task: 13539 case OMPD_taskloop: 13540 case OMPD_taskloop_simd: 13541 case OMPD_master_taskloop: 13542 case OMPD_master_taskloop_simd: 13543 break; 13544 case OMPD_parallel_master_taskloop: 13545 case OMPD_parallel_master_taskloop_simd: 13546 CaptureRegion = OMPD_parallel; 13547 break; 13548 case OMPD_target_update: 13549 case OMPD_target_enter_data: 13550 case OMPD_target_exit_data: 13551 case OMPD_target: 13552 case OMPD_target_simd: 13553 case OMPD_target_teams: 13554 case OMPD_target_parallel: 13555 case OMPD_target_teams_distribute: 13556 case OMPD_target_teams_distribute_simd: 13557 case OMPD_target_parallel_for: 13558 case OMPD_target_parallel_for_simd: 13559 case OMPD_target_teams_distribute_parallel_for: 13560 case OMPD_target_teams_distribute_parallel_for_simd: 13561 case OMPD_target_data: 13562 case OMPD_teams_distribute_parallel_for: 13563 case OMPD_teams_distribute_parallel_for_simd: 13564 case OMPD_teams: 13565 case OMPD_teams_distribute: 13566 case OMPD_teams_distribute_simd: 13567 case OMPD_distribute_parallel_for: 13568 case OMPD_distribute_parallel_for_simd: 13569 case OMPD_cancel: 13570 case OMPD_parallel: 13571 case OMPD_parallel_master: 13572 case OMPD_parallel_sections: 13573 case OMPD_parallel_for: 13574 case OMPD_parallel_for_simd: 13575 case OMPD_threadprivate: 13576 case OMPD_allocate: 13577 case OMPD_taskyield: 13578 case OMPD_barrier: 13579 case OMPD_taskwait: 13580 case OMPD_cancellation_point: 13581 case OMPD_flush: 13582 case OMPD_depobj: 13583 case OMPD_scan: 13584 case OMPD_declare_reduction: 13585 case OMPD_declare_mapper: 13586 case OMPD_declare_simd: 13587 case OMPD_declare_variant: 13588 case OMPD_begin_declare_variant: 13589 case OMPD_end_declare_variant: 13590 case OMPD_declare_target: 13591 case OMPD_end_declare_target: 13592 case OMPD_simd: 13593 case OMPD_tile: 13594 case OMPD_for: 13595 case OMPD_for_simd: 13596 case OMPD_sections: 13597 case OMPD_section: 13598 case OMPD_single: 13599 case OMPD_master: 13600 case OMPD_masked: 13601 case OMPD_critical: 13602 case OMPD_taskgroup: 13603 case OMPD_distribute: 13604 case OMPD_ordered: 13605 case OMPD_atomic: 13606 case OMPD_distribute_simd: 13607 case OMPD_requires: 13608 llvm_unreachable("Unexpected OpenMP directive with grainsize-clause"); 13609 case OMPD_unknown: 13610 default: 13611 llvm_unreachable("Unknown OpenMP directive"); 13612 } 13613 break; 13614 case OMPC_novariants: 13615 case OMPC_nocontext: 13616 switch (DKind) { 13617 case OMPD_dispatch: 13618 CaptureRegion = OMPD_task; 13619 break; 13620 default: 13621 llvm_unreachable("Unexpected OpenMP directive"); 13622 } 13623 break; 13624 case OMPC_filter: 13625 // Do not capture filter-clause expressions. 13626 break; 13627 case OMPC_firstprivate: 13628 case OMPC_lastprivate: 13629 case OMPC_reduction: 13630 case OMPC_task_reduction: 13631 case OMPC_in_reduction: 13632 case OMPC_linear: 13633 case OMPC_default: 13634 case OMPC_proc_bind: 13635 case OMPC_safelen: 13636 case OMPC_simdlen: 13637 case OMPC_sizes: 13638 case OMPC_allocator: 13639 case OMPC_collapse: 13640 case OMPC_private: 13641 case OMPC_shared: 13642 case OMPC_aligned: 13643 case OMPC_copyin: 13644 case OMPC_copyprivate: 13645 case OMPC_ordered: 13646 case OMPC_nowait: 13647 case OMPC_untied: 13648 case OMPC_mergeable: 13649 case OMPC_threadprivate: 13650 case OMPC_allocate: 13651 case OMPC_flush: 13652 case OMPC_depobj: 13653 case OMPC_read: 13654 case OMPC_write: 13655 case OMPC_update: 13656 case OMPC_capture: 13657 case OMPC_seq_cst: 13658 case OMPC_acq_rel: 13659 case OMPC_acquire: 13660 case OMPC_release: 13661 case OMPC_relaxed: 13662 case OMPC_depend: 13663 case OMPC_threads: 13664 case OMPC_simd: 13665 case OMPC_map: 13666 case OMPC_nogroup: 13667 case OMPC_hint: 13668 case OMPC_defaultmap: 13669 case OMPC_unknown: 13670 case OMPC_uniform: 13671 case OMPC_to: 13672 case OMPC_from: 13673 case OMPC_use_device_ptr: 13674 case OMPC_use_device_addr: 13675 case OMPC_is_device_ptr: 13676 case OMPC_unified_address: 13677 case OMPC_unified_shared_memory: 13678 case OMPC_reverse_offload: 13679 case OMPC_dynamic_allocators: 13680 case OMPC_atomic_default_mem_order: 13681 case OMPC_device_type: 13682 case OMPC_match: 13683 case OMPC_nontemporal: 13684 case OMPC_order: 13685 case OMPC_destroy: 13686 case OMPC_detach: 13687 case OMPC_inclusive: 13688 case OMPC_exclusive: 13689 case OMPC_uses_allocators: 13690 case OMPC_affinity: 13691 default: 13692 llvm_unreachable("Unexpected OpenMP clause."); 13693 } 13694 return CaptureRegion; 13695 } 13696 13697 OMPClause *Sema::ActOnOpenMPIfClause(OpenMPDirectiveKind NameModifier, 13698 Expr *Condition, SourceLocation StartLoc, 13699 SourceLocation LParenLoc, 13700 SourceLocation NameModifierLoc, 13701 SourceLocation ColonLoc, 13702 SourceLocation EndLoc) { 13703 Expr *ValExpr = Condition; 13704 Stmt *HelperValStmt = nullptr; 13705 OpenMPDirectiveKind CaptureRegion = OMPD_unknown; 13706 if (!Condition->isValueDependent() && !Condition->isTypeDependent() && 13707 !Condition->isInstantiationDependent() && 13708 !Condition->containsUnexpandedParameterPack()) { 13709 ExprResult Val = CheckBooleanCondition(StartLoc, Condition); 13710 if (Val.isInvalid()) 13711 return nullptr; 13712 13713 ValExpr = Val.get(); 13714 13715 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 13716 CaptureRegion = getOpenMPCaptureRegionForClause( 13717 DKind, OMPC_if, LangOpts.OpenMP, NameModifier); 13718 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 13719 ValExpr = MakeFullExpr(ValExpr).get(); 13720 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 13721 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 13722 HelperValStmt = buildPreInits(Context, Captures); 13723 } 13724 } 13725 13726 return new (Context) 13727 OMPIfClause(NameModifier, ValExpr, HelperValStmt, CaptureRegion, StartLoc, 13728 LParenLoc, NameModifierLoc, ColonLoc, EndLoc); 13729 } 13730 13731 OMPClause *Sema::ActOnOpenMPFinalClause(Expr *Condition, 13732 SourceLocation StartLoc, 13733 SourceLocation LParenLoc, 13734 SourceLocation EndLoc) { 13735 Expr *ValExpr = Condition; 13736 Stmt *HelperValStmt = nullptr; 13737 OpenMPDirectiveKind CaptureRegion = OMPD_unknown; 13738 if (!Condition->isValueDependent() && !Condition->isTypeDependent() && 13739 !Condition->isInstantiationDependent() && 13740 !Condition->containsUnexpandedParameterPack()) { 13741 ExprResult Val = CheckBooleanCondition(StartLoc, Condition); 13742 if (Val.isInvalid()) 13743 return nullptr; 13744 13745 ValExpr = MakeFullExpr(Val.get()).get(); 13746 13747 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 13748 CaptureRegion = 13749 getOpenMPCaptureRegionForClause(DKind, OMPC_final, LangOpts.OpenMP); 13750 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 13751 ValExpr = MakeFullExpr(ValExpr).get(); 13752 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 13753 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 13754 HelperValStmt = buildPreInits(Context, Captures); 13755 } 13756 } 13757 13758 return new (Context) OMPFinalClause(ValExpr, HelperValStmt, CaptureRegion, 13759 StartLoc, LParenLoc, EndLoc); 13760 } 13761 13762 ExprResult Sema::PerformOpenMPImplicitIntegerConversion(SourceLocation Loc, 13763 Expr *Op) { 13764 if (!Op) 13765 return ExprError(); 13766 13767 class IntConvertDiagnoser : public ICEConvertDiagnoser { 13768 public: 13769 IntConvertDiagnoser() 13770 : ICEConvertDiagnoser(/*AllowScopedEnumerations*/ false, false, true) {} 13771 SemaDiagnosticBuilder diagnoseNotInt(Sema &S, SourceLocation Loc, 13772 QualType T) override { 13773 return S.Diag(Loc, diag::err_omp_not_integral) << T; 13774 } 13775 SemaDiagnosticBuilder diagnoseIncomplete(Sema &S, SourceLocation Loc, 13776 QualType T) override { 13777 return S.Diag(Loc, diag::err_omp_incomplete_type) << T; 13778 } 13779 SemaDiagnosticBuilder diagnoseExplicitConv(Sema &S, SourceLocation Loc, 13780 QualType T, 13781 QualType ConvTy) override { 13782 return S.Diag(Loc, diag::err_omp_explicit_conversion) << T << ConvTy; 13783 } 13784 SemaDiagnosticBuilder noteExplicitConv(Sema &S, CXXConversionDecl *Conv, 13785 QualType ConvTy) override { 13786 return S.Diag(Conv->getLocation(), diag::note_omp_conversion_here) 13787 << ConvTy->isEnumeralType() << ConvTy; 13788 } 13789 SemaDiagnosticBuilder diagnoseAmbiguous(Sema &S, SourceLocation Loc, 13790 QualType T) override { 13791 return S.Diag(Loc, diag::err_omp_ambiguous_conversion) << T; 13792 } 13793 SemaDiagnosticBuilder noteAmbiguous(Sema &S, CXXConversionDecl *Conv, 13794 QualType ConvTy) override { 13795 return S.Diag(Conv->getLocation(), diag::note_omp_conversion_here) 13796 << ConvTy->isEnumeralType() << ConvTy; 13797 } 13798 SemaDiagnosticBuilder diagnoseConversion(Sema &, SourceLocation, QualType, 13799 QualType) override { 13800 llvm_unreachable("conversion functions are permitted"); 13801 } 13802 } ConvertDiagnoser; 13803 return PerformContextualImplicitConversion(Loc, Op, ConvertDiagnoser); 13804 } 13805 13806 static bool 13807 isNonNegativeIntegerValue(Expr *&ValExpr, Sema &SemaRef, OpenMPClauseKind CKind, 13808 bool StrictlyPositive, bool BuildCapture = false, 13809 OpenMPDirectiveKind DKind = OMPD_unknown, 13810 OpenMPDirectiveKind *CaptureRegion = nullptr, 13811 Stmt **HelperValStmt = nullptr) { 13812 if (!ValExpr->isTypeDependent() && !ValExpr->isValueDependent() && 13813 !ValExpr->isInstantiationDependent()) { 13814 SourceLocation Loc = ValExpr->getExprLoc(); 13815 ExprResult Value = 13816 SemaRef.PerformOpenMPImplicitIntegerConversion(Loc, ValExpr); 13817 if (Value.isInvalid()) 13818 return false; 13819 13820 ValExpr = Value.get(); 13821 // The expression must evaluate to a non-negative integer value. 13822 if (Optional<llvm::APSInt> Result = 13823 ValExpr->getIntegerConstantExpr(SemaRef.Context)) { 13824 if (Result->isSigned() && 13825 !((!StrictlyPositive && Result->isNonNegative()) || 13826 (StrictlyPositive && Result->isStrictlyPositive()))) { 13827 SemaRef.Diag(Loc, diag::err_omp_negative_expression_in_clause) 13828 << getOpenMPClauseName(CKind) << (StrictlyPositive ? 1 : 0) 13829 << ValExpr->getSourceRange(); 13830 return false; 13831 } 13832 } 13833 if (!BuildCapture) 13834 return true; 13835 *CaptureRegion = 13836 getOpenMPCaptureRegionForClause(DKind, CKind, SemaRef.LangOpts.OpenMP); 13837 if (*CaptureRegion != OMPD_unknown && 13838 !SemaRef.CurContext->isDependentContext()) { 13839 ValExpr = SemaRef.MakeFullExpr(ValExpr).get(); 13840 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 13841 ValExpr = tryBuildCapture(SemaRef, ValExpr, Captures).get(); 13842 *HelperValStmt = buildPreInits(SemaRef.Context, Captures); 13843 } 13844 } 13845 return true; 13846 } 13847 13848 OMPClause *Sema::ActOnOpenMPNumThreadsClause(Expr *NumThreads, 13849 SourceLocation StartLoc, 13850 SourceLocation LParenLoc, 13851 SourceLocation EndLoc) { 13852 Expr *ValExpr = NumThreads; 13853 Stmt *HelperValStmt = nullptr; 13854 13855 // OpenMP [2.5, Restrictions] 13856 // The num_threads expression must evaluate to a positive integer value. 13857 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_num_threads, 13858 /*StrictlyPositive=*/true)) 13859 return nullptr; 13860 13861 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 13862 OpenMPDirectiveKind CaptureRegion = 13863 getOpenMPCaptureRegionForClause(DKind, OMPC_num_threads, LangOpts.OpenMP); 13864 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 13865 ValExpr = MakeFullExpr(ValExpr).get(); 13866 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 13867 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 13868 HelperValStmt = buildPreInits(Context, Captures); 13869 } 13870 13871 return new (Context) OMPNumThreadsClause( 13872 ValExpr, HelperValStmt, CaptureRegion, StartLoc, LParenLoc, EndLoc); 13873 } 13874 13875 ExprResult Sema::VerifyPositiveIntegerConstantInClause(Expr *E, 13876 OpenMPClauseKind CKind, 13877 bool StrictlyPositive) { 13878 if (!E) 13879 return ExprError(); 13880 if (E->isValueDependent() || E->isTypeDependent() || 13881 E->isInstantiationDependent() || E->containsUnexpandedParameterPack()) 13882 return E; 13883 llvm::APSInt Result; 13884 ExprResult ICE = 13885 VerifyIntegerConstantExpression(E, &Result, /*FIXME*/ AllowFold); 13886 if (ICE.isInvalid()) 13887 return ExprError(); 13888 if ((StrictlyPositive && !Result.isStrictlyPositive()) || 13889 (!StrictlyPositive && !Result.isNonNegative())) { 13890 Diag(E->getExprLoc(), diag::err_omp_negative_expression_in_clause) 13891 << getOpenMPClauseName(CKind) << (StrictlyPositive ? 1 : 0) 13892 << E->getSourceRange(); 13893 return ExprError(); 13894 } 13895 if (CKind == OMPC_aligned && !Result.isPowerOf2()) { 13896 Diag(E->getExprLoc(), diag::warn_omp_alignment_not_power_of_two) 13897 << E->getSourceRange(); 13898 return ExprError(); 13899 } 13900 if (CKind == OMPC_collapse && DSAStack->getAssociatedLoops() == 1) 13901 DSAStack->setAssociatedLoops(Result.getExtValue()); 13902 else if (CKind == OMPC_ordered) 13903 DSAStack->setAssociatedLoops(Result.getExtValue()); 13904 return ICE; 13905 } 13906 13907 OMPClause *Sema::ActOnOpenMPSafelenClause(Expr *Len, SourceLocation StartLoc, 13908 SourceLocation LParenLoc, 13909 SourceLocation EndLoc) { 13910 // OpenMP [2.8.1, simd construct, Description] 13911 // The parameter of the safelen clause must be a constant 13912 // positive integer expression. 13913 ExprResult Safelen = VerifyPositiveIntegerConstantInClause(Len, OMPC_safelen); 13914 if (Safelen.isInvalid()) 13915 return nullptr; 13916 return new (Context) 13917 OMPSafelenClause(Safelen.get(), StartLoc, LParenLoc, EndLoc); 13918 } 13919 13920 OMPClause *Sema::ActOnOpenMPSimdlenClause(Expr *Len, SourceLocation StartLoc, 13921 SourceLocation LParenLoc, 13922 SourceLocation EndLoc) { 13923 // OpenMP [2.8.1, simd construct, Description] 13924 // The parameter of the simdlen clause must be a constant 13925 // positive integer expression. 13926 ExprResult Simdlen = VerifyPositiveIntegerConstantInClause(Len, OMPC_simdlen); 13927 if (Simdlen.isInvalid()) 13928 return nullptr; 13929 return new (Context) 13930 OMPSimdlenClause(Simdlen.get(), StartLoc, LParenLoc, EndLoc); 13931 } 13932 13933 /// Tries to find omp_allocator_handle_t type. 13934 static bool findOMPAllocatorHandleT(Sema &S, SourceLocation Loc, 13935 DSAStackTy *Stack) { 13936 QualType OMPAllocatorHandleT = Stack->getOMPAllocatorHandleT(); 13937 if (!OMPAllocatorHandleT.isNull()) 13938 return true; 13939 // Build the predefined allocator expressions. 13940 bool ErrorFound = false; 13941 for (int I = 0; I < OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; ++I) { 13942 auto AllocatorKind = static_cast<OMPAllocateDeclAttr::AllocatorTypeTy>(I); 13943 StringRef Allocator = 13944 OMPAllocateDeclAttr::ConvertAllocatorTypeTyToStr(AllocatorKind); 13945 DeclarationName AllocatorName = &S.getASTContext().Idents.get(Allocator); 13946 auto *VD = dyn_cast_or_null<ValueDecl>( 13947 S.LookupSingleName(S.TUScope, AllocatorName, Loc, Sema::LookupAnyName)); 13948 if (!VD) { 13949 ErrorFound = true; 13950 break; 13951 } 13952 QualType AllocatorType = 13953 VD->getType().getNonLValueExprType(S.getASTContext()); 13954 ExprResult Res = S.BuildDeclRefExpr(VD, AllocatorType, VK_LValue, Loc); 13955 if (!Res.isUsable()) { 13956 ErrorFound = true; 13957 break; 13958 } 13959 if (OMPAllocatorHandleT.isNull()) 13960 OMPAllocatorHandleT = AllocatorType; 13961 if (!S.getASTContext().hasSameType(OMPAllocatorHandleT, AllocatorType)) { 13962 ErrorFound = true; 13963 break; 13964 } 13965 Stack->setAllocator(AllocatorKind, Res.get()); 13966 } 13967 if (ErrorFound) { 13968 S.Diag(Loc, diag::err_omp_implied_type_not_found) 13969 << "omp_allocator_handle_t"; 13970 return false; 13971 } 13972 OMPAllocatorHandleT.addConst(); 13973 Stack->setOMPAllocatorHandleT(OMPAllocatorHandleT); 13974 return true; 13975 } 13976 13977 OMPClause *Sema::ActOnOpenMPAllocatorClause(Expr *A, SourceLocation StartLoc, 13978 SourceLocation LParenLoc, 13979 SourceLocation EndLoc) { 13980 // OpenMP [2.11.3, allocate Directive, Description] 13981 // allocator is an expression of omp_allocator_handle_t type. 13982 if (!findOMPAllocatorHandleT(*this, A->getExprLoc(), DSAStack)) 13983 return nullptr; 13984 13985 ExprResult Allocator = DefaultLvalueConversion(A); 13986 if (Allocator.isInvalid()) 13987 return nullptr; 13988 Allocator = PerformImplicitConversion(Allocator.get(), 13989 DSAStack->getOMPAllocatorHandleT(), 13990 Sema::AA_Initializing, 13991 /*AllowExplicit=*/true); 13992 if (Allocator.isInvalid()) 13993 return nullptr; 13994 return new (Context) 13995 OMPAllocatorClause(Allocator.get(), StartLoc, LParenLoc, EndLoc); 13996 } 13997 13998 OMPClause *Sema::ActOnOpenMPCollapseClause(Expr *NumForLoops, 13999 SourceLocation StartLoc, 14000 SourceLocation LParenLoc, 14001 SourceLocation EndLoc) { 14002 // OpenMP [2.7.1, loop construct, Description] 14003 // OpenMP [2.8.1, simd construct, Description] 14004 // OpenMP [2.9.6, distribute construct, Description] 14005 // The parameter of the collapse clause must be a constant 14006 // positive integer expression. 14007 ExprResult NumForLoopsResult = 14008 VerifyPositiveIntegerConstantInClause(NumForLoops, OMPC_collapse); 14009 if (NumForLoopsResult.isInvalid()) 14010 return nullptr; 14011 return new (Context) 14012 OMPCollapseClause(NumForLoopsResult.get(), StartLoc, LParenLoc, EndLoc); 14013 } 14014 14015 OMPClause *Sema::ActOnOpenMPOrderedClause(SourceLocation StartLoc, 14016 SourceLocation EndLoc, 14017 SourceLocation LParenLoc, 14018 Expr *NumForLoops) { 14019 // OpenMP [2.7.1, loop construct, Description] 14020 // OpenMP [2.8.1, simd construct, Description] 14021 // OpenMP [2.9.6, distribute construct, Description] 14022 // The parameter of the ordered clause must be a constant 14023 // positive integer expression if any. 14024 if (NumForLoops && LParenLoc.isValid()) { 14025 ExprResult NumForLoopsResult = 14026 VerifyPositiveIntegerConstantInClause(NumForLoops, OMPC_ordered); 14027 if (NumForLoopsResult.isInvalid()) 14028 return nullptr; 14029 NumForLoops = NumForLoopsResult.get(); 14030 } else { 14031 NumForLoops = nullptr; 14032 } 14033 auto *Clause = OMPOrderedClause::Create( 14034 Context, NumForLoops, NumForLoops ? DSAStack->getAssociatedLoops() : 0, 14035 StartLoc, LParenLoc, EndLoc); 14036 DSAStack->setOrderedRegion(/*IsOrdered=*/true, NumForLoops, Clause); 14037 return Clause; 14038 } 14039 14040 OMPClause *Sema::ActOnOpenMPSimpleClause( 14041 OpenMPClauseKind Kind, unsigned Argument, SourceLocation ArgumentLoc, 14042 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) { 14043 OMPClause *Res = nullptr; 14044 switch (Kind) { 14045 case OMPC_default: 14046 Res = ActOnOpenMPDefaultClause(static_cast<DefaultKind>(Argument), 14047 ArgumentLoc, StartLoc, LParenLoc, EndLoc); 14048 break; 14049 case OMPC_proc_bind: 14050 Res = ActOnOpenMPProcBindClause(static_cast<ProcBindKind>(Argument), 14051 ArgumentLoc, StartLoc, LParenLoc, EndLoc); 14052 break; 14053 case OMPC_atomic_default_mem_order: 14054 Res = ActOnOpenMPAtomicDefaultMemOrderClause( 14055 static_cast<OpenMPAtomicDefaultMemOrderClauseKind>(Argument), 14056 ArgumentLoc, StartLoc, LParenLoc, EndLoc); 14057 break; 14058 case OMPC_order: 14059 Res = ActOnOpenMPOrderClause(static_cast<OpenMPOrderClauseKind>(Argument), 14060 ArgumentLoc, StartLoc, LParenLoc, EndLoc); 14061 break; 14062 case OMPC_update: 14063 Res = ActOnOpenMPUpdateClause(static_cast<OpenMPDependClauseKind>(Argument), 14064 ArgumentLoc, StartLoc, LParenLoc, EndLoc); 14065 break; 14066 case OMPC_if: 14067 case OMPC_final: 14068 case OMPC_num_threads: 14069 case OMPC_safelen: 14070 case OMPC_simdlen: 14071 case OMPC_sizes: 14072 case OMPC_allocator: 14073 case OMPC_collapse: 14074 case OMPC_schedule: 14075 case OMPC_private: 14076 case OMPC_firstprivate: 14077 case OMPC_lastprivate: 14078 case OMPC_shared: 14079 case OMPC_reduction: 14080 case OMPC_task_reduction: 14081 case OMPC_in_reduction: 14082 case OMPC_linear: 14083 case OMPC_aligned: 14084 case OMPC_copyin: 14085 case OMPC_copyprivate: 14086 case OMPC_ordered: 14087 case OMPC_nowait: 14088 case OMPC_untied: 14089 case OMPC_mergeable: 14090 case OMPC_threadprivate: 14091 case OMPC_allocate: 14092 case OMPC_flush: 14093 case OMPC_depobj: 14094 case OMPC_read: 14095 case OMPC_write: 14096 case OMPC_capture: 14097 case OMPC_seq_cst: 14098 case OMPC_acq_rel: 14099 case OMPC_acquire: 14100 case OMPC_release: 14101 case OMPC_relaxed: 14102 case OMPC_depend: 14103 case OMPC_device: 14104 case OMPC_threads: 14105 case OMPC_simd: 14106 case OMPC_map: 14107 case OMPC_num_teams: 14108 case OMPC_thread_limit: 14109 case OMPC_priority: 14110 case OMPC_grainsize: 14111 case OMPC_nogroup: 14112 case OMPC_num_tasks: 14113 case OMPC_hint: 14114 case OMPC_dist_schedule: 14115 case OMPC_defaultmap: 14116 case OMPC_unknown: 14117 case OMPC_uniform: 14118 case OMPC_to: 14119 case OMPC_from: 14120 case OMPC_use_device_ptr: 14121 case OMPC_use_device_addr: 14122 case OMPC_is_device_ptr: 14123 case OMPC_unified_address: 14124 case OMPC_unified_shared_memory: 14125 case OMPC_reverse_offload: 14126 case OMPC_dynamic_allocators: 14127 case OMPC_device_type: 14128 case OMPC_match: 14129 case OMPC_nontemporal: 14130 case OMPC_destroy: 14131 case OMPC_novariants: 14132 case OMPC_nocontext: 14133 case OMPC_detach: 14134 case OMPC_inclusive: 14135 case OMPC_exclusive: 14136 case OMPC_uses_allocators: 14137 case OMPC_affinity: 14138 default: 14139 llvm_unreachable("Clause is not allowed."); 14140 } 14141 return Res; 14142 } 14143 14144 static std::string 14145 getListOfPossibleValues(OpenMPClauseKind K, unsigned First, unsigned Last, 14146 ArrayRef<unsigned> Exclude = llvm::None) { 14147 SmallString<256> Buffer; 14148 llvm::raw_svector_ostream Out(Buffer); 14149 unsigned Skipped = Exclude.size(); 14150 auto S = Exclude.begin(), E = Exclude.end(); 14151 for (unsigned I = First; I < Last; ++I) { 14152 if (std::find(S, E, I) != E) { 14153 --Skipped; 14154 continue; 14155 } 14156 Out << "'" << getOpenMPSimpleClauseTypeName(K, I) << "'"; 14157 if (I + Skipped + 2 == Last) 14158 Out << " or "; 14159 else if (I + Skipped + 1 != Last) 14160 Out << ", "; 14161 } 14162 return std::string(Out.str()); 14163 } 14164 14165 OMPClause *Sema::ActOnOpenMPDefaultClause(DefaultKind Kind, 14166 SourceLocation KindKwLoc, 14167 SourceLocation StartLoc, 14168 SourceLocation LParenLoc, 14169 SourceLocation EndLoc) { 14170 if (Kind == OMP_DEFAULT_unknown) { 14171 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value) 14172 << getListOfPossibleValues(OMPC_default, /*First=*/0, 14173 /*Last=*/unsigned(OMP_DEFAULT_unknown)) 14174 << getOpenMPClauseName(OMPC_default); 14175 return nullptr; 14176 } 14177 14178 switch (Kind) { 14179 case OMP_DEFAULT_none: 14180 DSAStack->setDefaultDSANone(KindKwLoc); 14181 break; 14182 case OMP_DEFAULT_shared: 14183 DSAStack->setDefaultDSAShared(KindKwLoc); 14184 break; 14185 case OMP_DEFAULT_firstprivate: 14186 DSAStack->setDefaultDSAFirstPrivate(KindKwLoc); 14187 break; 14188 default: 14189 llvm_unreachable("DSA unexpected in OpenMP default clause"); 14190 } 14191 14192 return new (Context) 14193 OMPDefaultClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc); 14194 } 14195 14196 OMPClause *Sema::ActOnOpenMPProcBindClause(ProcBindKind Kind, 14197 SourceLocation KindKwLoc, 14198 SourceLocation StartLoc, 14199 SourceLocation LParenLoc, 14200 SourceLocation EndLoc) { 14201 if (Kind == OMP_PROC_BIND_unknown) { 14202 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value) 14203 << getListOfPossibleValues(OMPC_proc_bind, 14204 /*First=*/unsigned(OMP_PROC_BIND_master), 14205 /*Last=*/ 14206 unsigned(LangOpts.OpenMP > 50 14207 ? OMP_PROC_BIND_primary 14208 : OMP_PROC_BIND_spread) + 14209 1) 14210 << getOpenMPClauseName(OMPC_proc_bind); 14211 return nullptr; 14212 } 14213 if (Kind == OMP_PROC_BIND_primary && LangOpts.OpenMP < 51) 14214 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value) 14215 << getListOfPossibleValues(OMPC_proc_bind, 14216 /*First=*/unsigned(OMP_PROC_BIND_master), 14217 /*Last=*/ 14218 unsigned(OMP_PROC_BIND_spread) + 1) 14219 << getOpenMPClauseName(OMPC_proc_bind); 14220 return new (Context) 14221 OMPProcBindClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc); 14222 } 14223 14224 OMPClause *Sema::ActOnOpenMPAtomicDefaultMemOrderClause( 14225 OpenMPAtomicDefaultMemOrderClauseKind Kind, SourceLocation KindKwLoc, 14226 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) { 14227 if (Kind == OMPC_ATOMIC_DEFAULT_MEM_ORDER_unknown) { 14228 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value) 14229 << getListOfPossibleValues( 14230 OMPC_atomic_default_mem_order, /*First=*/0, 14231 /*Last=*/OMPC_ATOMIC_DEFAULT_MEM_ORDER_unknown) 14232 << getOpenMPClauseName(OMPC_atomic_default_mem_order); 14233 return nullptr; 14234 } 14235 return new (Context) OMPAtomicDefaultMemOrderClause(Kind, KindKwLoc, StartLoc, 14236 LParenLoc, EndLoc); 14237 } 14238 14239 OMPClause *Sema::ActOnOpenMPOrderClause(OpenMPOrderClauseKind Kind, 14240 SourceLocation KindKwLoc, 14241 SourceLocation StartLoc, 14242 SourceLocation LParenLoc, 14243 SourceLocation EndLoc) { 14244 if (Kind == OMPC_ORDER_unknown) { 14245 static_assert(OMPC_ORDER_unknown > 0, 14246 "OMPC_ORDER_unknown not greater than 0"); 14247 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value) 14248 << getListOfPossibleValues(OMPC_order, /*First=*/0, 14249 /*Last=*/OMPC_ORDER_unknown) 14250 << getOpenMPClauseName(OMPC_order); 14251 return nullptr; 14252 } 14253 return new (Context) 14254 OMPOrderClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc); 14255 } 14256 14257 OMPClause *Sema::ActOnOpenMPUpdateClause(OpenMPDependClauseKind Kind, 14258 SourceLocation KindKwLoc, 14259 SourceLocation StartLoc, 14260 SourceLocation LParenLoc, 14261 SourceLocation EndLoc) { 14262 if (Kind == OMPC_DEPEND_unknown || Kind == OMPC_DEPEND_source || 14263 Kind == OMPC_DEPEND_sink || Kind == OMPC_DEPEND_depobj) { 14264 unsigned Except[] = {OMPC_DEPEND_source, OMPC_DEPEND_sink, 14265 OMPC_DEPEND_depobj}; 14266 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value) 14267 << getListOfPossibleValues(OMPC_depend, /*First=*/0, 14268 /*Last=*/OMPC_DEPEND_unknown, Except) 14269 << getOpenMPClauseName(OMPC_update); 14270 return nullptr; 14271 } 14272 return OMPUpdateClause::Create(Context, StartLoc, LParenLoc, KindKwLoc, Kind, 14273 EndLoc); 14274 } 14275 14276 OMPClause *Sema::ActOnOpenMPSizesClause(ArrayRef<Expr *> SizeExprs, 14277 SourceLocation StartLoc, 14278 SourceLocation LParenLoc, 14279 SourceLocation EndLoc) { 14280 for (Expr *SizeExpr : SizeExprs) { 14281 ExprResult NumForLoopsResult = VerifyPositiveIntegerConstantInClause( 14282 SizeExpr, OMPC_sizes, /*StrictlyPositive=*/true); 14283 if (!NumForLoopsResult.isUsable()) 14284 return nullptr; 14285 } 14286 14287 DSAStack->setAssociatedLoops(SizeExprs.size()); 14288 return OMPSizesClause::Create(Context, StartLoc, LParenLoc, EndLoc, 14289 SizeExprs); 14290 } 14291 14292 OMPClause *Sema::ActOnOpenMPSingleExprWithArgClause( 14293 OpenMPClauseKind Kind, ArrayRef<unsigned> Argument, Expr *Expr, 14294 SourceLocation StartLoc, SourceLocation LParenLoc, 14295 ArrayRef<SourceLocation> ArgumentLoc, SourceLocation DelimLoc, 14296 SourceLocation EndLoc) { 14297 OMPClause *Res = nullptr; 14298 switch (Kind) { 14299 case OMPC_schedule: 14300 enum { Modifier1, Modifier2, ScheduleKind, NumberOfElements }; 14301 assert(Argument.size() == NumberOfElements && 14302 ArgumentLoc.size() == NumberOfElements); 14303 Res = ActOnOpenMPScheduleClause( 14304 static_cast<OpenMPScheduleClauseModifier>(Argument[Modifier1]), 14305 static_cast<OpenMPScheduleClauseModifier>(Argument[Modifier2]), 14306 static_cast<OpenMPScheduleClauseKind>(Argument[ScheduleKind]), Expr, 14307 StartLoc, LParenLoc, ArgumentLoc[Modifier1], ArgumentLoc[Modifier2], 14308 ArgumentLoc[ScheduleKind], DelimLoc, EndLoc); 14309 break; 14310 case OMPC_if: 14311 assert(Argument.size() == 1 && ArgumentLoc.size() == 1); 14312 Res = ActOnOpenMPIfClause(static_cast<OpenMPDirectiveKind>(Argument.back()), 14313 Expr, StartLoc, LParenLoc, ArgumentLoc.back(), 14314 DelimLoc, EndLoc); 14315 break; 14316 case OMPC_dist_schedule: 14317 Res = ActOnOpenMPDistScheduleClause( 14318 static_cast<OpenMPDistScheduleClauseKind>(Argument.back()), Expr, 14319 StartLoc, LParenLoc, ArgumentLoc.back(), DelimLoc, EndLoc); 14320 break; 14321 case OMPC_defaultmap: 14322 enum { Modifier, DefaultmapKind }; 14323 Res = ActOnOpenMPDefaultmapClause( 14324 static_cast<OpenMPDefaultmapClauseModifier>(Argument[Modifier]), 14325 static_cast<OpenMPDefaultmapClauseKind>(Argument[DefaultmapKind]), 14326 StartLoc, LParenLoc, ArgumentLoc[Modifier], ArgumentLoc[DefaultmapKind], 14327 EndLoc); 14328 break; 14329 case OMPC_device: 14330 assert(Argument.size() == 1 && ArgumentLoc.size() == 1); 14331 Res = ActOnOpenMPDeviceClause( 14332 static_cast<OpenMPDeviceClauseModifier>(Argument.back()), Expr, 14333 StartLoc, LParenLoc, ArgumentLoc.back(), EndLoc); 14334 break; 14335 case OMPC_final: 14336 case OMPC_num_threads: 14337 case OMPC_safelen: 14338 case OMPC_simdlen: 14339 case OMPC_sizes: 14340 case OMPC_allocator: 14341 case OMPC_collapse: 14342 case OMPC_default: 14343 case OMPC_proc_bind: 14344 case OMPC_private: 14345 case OMPC_firstprivate: 14346 case OMPC_lastprivate: 14347 case OMPC_shared: 14348 case OMPC_reduction: 14349 case OMPC_task_reduction: 14350 case OMPC_in_reduction: 14351 case OMPC_linear: 14352 case OMPC_aligned: 14353 case OMPC_copyin: 14354 case OMPC_copyprivate: 14355 case OMPC_ordered: 14356 case OMPC_nowait: 14357 case OMPC_untied: 14358 case OMPC_mergeable: 14359 case OMPC_threadprivate: 14360 case OMPC_allocate: 14361 case OMPC_flush: 14362 case OMPC_depobj: 14363 case OMPC_read: 14364 case OMPC_write: 14365 case OMPC_update: 14366 case OMPC_capture: 14367 case OMPC_seq_cst: 14368 case OMPC_acq_rel: 14369 case OMPC_acquire: 14370 case OMPC_release: 14371 case OMPC_relaxed: 14372 case OMPC_depend: 14373 case OMPC_threads: 14374 case OMPC_simd: 14375 case OMPC_map: 14376 case OMPC_num_teams: 14377 case OMPC_thread_limit: 14378 case OMPC_priority: 14379 case OMPC_grainsize: 14380 case OMPC_nogroup: 14381 case OMPC_num_tasks: 14382 case OMPC_hint: 14383 case OMPC_unknown: 14384 case OMPC_uniform: 14385 case OMPC_to: 14386 case OMPC_from: 14387 case OMPC_use_device_ptr: 14388 case OMPC_use_device_addr: 14389 case OMPC_is_device_ptr: 14390 case OMPC_unified_address: 14391 case OMPC_unified_shared_memory: 14392 case OMPC_reverse_offload: 14393 case OMPC_dynamic_allocators: 14394 case OMPC_atomic_default_mem_order: 14395 case OMPC_device_type: 14396 case OMPC_match: 14397 case OMPC_nontemporal: 14398 case OMPC_order: 14399 case OMPC_destroy: 14400 case OMPC_novariants: 14401 case OMPC_nocontext: 14402 case OMPC_detach: 14403 case OMPC_inclusive: 14404 case OMPC_exclusive: 14405 case OMPC_uses_allocators: 14406 case OMPC_affinity: 14407 default: 14408 llvm_unreachable("Clause is not allowed."); 14409 } 14410 return Res; 14411 } 14412 14413 static bool checkScheduleModifiers(Sema &S, OpenMPScheduleClauseModifier M1, 14414 OpenMPScheduleClauseModifier M2, 14415 SourceLocation M1Loc, SourceLocation M2Loc) { 14416 if (M1 == OMPC_SCHEDULE_MODIFIER_unknown && M1Loc.isValid()) { 14417 SmallVector<unsigned, 2> Excluded; 14418 if (M2 != OMPC_SCHEDULE_MODIFIER_unknown) 14419 Excluded.push_back(M2); 14420 if (M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) 14421 Excluded.push_back(OMPC_SCHEDULE_MODIFIER_monotonic); 14422 if (M2 == OMPC_SCHEDULE_MODIFIER_monotonic) 14423 Excluded.push_back(OMPC_SCHEDULE_MODIFIER_nonmonotonic); 14424 S.Diag(M1Loc, diag::err_omp_unexpected_clause_value) 14425 << getListOfPossibleValues(OMPC_schedule, 14426 /*First=*/OMPC_SCHEDULE_MODIFIER_unknown + 1, 14427 /*Last=*/OMPC_SCHEDULE_MODIFIER_last, 14428 Excluded) 14429 << getOpenMPClauseName(OMPC_schedule); 14430 return true; 14431 } 14432 return false; 14433 } 14434 14435 OMPClause *Sema::ActOnOpenMPScheduleClause( 14436 OpenMPScheduleClauseModifier M1, OpenMPScheduleClauseModifier M2, 14437 OpenMPScheduleClauseKind Kind, Expr *ChunkSize, SourceLocation StartLoc, 14438 SourceLocation LParenLoc, SourceLocation M1Loc, SourceLocation M2Loc, 14439 SourceLocation KindLoc, SourceLocation CommaLoc, SourceLocation EndLoc) { 14440 if (checkScheduleModifiers(*this, M1, M2, M1Loc, M2Loc) || 14441 checkScheduleModifiers(*this, M2, M1, M2Loc, M1Loc)) 14442 return nullptr; 14443 // OpenMP, 2.7.1, Loop Construct, Restrictions 14444 // Either the monotonic modifier or the nonmonotonic modifier can be specified 14445 // but not both. 14446 if ((M1 == M2 && M1 != OMPC_SCHEDULE_MODIFIER_unknown) || 14447 (M1 == OMPC_SCHEDULE_MODIFIER_monotonic && 14448 M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) || 14449 (M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic && 14450 M2 == OMPC_SCHEDULE_MODIFIER_monotonic)) { 14451 Diag(M2Loc, diag::err_omp_unexpected_schedule_modifier) 14452 << getOpenMPSimpleClauseTypeName(OMPC_schedule, M2) 14453 << getOpenMPSimpleClauseTypeName(OMPC_schedule, M1); 14454 return nullptr; 14455 } 14456 if (Kind == OMPC_SCHEDULE_unknown) { 14457 std::string Values; 14458 if (M1Loc.isInvalid() && M2Loc.isInvalid()) { 14459 unsigned Exclude[] = {OMPC_SCHEDULE_unknown}; 14460 Values = getListOfPossibleValues(OMPC_schedule, /*First=*/0, 14461 /*Last=*/OMPC_SCHEDULE_MODIFIER_last, 14462 Exclude); 14463 } else { 14464 Values = getListOfPossibleValues(OMPC_schedule, /*First=*/0, 14465 /*Last=*/OMPC_SCHEDULE_unknown); 14466 } 14467 Diag(KindLoc, diag::err_omp_unexpected_clause_value) 14468 << Values << getOpenMPClauseName(OMPC_schedule); 14469 return nullptr; 14470 } 14471 // OpenMP, 2.7.1, Loop Construct, Restrictions 14472 // The nonmonotonic modifier can only be specified with schedule(dynamic) or 14473 // schedule(guided). 14474 // OpenMP 5.0 does not have this restriction. 14475 if (LangOpts.OpenMP < 50 && 14476 (M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic || 14477 M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) && 14478 Kind != OMPC_SCHEDULE_dynamic && Kind != OMPC_SCHEDULE_guided) { 14479 Diag(M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic ? M1Loc : M2Loc, 14480 diag::err_omp_schedule_nonmonotonic_static); 14481 return nullptr; 14482 } 14483 Expr *ValExpr = ChunkSize; 14484 Stmt *HelperValStmt = nullptr; 14485 if (ChunkSize) { 14486 if (!ChunkSize->isValueDependent() && !ChunkSize->isTypeDependent() && 14487 !ChunkSize->isInstantiationDependent() && 14488 !ChunkSize->containsUnexpandedParameterPack()) { 14489 SourceLocation ChunkSizeLoc = ChunkSize->getBeginLoc(); 14490 ExprResult Val = 14491 PerformOpenMPImplicitIntegerConversion(ChunkSizeLoc, ChunkSize); 14492 if (Val.isInvalid()) 14493 return nullptr; 14494 14495 ValExpr = Val.get(); 14496 14497 // OpenMP [2.7.1, Restrictions] 14498 // chunk_size must be a loop invariant integer expression with a positive 14499 // value. 14500 if (Optional<llvm::APSInt> Result = 14501 ValExpr->getIntegerConstantExpr(Context)) { 14502 if (Result->isSigned() && !Result->isStrictlyPositive()) { 14503 Diag(ChunkSizeLoc, diag::err_omp_negative_expression_in_clause) 14504 << "schedule" << 1 << ChunkSize->getSourceRange(); 14505 return nullptr; 14506 } 14507 } else if (getOpenMPCaptureRegionForClause( 14508 DSAStack->getCurrentDirective(), OMPC_schedule, 14509 LangOpts.OpenMP) != OMPD_unknown && 14510 !CurContext->isDependentContext()) { 14511 ValExpr = MakeFullExpr(ValExpr).get(); 14512 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 14513 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 14514 HelperValStmt = buildPreInits(Context, Captures); 14515 } 14516 } 14517 } 14518 14519 return new (Context) 14520 OMPScheduleClause(StartLoc, LParenLoc, KindLoc, CommaLoc, EndLoc, Kind, 14521 ValExpr, HelperValStmt, M1, M1Loc, M2, M2Loc); 14522 } 14523 14524 OMPClause *Sema::ActOnOpenMPClause(OpenMPClauseKind Kind, 14525 SourceLocation StartLoc, 14526 SourceLocation EndLoc) { 14527 OMPClause *Res = nullptr; 14528 switch (Kind) { 14529 case OMPC_ordered: 14530 Res = ActOnOpenMPOrderedClause(StartLoc, EndLoc); 14531 break; 14532 case OMPC_nowait: 14533 Res = ActOnOpenMPNowaitClause(StartLoc, EndLoc); 14534 break; 14535 case OMPC_untied: 14536 Res = ActOnOpenMPUntiedClause(StartLoc, EndLoc); 14537 break; 14538 case OMPC_mergeable: 14539 Res = ActOnOpenMPMergeableClause(StartLoc, EndLoc); 14540 break; 14541 case OMPC_read: 14542 Res = ActOnOpenMPReadClause(StartLoc, EndLoc); 14543 break; 14544 case OMPC_write: 14545 Res = ActOnOpenMPWriteClause(StartLoc, EndLoc); 14546 break; 14547 case OMPC_update: 14548 Res = ActOnOpenMPUpdateClause(StartLoc, EndLoc); 14549 break; 14550 case OMPC_capture: 14551 Res = ActOnOpenMPCaptureClause(StartLoc, EndLoc); 14552 break; 14553 case OMPC_seq_cst: 14554 Res = ActOnOpenMPSeqCstClause(StartLoc, EndLoc); 14555 break; 14556 case OMPC_acq_rel: 14557 Res = ActOnOpenMPAcqRelClause(StartLoc, EndLoc); 14558 break; 14559 case OMPC_acquire: 14560 Res = ActOnOpenMPAcquireClause(StartLoc, EndLoc); 14561 break; 14562 case OMPC_release: 14563 Res = ActOnOpenMPReleaseClause(StartLoc, EndLoc); 14564 break; 14565 case OMPC_relaxed: 14566 Res = ActOnOpenMPRelaxedClause(StartLoc, EndLoc); 14567 break; 14568 case OMPC_threads: 14569 Res = ActOnOpenMPThreadsClause(StartLoc, EndLoc); 14570 break; 14571 case OMPC_simd: 14572 Res = ActOnOpenMPSIMDClause(StartLoc, EndLoc); 14573 break; 14574 case OMPC_nogroup: 14575 Res = ActOnOpenMPNogroupClause(StartLoc, EndLoc); 14576 break; 14577 case OMPC_unified_address: 14578 Res = ActOnOpenMPUnifiedAddressClause(StartLoc, EndLoc); 14579 break; 14580 case OMPC_unified_shared_memory: 14581 Res = ActOnOpenMPUnifiedSharedMemoryClause(StartLoc, EndLoc); 14582 break; 14583 case OMPC_reverse_offload: 14584 Res = ActOnOpenMPReverseOffloadClause(StartLoc, EndLoc); 14585 break; 14586 case OMPC_dynamic_allocators: 14587 Res = ActOnOpenMPDynamicAllocatorsClause(StartLoc, EndLoc); 14588 break; 14589 case OMPC_destroy: 14590 Res = ActOnOpenMPDestroyClause(/*InteropVar=*/nullptr, StartLoc, 14591 /*LParenLoc=*/SourceLocation(), 14592 /*VarLoc=*/SourceLocation(), EndLoc); 14593 break; 14594 case OMPC_if: 14595 case OMPC_final: 14596 case OMPC_num_threads: 14597 case OMPC_safelen: 14598 case OMPC_simdlen: 14599 case OMPC_sizes: 14600 case OMPC_allocator: 14601 case OMPC_collapse: 14602 case OMPC_schedule: 14603 case OMPC_private: 14604 case OMPC_firstprivate: 14605 case OMPC_lastprivate: 14606 case OMPC_shared: 14607 case OMPC_reduction: 14608 case OMPC_task_reduction: 14609 case OMPC_in_reduction: 14610 case OMPC_linear: 14611 case OMPC_aligned: 14612 case OMPC_copyin: 14613 case OMPC_copyprivate: 14614 case OMPC_default: 14615 case OMPC_proc_bind: 14616 case OMPC_threadprivate: 14617 case OMPC_allocate: 14618 case OMPC_flush: 14619 case OMPC_depobj: 14620 case OMPC_depend: 14621 case OMPC_device: 14622 case OMPC_map: 14623 case OMPC_num_teams: 14624 case OMPC_thread_limit: 14625 case OMPC_priority: 14626 case OMPC_grainsize: 14627 case OMPC_num_tasks: 14628 case OMPC_hint: 14629 case OMPC_dist_schedule: 14630 case OMPC_defaultmap: 14631 case OMPC_unknown: 14632 case OMPC_uniform: 14633 case OMPC_to: 14634 case OMPC_from: 14635 case OMPC_use_device_ptr: 14636 case OMPC_use_device_addr: 14637 case OMPC_is_device_ptr: 14638 case OMPC_atomic_default_mem_order: 14639 case OMPC_device_type: 14640 case OMPC_match: 14641 case OMPC_nontemporal: 14642 case OMPC_order: 14643 case OMPC_novariants: 14644 case OMPC_nocontext: 14645 case OMPC_detach: 14646 case OMPC_inclusive: 14647 case OMPC_exclusive: 14648 case OMPC_uses_allocators: 14649 case OMPC_affinity: 14650 default: 14651 llvm_unreachable("Clause is not allowed."); 14652 } 14653 return Res; 14654 } 14655 14656 OMPClause *Sema::ActOnOpenMPNowaitClause(SourceLocation StartLoc, 14657 SourceLocation EndLoc) { 14658 DSAStack->setNowaitRegion(); 14659 return new (Context) OMPNowaitClause(StartLoc, EndLoc); 14660 } 14661 14662 OMPClause *Sema::ActOnOpenMPUntiedClause(SourceLocation StartLoc, 14663 SourceLocation EndLoc) { 14664 return new (Context) OMPUntiedClause(StartLoc, EndLoc); 14665 } 14666 14667 OMPClause *Sema::ActOnOpenMPMergeableClause(SourceLocation StartLoc, 14668 SourceLocation EndLoc) { 14669 return new (Context) OMPMergeableClause(StartLoc, EndLoc); 14670 } 14671 14672 OMPClause *Sema::ActOnOpenMPReadClause(SourceLocation StartLoc, 14673 SourceLocation EndLoc) { 14674 return new (Context) OMPReadClause(StartLoc, EndLoc); 14675 } 14676 14677 OMPClause *Sema::ActOnOpenMPWriteClause(SourceLocation StartLoc, 14678 SourceLocation EndLoc) { 14679 return new (Context) OMPWriteClause(StartLoc, EndLoc); 14680 } 14681 14682 OMPClause *Sema::ActOnOpenMPUpdateClause(SourceLocation StartLoc, 14683 SourceLocation EndLoc) { 14684 return OMPUpdateClause::Create(Context, StartLoc, EndLoc); 14685 } 14686 14687 OMPClause *Sema::ActOnOpenMPCaptureClause(SourceLocation StartLoc, 14688 SourceLocation EndLoc) { 14689 return new (Context) OMPCaptureClause(StartLoc, EndLoc); 14690 } 14691 14692 OMPClause *Sema::ActOnOpenMPSeqCstClause(SourceLocation StartLoc, 14693 SourceLocation EndLoc) { 14694 return new (Context) OMPSeqCstClause(StartLoc, EndLoc); 14695 } 14696 14697 OMPClause *Sema::ActOnOpenMPAcqRelClause(SourceLocation StartLoc, 14698 SourceLocation EndLoc) { 14699 return new (Context) OMPAcqRelClause(StartLoc, EndLoc); 14700 } 14701 14702 OMPClause *Sema::ActOnOpenMPAcquireClause(SourceLocation StartLoc, 14703 SourceLocation EndLoc) { 14704 return new (Context) OMPAcquireClause(StartLoc, EndLoc); 14705 } 14706 14707 OMPClause *Sema::ActOnOpenMPReleaseClause(SourceLocation StartLoc, 14708 SourceLocation EndLoc) { 14709 return new (Context) OMPReleaseClause(StartLoc, EndLoc); 14710 } 14711 14712 OMPClause *Sema::ActOnOpenMPRelaxedClause(SourceLocation StartLoc, 14713 SourceLocation EndLoc) { 14714 return new (Context) OMPRelaxedClause(StartLoc, EndLoc); 14715 } 14716 14717 OMPClause *Sema::ActOnOpenMPThreadsClause(SourceLocation StartLoc, 14718 SourceLocation EndLoc) { 14719 return new (Context) OMPThreadsClause(StartLoc, EndLoc); 14720 } 14721 14722 OMPClause *Sema::ActOnOpenMPSIMDClause(SourceLocation StartLoc, 14723 SourceLocation EndLoc) { 14724 return new (Context) OMPSIMDClause(StartLoc, EndLoc); 14725 } 14726 14727 OMPClause *Sema::ActOnOpenMPNogroupClause(SourceLocation StartLoc, 14728 SourceLocation EndLoc) { 14729 return new (Context) OMPNogroupClause(StartLoc, EndLoc); 14730 } 14731 14732 OMPClause *Sema::ActOnOpenMPUnifiedAddressClause(SourceLocation StartLoc, 14733 SourceLocation EndLoc) { 14734 return new (Context) OMPUnifiedAddressClause(StartLoc, EndLoc); 14735 } 14736 14737 OMPClause *Sema::ActOnOpenMPUnifiedSharedMemoryClause(SourceLocation StartLoc, 14738 SourceLocation EndLoc) { 14739 return new (Context) OMPUnifiedSharedMemoryClause(StartLoc, EndLoc); 14740 } 14741 14742 OMPClause *Sema::ActOnOpenMPReverseOffloadClause(SourceLocation StartLoc, 14743 SourceLocation EndLoc) { 14744 return new (Context) OMPReverseOffloadClause(StartLoc, EndLoc); 14745 } 14746 14747 OMPClause *Sema::ActOnOpenMPDynamicAllocatorsClause(SourceLocation StartLoc, 14748 SourceLocation EndLoc) { 14749 return new (Context) OMPDynamicAllocatorsClause(StartLoc, EndLoc); 14750 } 14751 14752 StmtResult Sema::ActOnOpenMPInteropDirective(ArrayRef<OMPClause *> Clauses, 14753 SourceLocation StartLoc, 14754 SourceLocation EndLoc) { 14755 14756 // OpenMP 5.1 [2.15.1, interop Construct, Restrictions] 14757 // At least one action-clause must appear on a directive. 14758 if (!hasClauses(Clauses, OMPC_init, OMPC_use, OMPC_destroy, OMPC_nowait)) { 14759 StringRef Expected = "'init', 'use', 'destroy', or 'nowait'"; 14760 Diag(StartLoc, diag::err_omp_no_clause_for_directive) 14761 << Expected << getOpenMPDirectiveName(OMPD_interop); 14762 return StmtError(); 14763 } 14764 14765 // OpenMP 5.1 [2.15.1, interop Construct, Restrictions] 14766 // A depend clause can only appear on the directive if a targetsync 14767 // interop-type is present or the interop-var was initialized with 14768 // the targetsync interop-type. 14769 14770 // If there is any 'init' clause diagnose if there is no 'init' clause with 14771 // interop-type of 'targetsync'. Cases involving other directives cannot be 14772 // diagnosed. 14773 const OMPDependClause *DependClause = nullptr; 14774 bool HasInitClause = false; 14775 bool IsTargetSync = false; 14776 for (const OMPClause *C : Clauses) { 14777 if (IsTargetSync) 14778 break; 14779 if (const auto *InitClause = dyn_cast<OMPInitClause>(C)) { 14780 HasInitClause = true; 14781 if (InitClause->getIsTargetSync()) 14782 IsTargetSync = true; 14783 } else if (const auto *DC = dyn_cast<OMPDependClause>(C)) { 14784 DependClause = DC; 14785 } 14786 } 14787 if (DependClause && HasInitClause && !IsTargetSync) { 14788 Diag(DependClause->getBeginLoc(), diag::err_omp_interop_bad_depend_clause); 14789 return StmtError(); 14790 } 14791 14792 // OpenMP 5.1 [2.15.1, interop Construct, Restrictions] 14793 // Each interop-var may be specified for at most one action-clause of each 14794 // interop construct. 14795 llvm::SmallPtrSet<const VarDecl *, 4> InteropVars; 14796 for (const OMPClause *C : Clauses) { 14797 OpenMPClauseKind ClauseKind = C->getClauseKind(); 14798 const DeclRefExpr *DRE = nullptr; 14799 SourceLocation VarLoc; 14800 14801 if (ClauseKind == OMPC_init) { 14802 const auto *IC = cast<OMPInitClause>(C); 14803 VarLoc = IC->getVarLoc(); 14804 DRE = dyn_cast_or_null<DeclRefExpr>(IC->getInteropVar()); 14805 } else if (ClauseKind == OMPC_use) { 14806 const auto *UC = cast<OMPUseClause>(C); 14807 VarLoc = UC->getVarLoc(); 14808 DRE = dyn_cast_or_null<DeclRefExpr>(UC->getInteropVar()); 14809 } else if (ClauseKind == OMPC_destroy) { 14810 const auto *DC = cast<OMPDestroyClause>(C); 14811 VarLoc = DC->getVarLoc(); 14812 DRE = dyn_cast_or_null<DeclRefExpr>(DC->getInteropVar()); 14813 } 14814 14815 if (!DRE) 14816 continue; 14817 14818 if (const auto *VD = dyn_cast<VarDecl>(DRE->getDecl())) { 14819 if (!InteropVars.insert(VD->getCanonicalDecl()).second) { 14820 Diag(VarLoc, diag::err_omp_interop_var_multiple_actions) << VD; 14821 return StmtError(); 14822 } 14823 } 14824 } 14825 14826 return OMPInteropDirective::Create(Context, StartLoc, EndLoc, Clauses); 14827 } 14828 14829 static bool isValidInteropVariable(Sema &SemaRef, Expr *InteropVarExpr, 14830 SourceLocation VarLoc, 14831 OpenMPClauseKind Kind) { 14832 if (InteropVarExpr->isValueDependent() || InteropVarExpr->isTypeDependent() || 14833 InteropVarExpr->isInstantiationDependent() || 14834 InteropVarExpr->containsUnexpandedParameterPack()) 14835 return true; 14836 14837 const auto *DRE = dyn_cast<DeclRefExpr>(InteropVarExpr); 14838 if (!DRE || !isa<VarDecl>(DRE->getDecl())) { 14839 SemaRef.Diag(VarLoc, diag::err_omp_interop_variable_expected) << 0; 14840 return false; 14841 } 14842 14843 // Interop variable should be of type omp_interop_t. 14844 bool HasError = false; 14845 QualType InteropType; 14846 LookupResult Result(SemaRef, &SemaRef.Context.Idents.get("omp_interop_t"), 14847 VarLoc, Sema::LookupOrdinaryName); 14848 if (SemaRef.LookupName(Result, SemaRef.getCurScope())) { 14849 NamedDecl *ND = Result.getFoundDecl(); 14850 if (const auto *TD = dyn_cast<TypeDecl>(ND)) { 14851 InteropType = QualType(TD->getTypeForDecl(), 0); 14852 } else { 14853 HasError = true; 14854 } 14855 } else { 14856 HasError = true; 14857 } 14858 14859 if (HasError) { 14860 SemaRef.Diag(VarLoc, diag::err_omp_implied_type_not_found) 14861 << "omp_interop_t"; 14862 return false; 14863 } 14864 14865 QualType VarType = InteropVarExpr->getType().getUnqualifiedType(); 14866 if (!SemaRef.Context.hasSameType(InteropType, VarType)) { 14867 SemaRef.Diag(VarLoc, diag::err_omp_interop_variable_wrong_type); 14868 return false; 14869 } 14870 14871 // OpenMP 5.1 [2.15.1, interop Construct, Restrictions] 14872 // The interop-var passed to init or destroy must be non-const. 14873 if ((Kind == OMPC_init || Kind == OMPC_destroy) && 14874 isConstNotMutableType(SemaRef, InteropVarExpr->getType())) { 14875 SemaRef.Diag(VarLoc, diag::err_omp_interop_variable_expected) 14876 << /*non-const*/ 1; 14877 return false; 14878 } 14879 return true; 14880 } 14881 14882 OMPClause * 14883 Sema::ActOnOpenMPInitClause(Expr *InteropVar, ArrayRef<Expr *> PrefExprs, 14884 bool IsTarget, bool IsTargetSync, 14885 SourceLocation StartLoc, SourceLocation LParenLoc, 14886 SourceLocation VarLoc, SourceLocation EndLoc) { 14887 14888 if (!isValidInteropVariable(*this, InteropVar, VarLoc, OMPC_init)) 14889 return nullptr; 14890 14891 // Check prefer_type values. These foreign-runtime-id values are either 14892 // string literals or constant integral expressions. 14893 for (const Expr *E : PrefExprs) { 14894 if (E->isValueDependent() || E->isTypeDependent() || 14895 E->isInstantiationDependent() || E->containsUnexpandedParameterPack()) 14896 continue; 14897 if (E->isIntegerConstantExpr(Context)) 14898 continue; 14899 if (isa<StringLiteral>(E)) 14900 continue; 14901 Diag(E->getExprLoc(), diag::err_omp_interop_prefer_type); 14902 return nullptr; 14903 } 14904 14905 return OMPInitClause::Create(Context, InteropVar, PrefExprs, IsTarget, 14906 IsTargetSync, StartLoc, LParenLoc, VarLoc, 14907 EndLoc); 14908 } 14909 14910 OMPClause *Sema::ActOnOpenMPUseClause(Expr *InteropVar, SourceLocation StartLoc, 14911 SourceLocation LParenLoc, 14912 SourceLocation VarLoc, 14913 SourceLocation EndLoc) { 14914 14915 if (!isValidInteropVariable(*this, InteropVar, VarLoc, OMPC_use)) 14916 return nullptr; 14917 14918 return new (Context) 14919 OMPUseClause(InteropVar, StartLoc, LParenLoc, VarLoc, EndLoc); 14920 } 14921 14922 OMPClause *Sema::ActOnOpenMPDestroyClause(Expr *InteropVar, 14923 SourceLocation StartLoc, 14924 SourceLocation LParenLoc, 14925 SourceLocation VarLoc, 14926 SourceLocation EndLoc) { 14927 if (InteropVar && 14928 !isValidInteropVariable(*this, InteropVar, VarLoc, OMPC_destroy)) 14929 return nullptr; 14930 14931 return new (Context) 14932 OMPDestroyClause(InteropVar, StartLoc, LParenLoc, VarLoc, EndLoc); 14933 } 14934 14935 OMPClause *Sema::ActOnOpenMPNovariantsClause(Expr *Condition, 14936 SourceLocation StartLoc, 14937 SourceLocation LParenLoc, 14938 SourceLocation EndLoc) { 14939 Expr *ValExpr = Condition; 14940 Stmt *HelperValStmt = nullptr; 14941 OpenMPDirectiveKind CaptureRegion = OMPD_unknown; 14942 if (!Condition->isValueDependent() && !Condition->isTypeDependent() && 14943 !Condition->isInstantiationDependent() && 14944 !Condition->containsUnexpandedParameterPack()) { 14945 ExprResult Val = CheckBooleanCondition(StartLoc, Condition); 14946 if (Val.isInvalid()) 14947 return nullptr; 14948 14949 ValExpr = MakeFullExpr(Val.get()).get(); 14950 14951 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 14952 CaptureRegion = getOpenMPCaptureRegionForClause(DKind, OMPC_novariants, 14953 LangOpts.OpenMP); 14954 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 14955 ValExpr = MakeFullExpr(ValExpr).get(); 14956 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 14957 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 14958 HelperValStmt = buildPreInits(Context, Captures); 14959 } 14960 } 14961 14962 return new (Context) OMPNovariantsClause( 14963 ValExpr, HelperValStmt, CaptureRegion, StartLoc, LParenLoc, EndLoc); 14964 } 14965 14966 OMPClause *Sema::ActOnOpenMPNocontextClause(Expr *Condition, 14967 SourceLocation StartLoc, 14968 SourceLocation LParenLoc, 14969 SourceLocation EndLoc) { 14970 Expr *ValExpr = Condition; 14971 Stmt *HelperValStmt = nullptr; 14972 OpenMPDirectiveKind CaptureRegion = OMPD_unknown; 14973 if (!Condition->isValueDependent() && !Condition->isTypeDependent() && 14974 !Condition->isInstantiationDependent() && 14975 !Condition->containsUnexpandedParameterPack()) { 14976 ExprResult Val = CheckBooleanCondition(StartLoc, Condition); 14977 if (Val.isInvalid()) 14978 return nullptr; 14979 14980 ValExpr = MakeFullExpr(Val.get()).get(); 14981 14982 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 14983 CaptureRegion = 14984 getOpenMPCaptureRegionForClause(DKind, OMPC_nocontext, LangOpts.OpenMP); 14985 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 14986 ValExpr = MakeFullExpr(ValExpr).get(); 14987 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 14988 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 14989 HelperValStmt = buildPreInits(Context, Captures); 14990 } 14991 } 14992 14993 return new (Context) OMPNocontextClause(ValExpr, HelperValStmt, CaptureRegion, 14994 StartLoc, LParenLoc, EndLoc); 14995 } 14996 14997 OMPClause *Sema::ActOnOpenMPFilterClause(Expr *ThreadID, 14998 SourceLocation StartLoc, 14999 SourceLocation LParenLoc, 15000 SourceLocation EndLoc) { 15001 Expr *ValExpr = ThreadID; 15002 Stmt *HelperValStmt = nullptr; 15003 15004 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 15005 OpenMPDirectiveKind CaptureRegion = 15006 getOpenMPCaptureRegionForClause(DKind, OMPC_filter, LangOpts.OpenMP); 15007 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 15008 ValExpr = MakeFullExpr(ValExpr).get(); 15009 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 15010 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 15011 HelperValStmt = buildPreInits(Context, Captures); 15012 } 15013 15014 return new (Context) OMPFilterClause(ValExpr, HelperValStmt, CaptureRegion, 15015 StartLoc, LParenLoc, EndLoc); 15016 } 15017 15018 OMPClause *Sema::ActOnOpenMPVarListClause( 15019 OpenMPClauseKind Kind, ArrayRef<Expr *> VarList, Expr *DepModOrTailExpr, 15020 const OMPVarListLocTy &Locs, SourceLocation ColonLoc, 15021 CXXScopeSpec &ReductionOrMapperIdScopeSpec, 15022 DeclarationNameInfo &ReductionOrMapperId, int ExtraModifier, 15023 ArrayRef<OpenMPMapModifierKind> MapTypeModifiers, 15024 ArrayRef<SourceLocation> MapTypeModifiersLoc, bool IsMapTypeImplicit, 15025 SourceLocation ExtraModifierLoc, 15026 ArrayRef<OpenMPMotionModifierKind> MotionModifiers, 15027 ArrayRef<SourceLocation> MotionModifiersLoc) { 15028 SourceLocation StartLoc = Locs.StartLoc; 15029 SourceLocation LParenLoc = Locs.LParenLoc; 15030 SourceLocation EndLoc = Locs.EndLoc; 15031 OMPClause *Res = nullptr; 15032 switch (Kind) { 15033 case OMPC_private: 15034 Res = ActOnOpenMPPrivateClause(VarList, StartLoc, LParenLoc, EndLoc); 15035 break; 15036 case OMPC_firstprivate: 15037 Res = ActOnOpenMPFirstprivateClause(VarList, StartLoc, LParenLoc, EndLoc); 15038 break; 15039 case OMPC_lastprivate: 15040 assert(0 <= ExtraModifier && ExtraModifier <= OMPC_LASTPRIVATE_unknown && 15041 "Unexpected lastprivate modifier."); 15042 Res = ActOnOpenMPLastprivateClause( 15043 VarList, static_cast<OpenMPLastprivateModifier>(ExtraModifier), 15044 ExtraModifierLoc, ColonLoc, StartLoc, LParenLoc, EndLoc); 15045 break; 15046 case OMPC_shared: 15047 Res = ActOnOpenMPSharedClause(VarList, StartLoc, LParenLoc, EndLoc); 15048 break; 15049 case OMPC_reduction: 15050 assert(0 <= ExtraModifier && ExtraModifier <= OMPC_REDUCTION_unknown && 15051 "Unexpected lastprivate modifier."); 15052 Res = ActOnOpenMPReductionClause( 15053 VarList, static_cast<OpenMPReductionClauseModifier>(ExtraModifier), 15054 StartLoc, LParenLoc, ExtraModifierLoc, ColonLoc, EndLoc, 15055 ReductionOrMapperIdScopeSpec, ReductionOrMapperId); 15056 break; 15057 case OMPC_task_reduction: 15058 Res = ActOnOpenMPTaskReductionClause(VarList, StartLoc, LParenLoc, ColonLoc, 15059 EndLoc, ReductionOrMapperIdScopeSpec, 15060 ReductionOrMapperId); 15061 break; 15062 case OMPC_in_reduction: 15063 Res = ActOnOpenMPInReductionClause(VarList, StartLoc, LParenLoc, ColonLoc, 15064 EndLoc, ReductionOrMapperIdScopeSpec, 15065 ReductionOrMapperId); 15066 break; 15067 case OMPC_linear: 15068 assert(0 <= ExtraModifier && ExtraModifier <= OMPC_LINEAR_unknown && 15069 "Unexpected linear modifier."); 15070 Res = ActOnOpenMPLinearClause( 15071 VarList, DepModOrTailExpr, StartLoc, LParenLoc, 15072 static_cast<OpenMPLinearClauseKind>(ExtraModifier), ExtraModifierLoc, 15073 ColonLoc, EndLoc); 15074 break; 15075 case OMPC_aligned: 15076 Res = ActOnOpenMPAlignedClause(VarList, DepModOrTailExpr, StartLoc, 15077 LParenLoc, ColonLoc, EndLoc); 15078 break; 15079 case OMPC_copyin: 15080 Res = ActOnOpenMPCopyinClause(VarList, StartLoc, LParenLoc, EndLoc); 15081 break; 15082 case OMPC_copyprivate: 15083 Res = ActOnOpenMPCopyprivateClause(VarList, StartLoc, LParenLoc, EndLoc); 15084 break; 15085 case OMPC_flush: 15086 Res = ActOnOpenMPFlushClause(VarList, StartLoc, LParenLoc, EndLoc); 15087 break; 15088 case OMPC_depend: 15089 assert(0 <= ExtraModifier && ExtraModifier <= OMPC_DEPEND_unknown && 15090 "Unexpected depend modifier."); 15091 Res = ActOnOpenMPDependClause( 15092 DepModOrTailExpr, static_cast<OpenMPDependClauseKind>(ExtraModifier), 15093 ExtraModifierLoc, ColonLoc, VarList, StartLoc, LParenLoc, EndLoc); 15094 break; 15095 case OMPC_map: 15096 assert(0 <= ExtraModifier && ExtraModifier <= OMPC_MAP_unknown && 15097 "Unexpected map modifier."); 15098 Res = ActOnOpenMPMapClause( 15099 MapTypeModifiers, MapTypeModifiersLoc, ReductionOrMapperIdScopeSpec, 15100 ReductionOrMapperId, static_cast<OpenMPMapClauseKind>(ExtraModifier), 15101 IsMapTypeImplicit, ExtraModifierLoc, ColonLoc, VarList, Locs); 15102 break; 15103 case OMPC_to: 15104 Res = ActOnOpenMPToClause(MotionModifiers, MotionModifiersLoc, 15105 ReductionOrMapperIdScopeSpec, ReductionOrMapperId, 15106 ColonLoc, VarList, Locs); 15107 break; 15108 case OMPC_from: 15109 Res = ActOnOpenMPFromClause(MotionModifiers, MotionModifiersLoc, 15110 ReductionOrMapperIdScopeSpec, 15111 ReductionOrMapperId, ColonLoc, VarList, Locs); 15112 break; 15113 case OMPC_use_device_ptr: 15114 Res = ActOnOpenMPUseDevicePtrClause(VarList, Locs); 15115 break; 15116 case OMPC_use_device_addr: 15117 Res = ActOnOpenMPUseDeviceAddrClause(VarList, Locs); 15118 break; 15119 case OMPC_is_device_ptr: 15120 Res = ActOnOpenMPIsDevicePtrClause(VarList, Locs); 15121 break; 15122 case OMPC_allocate: 15123 Res = ActOnOpenMPAllocateClause(DepModOrTailExpr, VarList, StartLoc, 15124 LParenLoc, ColonLoc, EndLoc); 15125 break; 15126 case OMPC_nontemporal: 15127 Res = ActOnOpenMPNontemporalClause(VarList, StartLoc, LParenLoc, EndLoc); 15128 break; 15129 case OMPC_inclusive: 15130 Res = ActOnOpenMPInclusiveClause(VarList, StartLoc, LParenLoc, EndLoc); 15131 break; 15132 case OMPC_exclusive: 15133 Res = ActOnOpenMPExclusiveClause(VarList, StartLoc, LParenLoc, EndLoc); 15134 break; 15135 case OMPC_affinity: 15136 Res = ActOnOpenMPAffinityClause(StartLoc, LParenLoc, ColonLoc, EndLoc, 15137 DepModOrTailExpr, VarList); 15138 break; 15139 case OMPC_if: 15140 case OMPC_depobj: 15141 case OMPC_final: 15142 case OMPC_num_threads: 15143 case OMPC_safelen: 15144 case OMPC_simdlen: 15145 case OMPC_sizes: 15146 case OMPC_allocator: 15147 case OMPC_collapse: 15148 case OMPC_default: 15149 case OMPC_proc_bind: 15150 case OMPC_schedule: 15151 case OMPC_ordered: 15152 case OMPC_nowait: 15153 case OMPC_untied: 15154 case OMPC_mergeable: 15155 case OMPC_threadprivate: 15156 case OMPC_read: 15157 case OMPC_write: 15158 case OMPC_update: 15159 case OMPC_capture: 15160 case OMPC_seq_cst: 15161 case OMPC_acq_rel: 15162 case OMPC_acquire: 15163 case OMPC_release: 15164 case OMPC_relaxed: 15165 case OMPC_device: 15166 case OMPC_threads: 15167 case OMPC_simd: 15168 case OMPC_num_teams: 15169 case OMPC_thread_limit: 15170 case OMPC_priority: 15171 case OMPC_grainsize: 15172 case OMPC_nogroup: 15173 case OMPC_num_tasks: 15174 case OMPC_hint: 15175 case OMPC_dist_schedule: 15176 case OMPC_defaultmap: 15177 case OMPC_unknown: 15178 case OMPC_uniform: 15179 case OMPC_unified_address: 15180 case OMPC_unified_shared_memory: 15181 case OMPC_reverse_offload: 15182 case OMPC_dynamic_allocators: 15183 case OMPC_atomic_default_mem_order: 15184 case OMPC_device_type: 15185 case OMPC_match: 15186 case OMPC_order: 15187 case OMPC_destroy: 15188 case OMPC_novariants: 15189 case OMPC_nocontext: 15190 case OMPC_detach: 15191 case OMPC_uses_allocators: 15192 default: 15193 llvm_unreachable("Clause is not allowed."); 15194 } 15195 return Res; 15196 } 15197 15198 ExprResult Sema::getOpenMPCapturedExpr(VarDecl *Capture, ExprValueKind VK, 15199 ExprObjectKind OK, SourceLocation Loc) { 15200 ExprResult Res = BuildDeclRefExpr( 15201 Capture, Capture->getType().getNonReferenceType(), VK_LValue, Loc); 15202 if (!Res.isUsable()) 15203 return ExprError(); 15204 if (OK == OK_Ordinary && !getLangOpts().CPlusPlus) { 15205 Res = CreateBuiltinUnaryOp(Loc, UO_Deref, Res.get()); 15206 if (!Res.isUsable()) 15207 return ExprError(); 15208 } 15209 if (VK != VK_LValue && Res.get()->isGLValue()) { 15210 Res = DefaultLvalueConversion(Res.get()); 15211 if (!Res.isUsable()) 15212 return ExprError(); 15213 } 15214 return Res; 15215 } 15216 15217 OMPClause *Sema::ActOnOpenMPPrivateClause(ArrayRef<Expr *> VarList, 15218 SourceLocation StartLoc, 15219 SourceLocation LParenLoc, 15220 SourceLocation EndLoc) { 15221 SmallVector<Expr *, 8> Vars; 15222 SmallVector<Expr *, 8> PrivateCopies; 15223 for (Expr *RefExpr : VarList) { 15224 assert(RefExpr && "NULL expr in OpenMP private clause."); 15225 SourceLocation ELoc; 15226 SourceRange ERange; 15227 Expr *SimpleRefExpr = RefExpr; 15228 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 15229 if (Res.second) { 15230 // It will be analyzed later. 15231 Vars.push_back(RefExpr); 15232 PrivateCopies.push_back(nullptr); 15233 } 15234 ValueDecl *D = Res.first; 15235 if (!D) 15236 continue; 15237 15238 QualType Type = D->getType(); 15239 auto *VD = dyn_cast<VarDecl>(D); 15240 15241 // OpenMP [2.9.3.3, Restrictions, C/C++, p.3] 15242 // A variable that appears in a private clause must not have an incomplete 15243 // type or a reference type. 15244 if (RequireCompleteType(ELoc, Type, diag::err_omp_private_incomplete_type)) 15245 continue; 15246 Type = Type.getNonReferenceType(); 15247 15248 // OpenMP 5.0 [2.19.3, List Item Privatization, Restrictions] 15249 // A variable that is privatized must not have a const-qualified type 15250 // unless it is of class type with a mutable member. This restriction does 15251 // not apply to the firstprivate clause. 15252 // 15253 // OpenMP 3.1 [2.9.3.3, private clause, Restrictions] 15254 // A variable that appears in a private clause must not have a 15255 // const-qualified type unless it is of class type with a mutable member. 15256 if (rejectConstNotMutableType(*this, D, Type, OMPC_private, ELoc)) 15257 continue; 15258 15259 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 15260 // in a Construct] 15261 // Variables with the predetermined data-sharing attributes may not be 15262 // listed in data-sharing attributes clauses, except for the cases 15263 // listed below. For these exceptions only, listing a predetermined 15264 // variable in a data-sharing attribute clause is allowed and overrides 15265 // the variable's predetermined data-sharing attributes. 15266 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false); 15267 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_private) { 15268 Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind) 15269 << getOpenMPClauseName(OMPC_private); 15270 reportOriginalDsa(*this, DSAStack, D, DVar); 15271 continue; 15272 } 15273 15274 OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective(); 15275 // Variably modified types are not supported for tasks. 15276 if (!Type->isAnyPointerType() && Type->isVariablyModifiedType() && 15277 isOpenMPTaskingDirective(CurrDir)) { 15278 Diag(ELoc, diag::err_omp_variably_modified_type_not_supported) 15279 << getOpenMPClauseName(OMPC_private) << Type 15280 << getOpenMPDirectiveName(CurrDir); 15281 bool IsDecl = 15282 !VD || 15283 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 15284 Diag(D->getLocation(), 15285 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 15286 << D; 15287 continue; 15288 } 15289 15290 // OpenMP 4.5 [2.15.5.1, Restrictions, p.3] 15291 // A list item cannot appear in both a map clause and a data-sharing 15292 // attribute clause on the same construct 15293 // 15294 // OpenMP 5.0 [2.19.7.1, Restrictions, p.7] 15295 // A list item cannot appear in both a map clause and a data-sharing 15296 // attribute clause on the same construct unless the construct is a 15297 // combined construct. 15298 if ((LangOpts.OpenMP <= 45 && isOpenMPTargetExecutionDirective(CurrDir)) || 15299 CurrDir == OMPD_target) { 15300 OpenMPClauseKind ConflictKind; 15301 if (DSAStack->checkMappableExprComponentListsForDecl( 15302 VD, /*CurrentRegionOnly=*/true, 15303 [&](OMPClauseMappableExprCommon::MappableExprComponentListRef, 15304 OpenMPClauseKind WhereFoundClauseKind) -> bool { 15305 ConflictKind = WhereFoundClauseKind; 15306 return true; 15307 })) { 15308 Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa) 15309 << getOpenMPClauseName(OMPC_private) 15310 << getOpenMPClauseName(ConflictKind) 15311 << getOpenMPDirectiveName(CurrDir); 15312 reportOriginalDsa(*this, DSAStack, D, DVar); 15313 continue; 15314 } 15315 } 15316 15317 // OpenMP [2.9.3.3, Restrictions, C/C++, p.1] 15318 // A variable of class type (or array thereof) that appears in a private 15319 // clause requires an accessible, unambiguous default constructor for the 15320 // class type. 15321 // Generate helper private variable and initialize it with the default 15322 // value. The address of the original variable is replaced by the address of 15323 // the new private variable in CodeGen. This new variable is not added to 15324 // IdResolver, so the code in the OpenMP region uses original variable for 15325 // proper diagnostics. 15326 Type = Type.getUnqualifiedType(); 15327 VarDecl *VDPrivate = 15328 buildVarDecl(*this, ELoc, Type, D->getName(), 15329 D->hasAttrs() ? &D->getAttrs() : nullptr, 15330 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr); 15331 ActOnUninitializedDecl(VDPrivate); 15332 if (VDPrivate->isInvalidDecl()) 15333 continue; 15334 DeclRefExpr *VDPrivateRefExpr = buildDeclRefExpr( 15335 *this, VDPrivate, RefExpr->getType().getUnqualifiedType(), ELoc); 15336 15337 DeclRefExpr *Ref = nullptr; 15338 if (!VD && !CurContext->isDependentContext()) 15339 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false); 15340 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_private, Ref); 15341 Vars.push_back((VD || CurContext->isDependentContext()) 15342 ? RefExpr->IgnoreParens() 15343 : Ref); 15344 PrivateCopies.push_back(VDPrivateRefExpr); 15345 } 15346 15347 if (Vars.empty()) 15348 return nullptr; 15349 15350 return OMPPrivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars, 15351 PrivateCopies); 15352 } 15353 15354 namespace { 15355 class DiagsUninitializedSeveretyRAII { 15356 private: 15357 DiagnosticsEngine &Diags; 15358 SourceLocation SavedLoc; 15359 bool IsIgnored = false; 15360 15361 public: 15362 DiagsUninitializedSeveretyRAII(DiagnosticsEngine &Diags, SourceLocation Loc, 15363 bool IsIgnored) 15364 : Diags(Diags), SavedLoc(Loc), IsIgnored(IsIgnored) { 15365 if (!IsIgnored) { 15366 Diags.setSeverity(/*Diag*/ diag::warn_uninit_self_reference_in_init, 15367 /*Map*/ diag::Severity::Ignored, Loc); 15368 } 15369 } 15370 ~DiagsUninitializedSeveretyRAII() { 15371 if (!IsIgnored) 15372 Diags.popMappings(SavedLoc); 15373 } 15374 }; 15375 } 15376 15377 OMPClause *Sema::ActOnOpenMPFirstprivateClause(ArrayRef<Expr *> VarList, 15378 SourceLocation StartLoc, 15379 SourceLocation LParenLoc, 15380 SourceLocation EndLoc) { 15381 SmallVector<Expr *, 8> Vars; 15382 SmallVector<Expr *, 8> PrivateCopies; 15383 SmallVector<Expr *, 8> Inits; 15384 SmallVector<Decl *, 4> ExprCaptures; 15385 bool IsImplicitClause = 15386 StartLoc.isInvalid() && LParenLoc.isInvalid() && EndLoc.isInvalid(); 15387 SourceLocation ImplicitClauseLoc = DSAStack->getConstructLoc(); 15388 15389 for (Expr *RefExpr : VarList) { 15390 assert(RefExpr && "NULL expr in OpenMP firstprivate clause."); 15391 SourceLocation ELoc; 15392 SourceRange ERange; 15393 Expr *SimpleRefExpr = RefExpr; 15394 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 15395 if (Res.second) { 15396 // It will be analyzed later. 15397 Vars.push_back(RefExpr); 15398 PrivateCopies.push_back(nullptr); 15399 Inits.push_back(nullptr); 15400 } 15401 ValueDecl *D = Res.first; 15402 if (!D) 15403 continue; 15404 15405 ELoc = IsImplicitClause ? ImplicitClauseLoc : ELoc; 15406 QualType Type = D->getType(); 15407 auto *VD = dyn_cast<VarDecl>(D); 15408 15409 // OpenMP [2.9.3.3, Restrictions, C/C++, p.3] 15410 // A variable that appears in a private clause must not have an incomplete 15411 // type or a reference type. 15412 if (RequireCompleteType(ELoc, Type, 15413 diag::err_omp_firstprivate_incomplete_type)) 15414 continue; 15415 Type = Type.getNonReferenceType(); 15416 15417 // OpenMP [2.9.3.4, Restrictions, C/C++, p.1] 15418 // A variable of class type (or array thereof) that appears in a private 15419 // clause requires an accessible, unambiguous copy constructor for the 15420 // class type. 15421 QualType ElemType = Context.getBaseElementType(Type).getNonReferenceType(); 15422 15423 // If an implicit firstprivate variable found it was checked already. 15424 DSAStackTy::DSAVarData TopDVar; 15425 if (!IsImplicitClause) { 15426 DSAStackTy::DSAVarData DVar = 15427 DSAStack->getTopDSA(D, /*FromParent=*/false); 15428 TopDVar = DVar; 15429 OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective(); 15430 bool IsConstant = ElemType.isConstant(Context); 15431 // OpenMP [2.4.13, Data-sharing Attribute Clauses] 15432 // A list item that specifies a given variable may not appear in more 15433 // than one clause on the same directive, except that a variable may be 15434 // specified in both firstprivate and lastprivate clauses. 15435 // OpenMP 4.5 [2.10.8, Distribute Construct, p.3] 15436 // A list item may appear in a firstprivate or lastprivate clause but not 15437 // both. 15438 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_firstprivate && 15439 (isOpenMPDistributeDirective(CurrDir) || 15440 DVar.CKind != OMPC_lastprivate) && 15441 DVar.RefExpr) { 15442 Diag(ELoc, diag::err_omp_wrong_dsa) 15443 << getOpenMPClauseName(DVar.CKind) 15444 << getOpenMPClauseName(OMPC_firstprivate); 15445 reportOriginalDsa(*this, DSAStack, D, DVar); 15446 continue; 15447 } 15448 15449 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 15450 // in a Construct] 15451 // Variables with the predetermined data-sharing attributes may not be 15452 // listed in data-sharing attributes clauses, except for the cases 15453 // listed below. For these exceptions only, listing a predetermined 15454 // variable in a data-sharing attribute clause is allowed and overrides 15455 // the variable's predetermined data-sharing attributes. 15456 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 15457 // in a Construct, C/C++, p.2] 15458 // Variables with const-qualified type having no mutable member may be 15459 // listed in a firstprivate clause, even if they are static data members. 15460 if (!(IsConstant || (VD && VD->isStaticDataMember())) && !DVar.RefExpr && 15461 DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_shared) { 15462 Diag(ELoc, diag::err_omp_wrong_dsa) 15463 << getOpenMPClauseName(DVar.CKind) 15464 << getOpenMPClauseName(OMPC_firstprivate); 15465 reportOriginalDsa(*this, DSAStack, D, DVar); 15466 continue; 15467 } 15468 15469 // OpenMP [2.9.3.4, Restrictions, p.2] 15470 // A list item that is private within a parallel region must not appear 15471 // in a firstprivate clause on a worksharing construct if any of the 15472 // worksharing regions arising from the worksharing construct ever bind 15473 // to any of the parallel regions arising from the parallel construct. 15474 // OpenMP 4.5 [2.15.3.4, Restrictions, p.3] 15475 // A list item that is private within a teams region must not appear in a 15476 // firstprivate clause on a distribute construct if any of the distribute 15477 // regions arising from the distribute construct ever bind to any of the 15478 // teams regions arising from the teams construct. 15479 // OpenMP 4.5 [2.15.3.4, Restrictions, p.3] 15480 // A list item that appears in a reduction clause of a teams construct 15481 // must not appear in a firstprivate clause on a distribute construct if 15482 // any of the distribute regions arising from the distribute construct 15483 // ever bind to any of the teams regions arising from the teams construct. 15484 if ((isOpenMPWorksharingDirective(CurrDir) || 15485 isOpenMPDistributeDirective(CurrDir)) && 15486 !isOpenMPParallelDirective(CurrDir) && 15487 !isOpenMPTeamsDirective(CurrDir)) { 15488 DVar = DSAStack->getImplicitDSA(D, true); 15489 if (DVar.CKind != OMPC_shared && 15490 (isOpenMPParallelDirective(DVar.DKind) || 15491 isOpenMPTeamsDirective(DVar.DKind) || 15492 DVar.DKind == OMPD_unknown)) { 15493 Diag(ELoc, diag::err_omp_required_access) 15494 << getOpenMPClauseName(OMPC_firstprivate) 15495 << getOpenMPClauseName(OMPC_shared); 15496 reportOriginalDsa(*this, DSAStack, D, DVar); 15497 continue; 15498 } 15499 } 15500 // OpenMP [2.9.3.4, Restrictions, p.3] 15501 // A list item that appears in a reduction clause of a parallel construct 15502 // must not appear in a firstprivate clause on a worksharing or task 15503 // construct if any of the worksharing or task regions arising from the 15504 // worksharing or task construct ever bind to any of the parallel regions 15505 // arising from the parallel construct. 15506 // OpenMP [2.9.3.4, Restrictions, p.4] 15507 // A list item that appears in a reduction clause in worksharing 15508 // construct must not appear in a firstprivate clause in a task construct 15509 // encountered during execution of any of the worksharing regions arising 15510 // from the worksharing construct. 15511 if (isOpenMPTaskingDirective(CurrDir)) { 15512 DVar = DSAStack->hasInnermostDSA( 15513 D, 15514 [](OpenMPClauseKind C, bool AppliedToPointee) { 15515 return C == OMPC_reduction && !AppliedToPointee; 15516 }, 15517 [](OpenMPDirectiveKind K) { 15518 return isOpenMPParallelDirective(K) || 15519 isOpenMPWorksharingDirective(K) || 15520 isOpenMPTeamsDirective(K); 15521 }, 15522 /*FromParent=*/true); 15523 if (DVar.CKind == OMPC_reduction && 15524 (isOpenMPParallelDirective(DVar.DKind) || 15525 isOpenMPWorksharingDirective(DVar.DKind) || 15526 isOpenMPTeamsDirective(DVar.DKind))) { 15527 Diag(ELoc, diag::err_omp_parallel_reduction_in_task_firstprivate) 15528 << getOpenMPDirectiveName(DVar.DKind); 15529 reportOriginalDsa(*this, DSAStack, D, DVar); 15530 continue; 15531 } 15532 } 15533 15534 // OpenMP 4.5 [2.15.5.1, Restrictions, p.3] 15535 // A list item cannot appear in both a map clause and a data-sharing 15536 // attribute clause on the same construct 15537 // 15538 // OpenMP 5.0 [2.19.7.1, Restrictions, p.7] 15539 // A list item cannot appear in both a map clause and a data-sharing 15540 // attribute clause on the same construct unless the construct is a 15541 // combined construct. 15542 if ((LangOpts.OpenMP <= 45 && 15543 isOpenMPTargetExecutionDirective(CurrDir)) || 15544 CurrDir == OMPD_target) { 15545 OpenMPClauseKind ConflictKind; 15546 if (DSAStack->checkMappableExprComponentListsForDecl( 15547 VD, /*CurrentRegionOnly=*/true, 15548 [&ConflictKind]( 15549 OMPClauseMappableExprCommon::MappableExprComponentListRef, 15550 OpenMPClauseKind WhereFoundClauseKind) { 15551 ConflictKind = WhereFoundClauseKind; 15552 return true; 15553 })) { 15554 Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa) 15555 << getOpenMPClauseName(OMPC_firstprivate) 15556 << getOpenMPClauseName(ConflictKind) 15557 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 15558 reportOriginalDsa(*this, DSAStack, D, DVar); 15559 continue; 15560 } 15561 } 15562 } 15563 15564 // Variably modified types are not supported for tasks. 15565 if (!Type->isAnyPointerType() && Type->isVariablyModifiedType() && 15566 isOpenMPTaskingDirective(DSAStack->getCurrentDirective())) { 15567 Diag(ELoc, diag::err_omp_variably_modified_type_not_supported) 15568 << getOpenMPClauseName(OMPC_firstprivate) << Type 15569 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 15570 bool IsDecl = 15571 !VD || 15572 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 15573 Diag(D->getLocation(), 15574 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 15575 << D; 15576 continue; 15577 } 15578 15579 Type = Type.getUnqualifiedType(); 15580 VarDecl *VDPrivate = 15581 buildVarDecl(*this, ELoc, Type, D->getName(), 15582 D->hasAttrs() ? &D->getAttrs() : nullptr, 15583 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr); 15584 // Generate helper private variable and initialize it with the value of the 15585 // original variable. The address of the original variable is replaced by 15586 // the address of the new private variable in the CodeGen. This new variable 15587 // is not added to IdResolver, so the code in the OpenMP region uses 15588 // original variable for proper diagnostics and variable capturing. 15589 Expr *VDInitRefExpr = nullptr; 15590 // For arrays generate initializer for single element and replace it by the 15591 // original array element in CodeGen. 15592 if (Type->isArrayType()) { 15593 VarDecl *VDInit = 15594 buildVarDecl(*this, RefExpr->getExprLoc(), ElemType, D->getName()); 15595 VDInitRefExpr = buildDeclRefExpr(*this, VDInit, ElemType, ELoc); 15596 Expr *Init = DefaultLvalueConversion(VDInitRefExpr).get(); 15597 ElemType = ElemType.getUnqualifiedType(); 15598 VarDecl *VDInitTemp = buildVarDecl(*this, RefExpr->getExprLoc(), ElemType, 15599 ".firstprivate.temp"); 15600 InitializedEntity Entity = 15601 InitializedEntity::InitializeVariable(VDInitTemp); 15602 InitializationKind Kind = InitializationKind::CreateCopy(ELoc, ELoc); 15603 15604 InitializationSequence InitSeq(*this, Entity, Kind, Init); 15605 ExprResult Result = InitSeq.Perform(*this, Entity, Kind, Init); 15606 if (Result.isInvalid()) 15607 VDPrivate->setInvalidDecl(); 15608 else 15609 VDPrivate->setInit(Result.getAs<Expr>()); 15610 // Remove temp variable declaration. 15611 Context.Deallocate(VDInitTemp); 15612 } else { 15613 VarDecl *VDInit = buildVarDecl(*this, RefExpr->getExprLoc(), Type, 15614 ".firstprivate.temp"); 15615 VDInitRefExpr = buildDeclRefExpr(*this, VDInit, RefExpr->getType(), 15616 RefExpr->getExprLoc()); 15617 AddInitializerToDecl(VDPrivate, 15618 DefaultLvalueConversion(VDInitRefExpr).get(), 15619 /*DirectInit=*/false); 15620 } 15621 if (VDPrivate->isInvalidDecl()) { 15622 if (IsImplicitClause) { 15623 Diag(RefExpr->getExprLoc(), 15624 diag::note_omp_task_predetermined_firstprivate_here); 15625 } 15626 continue; 15627 } 15628 CurContext->addDecl(VDPrivate); 15629 DeclRefExpr *VDPrivateRefExpr = buildDeclRefExpr( 15630 *this, VDPrivate, RefExpr->getType().getUnqualifiedType(), 15631 RefExpr->getExprLoc()); 15632 DeclRefExpr *Ref = nullptr; 15633 if (!VD && !CurContext->isDependentContext()) { 15634 if (TopDVar.CKind == OMPC_lastprivate) { 15635 Ref = TopDVar.PrivateCopy; 15636 } else { 15637 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true); 15638 if (!isOpenMPCapturedDecl(D)) 15639 ExprCaptures.push_back(Ref->getDecl()); 15640 } 15641 } 15642 if (!IsImplicitClause) 15643 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_firstprivate, Ref); 15644 Vars.push_back((VD || CurContext->isDependentContext()) 15645 ? RefExpr->IgnoreParens() 15646 : Ref); 15647 PrivateCopies.push_back(VDPrivateRefExpr); 15648 Inits.push_back(VDInitRefExpr); 15649 } 15650 15651 if (Vars.empty()) 15652 return nullptr; 15653 15654 return OMPFirstprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, 15655 Vars, PrivateCopies, Inits, 15656 buildPreInits(Context, ExprCaptures)); 15657 } 15658 15659 OMPClause *Sema::ActOnOpenMPLastprivateClause( 15660 ArrayRef<Expr *> VarList, OpenMPLastprivateModifier LPKind, 15661 SourceLocation LPKindLoc, SourceLocation ColonLoc, SourceLocation StartLoc, 15662 SourceLocation LParenLoc, SourceLocation EndLoc) { 15663 if (LPKind == OMPC_LASTPRIVATE_unknown && LPKindLoc.isValid()) { 15664 assert(ColonLoc.isValid() && "Colon location must be valid."); 15665 Diag(LPKindLoc, diag::err_omp_unexpected_clause_value) 15666 << getListOfPossibleValues(OMPC_lastprivate, /*First=*/0, 15667 /*Last=*/OMPC_LASTPRIVATE_unknown) 15668 << getOpenMPClauseName(OMPC_lastprivate); 15669 return nullptr; 15670 } 15671 15672 SmallVector<Expr *, 8> Vars; 15673 SmallVector<Expr *, 8> SrcExprs; 15674 SmallVector<Expr *, 8> DstExprs; 15675 SmallVector<Expr *, 8> AssignmentOps; 15676 SmallVector<Decl *, 4> ExprCaptures; 15677 SmallVector<Expr *, 4> ExprPostUpdates; 15678 for (Expr *RefExpr : VarList) { 15679 assert(RefExpr && "NULL expr in OpenMP lastprivate clause."); 15680 SourceLocation ELoc; 15681 SourceRange ERange; 15682 Expr *SimpleRefExpr = RefExpr; 15683 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 15684 if (Res.second) { 15685 // It will be analyzed later. 15686 Vars.push_back(RefExpr); 15687 SrcExprs.push_back(nullptr); 15688 DstExprs.push_back(nullptr); 15689 AssignmentOps.push_back(nullptr); 15690 } 15691 ValueDecl *D = Res.first; 15692 if (!D) 15693 continue; 15694 15695 QualType Type = D->getType(); 15696 auto *VD = dyn_cast<VarDecl>(D); 15697 15698 // OpenMP [2.14.3.5, Restrictions, C/C++, p.2] 15699 // A variable that appears in a lastprivate clause must not have an 15700 // incomplete type or a reference type. 15701 if (RequireCompleteType(ELoc, Type, 15702 diag::err_omp_lastprivate_incomplete_type)) 15703 continue; 15704 Type = Type.getNonReferenceType(); 15705 15706 // OpenMP 5.0 [2.19.3, List Item Privatization, Restrictions] 15707 // A variable that is privatized must not have a const-qualified type 15708 // unless it is of class type with a mutable member. This restriction does 15709 // not apply to the firstprivate clause. 15710 // 15711 // OpenMP 3.1 [2.9.3.5, lastprivate clause, Restrictions] 15712 // A variable that appears in a lastprivate clause must not have a 15713 // const-qualified type unless it is of class type with a mutable member. 15714 if (rejectConstNotMutableType(*this, D, Type, OMPC_lastprivate, ELoc)) 15715 continue; 15716 15717 // OpenMP 5.0 [2.19.4.5 lastprivate Clause, Restrictions] 15718 // A list item that appears in a lastprivate clause with the conditional 15719 // modifier must be a scalar variable. 15720 if (LPKind == OMPC_LASTPRIVATE_conditional && !Type->isScalarType()) { 15721 Diag(ELoc, diag::err_omp_lastprivate_conditional_non_scalar); 15722 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) == 15723 VarDecl::DeclarationOnly; 15724 Diag(D->getLocation(), 15725 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 15726 << D; 15727 continue; 15728 } 15729 15730 OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective(); 15731 // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables Referenced 15732 // in a Construct] 15733 // Variables with the predetermined data-sharing attributes may not be 15734 // listed in data-sharing attributes clauses, except for the cases 15735 // listed below. 15736 // OpenMP 4.5 [2.10.8, Distribute Construct, p.3] 15737 // A list item may appear in a firstprivate or lastprivate clause but not 15738 // both. 15739 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false); 15740 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_lastprivate && 15741 (isOpenMPDistributeDirective(CurrDir) || 15742 DVar.CKind != OMPC_firstprivate) && 15743 (DVar.CKind != OMPC_private || DVar.RefExpr != nullptr)) { 15744 Diag(ELoc, diag::err_omp_wrong_dsa) 15745 << getOpenMPClauseName(DVar.CKind) 15746 << getOpenMPClauseName(OMPC_lastprivate); 15747 reportOriginalDsa(*this, DSAStack, D, DVar); 15748 continue; 15749 } 15750 15751 // OpenMP [2.14.3.5, Restrictions, p.2] 15752 // A list item that is private within a parallel region, or that appears in 15753 // the reduction clause of a parallel construct, must not appear in a 15754 // lastprivate clause on a worksharing construct if any of the corresponding 15755 // worksharing regions ever binds to any of the corresponding parallel 15756 // regions. 15757 DSAStackTy::DSAVarData TopDVar = DVar; 15758 if (isOpenMPWorksharingDirective(CurrDir) && 15759 !isOpenMPParallelDirective(CurrDir) && 15760 !isOpenMPTeamsDirective(CurrDir)) { 15761 DVar = DSAStack->getImplicitDSA(D, true); 15762 if (DVar.CKind != OMPC_shared) { 15763 Diag(ELoc, diag::err_omp_required_access) 15764 << getOpenMPClauseName(OMPC_lastprivate) 15765 << getOpenMPClauseName(OMPC_shared); 15766 reportOriginalDsa(*this, DSAStack, D, DVar); 15767 continue; 15768 } 15769 } 15770 15771 // OpenMP [2.14.3.5, Restrictions, C++, p.1,2] 15772 // A variable of class type (or array thereof) that appears in a 15773 // lastprivate clause requires an accessible, unambiguous default 15774 // constructor for the class type, unless the list item is also specified 15775 // in a firstprivate clause. 15776 // A variable of class type (or array thereof) that appears in a 15777 // lastprivate clause requires an accessible, unambiguous copy assignment 15778 // operator for the class type. 15779 Type = Context.getBaseElementType(Type).getNonReferenceType(); 15780 VarDecl *SrcVD = buildVarDecl(*this, ERange.getBegin(), 15781 Type.getUnqualifiedType(), ".lastprivate.src", 15782 D->hasAttrs() ? &D->getAttrs() : nullptr); 15783 DeclRefExpr *PseudoSrcExpr = 15784 buildDeclRefExpr(*this, SrcVD, Type.getUnqualifiedType(), ELoc); 15785 VarDecl *DstVD = 15786 buildVarDecl(*this, ERange.getBegin(), Type, ".lastprivate.dst", 15787 D->hasAttrs() ? &D->getAttrs() : nullptr); 15788 DeclRefExpr *PseudoDstExpr = buildDeclRefExpr(*this, DstVD, Type, ELoc); 15789 // For arrays generate assignment operation for single element and replace 15790 // it by the original array element in CodeGen. 15791 ExprResult AssignmentOp = BuildBinOp(/*S=*/nullptr, ELoc, BO_Assign, 15792 PseudoDstExpr, PseudoSrcExpr); 15793 if (AssignmentOp.isInvalid()) 15794 continue; 15795 AssignmentOp = 15796 ActOnFinishFullExpr(AssignmentOp.get(), ELoc, /*DiscardedValue*/ false); 15797 if (AssignmentOp.isInvalid()) 15798 continue; 15799 15800 DeclRefExpr *Ref = nullptr; 15801 if (!VD && !CurContext->isDependentContext()) { 15802 if (TopDVar.CKind == OMPC_firstprivate) { 15803 Ref = TopDVar.PrivateCopy; 15804 } else { 15805 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false); 15806 if (!isOpenMPCapturedDecl(D)) 15807 ExprCaptures.push_back(Ref->getDecl()); 15808 } 15809 if ((TopDVar.CKind == OMPC_firstprivate && !TopDVar.PrivateCopy) || 15810 (!isOpenMPCapturedDecl(D) && 15811 Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>())) { 15812 ExprResult RefRes = DefaultLvalueConversion(Ref); 15813 if (!RefRes.isUsable()) 15814 continue; 15815 ExprResult PostUpdateRes = 15816 BuildBinOp(DSAStack->getCurScope(), ELoc, BO_Assign, SimpleRefExpr, 15817 RefRes.get()); 15818 if (!PostUpdateRes.isUsable()) 15819 continue; 15820 ExprPostUpdates.push_back( 15821 IgnoredValueConversions(PostUpdateRes.get()).get()); 15822 } 15823 } 15824 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_lastprivate, Ref); 15825 Vars.push_back((VD || CurContext->isDependentContext()) 15826 ? RefExpr->IgnoreParens() 15827 : Ref); 15828 SrcExprs.push_back(PseudoSrcExpr); 15829 DstExprs.push_back(PseudoDstExpr); 15830 AssignmentOps.push_back(AssignmentOp.get()); 15831 } 15832 15833 if (Vars.empty()) 15834 return nullptr; 15835 15836 return OMPLastprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, 15837 Vars, SrcExprs, DstExprs, AssignmentOps, 15838 LPKind, LPKindLoc, ColonLoc, 15839 buildPreInits(Context, ExprCaptures), 15840 buildPostUpdate(*this, ExprPostUpdates)); 15841 } 15842 15843 OMPClause *Sema::ActOnOpenMPSharedClause(ArrayRef<Expr *> VarList, 15844 SourceLocation StartLoc, 15845 SourceLocation LParenLoc, 15846 SourceLocation EndLoc) { 15847 SmallVector<Expr *, 8> Vars; 15848 for (Expr *RefExpr : VarList) { 15849 assert(RefExpr && "NULL expr in OpenMP lastprivate clause."); 15850 SourceLocation ELoc; 15851 SourceRange ERange; 15852 Expr *SimpleRefExpr = RefExpr; 15853 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 15854 if (Res.second) { 15855 // It will be analyzed later. 15856 Vars.push_back(RefExpr); 15857 } 15858 ValueDecl *D = Res.first; 15859 if (!D) 15860 continue; 15861 15862 auto *VD = dyn_cast<VarDecl>(D); 15863 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 15864 // in a Construct] 15865 // Variables with the predetermined data-sharing attributes may not be 15866 // listed in data-sharing attributes clauses, except for the cases 15867 // listed below. For these exceptions only, listing a predetermined 15868 // variable in a data-sharing attribute clause is allowed and overrides 15869 // the variable's predetermined data-sharing attributes. 15870 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false); 15871 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_shared && 15872 DVar.RefExpr) { 15873 Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind) 15874 << getOpenMPClauseName(OMPC_shared); 15875 reportOriginalDsa(*this, DSAStack, D, DVar); 15876 continue; 15877 } 15878 15879 DeclRefExpr *Ref = nullptr; 15880 if (!VD && isOpenMPCapturedDecl(D) && !CurContext->isDependentContext()) 15881 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true); 15882 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_shared, Ref); 15883 Vars.push_back((VD || !Ref || CurContext->isDependentContext()) 15884 ? RefExpr->IgnoreParens() 15885 : Ref); 15886 } 15887 15888 if (Vars.empty()) 15889 return nullptr; 15890 15891 return OMPSharedClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars); 15892 } 15893 15894 namespace { 15895 class DSARefChecker : public StmtVisitor<DSARefChecker, bool> { 15896 DSAStackTy *Stack; 15897 15898 public: 15899 bool VisitDeclRefExpr(DeclRefExpr *E) { 15900 if (auto *VD = dyn_cast<VarDecl>(E->getDecl())) { 15901 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(VD, /*FromParent=*/false); 15902 if (DVar.CKind == OMPC_shared && !DVar.RefExpr) 15903 return false; 15904 if (DVar.CKind != OMPC_unknown) 15905 return true; 15906 DSAStackTy::DSAVarData DVarPrivate = Stack->hasDSA( 15907 VD, 15908 [](OpenMPClauseKind C, bool AppliedToPointee) { 15909 return isOpenMPPrivate(C) && !AppliedToPointee; 15910 }, 15911 [](OpenMPDirectiveKind) { return true; }, 15912 /*FromParent=*/true); 15913 return DVarPrivate.CKind != OMPC_unknown; 15914 } 15915 return false; 15916 } 15917 bool VisitStmt(Stmt *S) { 15918 for (Stmt *Child : S->children()) { 15919 if (Child && Visit(Child)) 15920 return true; 15921 } 15922 return false; 15923 } 15924 explicit DSARefChecker(DSAStackTy *S) : Stack(S) {} 15925 }; 15926 } // namespace 15927 15928 namespace { 15929 // Transform MemberExpression for specified FieldDecl of current class to 15930 // DeclRefExpr to specified OMPCapturedExprDecl. 15931 class TransformExprToCaptures : public TreeTransform<TransformExprToCaptures> { 15932 typedef TreeTransform<TransformExprToCaptures> BaseTransform; 15933 ValueDecl *Field = nullptr; 15934 DeclRefExpr *CapturedExpr = nullptr; 15935 15936 public: 15937 TransformExprToCaptures(Sema &SemaRef, ValueDecl *FieldDecl) 15938 : BaseTransform(SemaRef), Field(FieldDecl), CapturedExpr(nullptr) {} 15939 15940 ExprResult TransformMemberExpr(MemberExpr *E) { 15941 if (isa<CXXThisExpr>(E->getBase()->IgnoreParenImpCasts()) && 15942 E->getMemberDecl() == Field) { 15943 CapturedExpr = buildCapture(SemaRef, Field, E, /*WithInit=*/false); 15944 return CapturedExpr; 15945 } 15946 return BaseTransform::TransformMemberExpr(E); 15947 } 15948 DeclRefExpr *getCapturedExpr() { return CapturedExpr; } 15949 }; 15950 } // namespace 15951 15952 template <typename T, typename U> 15953 static T filterLookupForUDReductionAndMapper( 15954 SmallVectorImpl<U> &Lookups, const llvm::function_ref<T(ValueDecl *)> Gen) { 15955 for (U &Set : Lookups) { 15956 for (auto *D : Set) { 15957 if (T Res = Gen(cast<ValueDecl>(D))) 15958 return Res; 15959 } 15960 } 15961 return T(); 15962 } 15963 15964 static NamedDecl *findAcceptableDecl(Sema &SemaRef, NamedDecl *D) { 15965 assert(!LookupResult::isVisible(SemaRef, D) && "not in slow case"); 15966 15967 for (auto RD : D->redecls()) { 15968 // Don't bother with extra checks if we already know this one isn't visible. 15969 if (RD == D) 15970 continue; 15971 15972 auto ND = cast<NamedDecl>(RD); 15973 if (LookupResult::isVisible(SemaRef, ND)) 15974 return ND; 15975 } 15976 15977 return nullptr; 15978 } 15979 15980 static void 15981 argumentDependentLookup(Sema &SemaRef, const DeclarationNameInfo &Id, 15982 SourceLocation Loc, QualType Ty, 15983 SmallVectorImpl<UnresolvedSet<8>> &Lookups) { 15984 // Find all of the associated namespaces and classes based on the 15985 // arguments we have. 15986 Sema::AssociatedNamespaceSet AssociatedNamespaces; 15987 Sema::AssociatedClassSet AssociatedClasses; 15988 OpaqueValueExpr OVE(Loc, Ty, VK_LValue); 15989 SemaRef.FindAssociatedClassesAndNamespaces(Loc, &OVE, AssociatedNamespaces, 15990 AssociatedClasses); 15991 15992 // C++ [basic.lookup.argdep]p3: 15993 // Let X be the lookup set produced by unqualified lookup (3.4.1) 15994 // and let Y be the lookup set produced by argument dependent 15995 // lookup (defined as follows). If X contains [...] then Y is 15996 // empty. Otherwise Y is the set of declarations found in the 15997 // namespaces associated with the argument types as described 15998 // below. The set of declarations found by the lookup of the name 15999 // is the union of X and Y. 16000 // 16001 // Here, we compute Y and add its members to the overloaded 16002 // candidate set. 16003 for (auto *NS : AssociatedNamespaces) { 16004 // When considering an associated namespace, the lookup is the 16005 // same as the lookup performed when the associated namespace is 16006 // used as a qualifier (3.4.3.2) except that: 16007 // 16008 // -- Any using-directives in the associated namespace are 16009 // ignored. 16010 // 16011 // -- Any namespace-scope friend functions declared in 16012 // associated classes are visible within their respective 16013 // namespaces even if they are not visible during an ordinary 16014 // lookup (11.4). 16015 DeclContext::lookup_result R = NS->lookup(Id.getName()); 16016 for (auto *D : R) { 16017 auto *Underlying = D; 16018 if (auto *USD = dyn_cast<UsingShadowDecl>(D)) 16019 Underlying = USD->getTargetDecl(); 16020 16021 if (!isa<OMPDeclareReductionDecl>(Underlying) && 16022 !isa<OMPDeclareMapperDecl>(Underlying)) 16023 continue; 16024 16025 if (!SemaRef.isVisible(D)) { 16026 D = findAcceptableDecl(SemaRef, D); 16027 if (!D) 16028 continue; 16029 if (auto *USD = dyn_cast<UsingShadowDecl>(D)) 16030 Underlying = USD->getTargetDecl(); 16031 } 16032 Lookups.emplace_back(); 16033 Lookups.back().addDecl(Underlying); 16034 } 16035 } 16036 } 16037 16038 static ExprResult 16039 buildDeclareReductionRef(Sema &SemaRef, SourceLocation Loc, SourceRange Range, 16040 Scope *S, CXXScopeSpec &ReductionIdScopeSpec, 16041 const DeclarationNameInfo &ReductionId, QualType Ty, 16042 CXXCastPath &BasePath, Expr *UnresolvedReduction) { 16043 if (ReductionIdScopeSpec.isInvalid()) 16044 return ExprError(); 16045 SmallVector<UnresolvedSet<8>, 4> Lookups; 16046 if (S) { 16047 LookupResult Lookup(SemaRef, ReductionId, Sema::LookupOMPReductionName); 16048 Lookup.suppressDiagnostics(); 16049 while (S && SemaRef.LookupParsedName(Lookup, S, &ReductionIdScopeSpec)) { 16050 NamedDecl *D = Lookup.getRepresentativeDecl(); 16051 do { 16052 S = S->getParent(); 16053 } while (S && !S->isDeclScope(D)); 16054 if (S) 16055 S = S->getParent(); 16056 Lookups.emplace_back(); 16057 Lookups.back().append(Lookup.begin(), Lookup.end()); 16058 Lookup.clear(); 16059 } 16060 } else if (auto *ULE = 16061 cast_or_null<UnresolvedLookupExpr>(UnresolvedReduction)) { 16062 Lookups.push_back(UnresolvedSet<8>()); 16063 Decl *PrevD = nullptr; 16064 for (NamedDecl *D : ULE->decls()) { 16065 if (D == PrevD) 16066 Lookups.push_back(UnresolvedSet<8>()); 16067 else if (auto *DRD = dyn_cast<OMPDeclareReductionDecl>(D)) 16068 Lookups.back().addDecl(DRD); 16069 PrevD = D; 16070 } 16071 } 16072 if (SemaRef.CurContext->isDependentContext() || Ty->isDependentType() || 16073 Ty->isInstantiationDependentType() || 16074 Ty->containsUnexpandedParameterPack() || 16075 filterLookupForUDReductionAndMapper<bool>(Lookups, [](ValueDecl *D) { 16076 return !D->isInvalidDecl() && 16077 (D->getType()->isDependentType() || 16078 D->getType()->isInstantiationDependentType() || 16079 D->getType()->containsUnexpandedParameterPack()); 16080 })) { 16081 UnresolvedSet<8> ResSet; 16082 for (const UnresolvedSet<8> &Set : Lookups) { 16083 if (Set.empty()) 16084 continue; 16085 ResSet.append(Set.begin(), Set.end()); 16086 // The last item marks the end of all declarations at the specified scope. 16087 ResSet.addDecl(Set[Set.size() - 1]); 16088 } 16089 return UnresolvedLookupExpr::Create( 16090 SemaRef.Context, /*NamingClass=*/nullptr, 16091 ReductionIdScopeSpec.getWithLocInContext(SemaRef.Context), ReductionId, 16092 /*ADL=*/true, /*Overloaded=*/true, ResSet.begin(), ResSet.end()); 16093 } 16094 // Lookup inside the classes. 16095 // C++ [over.match.oper]p3: 16096 // For a unary operator @ with an operand of a type whose 16097 // cv-unqualified version is T1, and for a binary operator @ with 16098 // a left operand of a type whose cv-unqualified version is T1 and 16099 // a right operand of a type whose cv-unqualified version is T2, 16100 // three sets of candidate functions, designated member 16101 // candidates, non-member candidates and built-in candidates, are 16102 // constructed as follows: 16103 // -- If T1 is a complete class type or a class currently being 16104 // defined, the set of member candidates is the result of the 16105 // qualified lookup of T1::operator@ (13.3.1.1.1); otherwise, 16106 // the set of member candidates is empty. 16107 LookupResult Lookup(SemaRef, ReductionId, Sema::LookupOMPReductionName); 16108 Lookup.suppressDiagnostics(); 16109 if (const auto *TyRec = Ty->getAs<RecordType>()) { 16110 // Complete the type if it can be completed. 16111 // If the type is neither complete nor being defined, bail out now. 16112 if (SemaRef.isCompleteType(Loc, Ty) || TyRec->isBeingDefined() || 16113 TyRec->getDecl()->getDefinition()) { 16114 Lookup.clear(); 16115 SemaRef.LookupQualifiedName(Lookup, TyRec->getDecl()); 16116 if (Lookup.empty()) { 16117 Lookups.emplace_back(); 16118 Lookups.back().append(Lookup.begin(), Lookup.end()); 16119 } 16120 } 16121 } 16122 // Perform ADL. 16123 if (SemaRef.getLangOpts().CPlusPlus) 16124 argumentDependentLookup(SemaRef, ReductionId, Loc, Ty, Lookups); 16125 if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>( 16126 Lookups, [&SemaRef, Ty](ValueDecl *D) -> ValueDecl * { 16127 if (!D->isInvalidDecl() && 16128 SemaRef.Context.hasSameType(D->getType(), Ty)) 16129 return D; 16130 return nullptr; 16131 })) 16132 return SemaRef.BuildDeclRefExpr(VD, VD->getType().getNonReferenceType(), 16133 VK_LValue, Loc); 16134 if (SemaRef.getLangOpts().CPlusPlus) { 16135 if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>( 16136 Lookups, [&SemaRef, Ty, Loc](ValueDecl *D) -> ValueDecl * { 16137 if (!D->isInvalidDecl() && 16138 SemaRef.IsDerivedFrom(Loc, Ty, D->getType()) && 16139 !Ty.isMoreQualifiedThan(D->getType())) 16140 return D; 16141 return nullptr; 16142 })) { 16143 CXXBasePaths Paths(/*FindAmbiguities=*/true, /*RecordPaths=*/true, 16144 /*DetectVirtual=*/false); 16145 if (SemaRef.IsDerivedFrom(Loc, Ty, VD->getType(), Paths)) { 16146 if (!Paths.isAmbiguous(SemaRef.Context.getCanonicalType( 16147 VD->getType().getUnqualifiedType()))) { 16148 if (SemaRef.CheckBaseClassAccess( 16149 Loc, VD->getType(), Ty, Paths.front(), 16150 /*DiagID=*/0) != Sema::AR_inaccessible) { 16151 SemaRef.BuildBasePathArray(Paths, BasePath); 16152 return SemaRef.BuildDeclRefExpr( 16153 VD, VD->getType().getNonReferenceType(), VK_LValue, Loc); 16154 } 16155 } 16156 } 16157 } 16158 } 16159 if (ReductionIdScopeSpec.isSet()) { 16160 SemaRef.Diag(Loc, diag::err_omp_not_resolved_reduction_identifier) 16161 << Ty << Range; 16162 return ExprError(); 16163 } 16164 return ExprEmpty(); 16165 } 16166 16167 namespace { 16168 /// Data for the reduction-based clauses. 16169 struct ReductionData { 16170 /// List of original reduction items. 16171 SmallVector<Expr *, 8> Vars; 16172 /// List of private copies of the reduction items. 16173 SmallVector<Expr *, 8> Privates; 16174 /// LHS expressions for the reduction_op expressions. 16175 SmallVector<Expr *, 8> LHSs; 16176 /// RHS expressions for the reduction_op expressions. 16177 SmallVector<Expr *, 8> RHSs; 16178 /// Reduction operation expression. 16179 SmallVector<Expr *, 8> ReductionOps; 16180 /// inscan copy operation expressions. 16181 SmallVector<Expr *, 8> InscanCopyOps; 16182 /// inscan copy temp array expressions for prefix sums. 16183 SmallVector<Expr *, 8> InscanCopyArrayTemps; 16184 /// inscan copy temp array element expressions for prefix sums. 16185 SmallVector<Expr *, 8> InscanCopyArrayElems; 16186 /// Taskgroup descriptors for the corresponding reduction items in 16187 /// in_reduction clauses. 16188 SmallVector<Expr *, 8> TaskgroupDescriptors; 16189 /// List of captures for clause. 16190 SmallVector<Decl *, 4> ExprCaptures; 16191 /// List of postupdate expressions. 16192 SmallVector<Expr *, 4> ExprPostUpdates; 16193 /// Reduction modifier. 16194 unsigned RedModifier = 0; 16195 ReductionData() = delete; 16196 /// Reserves required memory for the reduction data. 16197 ReductionData(unsigned Size, unsigned Modifier = 0) : RedModifier(Modifier) { 16198 Vars.reserve(Size); 16199 Privates.reserve(Size); 16200 LHSs.reserve(Size); 16201 RHSs.reserve(Size); 16202 ReductionOps.reserve(Size); 16203 if (RedModifier == OMPC_REDUCTION_inscan) { 16204 InscanCopyOps.reserve(Size); 16205 InscanCopyArrayTemps.reserve(Size); 16206 InscanCopyArrayElems.reserve(Size); 16207 } 16208 TaskgroupDescriptors.reserve(Size); 16209 ExprCaptures.reserve(Size); 16210 ExprPostUpdates.reserve(Size); 16211 } 16212 /// Stores reduction item and reduction operation only (required for dependent 16213 /// reduction item). 16214 void push(Expr *Item, Expr *ReductionOp) { 16215 Vars.emplace_back(Item); 16216 Privates.emplace_back(nullptr); 16217 LHSs.emplace_back(nullptr); 16218 RHSs.emplace_back(nullptr); 16219 ReductionOps.emplace_back(ReductionOp); 16220 TaskgroupDescriptors.emplace_back(nullptr); 16221 if (RedModifier == OMPC_REDUCTION_inscan) { 16222 InscanCopyOps.push_back(nullptr); 16223 InscanCopyArrayTemps.push_back(nullptr); 16224 InscanCopyArrayElems.push_back(nullptr); 16225 } 16226 } 16227 /// Stores reduction data. 16228 void push(Expr *Item, Expr *Private, Expr *LHS, Expr *RHS, Expr *ReductionOp, 16229 Expr *TaskgroupDescriptor, Expr *CopyOp, Expr *CopyArrayTemp, 16230 Expr *CopyArrayElem) { 16231 Vars.emplace_back(Item); 16232 Privates.emplace_back(Private); 16233 LHSs.emplace_back(LHS); 16234 RHSs.emplace_back(RHS); 16235 ReductionOps.emplace_back(ReductionOp); 16236 TaskgroupDescriptors.emplace_back(TaskgroupDescriptor); 16237 if (RedModifier == OMPC_REDUCTION_inscan) { 16238 InscanCopyOps.push_back(CopyOp); 16239 InscanCopyArrayTemps.push_back(CopyArrayTemp); 16240 InscanCopyArrayElems.push_back(CopyArrayElem); 16241 } else { 16242 assert(CopyOp == nullptr && CopyArrayTemp == nullptr && 16243 CopyArrayElem == nullptr && 16244 "Copy operation must be used for inscan reductions only."); 16245 } 16246 } 16247 }; 16248 } // namespace 16249 16250 static bool checkOMPArraySectionConstantForReduction( 16251 ASTContext &Context, const OMPArraySectionExpr *OASE, bool &SingleElement, 16252 SmallVectorImpl<llvm::APSInt> &ArraySizes) { 16253 const Expr *Length = OASE->getLength(); 16254 if (Length == nullptr) { 16255 // For array sections of the form [1:] or [:], we would need to analyze 16256 // the lower bound... 16257 if (OASE->getColonLocFirst().isValid()) 16258 return false; 16259 16260 // This is an array subscript which has implicit length 1! 16261 SingleElement = true; 16262 ArraySizes.push_back(llvm::APSInt::get(1)); 16263 } else { 16264 Expr::EvalResult Result; 16265 if (!Length->EvaluateAsInt(Result, Context)) 16266 return false; 16267 16268 llvm::APSInt ConstantLengthValue = Result.Val.getInt(); 16269 SingleElement = (ConstantLengthValue.getSExtValue() == 1); 16270 ArraySizes.push_back(ConstantLengthValue); 16271 } 16272 16273 // Get the base of this array section and walk up from there. 16274 const Expr *Base = OASE->getBase()->IgnoreParenImpCasts(); 16275 16276 // We require length = 1 for all array sections except the right-most to 16277 // guarantee that the memory region is contiguous and has no holes in it. 16278 while (const auto *TempOASE = dyn_cast<OMPArraySectionExpr>(Base)) { 16279 Length = TempOASE->getLength(); 16280 if (Length == nullptr) { 16281 // For array sections of the form [1:] or [:], we would need to analyze 16282 // the lower bound... 16283 if (OASE->getColonLocFirst().isValid()) 16284 return false; 16285 16286 // This is an array subscript which has implicit length 1! 16287 ArraySizes.push_back(llvm::APSInt::get(1)); 16288 } else { 16289 Expr::EvalResult Result; 16290 if (!Length->EvaluateAsInt(Result, Context)) 16291 return false; 16292 16293 llvm::APSInt ConstantLengthValue = Result.Val.getInt(); 16294 if (ConstantLengthValue.getSExtValue() != 1) 16295 return false; 16296 16297 ArraySizes.push_back(ConstantLengthValue); 16298 } 16299 Base = TempOASE->getBase()->IgnoreParenImpCasts(); 16300 } 16301 16302 // If we have a single element, we don't need to add the implicit lengths. 16303 if (!SingleElement) { 16304 while (const auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base)) { 16305 // Has implicit length 1! 16306 ArraySizes.push_back(llvm::APSInt::get(1)); 16307 Base = TempASE->getBase()->IgnoreParenImpCasts(); 16308 } 16309 } 16310 16311 // This array section can be privatized as a single value or as a constant 16312 // sized array. 16313 return true; 16314 } 16315 16316 static bool actOnOMPReductionKindClause( 16317 Sema &S, DSAStackTy *Stack, OpenMPClauseKind ClauseKind, 16318 ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, 16319 SourceLocation ColonLoc, SourceLocation EndLoc, 16320 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, 16321 ArrayRef<Expr *> UnresolvedReductions, ReductionData &RD) { 16322 DeclarationName DN = ReductionId.getName(); 16323 OverloadedOperatorKind OOK = DN.getCXXOverloadedOperator(); 16324 BinaryOperatorKind BOK = BO_Comma; 16325 16326 ASTContext &Context = S.Context; 16327 // OpenMP [2.14.3.6, reduction clause] 16328 // C 16329 // reduction-identifier is either an identifier or one of the following 16330 // operators: +, -, *, &, |, ^, && and || 16331 // C++ 16332 // reduction-identifier is either an id-expression or one of the following 16333 // operators: +, -, *, &, |, ^, && and || 16334 switch (OOK) { 16335 case OO_Plus: 16336 case OO_Minus: 16337 BOK = BO_Add; 16338 break; 16339 case OO_Star: 16340 BOK = BO_Mul; 16341 break; 16342 case OO_Amp: 16343 BOK = BO_And; 16344 break; 16345 case OO_Pipe: 16346 BOK = BO_Or; 16347 break; 16348 case OO_Caret: 16349 BOK = BO_Xor; 16350 break; 16351 case OO_AmpAmp: 16352 BOK = BO_LAnd; 16353 break; 16354 case OO_PipePipe: 16355 BOK = BO_LOr; 16356 break; 16357 case OO_New: 16358 case OO_Delete: 16359 case OO_Array_New: 16360 case OO_Array_Delete: 16361 case OO_Slash: 16362 case OO_Percent: 16363 case OO_Tilde: 16364 case OO_Exclaim: 16365 case OO_Equal: 16366 case OO_Less: 16367 case OO_Greater: 16368 case OO_LessEqual: 16369 case OO_GreaterEqual: 16370 case OO_PlusEqual: 16371 case OO_MinusEqual: 16372 case OO_StarEqual: 16373 case OO_SlashEqual: 16374 case OO_PercentEqual: 16375 case OO_CaretEqual: 16376 case OO_AmpEqual: 16377 case OO_PipeEqual: 16378 case OO_LessLess: 16379 case OO_GreaterGreater: 16380 case OO_LessLessEqual: 16381 case OO_GreaterGreaterEqual: 16382 case OO_EqualEqual: 16383 case OO_ExclaimEqual: 16384 case OO_Spaceship: 16385 case OO_PlusPlus: 16386 case OO_MinusMinus: 16387 case OO_Comma: 16388 case OO_ArrowStar: 16389 case OO_Arrow: 16390 case OO_Call: 16391 case OO_Subscript: 16392 case OO_Conditional: 16393 case OO_Coawait: 16394 case NUM_OVERLOADED_OPERATORS: 16395 llvm_unreachable("Unexpected reduction identifier"); 16396 case OO_None: 16397 if (IdentifierInfo *II = DN.getAsIdentifierInfo()) { 16398 if (II->isStr("max")) 16399 BOK = BO_GT; 16400 else if (II->isStr("min")) 16401 BOK = BO_LT; 16402 } 16403 break; 16404 } 16405 SourceRange ReductionIdRange; 16406 if (ReductionIdScopeSpec.isValid()) 16407 ReductionIdRange.setBegin(ReductionIdScopeSpec.getBeginLoc()); 16408 else 16409 ReductionIdRange.setBegin(ReductionId.getBeginLoc()); 16410 ReductionIdRange.setEnd(ReductionId.getEndLoc()); 16411 16412 auto IR = UnresolvedReductions.begin(), ER = UnresolvedReductions.end(); 16413 bool FirstIter = true; 16414 for (Expr *RefExpr : VarList) { 16415 assert(RefExpr && "nullptr expr in OpenMP reduction clause."); 16416 // OpenMP [2.1, C/C++] 16417 // A list item is a variable or array section, subject to the restrictions 16418 // specified in Section 2.4 on page 42 and in each of the sections 16419 // describing clauses and directives for which a list appears. 16420 // OpenMP [2.14.3.3, Restrictions, p.1] 16421 // A variable that is part of another variable (as an array or 16422 // structure element) cannot appear in a private clause. 16423 if (!FirstIter && IR != ER) 16424 ++IR; 16425 FirstIter = false; 16426 SourceLocation ELoc; 16427 SourceRange ERange; 16428 Expr *SimpleRefExpr = RefExpr; 16429 auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange, 16430 /*AllowArraySection=*/true); 16431 if (Res.second) { 16432 // Try to find 'declare reduction' corresponding construct before using 16433 // builtin/overloaded operators. 16434 QualType Type = Context.DependentTy; 16435 CXXCastPath BasePath; 16436 ExprResult DeclareReductionRef = buildDeclareReductionRef( 16437 S, ELoc, ERange, Stack->getCurScope(), ReductionIdScopeSpec, 16438 ReductionId, Type, BasePath, IR == ER ? nullptr : *IR); 16439 Expr *ReductionOp = nullptr; 16440 if (S.CurContext->isDependentContext() && 16441 (DeclareReductionRef.isUnset() || 16442 isa<UnresolvedLookupExpr>(DeclareReductionRef.get()))) 16443 ReductionOp = DeclareReductionRef.get(); 16444 // It will be analyzed later. 16445 RD.push(RefExpr, ReductionOp); 16446 } 16447 ValueDecl *D = Res.first; 16448 if (!D) 16449 continue; 16450 16451 Expr *TaskgroupDescriptor = nullptr; 16452 QualType Type; 16453 auto *ASE = dyn_cast<ArraySubscriptExpr>(RefExpr->IgnoreParens()); 16454 auto *OASE = dyn_cast<OMPArraySectionExpr>(RefExpr->IgnoreParens()); 16455 if (ASE) { 16456 Type = ASE->getType().getNonReferenceType(); 16457 } else if (OASE) { 16458 QualType BaseType = 16459 OMPArraySectionExpr::getBaseOriginalType(OASE->getBase()); 16460 if (const auto *ATy = BaseType->getAsArrayTypeUnsafe()) 16461 Type = ATy->getElementType(); 16462 else 16463 Type = BaseType->getPointeeType(); 16464 Type = Type.getNonReferenceType(); 16465 } else { 16466 Type = Context.getBaseElementType(D->getType().getNonReferenceType()); 16467 } 16468 auto *VD = dyn_cast<VarDecl>(D); 16469 16470 // OpenMP [2.9.3.3, Restrictions, C/C++, p.3] 16471 // A variable that appears in a private clause must not have an incomplete 16472 // type or a reference type. 16473 if (S.RequireCompleteType(ELoc, D->getType(), 16474 diag::err_omp_reduction_incomplete_type)) 16475 continue; 16476 // OpenMP [2.14.3.6, reduction clause, Restrictions] 16477 // A list item that appears in a reduction clause must not be 16478 // const-qualified. 16479 if (rejectConstNotMutableType(S, D, Type, ClauseKind, ELoc, 16480 /*AcceptIfMutable*/ false, ASE || OASE)) 16481 continue; 16482 16483 OpenMPDirectiveKind CurrDir = Stack->getCurrentDirective(); 16484 // OpenMP [2.9.3.6, Restrictions, C/C++, p.4] 16485 // If a list-item is a reference type then it must bind to the same object 16486 // for all threads of the team. 16487 if (!ASE && !OASE) { 16488 if (VD) { 16489 VarDecl *VDDef = VD->getDefinition(); 16490 if (VD->getType()->isReferenceType() && VDDef && VDDef->hasInit()) { 16491 DSARefChecker Check(Stack); 16492 if (Check.Visit(VDDef->getInit())) { 16493 S.Diag(ELoc, diag::err_omp_reduction_ref_type_arg) 16494 << getOpenMPClauseName(ClauseKind) << ERange; 16495 S.Diag(VDDef->getLocation(), diag::note_defined_here) << VDDef; 16496 continue; 16497 } 16498 } 16499 } 16500 16501 // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables Referenced 16502 // in a Construct] 16503 // Variables with the predetermined data-sharing attributes may not be 16504 // listed in data-sharing attributes clauses, except for the cases 16505 // listed below. For these exceptions only, listing a predetermined 16506 // variable in a data-sharing attribute clause is allowed and overrides 16507 // the variable's predetermined data-sharing attributes. 16508 // OpenMP [2.14.3.6, Restrictions, p.3] 16509 // Any number of reduction clauses can be specified on the directive, 16510 // but a list item can appear only once in the reduction clauses for that 16511 // directive. 16512 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(D, /*FromParent=*/false); 16513 if (DVar.CKind == OMPC_reduction) { 16514 S.Diag(ELoc, diag::err_omp_once_referenced) 16515 << getOpenMPClauseName(ClauseKind); 16516 if (DVar.RefExpr) 16517 S.Diag(DVar.RefExpr->getExprLoc(), diag::note_omp_referenced); 16518 continue; 16519 } 16520 if (DVar.CKind != OMPC_unknown) { 16521 S.Diag(ELoc, diag::err_omp_wrong_dsa) 16522 << getOpenMPClauseName(DVar.CKind) 16523 << getOpenMPClauseName(OMPC_reduction); 16524 reportOriginalDsa(S, Stack, D, DVar); 16525 continue; 16526 } 16527 16528 // OpenMP [2.14.3.6, Restrictions, p.1] 16529 // A list item that appears in a reduction clause of a worksharing 16530 // construct must be shared in the parallel regions to which any of the 16531 // worksharing regions arising from the worksharing construct bind. 16532 if (isOpenMPWorksharingDirective(CurrDir) && 16533 !isOpenMPParallelDirective(CurrDir) && 16534 !isOpenMPTeamsDirective(CurrDir)) { 16535 DVar = Stack->getImplicitDSA(D, true); 16536 if (DVar.CKind != OMPC_shared) { 16537 S.Diag(ELoc, diag::err_omp_required_access) 16538 << getOpenMPClauseName(OMPC_reduction) 16539 << getOpenMPClauseName(OMPC_shared); 16540 reportOriginalDsa(S, Stack, D, DVar); 16541 continue; 16542 } 16543 } 16544 } else { 16545 // Threadprivates cannot be shared between threads, so dignose if the base 16546 // is a threadprivate variable. 16547 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(D, /*FromParent=*/false); 16548 if (DVar.CKind == OMPC_threadprivate) { 16549 S.Diag(ELoc, diag::err_omp_wrong_dsa) 16550 << getOpenMPClauseName(DVar.CKind) 16551 << getOpenMPClauseName(OMPC_reduction); 16552 reportOriginalDsa(S, Stack, D, DVar); 16553 continue; 16554 } 16555 } 16556 16557 // Try to find 'declare reduction' corresponding construct before using 16558 // builtin/overloaded operators. 16559 CXXCastPath BasePath; 16560 ExprResult DeclareReductionRef = buildDeclareReductionRef( 16561 S, ELoc, ERange, Stack->getCurScope(), ReductionIdScopeSpec, 16562 ReductionId, Type, BasePath, IR == ER ? nullptr : *IR); 16563 if (DeclareReductionRef.isInvalid()) 16564 continue; 16565 if (S.CurContext->isDependentContext() && 16566 (DeclareReductionRef.isUnset() || 16567 isa<UnresolvedLookupExpr>(DeclareReductionRef.get()))) { 16568 RD.push(RefExpr, DeclareReductionRef.get()); 16569 continue; 16570 } 16571 if (BOK == BO_Comma && DeclareReductionRef.isUnset()) { 16572 // Not allowed reduction identifier is found. 16573 S.Diag(ReductionId.getBeginLoc(), 16574 diag::err_omp_unknown_reduction_identifier) 16575 << Type << ReductionIdRange; 16576 continue; 16577 } 16578 16579 // OpenMP [2.14.3.6, reduction clause, Restrictions] 16580 // The type of a list item that appears in a reduction clause must be valid 16581 // for the reduction-identifier. For a max or min reduction in C, the type 16582 // of the list item must be an allowed arithmetic data type: char, int, 16583 // float, double, or _Bool, possibly modified with long, short, signed, or 16584 // unsigned. For a max or min reduction in C++, the type of the list item 16585 // must be an allowed arithmetic data type: char, wchar_t, int, float, 16586 // double, or bool, possibly modified with long, short, signed, or unsigned. 16587 if (DeclareReductionRef.isUnset()) { 16588 if ((BOK == BO_GT || BOK == BO_LT) && 16589 !(Type->isScalarType() || 16590 (S.getLangOpts().CPlusPlus && Type->isArithmeticType()))) { 16591 S.Diag(ELoc, diag::err_omp_clause_not_arithmetic_type_arg) 16592 << getOpenMPClauseName(ClauseKind) << S.getLangOpts().CPlusPlus; 16593 if (!ASE && !OASE) { 16594 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) == 16595 VarDecl::DeclarationOnly; 16596 S.Diag(D->getLocation(), 16597 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 16598 << D; 16599 } 16600 continue; 16601 } 16602 if ((BOK == BO_OrAssign || BOK == BO_AndAssign || BOK == BO_XorAssign) && 16603 !S.getLangOpts().CPlusPlus && Type->isFloatingType()) { 16604 S.Diag(ELoc, diag::err_omp_clause_floating_type_arg) 16605 << getOpenMPClauseName(ClauseKind); 16606 if (!ASE && !OASE) { 16607 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) == 16608 VarDecl::DeclarationOnly; 16609 S.Diag(D->getLocation(), 16610 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 16611 << D; 16612 } 16613 continue; 16614 } 16615 } 16616 16617 Type = Type.getNonLValueExprType(Context).getUnqualifiedType(); 16618 VarDecl *LHSVD = buildVarDecl(S, ELoc, Type, ".reduction.lhs", 16619 D->hasAttrs() ? &D->getAttrs() : nullptr); 16620 VarDecl *RHSVD = buildVarDecl(S, ELoc, Type, D->getName(), 16621 D->hasAttrs() ? &D->getAttrs() : nullptr); 16622 QualType PrivateTy = Type; 16623 16624 // Try if we can determine constant lengths for all array sections and avoid 16625 // the VLA. 16626 bool ConstantLengthOASE = false; 16627 if (OASE) { 16628 bool SingleElement; 16629 llvm::SmallVector<llvm::APSInt, 4> ArraySizes; 16630 ConstantLengthOASE = checkOMPArraySectionConstantForReduction( 16631 Context, OASE, SingleElement, ArraySizes); 16632 16633 // If we don't have a single element, we must emit a constant array type. 16634 if (ConstantLengthOASE && !SingleElement) { 16635 for (llvm::APSInt &Size : ArraySizes) 16636 PrivateTy = Context.getConstantArrayType(PrivateTy, Size, nullptr, 16637 ArrayType::Normal, 16638 /*IndexTypeQuals=*/0); 16639 } 16640 } 16641 16642 if ((OASE && !ConstantLengthOASE) || 16643 (!OASE && !ASE && 16644 D->getType().getNonReferenceType()->isVariablyModifiedType())) { 16645 if (!Context.getTargetInfo().isVLASupported()) { 16646 if (isOpenMPTargetExecutionDirective(Stack->getCurrentDirective())) { 16647 S.Diag(ELoc, diag::err_omp_reduction_vla_unsupported) << !!OASE; 16648 S.Diag(ELoc, diag::note_vla_unsupported); 16649 continue; 16650 } else { 16651 S.targetDiag(ELoc, diag::err_omp_reduction_vla_unsupported) << !!OASE; 16652 S.targetDiag(ELoc, diag::note_vla_unsupported); 16653 } 16654 } 16655 // For arrays/array sections only: 16656 // Create pseudo array type for private copy. The size for this array will 16657 // be generated during codegen. 16658 // For array subscripts or single variables Private Ty is the same as Type 16659 // (type of the variable or single array element). 16660 PrivateTy = Context.getVariableArrayType( 16661 Type, 16662 new (Context) OpaqueValueExpr(ELoc, Context.getSizeType(), VK_RValue), 16663 ArrayType::Normal, /*IndexTypeQuals=*/0, SourceRange()); 16664 } else if (!ASE && !OASE && 16665 Context.getAsArrayType(D->getType().getNonReferenceType())) { 16666 PrivateTy = D->getType().getNonReferenceType(); 16667 } 16668 // Private copy. 16669 VarDecl *PrivateVD = 16670 buildVarDecl(S, ELoc, PrivateTy, D->getName(), 16671 D->hasAttrs() ? &D->getAttrs() : nullptr, 16672 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr); 16673 // Add initializer for private variable. 16674 Expr *Init = nullptr; 16675 DeclRefExpr *LHSDRE = buildDeclRefExpr(S, LHSVD, Type, ELoc); 16676 DeclRefExpr *RHSDRE = buildDeclRefExpr(S, RHSVD, Type, ELoc); 16677 if (DeclareReductionRef.isUsable()) { 16678 auto *DRDRef = DeclareReductionRef.getAs<DeclRefExpr>(); 16679 auto *DRD = cast<OMPDeclareReductionDecl>(DRDRef->getDecl()); 16680 if (DRD->getInitializer()) { 16681 S.ActOnUninitializedDecl(PrivateVD); 16682 Init = DRDRef; 16683 RHSVD->setInit(DRDRef); 16684 RHSVD->setInitStyle(VarDecl::CallInit); 16685 } 16686 } else { 16687 switch (BOK) { 16688 case BO_Add: 16689 case BO_Xor: 16690 case BO_Or: 16691 case BO_LOr: 16692 // '+', '-', '^', '|', '||' reduction ops - initializer is '0'. 16693 if (Type->isScalarType() || Type->isAnyComplexType()) 16694 Init = S.ActOnIntegerConstant(ELoc, /*Val=*/0).get(); 16695 break; 16696 case BO_Mul: 16697 case BO_LAnd: 16698 if (Type->isScalarType() || Type->isAnyComplexType()) { 16699 // '*' and '&&' reduction ops - initializer is '1'. 16700 Init = S.ActOnIntegerConstant(ELoc, /*Val=*/1).get(); 16701 } 16702 break; 16703 case BO_And: { 16704 // '&' reduction op - initializer is '~0'. 16705 QualType OrigType = Type; 16706 if (auto *ComplexTy = OrigType->getAs<ComplexType>()) 16707 Type = ComplexTy->getElementType(); 16708 if (Type->isRealFloatingType()) { 16709 llvm::APFloat InitValue = llvm::APFloat::getAllOnesValue( 16710 Context.getFloatTypeSemantics(Type), 16711 Context.getTypeSize(Type)); 16712 Init = FloatingLiteral::Create(Context, InitValue, /*isexact=*/true, 16713 Type, ELoc); 16714 } else if (Type->isScalarType()) { 16715 uint64_t Size = Context.getTypeSize(Type); 16716 QualType IntTy = Context.getIntTypeForBitwidth(Size, /*Signed=*/0); 16717 llvm::APInt InitValue = llvm::APInt::getAllOnesValue(Size); 16718 Init = IntegerLiteral::Create(Context, InitValue, IntTy, ELoc); 16719 } 16720 if (Init && OrigType->isAnyComplexType()) { 16721 // Init = 0xFFFF + 0xFFFFi; 16722 auto *Im = new (Context) ImaginaryLiteral(Init, OrigType); 16723 Init = S.CreateBuiltinBinOp(ELoc, BO_Add, Init, Im).get(); 16724 } 16725 Type = OrigType; 16726 break; 16727 } 16728 case BO_LT: 16729 case BO_GT: { 16730 // 'min' reduction op - initializer is 'Largest representable number in 16731 // the reduction list item type'. 16732 // 'max' reduction op - initializer is 'Least representable number in 16733 // the reduction list item type'. 16734 if (Type->isIntegerType() || Type->isPointerType()) { 16735 bool IsSigned = Type->hasSignedIntegerRepresentation(); 16736 uint64_t Size = Context.getTypeSize(Type); 16737 QualType IntTy = 16738 Context.getIntTypeForBitwidth(Size, /*Signed=*/IsSigned); 16739 llvm::APInt InitValue = 16740 (BOK != BO_LT) ? IsSigned ? llvm::APInt::getSignedMinValue(Size) 16741 : llvm::APInt::getMinValue(Size) 16742 : IsSigned ? llvm::APInt::getSignedMaxValue(Size) 16743 : llvm::APInt::getMaxValue(Size); 16744 Init = IntegerLiteral::Create(Context, InitValue, IntTy, ELoc); 16745 if (Type->isPointerType()) { 16746 // Cast to pointer type. 16747 ExprResult CastExpr = S.BuildCStyleCastExpr( 16748 ELoc, Context.getTrivialTypeSourceInfo(Type, ELoc), ELoc, Init); 16749 if (CastExpr.isInvalid()) 16750 continue; 16751 Init = CastExpr.get(); 16752 } 16753 } else if (Type->isRealFloatingType()) { 16754 llvm::APFloat InitValue = llvm::APFloat::getLargest( 16755 Context.getFloatTypeSemantics(Type), BOK != BO_LT); 16756 Init = FloatingLiteral::Create(Context, InitValue, /*isexact=*/true, 16757 Type, ELoc); 16758 } 16759 break; 16760 } 16761 case BO_PtrMemD: 16762 case BO_PtrMemI: 16763 case BO_MulAssign: 16764 case BO_Div: 16765 case BO_Rem: 16766 case BO_Sub: 16767 case BO_Shl: 16768 case BO_Shr: 16769 case BO_LE: 16770 case BO_GE: 16771 case BO_EQ: 16772 case BO_NE: 16773 case BO_Cmp: 16774 case BO_AndAssign: 16775 case BO_XorAssign: 16776 case BO_OrAssign: 16777 case BO_Assign: 16778 case BO_AddAssign: 16779 case BO_SubAssign: 16780 case BO_DivAssign: 16781 case BO_RemAssign: 16782 case BO_ShlAssign: 16783 case BO_ShrAssign: 16784 case BO_Comma: 16785 llvm_unreachable("Unexpected reduction operation"); 16786 } 16787 } 16788 if (Init && DeclareReductionRef.isUnset()) { 16789 S.AddInitializerToDecl(RHSVD, Init, /*DirectInit=*/false); 16790 // Store initializer for single element in private copy. Will be used 16791 // during codegen. 16792 PrivateVD->setInit(RHSVD->getInit()); 16793 PrivateVD->setInitStyle(RHSVD->getInitStyle()); 16794 } else if (!Init) { 16795 S.ActOnUninitializedDecl(RHSVD); 16796 // Store initializer for single element in private copy. Will be used 16797 // during codegen. 16798 PrivateVD->setInit(RHSVD->getInit()); 16799 PrivateVD->setInitStyle(RHSVD->getInitStyle()); 16800 } 16801 if (RHSVD->isInvalidDecl()) 16802 continue; 16803 if (!RHSVD->hasInit() && DeclareReductionRef.isUnset()) { 16804 S.Diag(ELoc, diag::err_omp_reduction_id_not_compatible) 16805 << Type << ReductionIdRange; 16806 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) == 16807 VarDecl::DeclarationOnly; 16808 S.Diag(D->getLocation(), 16809 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 16810 << D; 16811 continue; 16812 } 16813 DeclRefExpr *PrivateDRE = buildDeclRefExpr(S, PrivateVD, PrivateTy, ELoc); 16814 ExprResult ReductionOp; 16815 if (DeclareReductionRef.isUsable()) { 16816 QualType RedTy = DeclareReductionRef.get()->getType(); 16817 QualType PtrRedTy = Context.getPointerType(RedTy); 16818 ExprResult LHS = S.CreateBuiltinUnaryOp(ELoc, UO_AddrOf, LHSDRE); 16819 ExprResult RHS = S.CreateBuiltinUnaryOp(ELoc, UO_AddrOf, RHSDRE); 16820 if (!BasePath.empty()) { 16821 LHS = S.DefaultLvalueConversion(LHS.get()); 16822 RHS = S.DefaultLvalueConversion(RHS.get()); 16823 LHS = ImplicitCastExpr::Create( 16824 Context, PtrRedTy, CK_UncheckedDerivedToBase, LHS.get(), &BasePath, 16825 LHS.get()->getValueKind(), FPOptionsOverride()); 16826 RHS = ImplicitCastExpr::Create( 16827 Context, PtrRedTy, CK_UncheckedDerivedToBase, RHS.get(), &BasePath, 16828 RHS.get()->getValueKind(), FPOptionsOverride()); 16829 } 16830 FunctionProtoType::ExtProtoInfo EPI; 16831 QualType Params[] = {PtrRedTy, PtrRedTy}; 16832 QualType FnTy = Context.getFunctionType(Context.VoidTy, Params, EPI); 16833 auto *OVE = new (Context) OpaqueValueExpr( 16834 ELoc, Context.getPointerType(FnTy), VK_RValue, OK_Ordinary, 16835 S.DefaultLvalueConversion(DeclareReductionRef.get()).get()); 16836 Expr *Args[] = {LHS.get(), RHS.get()}; 16837 ReductionOp = 16838 CallExpr::Create(Context, OVE, Args, Context.VoidTy, VK_RValue, ELoc, 16839 S.CurFPFeatureOverrides()); 16840 } else { 16841 ReductionOp = S.BuildBinOp( 16842 Stack->getCurScope(), ReductionId.getBeginLoc(), BOK, LHSDRE, RHSDRE); 16843 if (ReductionOp.isUsable()) { 16844 if (BOK != BO_LT && BOK != BO_GT) { 16845 ReductionOp = 16846 S.BuildBinOp(Stack->getCurScope(), ReductionId.getBeginLoc(), 16847 BO_Assign, LHSDRE, ReductionOp.get()); 16848 } else { 16849 auto *ConditionalOp = new (Context) 16850 ConditionalOperator(ReductionOp.get(), ELoc, LHSDRE, ELoc, RHSDRE, 16851 Type, VK_LValue, OK_Ordinary); 16852 ReductionOp = 16853 S.BuildBinOp(Stack->getCurScope(), ReductionId.getBeginLoc(), 16854 BO_Assign, LHSDRE, ConditionalOp); 16855 } 16856 if (ReductionOp.isUsable()) 16857 ReductionOp = S.ActOnFinishFullExpr(ReductionOp.get(), 16858 /*DiscardedValue*/ false); 16859 } 16860 if (!ReductionOp.isUsable()) 16861 continue; 16862 } 16863 16864 // Add copy operations for inscan reductions. 16865 // LHS = RHS; 16866 ExprResult CopyOpRes, TempArrayRes, TempArrayElem; 16867 if (ClauseKind == OMPC_reduction && 16868 RD.RedModifier == OMPC_REDUCTION_inscan) { 16869 ExprResult RHS = S.DefaultLvalueConversion(RHSDRE); 16870 CopyOpRes = S.BuildBinOp(Stack->getCurScope(), ELoc, BO_Assign, LHSDRE, 16871 RHS.get()); 16872 if (!CopyOpRes.isUsable()) 16873 continue; 16874 CopyOpRes = 16875 S.ActOnFinishFullExpr(CopyOpRes.get(), /*DiscardedValue=*/true); 16876 if (!CopyOpRes.isUsable()) 16877 continue; 16878 // For simd directive and simd-based directives in simd mode no need to 16879 // construct temp array, need just a single temp element. 16880 if (Stack->getCurrentDirective() == OMPD_simd || 16881 (S.getLangOpts().OpenMPSimd && 16882 isOpenMPSimdDirective(Stack->getCurrentDirective()))) { 16883 VarDecl *TempArrayVD = 16884 buildVarDecl(S, ELoc, PrivateTy, D->getName(), 16885 D->hasAttrs() ? &D->getAttrs() : nullptr); 16886 // Add a constructor to the temp decl. 16887 S.ActOnUninitializedDecl(TempArrayVD); 16888 TempArrayRes = buildDeclRefExpr(S, TempArrayVD, PrivateTy, ELoc); 16889 } else { 16890 // Build temp array for prefix sum. 16891 auto *Dim = new (S.Context) 16892 OpaqueValueExpr(ELoc, S.Context.getSizeType(), VK_RValue); 16893 QualType ArrayTy = 16894 S.Context.getVariableArrayType(PrivateTy, Dim, ArrayType::Normal, 16895 /*IndexTypeQuals=*/0, {ELoc, ELoc}); 16896 VarDecl *TempArrayVD = 16897 buildVarDecl(S, ELoc, ArrayTy, D->getName(), 16898 D->hasAttrs() ? &D->getAttrs() : nullptr); 16899 // Add a constructor to the temp decl. 16900 S.ActOnUninitializedDecl(TempArrayVD); 16901 TempArrayRes = buildDeclRefExpr(S, TempArrayVD, ArrayTy, ELoc); 16902 TempArrayElem = 16903 S.DefaultFunctionArrayLvalueConversion(TempArrayRes.get()); 16904 auto *Idx = new (S.Context) 16905 OpaqueValueExpr(ELoc, S.Context.getSizeType(), VK_RValue); 16906 TempArrayElem = S.CreateBuiltinArraySubscriptExpr(TempArrayElem.get(), 16907 ELoc, Idx, ELoc); 16908 } 16909 } 16910 16911 // OpenMP [2.15.4.6, Restrictions, p.2] 16912 // A list item that appears in an in_reduction clause of a task construct 16913 // must appear in a task_reduction clause of a construct associated with a 16914 // taskgroup region that includes the participating task in its taskgroup 16915 // set. The construct associated with the innermost region that meets this 16916 // condition must specify the same reduction-identifier as the in_reduction 16917 // clause. 16918 if (ClauseKind == OMPC_in_reduction) { 16919 SourceRange ParentSR; 16920 BinaryOperatorKind ParentBOK; 16921 const Expr *ParentReductionOp = nullptr; 16922 Expr *ParentBOKTD = nullptr, *ParentReductionOpTD = nullptr; 16923 DSAStackTy::DSAVarData ParentBOKDSA = 16924 Stack->getTopMostTaskgroupReductionData(D, ParentSR, ParentBOK, 16925 ParentBOKTD); 16926 DSAStackTy::DSAVarData ParentReductionOpDSA = 16927 Stack->getTopMostTaskgroupReductionData( 16928 D, ParentSR, ParentReductionOp, ParentReductionOpTD); 16929 bool IsParentBOK = ParentBOKDSA.DKind != OMPD_unknown; 16930 bool IsParentReductionOp = ParentReductionOpDSA.DKind != OMPD_unknown; 16931 if ((DeclareReductionRef.isUnset() && IsParentReductionOp) || 16932 (DeclareReductionRef.isUsable() && IsParentBOK) || 16933 (IsParentBOK && BOK != ParentBOK) || IsParentReductionOp) { 16934 bool EmitError = true; 16935 if (IsParentReductionOp && DeclareReductionRef.isUsable()) { 16936 llvm::FoldingSetNodeID RedId, ParentRedId; 16937 ParentReductionOp->Profile(ParentRedId, Context, /*Canonical=*/true); 16938 DeclareReductionRef.get()->Profile(RedId, Context, 16939 /*Canonical=*/true); 16940 EmitError = RedId != ParentRedId; 16941 } 16942 if (EmitError) { 16943 S.Diag(ReductionId.getBeginLoc(), 16944 diag::err_omp_reduction_identifier_mismatch) 16945 << ReductionIdRange << RefExpr->getSourceRange(); 16946 S.Diag(ParentSR.getBegin(), 16947 diag::note_omp_previous_reduction_identifier) 16948 << ParentSR 16949 << (IsParentBOK ? ParentBOKDSA.RefExpr 16950 : ParentReductionOpDSA.RefExpr) 16951 ->getSourceRange(); 16952 continue; 16953 } 16954 } 16955 TaskgroupDescriptor = IsParentBOK ? ParentBOKTD : ParentReductionOpTD; 16956 } 16957 16958 DeclRefExpr *Ref = nullptr; 16959 Expr *VarsExpr = RefExpr->IgnoreParens(); 16960 if (!VD && !S.CurContext->isDependentContext()) { 16961 if (ASE || OASE) { 16962 TransformExprToCaptures RebuildToCapture(S, D); 16963 VarsExpr = 16964 RebuildToCapture.TransformExpr(RefExpr->IgnoreParens()).get(); 16965 Ref = RebuildToCapture.getCapturedExpr(); 16966 } else { 16967 VarsExpr = Ref = buildCapture(S, D, SimpleRefExpr, /*WithInit=*/false); 16968 } 16969 if (!S.isOpenMPCapturedDecl(D)) { 16970 RD.ExprCaptures.emplace_back(Ref->getDecl()); 16971 if (Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>()) { 16972 ExprResult RefRes = S.DefaultLvalueConversion(Ref); 16973 if (!RefRes.isUsable()) 16974 continue; 16975 ExprResult PostUpdateRes = 16976 S.BuildBinOp(Stack->getCurScope(), ELoc, BO_Assign, SimpleRefExpr, 16977 RefRes.get()); 16978 if (!PostUpdateRes.isUsable()) 16979 continue; 16980 if (isOpenMPTaskingDirective(Stack->getCurrentDirective()) || 16981 Stack->getCurrentDirective() == OMPD_taskgroup) { 16982 S.Diag(RefExpr->getExprLoc(), 16983 diag::err_omp_reduction_non_addressable_expression) 16984 << RefExpr->getSourceRange(); 16985 continue; 16986 } 16987 RD.ExprPostUpdates.emplace_back( 16988 S.IgnoredValueConversions(PostUpdateRes.get()).get()); 16989 } 16990 } 16991 } 16992 // All reduction items are still marked as reduction (to do not increase 16993 // code base size). 16994 unsigned Modifier = RD.RedModifier; 16995 // Consider task_reductions as reductions with task modifier. Required for 16996 // correct analysis of in_reduction clauses. 16997 if (CurrDir == OMPD_taskgroup && ClauseKind == OMPC_task_reduction) 16998 Modifier = OMPC_REDUCTION_task; 16999 Stack->addDSA(D, RefExpr->IgnoreParens(), OMPC_reduction, Ref, Modifier, 17000 ASE || OASE); 17001 if (Modifier == OMPC_REDUCTION_task && 17002 (CurrDir == OMPD_taskgroup || 17003 ((isOpenMPParallelDirective(CurrDir) || 17004 isOpenMPWorksharingDirective(CurrDir)) && 17005 !isOpenMPSimdDirective(CurrDir)))) { 17006 if (DeclareReductionRef.isUsable()) 17007 Stack->addTaskgroupReductionData(D, ReductionIdRange, 17008 DeclareReductionRef.get()); 17009 else 17010 Stack->addTaskgroupReductionData(D, ReductionIdRange, BOK); 17011 } 17012 RD.push(VarsExpr, PrivateDRE, LHSDRE, RHSDRE, ReductionOp.get(), 17013 TaskgroupDescriptor, CopyOpRes.get(), TempArrayRes.get(), 17014 TempArrayElem.get()); 17015 } 17016 return RD.Vars.empty(); 17017 } 17018 17019 OMPClause *Sema::ActOnOpenMPReductionClause( 17020 ArrayRef<Expr *> VarList, OpenMPReductionClauseModifier Modifier, 17021 SourceLocation StartLoc, SourceLocation LParenLoc, 17022 SourceLocation ModifierLoc, SourceLocation ColonLoc, SourceLocation EndLoc, 17023 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, 17024 ArrayRef<Expr *> UnresolvedReductions) { 17025 if (ModifierLoc.isValid() && Modifier == OMPC_REDUCTION_unknown) { 17026 Diag(LParenLoc, diag::err_omp_unexpected_clause_value) 17027 << getListOfPossibleValues(OMPC_reduction, /*First=*/0, 17028 /*Last=*/OMPC_REDUCTION_unknown) 17029 << getOpenMPClauseName(OMPC_reduction); 17030 return nullptr; 17031 } 17032 // OpenMP 5.0, 2.19.5.4 reduction Clause, Restrictions 17033 // A reduction clause with the inscan reduction-modifier may only appear on a 17034 // worksharing-loop construct, a worksharing-loop SIMD construct, a simd 17035 // construct, a parallel worksharing-loop construct or a parallel 17036 // worksharing-loop SIMD construct. 17037 if (Modifier == OMPC_REDUCTION_inscan && 17038 (DSAStack->getCurrentDirective() != OMPD_for && 17039 DSAStack->getCurrentDirective() != OMPD_for_simd && 17040 DSAStack->getCurrentDirective() != OMPD_simd && 17041 DSAStack->getCurrentDirective() != OMPD_parallel_for && 17042 DSAStack->getCurrentDirective() != OMPD_parallel_for_simd)) { 17043 Diag(ModifierLoc, diag::err_omp_wrong_inscan_reduction); 17044 return nullptr; 17045 } 17046 17047 ReductionData RD(VarList.size(), Modifier); 17048 if (actOnOMPReductionKindClause(*this, DSAStack, OMPC_reduction, VarList, 17049 StartLoc, LParenLoc, ColonLoc, EndLoc, 17050 ReductionIdScopeSpec, ReductionId, 17051 UnresolvedReductions, RD)) 17052 return nullptr; 17053 17054 return OMPReductionClause::Create( 17055 Context, StartLoc, LParenLoc, ModifierLoc, ColonLoc, EndLoc, Modifier, 17056 RD.Vars, ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId, 17057 RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps, RD.InscanCopyOps, 17058 RD.InscanCopyArrayTemps, RD.InscanCopyArrayElems, 17059 buildPreInits(Context, RD.ExprCaptures), 17060 buildPostUpdate(*this, RD.ExprPostUpdates)); 17061 } 17062 17063 OMPClause *Sema::ActOnOpenMPTaskReductionClause( 17064 ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, 17065 SourceLocation ColonLoc, SourceLocation EndLoc, 17066 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, 17067 ArrayRef<Expr *> UnresolvedReductions) { 17068 ReductionData RD(VarList.size()); 17069 if (actOnOMPReductionKindClause(*this, DSAStack, OMPC_task_reduction, VarList, 17070 StartLoc, LParenLoc, ColonLoc, EndLoc, 17071 ReductionIdScopeSpec, ReductionId, 17072 UnresolvedReductions, RD)) 17073 return nullptr; 17074 17075 return OMPTaskReductionClause::Create( 17076 Context, StartLoc, LParenLoc, ColonLoc, EndLoc, RD.Vars, 17077 ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId, 17078 RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps, 17079 buildPreInits(Context, RD.ExprCaptures), 17080 buildPostUpdate(*this, RD.ExprPostUpdates)); 17081 } 17082 17083 OMPClause *Sema::ActOnOpenMPInReductionClause( 17084 ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, 17085 SourceLocation ColonLoc, SourceLocation EndLoc, 17086 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, 17087 ArrayRef<Expr *> UnresolvedReductions) { 17088 ReductionData RD(VarList.size()); 17089 if (actOnOMPReductionKindClause(*this, DSAStack, OMPC_in_reduction, VarList, 17090 StartLoc, LParenLoc, ColonLoc, EndLoc, 17091 ReductionIdScopeSpec, ReductionId, 17092 UnresolvedReductions, RD)) 17093 return nullptr; 17094 17095 return OMPInReductionClause::Create( 17096 Context, StartLoc, LParenLoc, ColonLoc, EndLoc, RD.Vars, 17097 ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId, 17098 RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps, RD.TaskgroupDescriptors, 17099 buildPreInits(Context, RD.ExprCaptures), 17100 buildPostUpdate(*this, RD.ExprPostUpdates)); 17101 } 17102 17103 bool Sema::CheckOpenMPLinearModifier(OpenMPLinearClauseKind LinKind, 17104 SourceLocation LinLoc) { 17105 if ((!LangOpts.CPlusPlus && LinKind != OMPC_LINEAR_val) || 17106 LinKind == OMPC_LINEAR_unknown) { 17107 Diag(LinLoc, diag::err_omp_wrong_linear_modifier) << LangOpts.CPlusPlus; 17108 return true; 17109 } 17110 return false; 17111 } 17112 17113 bool Sema::CheckOpenMPLinearDecl(const ValueDecl *D, SourceLocation ELoc, 17114 OpenMPLinearClauseKind LinKind, QualType Type, 17115 bool IsDeclareSimd) { 17116 const auto *VD = dyn_cast_or_null<VarDecl>(D); 17117 // A variable must not have an incomplete type or a reference type. 17118 if (RequireCompleteType(ELoc, Type, diag::err_omp_linear_incomplete_type)) 17119 return true; 17120 if ((LinKind == OMPC_LINEAR_uval || LinKind == OMPC_LINEAR_ref) && 17121 !Type->isReferenceType()) { 17122 Diag(ELoc, diag::err_omp_wrong_linear_modifier_non_reference) 17123 << Type << getOpenMPSimpleClauseTypeName(OMPC_linear, LinKind); 17124 return true; 17125 } 17126 Type = Type.getNonReferenceType(); 17127 17128 // OpenMP 5.0 [2.19.3, List Item Privatization, Restrictions] 17129 // A variable that is privatized must not have a const-qualified type 17130 // unless it is of class type with a mutable member. This restriction does 17131 // not apply to the firstprivate clause, nor to the linear clause on 17132 // declarative directives (like declare simd). 17133 if (!IsDeclareSimd && 17134 rejectConstNotMutableType(*this, D, Type, OMPC_linear, ELoc)) 17135 return true; 17136 17137 // A list item must be of integral or pointer type. 17138 Type = Type.getUnqualifiedType().getCanonicalType(); 17139 const auto *Ty = Type.getTypePtrOrNull(); 17140 if (!Ty || (LinKind != OMPC_LINEAR_ref && !Ty->isDependentType() && 17141 !Ty->isIntegralType(Context) && !Ty->isPointerType())) { 17142 Diag(ELoc, diag::err_omp_linear_expected_int_or_ptr) << Type; 17143 if (D) { 17144 bool IsDecl = 17145 !VD || 17146 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 17147 Diag(D->getLocation(), 17148 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 17149 << D; 17150 } 17151 return true; 17152 } 17153 return false; 17154 } 17155 17156 OMPClause *Sema::ActOnOpenMPLinearClause( 17157 ArrayRef<Expr *> VarList, Expr *Step, SourceLocation StartLoc, 17158 SourceLocation LParenLoc, OpenMPLinearClauseKind LinKind, 17159 SourceLocation LinLoc, SourceLocation ColonLoc, SourceLocation EndLoc) { 17160 SmallVector<Expr *, 8> Vars; 17161 SmallVector<Expr *, 8> Privates; 17162 SmallVector<Expr *, 8> Inits; 17163 SmallVector<Decl *, 4> ExprCaptures; 17164 SmallVector<Expr *, 4> ExprPostUpdates; 17165 if (CheckOpenMPLinearModifier(LinKind, LinLoc)) 17166 LinKind = OMPC_LINEAR_val; 17167 for (Expr *RefExpr : VarList) { 17168 assert(RefExpr && "NULL expr in OpenMP linear clause."); 17169 SourceLocation ELoc; 17170 SourceRange ERange; 17171 Expr *SimpleRefExpr = RefExpr; 17172 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 17173 if (Res.second) { 17174 // It will be analyzed later. 17175 Vars.push_back(RefExpr); 17176 Privates.push_back(nullptr); 17177 Inits.push_back(nullptr); 17178 } 17179 ValueDecl *D = Res.first; 17180 if (!D) 17181 continue; 17182 17183 QualType Type = D->getType(); 17184 auto *VD = dyn_cast<VarDecl>(D); 17185 17186 // OpenMP [2.14.3.7, linear clause] 17187 // A list-item cannot appear in more than one linear clause. 17188 // A list-item that appears in a linear clause cannot appear in any 17189 // other data-sharing attribute clause. 17190 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false); 17191 if (DVar.RefExpr) { 17192 Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind) 17193 << getOpenMPClauseName(OMPC_linear); 17194 reportOriginalDsa(*this, DSAStack, D, DVar); 17195 continue; 17196 } 17197 17198 if (CheckOpenMPLinearDecl(D, ELoc, LinKind, Type)) 17199 continue; 17200 Type = Type.getNonReferenceType().getUnqualifiedType().getCanonicalType(); 17201 17202 // Build private copy of original var. 17203 VarDecl *Private = 17204 buildVarDecl(*this, ELoc, Type, D->getName(), 17205 D->hasAttrs() ? &D->getAttrs() : nullptr, 17206 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr); 17207 DeclRefExpr *PrivateRef = buildDeclRefExpr(*this, Private, Type, ELoc); 17208 // Build var to save initial value. 17209 VarDecl *Init = buildVarDecl(*this, ELoc, Type, ".linear.start"); 17210 Expr *InitExpr; 17211 DeclRefExpr *Ref = nullptr; 17212 if (!VD && !CurContext->isDependentContext()) { 17213 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false); 17214 if (!isOpenMPCapturedDecl(D)) { 17215 ExprCaptures.push_back(Ref->getDecl()); 17216 if (Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>()) { 17217 ExprResult RefRes = DefaultLvalueConversion(Ref); 17218 if (!RefRes.isUsable()) 17219 continue; 17220 ExprResult PostUpdateRes = 17221 BuildBinOp(DSAStack->getCurScope(), ELoc, BO_Assign, 17222 SimpleRefExpr, RefRes.get()); 17223 if (!PostUpdateRes.isUsable()) 17224 continue; 17225 ExprPostUpdates.push_back( 17226 IgnoredValueConversions(PostUpdateRes.get()).get()); 17227 } 17228 } 17229 } 17230 if (LinKind == OMPC_LINEAR_uval) 17231 InitExpr = VD ? VD->getInit() : SimpleRefExpr; 17232 else 17233 InitExpr = VD ? SimpleRefExpr : Ref; 17234 AddInitializerToDecl(Init, DefaultLvalueConversion(InitExpr).get(), 17235 /*DirectInit=*/false); 17236 DeclRefExpr *InitRef = buildDeclRefExpr(*this, Init, Type, ELoc); 17237 17238 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_linear, Ref); 17239 Vars.push_back((VD || CurContext->isDependentContext()) 17240 ? RefExpr->IgnoreParens() 17241 : Ref); 17242 Privates.push_back(PrivateRef); 17243 Inits.push_back(InitRef); 17244 } 17245 17246 if (Vars.empty()) 17247 return nullptr; 17248 17249 Expr *StepExpr = Step; 17250 Expr *CalcStepExpr = nullptr; 17251 if (Step && !Step->isValueDependent() && !Step->isTypeDependent() && 17252 !Step->isInstantiationDependent() && 17253 !Step->containsUnexpandedParameterPack()) { 17254 SourceLocation StepLoc = Step->getBeginLoc(); 17255 ExprResult Val = PerformOpenMPImplicitIntegerConversion(StepLoc, Step); 17256 if (Val.isInvalid()) 17257 return nullptr; 17258 StepExpr = Val.get(); 17259 17260 // Build var to save the step value. 17261 VarDecl *SaveVar = 17262 buildVarDecl(*this, StepLoc, StepExpr->getType(), ".linear.step"); 17263 ExprResult SaveRef = 17264 buildDeclRefExpr(*this, SaveVar, StepExpr->getType(), StepLoc); 17265 ExprResult CalcStep = 17266 BuildBinOp(CurScope, StepLoc, BO_Assign, SaveRef.get(), StepExpr); 17267 CalcStep = ActOnFinishFullExpr(CalcStep.get(), /*DiscardedValue*/ false); 17268 17269 // Warn about zero linear step (it would be probably better specified as 17270 // making corresponding variables 'const'). 17271 if (Optional<llvm::APSInt> Result = 17272 StepExpr->getIntegerConstantExpr(Context)) { 17273 if (!Result->isNegative() && !Result->isStrictlyPositive()) 17274 Diag(StepLoc, diag::warn_omp_linear_step_zero) 17275 << Vars[0] << (Vars.size() > 1); 17276 } else if (CalcStep.isUsable()) { 17277 // Calculate the step beforehand instead of doing this on each iteration. 17278 // (This is not used if the number of iterations may be kfold-ed). 17279 CalcStepExpr = CalcStep.get(); 17280 } 17281 } 17282 17283 return OMPLinearClause::Create(Context, StartLoc, LParenLoc, LinKind, LinLoc, 17284 ColonLoc, EndLoc, Vars, Privates, Inits, 17285 StepExpr, CalcStepExpr, 17286 buildPreInits(Context, ExprCaptures), 17287 buildPostUpdate(*this, ExprPostUpdates)); 17288 } 17289 17290 static bool FinishOpenMPLinearClause(OMPLinearClause &Clause, DeclRefExpr *IV, 17291 Expr *NumIterations, Sema &SemaRef, 17292 Scope *S, DSAStackTy *Stack) { 17293 // Walk the vars and build update/final expressions for the CodeGen. 17294 SmallVector<Expr *, 8> Updates; 17295 SmallVector<Expr *, 8> Finals; 17296 SmallVector<Expr *, 8> UsedExprs; 17297 Expr *Step = Clause.getStep(); 17298 Expr *CalcStep = Clause.getCalcStep(); 17299 // OpenMP [2.14.3.7, linear clause] 17300 // If linear-step is not specified it is assumed to be 1. 17301 if (!Step) 17302 Step = SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get(); 17303 else if (CalcStep) 17304 Step = cast<BinaryOperator>(CalcStep)->getLHS(); 17305 bool HasErrors = false; 17306 auto CurInit = Clause.inits().begin(); 17307 auto CurPrivate = Clause.privates().begin(); 17308 OpenMPLinearClauseKind LinKind = Clause.getModifier(); 17309 for (Expr *RefExpr : Clause.varlists()) { 17310 SourceLocation ELoc; 17311 SourceRange ERange; 17312 Expr *SimpleRefExpr = RefExpr; 17313 auto Res = getPrivateItem(SemaRef, SimpleRefExpr, ELoc, ERange); 17314 ValueDecl *D = Res.first; 17315 if (Res.second || !D) { 17316 Updates.push_back(nullptr); 17317 Finals.push_back(nullptr); 17318 HasErrors = true; 17319 continue; 17320 } 17321 auto &&Info = Stack->isLoopControlVariable(D); 17322 // OpenMP [2.15.11, distribute simd Construct] 17323 // A list item may not appear in a linear clause, unless it is the loop 17324 // iteration variable. 17325 if (isOpenMPDistributeDirective(Stack->getCurrentDirective()) && 17326 isOpenMPSimdDirective(Stack->getCurrentDirective()) && !Info.first) { 17327 SemaRef.Diag(ELoc, 17328 diag::err_omp_linear_distribute_var_non_loop_iteration); 17329 Updates.push_back(nullptr); 17330 Finals.push_back(nullptr); 17331 HasErrors = true; 17332 continue; 17333 } 17334 Expr *InitExpr = *CurInit; 17335 17336 // Build privatized reference to the current linear var. 17337 auto *DE = cast<DeclRefExpr>(SimpleRefExpr); 17338 Expr *CapturedRef; 17339 if (LinKind == OMPC_LINEAR_uval) 17340 CapturedRef = cast<VarDecl>(DE->getDecl())->getInit(); 17341 else 17342 CapturedRef = 17343 buildDeclRefExpr(SemaRef, cast<VarDecl>(DE->getDecl()), 17344 DE->getType().getUnqualifiedType(), DE->getExprLoc(), 17345 /*RefersToCapture=*/true); 17346 17347 // Build update: Var = InitExpr + IV * Step 17348 ExprResult Update; 17349 if (!Info.first) 17350 Update = buildCounterUpdate( 17351 SemaRef, S, RefExpr->getExprLoc(), *CurPrivate, InitExpr, IV, Step, 17352 /*Subtract=*/false, /*IsNonRectangularLB=*/false); 17353 else 17354 Update = *CurPrivate; 17355 Update = SemaRef.ActOnFinishFullExpr(Update.get(), DE->getBeginLoc(), 17356 /*DiscardedValue*/ false); 17357 17358 // Build final: Var = InitExpr + NumIterations * Step 17359 ExprResult Final; 17360 if (!Info.first) 17361 Final = 17362 buildCounterUpdate(SemaRef, S, RefExpr->getExprLoc(), CapturedRef, 17363 InitExpr, NumIterations, Step, /*Subtract=*/false, 17364 /*IsNonRectangularLB=*/false); 17365 else 17366 Final = *CurPrivate; 17367 Final = SemaRef.ActOnFinishFullExpr(Final.get(), DE->getBeginLoc(), 17368 /*DiscardedValue*/ false); 17369 17370 if (!Update.isUsable() || !Final.isUsable()) { 17371 Updates.push_back(nullptr); 17372 Finals.push_back(nullptr); 17373 UsedExprs.push_back(nullptr); 17374 HasErrors = true; 17375 } else { 17376 Updates.push_back(Update.get()); 17377 Finals.push_back(Final.get()); 17378 if (!Info.first) 17379 UsedExprs.push_back(SimpleRefExpr); 17380 } 17381 ++CurInit; 17382 ++CurPrivate; 17383 } 17384 if (Expr *S = Clause.getStep()) 17385 UsedExprs.push_back(S); 17386 // Fill the remaining part with the nullptr. 17387 UsedExprs.append(Clause.varlist_size() + 1 - UsedExprs.size(), nullptr); 17388 Clause.setUpdates(Updates); 17389 Clause.setFinals(Finals); 17390 Clause.setUsedExprs(UsedExprs); 17391 return HasErrors; 17392 } 17393 17394 OMPClause *Sema::ActOnOpenMPAlignedClause( 17395 ArrayRef<Expr *> VarList, Expr *Alignment, SourceLocation StartLoc, 17396 SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc) { 17397 SmallVector<Expr *, 8> Vars; 17398 for (Expr *RefExpr : VarList) { 17399 assert(RefExpr && "NULL expr in OpenMP linear clause."); 17400 SourceLocation ELoc; 17401 SourceRange ERange; 17402 Expr *SimpleRefExpr = RefExpr; 17403 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 17404 if (Res.second) { 17405 // It will be analyzed later. 17406 Vars.push_back(RefExpr); 17407 } 17408 ValueDecl *D = Res.first; 17409 if (!D) 17410 continue; 17411 17412 QualType QType = D->getType(); 17413 auto *VD = dyn_cast<VarDecl>(D); 17414 17415 // OpenMP [2.8.1, simd construct, Restrictions] 17416 // The type of list items appearing in the aligned clause must be 17417 // array, pointer, reference to array, or reference to pointer. 17418 QType = QType.getNonReferenceType().getUnqualifiedType().getCanonicalType(); 17419 const Type *Ty = QType.getTypePtrOrNull(); 17420 if (!Ty || (!Ty->isArrayType() && !Ty->isPointerType())) { 17421 Diag(ELoc, diag::err_omp_aligned_expected_array_or_ptr) 17422 << QType << getLangOpts().CPlusPlus << ERange; 17423 bool IsDecl = 17424 !VD || 17425 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 17426 Diag(D->getLocation(), 17427 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 17428 << D; 17429 continue; 17430 } 17431 17432 // OpenMP [2.8.1, simd construct, Restrictions] 17433 // A list-item cannot appear in more than one aligned clause. 17434 if (const Expr *PrevRef = DSAStack->addUniqueAligned(D, SimpleRefExpr)) { 17435 Diag(ELoc, diag::err_omp_used_in_clause_twice) 17436 << 0 << getOpenMPClauseName(OMPC_aligned) << ERange; 17437 Diag(PrevRef->getExprLoc(), diag::note_omp_explicit_dsa) 17438 << getOpenMPClauseName(OMPC_aligned); 17439 continue; 17440 } 17441 17442 DeclRefExpr *Ref = nullptr; 17443 if (!VD && isOpenMPCapturedDecl(D)) 17444 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true); 17445 Vars.push_back(DefaultFunctionArrayConversion( 17446 (VD || !Ref) ? RefExpr->IgnoreParens() : Ref) 17447 .get()); 17448 } 17449 17450 // OpenMP [2.8.1, simd construct, Description] 17451 // The parameter of the aligned clause, alignment, must be a constant 17452 // positive integer expression. 17453 // If no optional parameter is specified, implementation-defined default 17454 // alignments for SIMD instructions on the target platforms are assumed. 17455 if (Alignment != nullptr) { 17456 ExprResult AlignResult = 17457 VerifyPositiveIntegerConstantInClause(Alignment, OMPC_aligned); 17458 if (AlignResult.isInvalid()) 17459 return nullptr; 17460 Alignment = AlignResult.get(); 17461 } 17462 if (Vars.empty()) 17463 return nullptr; 17464 17465 return OMPAlignedClause::Create(Context, StartLoc, LParenLoc, ColonLoc, 17466 EndLoc, Vars, Alignment); 17467 } 17468 17469 OMPClause *Sema::ActOnOpenMPCopyinClause(ArrayRef<Expr *> VarList, 17470 SourceLocation StartLoc, 17471 SourceLocation LParenLoc, 17472 SourceLocation EndLoc) { 17473 SmallVector<Expr *, 8> Vars; 17474 SmallVector<Expr *, 8> SrcExprs; 17475 SmallVector<Expr *, 8> DstExprs; 17476 SmallVector<Expr *, 8> AssignmentOps; 17477 for (Expr *RefExpr : VarList) { 17478 assert(RefExpr && "NULL expr in OpenMP copyin clause."); 17479 if (isa<DependentScopeDeclRefExpr>(RefExpr)) { 17480 // It will be analyzed later. 17481 Vars.push_back(RefExpr); 17482 SrcExprs.push_back(nullptr); 17483 DstExprs.push_back(nullptr); 17484 AssignmentOps.push_back(nullptr); 17485 continue; 17486 } 17487 17488 SourceLocation ELoc = RefExpr->getExprLoc(); 17489 // OpenMP [2.1, C/C++] 17490 // A list item is a variable name. 17491 // OpenMP [2.14.4.1, Restrictions, p.1] 17492 // A list item that appears in a copyin clause must be threadprivate. 17493 auto *DE = dyn_cast<DeclRefExpr>(RefExpr); 17494 if (!DE || !isa<VarDecl>(DE->getDecl())) { 17495 Diag(ELoc, diag::err_omp_expected_var_name_member_expr) 17496 << 0 << RefExpr->getSourceRange(); 17497 continue; 17498 } 17499 17500 Decl *D = DE->getDecl(); 17501 auto *VD = cast<VarDecl>(D); 17502 17503 QualType Type = VD->getType(); 17504 if (Type->isDependentType() || Type->isInstantiationDependentType()) { 17505 // It will be analyzed later. 17506 Vars.push_back(DE); 17507 SrcExprs.push_back(nullptr); 17508 DstExprs.push_back(nullptr); 17509 AssignmentOps.push_back(nullptr); 17510 continue; 17511 } 17512 17513 // OpenMP [2.14.4.1, Restrictions, C/C++, p.1] 17514 // A list item that appears in a copyin clause must be threadprivate. 17515 if (!DSAStack->isThreadPrivate(VD)) { 17516 Diag(ELoc, diag::err_omp_required_access) 17517 << getOpenMPClauseName(OMPC_copyin) 17518 << getOpenMPDirectiveName(OMPD_threadprivate); 17519 continue; 17520 } 17521 17522 // OpenMP [2.14.4.1, Restrictions, C/C++, p.2] 17523 // A variable of class type (or array thereof) that appears in a 17524 // copyin clause requires an accessible, unambiguous copy assignment 17525 // operator for the class type. 17526 QualType ElemType = Context.getBaseElementType(Type).getNonReferenceType(); 17527 VarDecl *SrcVD = 17528 buildVarDecl(*this, DE->getBeginLoc(), ElemType.getUnqualifiedType(), 17529 ".copyin.src", VD->hasAttrs() ? &VD->getAttrs() : nullptr); 17530 DeclRefExpr *PseudoSrcExpr = buildDeclRefExpr( 17531 *this, SrcVD, ElemType.getUnqualifiedType(), DE->getExprLoc()); 17532 VarDecl *DstVD = 17533 buildVarDecl(*this, DE->getBeginLoc(), ElemType, ".copyin.dst", 17534 VD->hasAttrs() ? &VD->getAttrs() : nullptr); 17535 DeclRefExpr *PseudoDstExpr = 17536 buildDeclRefExpr(*this, DstVD, ElemType, DE->getExprLoc()); 17537 // For arrays generate assignment operation for single element and replace 17538 // it by the original array element in CodeGen. 17539 ExprResult AssignmentOp = 17540 BuildBinOp(/*S=*/nullptr, DE->getExprLoc(), BO_Assign, PseudoDstExpr, 17541 PseudoSrcExpr); 17542 if (AssignmentOp.isInvalid()) 17543 continue; 17544 AssignmentOp = ActOnFinishFullExpr(AssignmentOp.get(), DE->getExprLoc(), 17545 /*DiscardedValue*/ false); 17546 if (AssignmentOp.isInvalid()) 17547 continue; 17548 17549 DSAStack->addDSA(VD, DE, OMPC_copyin); 17550 Vars.push_back(DE); 17551 SrcExprs.push_back(PseudoSrcExpr); 17552 DstExprs.push_back(PseudoDstExpr); 17553 AssignmentOps.push_back(AssignmentOp.get()); 17554 } 17555 17556 if (Vars.empty()) 17557 return nullptr; 17558 17559 return OMPCopyinClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars, 17560 SrcExprs, DstExprs, AssignmentOps); 17561 } 17562 17563 OMPClause *Sema::ActOnOpenMPCopyprivateClause(ArrayRef<Expr *> VarList, 17564 SourceLocation StartLoc, 17565 SourceLocation LParenLoc, 17566 SourceLocation EndLoc) { 17567 SmallVector<Expr *, 8> Vars; 17568 SmallVector<Expr *, 8> SrcExprs; 17569 SmallVector<Expr *, 8> DstExprs; 17570 SmallVector<Expr *, 8> AssignmentOps; 17571 for (Expr *RefExpr : VarList) { 17572 assert(RefExpr && "NULL expr in OpenMP linear clause."); 17573 SourceLocation ELoc; 17574 SourceRange ERange; 17575 Expr *SimpleRefExpr = RefExpr; 17576 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 17577 if (Res.second) { 17578 // It will be analyzed later. 17579 Vars.push_back(RefExpr); 17580 SrcExprs.push_back(nullptr); 17581 DstExprs.push_back(nullptr); 17582 AssignmentOps.push_back(nullptr); 17583 } 17584 ValueDecl *D = Res.first; 17585 if (!D) 17586 continue; 17587 17588 QualType Type = D->getType(); 17589 auto *VD = dyn_cast<VarDecl>(D); 17590 17591 // OpenMP [2.14.4.2, Restrictions, p.2] 17592 // A list item that appears in a copyprivate clause may not appear in a 17593 // private or firstprivate clause on the single construct. 17594 if (!VD || !DSAStack->isThreadPrivate(VD)) { 17595 DSAStackTy::DSAVarData DVar = 17596 DSAStack->getTopDSA(D, /*FromParent=*/false); 17597 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_copyprivate && 17598 DVar.RefExpr) { 17599 Diag(ELoc, diag::err_omp_wrong_dsa) 17600 << getOpenMPClauseName(DVar.CKind) 17601 << getOpenMPClauseName(OMPC_copyprivate); 17602 reportOriginalDsa(*this, DSAStack, D, DVar); 17603 continue; 17604 } 17605 17606 // OpenMP [2.11.4.2, Restrictions, p.1] 17607 // All list items that appear in a copyprivate clause must be either 17608 // threadprivate or private in the enclosing context. 17609 if (DVar.CKind == OMPC_unknown) { 17610 DVar = DSAStack->getImplicitDSA(D, false); 17611 if (DVar.CKind == OMPC_shared) { 17612 Diag(ELoc, diag::err_omp_required_access) 17613 << getOpenMPClauseName(OMPC_copyprivate) 17614 << "threadprivate or private in the enclosing context"; 17615 reportOriginalDsa(*this, DSAStack, D, DVar); 17616 continue; 17617 } 17618 } 17619 } 17620 17621 // Variably modified types are not supported. 17622 if (!Type->isAnyPointerType() && Type->isVariablyModifiedType()) { 17623 Diag(ELoc, diag::err_omp_variably_modified_type_not_supported) 17624 << getOpenMPClauseName(OMPC_copyprivate) << Type 17625 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 17626 bool IsDecl = 17627 !VD || 17628 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 17629 Diag(D->getLocation(), 17630 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 17631 << D; 17632 continue; 17633 } 17634 17635 // OpenMP [2.14.4.1, Restrictions, C/C++, p.2] 17636 // A variable of class type (or array thereof) that appears in a 17637 // copyin clause requires an accessible, unambiguous copy assignment 17638 // operator for the class type. 17639 Type = Context.getBaseElementType(Type.getNonReferenceType()) 17640 .getUnqualifiedType(); 17641 VarDecl *SrcVD = 17642 buildVarDecl(*this, RefExpr->getBeginLoc(), Type, ".copyprivate.src", 17643 D->hasAttrs() ? &D->getAttrs() : nullptr); 17644 DeclRefExpr *PseudoSrcExpr = buildDeclRefExpr(*this, SrcVD, Type, ELoc); 17645 VarDecl *DstVD = 17646 buildVarDecl(*this, RefExpr->getBeginLoc(), Type, ".copyprivate.dst", 17647 D->hasAttrs() ? &D->getAttrs() : nullptr); 17648 DeclRefExpr *PseudoDstExpr = buildDeclRefExpr(*this, DstVD, Type, ELoc); 17649 ExprResult AssignmentOp = BuildBinOp( 17650 DSAStack->getCurScope(), ELoc, BO_Assign, PseudoDstExpr, PseudoSrcExpr); 17651 if (AssignmentOp.isInvalid()) 17652 continue; 17653 AssignmentOp = 17654 ActOnFinishFullExpr(AssignmentOp.get(), ELoc, /*DiscardedValue*/ false); 17655 if (AssignmentOp.isInvalid()) 17656 continue; 17657 17658 // No need to mark vars as copyprivate, they are already threadprivate or 17659 // implicitly private. 17660 assert(VD || isOpenMPCapturedDecl(D)); 17661 Vars.push_back( 17662 VD ? RefExpr->IgnoreParens() 17663 : buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false)); 17664 SrcExprs.push_back(PseudoSrcExpr); 17665 DstExprs.push_back(PseudoDstExpr); 17666 AssignmentOps.push_back(AssignmentOp.get()); 17667 } 17668 17669 if (Vars.empty()) 17670 return nullptr; 17671 17672 return OMPCopyprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, 17673 Vars, SrcExprs, DstExprs, AssignmentOps); 17674 } 17675 17676 OMPClause *Sema::ActOnOpenMPFlushClause(ArrayRef<Expr *> VarList, 17677 SourceLocation StartLoc, 17678 SourceLocation LParenLoc, 17679 SourceLocation EndLoc) { 17680 if (VarList.empty()) 17681 return nullptr; 17682 17683 return OMPFlushClause::Create(Context, StartLoc, LParenLoc, EndLoc, VarList); 17684 } 17685 17686 /// Tries to find omp_depend_t. type. 17687 static bool findOMPDependT(Sema &S, SourceLocation Loc, DSAStackTy *Stack, 17688 bool Diagnose = true) { 17689 QualType OMPDependT = Stack->getOMPDependT(); 17690 if (!OMPDependT.isNull()) 17691 return true; 17692 IdentifierInfo *II = &S.PP.getIdentifierTable().get("omp_depend_t"); 17693 ParsedType PT = S.getTypeName(*II, Loc, S.getCurScope()); 17694 if (!PT.getAsOpaquePtr() || PT.get().isNull()) { 17695 if (Diagnose) 17696 S.Diag(Loc, diag::err_omp_implied_type_not_found) << "omp_depend_t"; 17697 return false; 17698 } 17699 Stack->setOMPDependT(PT.get()); 17700 return true; 17701 } 17702 17703 OMPClause *Sema::ActOnOpenMPDepobjClause(Expr *Depobj, SourceLocation StartLoc, 17704 SourceLocation LParenLoc, 17705 SourceLocation EndLoc) { 17706 if (!Depobj) 17707 return nullptr; 17708 17709 bool OMPDependTFound = findOMPDependT(*this, StartLoc, DSAStack); 17710 17711 // OpenMP 5.0, 2.17.10.1 depobj Construct 17712 // depobj is an lvalue expression of type omp_depend_t. 17713 if (!Depobj->isTypeDependent() && !Depobj->isValueDependent() && 17714 !Depobj->isInstantiationDependent() && 17715 !Depobj->containsUnexpandedParameterPack() && 17716 (OMPDependTFound && 17717 !Context.typesAreCompatible(DSAStack->getOMPDependT(), Depobj->getType(), 17718 /*CompareUnqualified=*/true))) { 17719 Diag(Depobj->getExprLoc(), diag::err_omp_expected_omp_depend_t_lvalue) 17720 << 0 << Depobj->getType() << Depobj->getSourceRange(); 17721 } 17722 17723 if (!Depobj->isLValue()) { 17724 Diag(Depobj->getExprLoc(), diag::err_omp_expected_omp_depend_t_lvalue) 17725 << 1 << Depobj->getSourceRange(); 17726 } 17727 17728 return OMPDepobjClause::Create(Context, StartLoc, LParenLoc, EndLoc, Depobj); 17729 } 17730 17731 OMPClause * 17732 Sema::ActOnOpenMPDependClause(Expr *DepModifier, OpenMPDependClauseKind DepKind, 17733 SourceLocation DepLoc, SourceLocation ColonLoc, 17734 ArrayRef<Expr *> VarList, SourceLocation StartLoc, 17735 SourceLocation LParenLoc, SourceLocation EndLoc) { 17736 if (DSAStack->getCurrentDirective() == OMPD_ordered && 17737 DepKind != OMPC_DEPEND_source && DepKind != OMPC_DEPEND_sink) { 17738 Diag(DepLoc, diag::err_omp_unexpected_clause_value) 17739 << "'source' or 'sink'" << getOpenMPClauseName(OMPC_depend); 17740 return nullptr; 17741 } 17742 if ((DSAStack->getCurrentDirective() != OMPD_ordered || 17743 DSAStack->getCurrentDirective() == OMPD_depobj) && 17744 (DepKind == OMPC_DEPEND_unknown || DepKind == OMPC_DEPEND_source || 17745 DepKind == OMPC_DEPEND_sink || 17746 ((LangOpts.OpenMP < 50 || 17747 DSAStack->getCurrentDirective() == OMPD_depobj) && 17748 DepKind == OMPC_DEPEND_depobj))) { 17749 SmallVector<unsigned, 3> Except; 17750 Except.push_back(OMPC_DEPEND_source); 17751 Except.push_back(OMPC_DEPEND_sink); 17752 if (LangOpts.OpenMP < 50 || DSAStack->getCurrentDirective() == OMPD_depobj) 17753 Except.push_back(OMPC_DEPEND_depobj); 17754 std::string Expected = (LangOpts.OpenMP >= 50 && !DepModifier) 17755 ? "depend modifier(iterator) or " 17756 : ""; 17757 Diag(DepLoc, diag::err_omp_unexpected_clause_value) 17758 << Expected + getListOfPossibleValues(OMPC_depend, /*First=*/0, 17759 /*Last=*/OMPC_DEPEND_unknown, 17760 Except) 17761 << getOpenMPClauseName(OMPC_depend); 17762 return nullptr; 17763 } 17764 if (DepModifier && 17765 (DepKind == OMPC_DEPEND_source || DepKind == OMPC_DEPEND_sink)) { 17766 Diag(DepModifier->getExprLoc(), 17767 diag::err_omp_depend_sink_source_with_modifier); 17768 return nullptr; 17769 } 17770 if (DepModifier && 17771 !DepModifier->getType()->isSpecificBuiltinType(BuiltinType::OMPIterator)) 17772 Diag(DepModifier->getExprLoc(), diag::err_omp_depend_modifier_not_iterator); 17773 17774 SmallVector<Expr *, 8> Vars; 17775 DSAStackTy::OperatorOffsetTy OpsOffs; 17776 llvm::APSInt DepCounter(/*BitWidth=*/32); 17777 llvm::APSInt TotalDepCount(/*BitWidth=*/32); 17778 if (DepKind == OMPC_DEPEND_sink || DepKind == OMPC_DEPEND_source) { 17779 if (const Expr *OrderedCountExpr = 17780 DSAStack->getParentOrderedRegionParam().first) { 17781 TotalDepCount = OrderedCountExpr->EvaluateKnownConstInt(Context); 17782 TotalDepCount.setIsUnsigned(/*Val=*/true); 17783 } 17784 } 17785 for (Expr *RefExpr : VarList) { 17786 assert(RefExpr && "NULL expr in OpenMP shared clause."); 17787 if (isa<DependentScopeDeclRefExpr>(RefExpr)) { 17788 // It will be analyzed later. 17789 Vars.push_back(RefExpr); 17790 continue; 17791 } 17792 17793 SourceLocation ELoc = RefExpr->getExprLoc(); 17794 Expr *SimpleExpr = RefExpr->IgnoreParenCasts(); 17795 if (DepKind == OMPC_DEPEND_sink) { 17796 if (DSAStack->getParentOrderedRegionParam().first && 17797 DepCounter >= TotalDepCount) { 17798 Diag(ELoc, diag::err_omp_depend_sink_unexpected_expr); 17799 continue; 17800 } 17801 ++DepCounter; 17802 // OpenMP [2.13.9, Summary] 17803 // depend(dependence-type : vec), where dependence-type is: 17804 // 'sink' and where vec is the iteration vector, which has the form: 17805 // x1 [+- d1], x2 [+- d2 ], . . . , xn [+- dn] 17806 // where n is the value specified by the ordered clause in the loop 17807 // directive, xi denotes the loop iteration variable of the i-th nested 17808 // loop associated with the loop directive, and di is a constant 17809 // non-negative integer. 17810 if (CurContext->isDependentContext()) { 17811 // It will be analyzed later. 17812 Vars.push_back(RefExpr); 17813 continue; 17814 } 17815 SimpleExpr = SimpleExpr->IgnoreImplicit(); 17816 OverloadedOperatorKind OOK = OO_None; 17817 SourceLocation OOLoc; 17818 Expr *LHS = SimpleExpr; 17819 Expr *RHS = nullptr; 17820 if (auto *BO = dyn_cast<BinaryOperator>(SimpleExpr)) { 17821 OOK = BinaryOperator::getOverloadedOperator(BO->getOpcode()); 17822 OOLoc = BO->getOperatorLoc(); 17823 LHS = BO->getLHS()->IgnoreParenImpCasts(); 17824 RHS = BO->getRHS()->IgnoreParenImpCasts(); 17825 } else if (auto *OCE = dyn_cast<CXXOperatorCallExpr>(SimpleExpr)) { 17826 OOK = OCE->getOperator(); 17827 OOLoc = OCE->getOperatorLoc(); 17828 LHS = OCE->getArg(/*Arg=*/0)->IgnoreParenImpCasts(); 17829 RHS = OCE->getArg(/*Arg=*/1)->IgnoreParenImpCasts(); 17830 } else if (auto *MCE = dyn_cast<CXXMemberCallExpr>(SimpleExpr)) { 17831 OOK = MCE->getMethodDecl() 17832 ->getNameInfo() 17833 .getName() 17834 .getCXXOverloadedOperator(); 17835 OOLoc = MCE->getCallee()->getExprLoc(); 17836 LHS = MCE->getImplicitObjectArgument()->IgnoreParenImpCasts(); 17837 RHS = MCE->getArg(/*Arg=*/0)->IgnoreParenImpCasts(); 17838 } 17839 SourceLocation ELoc; 17840 SourceRange ERange; 17841 auto Res = getPrivateItem(*this, LHS, ELoc, ERange); 17842 if (Res.second) { 17843 // It will be analyzed later. 17844 Vars.push_back(RefExpr); 17845 } 17846 ValueDecl *D = Res.first; 17847 if (!D) 17848 continue; 17849 17850 if (OOK != OO_Plus && OOK != OO_Minus && (RHS || OOK != OO_None)) { 17851 Diag(OOLoc, diag::err_omp_depend_sink_expected_plus_minus); 17852 continue; 17853 } 17854 if (RHS) { 17855 ExprResult RHSRes = VerifyPositiveIntegerConstantInClause( 17856 RHS, OMPC_depend, /*StrictlyPositive=*/false); 17857 if (RHSRes.isInvalid()) 17858 continue; 17859 } 17860 if (!CurContext->isDependentContext() && 17861 DSAStack->getParentOrderedRegionParam().first && 17862 DepCounter != DSAStack->isParentLoopControlVariable(D).first) { 17863 const ValueDecl *VD = 17864 DSAStack->getParentLoopControlVariable(DepCounter.getZExtValue()); 17865 if (VD) 17866 Diag(ELoc, diag::err_omp_depend_sink_expected_loop_iteration) 17867 << 1 << VD; 17868 else 17869 Diag(ELoc, diag::err_omp_depend_sink_expected_loop_iteration) << 0; 17870 continue; 17871 } 17872 OpsOffs.emplace_back(RHS, OOK); 17873 } else { 17874 bool OMPDependTFound = LangOpts.OpenMP >= 50; 17875 if (OMPDependTFound) 17876 OMPDependTFound = findOMPDependT(*this, StartLoc, DSAStack, 17877 DepKind == OMPC_DEPEND_depobj); 17878 if (DepKind == OMPC_DEPEND_depobj) { 17879 // OpenMP 5.0, 2.17.11 depend Clause, Restrictions, C/C++ 17880 // List items used in depend clauses with the depobj dependence type 17881 // must be expressions of the omp_depend_t type. 17882 if (!RefExpr->isValueDependent() && !RefExpr->isTypeDependent() && 17883 !RefExpr->isInstantiationDependent() && 17884 !RefExpr->containsUnexpandedParameterPack() && 17885 (OMPDependTFound && 17886 !Context.hasSameUnqualifiedType(DSAStack->getOMPDependT(), 17887 RefExpr->getType()))) { 17888 Diag(ELoc, diag::err_omp_expected_omp_depend_t_lvalue) 17889 << 0 << RefExpr->getType() << RefExpr->getSourceRange(); 17890 continue; 17891 } 17892 if (!RefExpr->isLValue()) { 17893 Diag(ELoc, diag::err_omp_expected_omp_depend_t_lvalue) 17894 << 1 << RefExpr->getType() << RefExpr->getSourceRange(); 17895 continue; 17896 } 17897 } else { 17898 // OpenMP 5.0 [2.17.11, Restrictions] 17899 // List items used in depend clauses cannot be zero-length array 17900 // sections. 17901 QualType ExprTy = RefExpr->getType().getNonReferenceType(); 17902 const auto *OASE = dyn_cast<OMPArraySectionExpr>(SimpleExpr); 17903 if (OASE) { 17904 QualType BaseType = 17905 OMPArraySectionExpr::getBaseOriginalType(OASE->getBase()); 17906 if (const auto *ATy = BaseType->getAsArrayTypeUnsafe()) 17907 ExprTy = ATy->getElementType(); 17908 else 17909 ExprTy = BaseType->getPointeeType(); 17910 ExprTy = ExprTy.getNonReferenceType(); 17911 const Expr *Length = OASE->getLength(); 17912 Expr::EvalResult Result; 17913 if (Length && !Length->isValueDependent() && 17914 Length->EvaluateAsInt(Result, Context) && 17915 Result.Val.getInt().isNullValue()) { 17916 Diag(ELoc, 17917 diag::err_omp_depend_zero_length_array_section_not_allowed) 17918 << SimpleExpr->getSourceRange(); 17919 continue; 17920 } 17921 } 17922 17923 // OpenMP 5.0, 2.17.11 depend Clause, Restrictions, C/C++ 17924 // List items used in depend clauses with the in, out, inout or 17925 // mutexinoutset dependence types cannot be expressions of the 17926 // omp_depend_t type. 17927 if (!RefExpr->isValueDependent() && !RefExpr->isTypeDependent() && 17928 !RefExpr->isInstantiationDependent() && 17929 !RefExpr->containsUnexpandedParameterPack() && 17930 (OMPDependTFound && 17931 DSAStack->getOMPDependT().getTypePtr() == ExprTy.getTypePtr())) { 17932 Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item) 17933 << (LangOpts.OpenMP >= 50 ? 1 : 0) << 1 17934 << RefExpr->getSourceRange(); 17935 continue; 17936 } 17937 17938 auto *ASE = dyn_cast<ArraySubscriptExpr>(SimpleExpr); 17939 if (!RefExpr->IgnoreParenImpCasts()->isLValue() || 17940 (ASE && !ASE->getBase()->isTypeDependent() && 17941 !ASE->getBase() 17942 ->getType() 17943 .getNonReferenceType() 17944 ->isPointerType() && 17945 !ASE->getBase()->getType().getNonReferenceType()->isArrayType())) { 17946 Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item) 17947 << (LangOpts.OpenMP >= 50 ? 1 : 0) 17948 << (LangOpts.OpenMP >= 50 ? 1 : 0) << RefExpr->getSourceRange(); 17949 continue; 17950 } 17951 17952 ExprResult Res; 17953 { 17954 Sema::TentativeAnalysisScope Trap(*this); 17955 Res = CreateBuiltinUnaryOp(ELoc, UO_AddrOf, 17956 RefExpr->IgnoreParenImpCasts()); 17957 } 17958 if (!Res.isUsable() && !isa<OMPArraySectionExpr>(SimpleExpr) && 17959 !isa<OMPArrayShapingExpr>(SimpleExpr)) { 17960 Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item) 17961 << (LangOpts.OpenMP >= 50 ? 1 : 0) 17962 << (LangOpts.OpenMP >= 50 ? 1 : 0) << RefExpr->getSourceRange(); 17963 continue; 17964 } 17965 } 17966 } 17967 Vars.push_back(RefExpr->IgnoreParenImpCasts()); 17968 } 17969 17970 if (!CurContext->isDependentContext() && DepKind == OMPC_DEPEND_sink && 17971 TotalDepCount > VarList.size() && 17972 DSAStack->getParentOrderedRegionParam().first && 17973 DSAStack->getParentLoopControlVariable(VarList.size() + 1)) { 17974 Diag(EndLoc, diag::err_omp_depend_sink_expected_loop_iteration) 17975 << 1 << DSAStack->getParentLoopControlVariable(VarList.size() + 1); 17976 } 17977 if (DepKind != OMPC_DEPEND_source && DepKind != OMPC_DEPEND_sink && 17978 Vars.empty()) 17979 return nullptr; 17980 17981 auto *C = OMPDependClause::Create(Context, StartLoc, LParenLoc, EndLoc, 17982 DepModifier, DepKind, DepLoc, ColonLoc, 17983 Vars, TotalDepCount.getZExtValue()); 17984 if ((DepKind == OMPC_DEPEND_sink || DepKind == OMPC_DEPEND_source) && 17985 DSAStack->isParentOrderedRegion()) 17986 DSAStack->addDoacrossDependClause(C, OpsOffs); 17987 return C; 17988 } 17989 17990 OMPClause *Sema::ActOnOpenMPDeviceClause(OpenMPDeviceClauseModifier Modifier, 17991 Expr *Device, SourceLocation StartLoc, 17992 SourceLocation LParenLoc, 17993 SourceLocation ModifierLoc, 17994 SourceLocation EndLoc) { 17995 assert((ModifierLoc.isInvalid() || LangOpts.OpenMP >= 50) && 17996 "Unexpected device modifier in OpenMP < 50."); 17997 17998 bool ErrorFound = false; 17999 if (ModifierLoc.isValid() && Modifier == OMPC_DEVICE_unknown) { 18000 std::string Values = 18001 getListOfPossibleValues(OMPC_device, /*First=*/0, OMPC_DEVICE_unknown); 18002 Diag(ModifierLoc, diag::err_omp_unexpected_clause_value) 18003 << Values << getOpenMPClauseName(OMPC_device); 18004 ErrorFound = true; 18005 } 18006 18007 Expr *ValExpr = Device; 18008 Stmt *HelperValStmt = nullptr; 18009 18010 // OpenMP [2.9.1, Restrictions] 18011 // The device expression must evaluate to a non-negative integer value. 18012 ErrorFound = !isNonNegativeIntegerValue(ValExpr, *this, OMPC_device, 18013 /*StrictlyPositive=*/false) || 18014 ErrorFound; 18015 if (ErrorFound) 18016 return nullptr; 18017 18018 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 18019 OpenMPDirectiveKind CaptureRegion = 18020 getOpenMPCaptureRegionForClause(DKind, OMPC_device, LangOpts.OpenMP); 18021 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 18022 ValExpr = MakeFullExpr(ValExpr).get(); 18023 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 18024 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 18025 HelperValStmt = buildPreInits(Context, Captures); 18026 } 18027 18028 return new (Context) 18029 OMPDeviceClause(Modifier, ValExpr, HelperValStmt, CaptureRegion, StartLoc, 18030 LParenLoc, ModifierLoc, EndLoc); 18031 } 18032 18033 static bool checkTypeMappable(SourceLocation SL, SourceRange SR, Sema &SemaRef, 18034 DSAStackTy *Stack, QualType QTy, 18035 bool FullCheck = true) { 18036 NamedDecl *ND; 18037 if (QTy->isIncompleteType(&ND)) { 18038 SemaRef.Diag(SL, diag::err_incomplete_type) << QTy << SR; 18039 return false; 18040 } 18041 if (FullCheck && !SemaRef.CurContext->isDependentContext() && 18042 !QTy.isTriviallyCopyableType(SemaRef.Context)) 18043 SemaRef.Diag(SL, diag::warn_omp_non_trivial_type_mapped) << QTy << SR; 18044 return true; 18045 } 18046 18047 /// Return true if it can be proven that the provided array expression 18048 /// (array section or array subscript) does NOT specify the whole size of the 18049 /// array whose base type is \a BaseQTy. 18050 static bool checkArrayExpressionDoesNotReferToWholeSize(Sema &SemaRef, 18051 const Expr *E, 18052 QualType BaseQTy) { 18053 const auto *OASE = dyn_cast<OMPArraySectionExpr>(E); 18054 18055 // If this is an array subscript, it refers to the whole size if the size of 18056 // the dimension is constant and equals 1. Also, an array section assumes the 18057 // format of an array subscript if no colon is used. 18058 if (isa<ArraySubscriptExpr>(E) || 18059 (OASE && OASE->getColonLocFirst().isInvalid())) { 18060 if (const auto *ATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr())) 18061 return ATy->getSize().getSExtValue() != 1; 18062 // Size can't be evaluated statically. 18063 return false; 18064 } 18065 18066 assert(OASE && "Expecting array section if not an array subscript."); 18067 const Expr *LowerBound = OASE->getLowerBound(); 18068 const Expr *Length = OASE->getLength(); 18069 18070 // If there is a lower bound that does not evaluates to zero, we are not 18071 // covering the whole dimension. 18072 if (LowerBound) { 18073 Expr::EvalResult Result; 18074 if (!LowerBound->EvaluateAsInt(Result, SemaRef.getASTContext())) 18075 return false; // Can't get the integer value as a constant. 18076 18077 llvm::APSInt ConstLowerBound = Result.Val.getInt(); 18078 if (ConstLowerBound.getSExtValue()) 18079 return true; 18080 } 18081 18082 // If we don't have a length we covering the whole dimension. 18083 if (!Length) 18084 return false; 18085 18086 // If the base is a pointer, we don't have a way to get the size of the 18087 // pointee. 18088 if (BaseQTy->isPointerType()) 18089 return false; 18090 18091 // We can only check if the length is the same as the size of the dimension 18092 // if we have a constant array. 18093 const auto *CATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr()); 18094 if (!CATy) 18095 return false; 18096 18097 Expr::EvalResult Result; 18098 if (!Length->EvaluateAsInt(Result, SemaRef.getASTContext())) 18099 return false; // Can't get the integer value as a constant. 18100 18101 llvm::APSInt ConstLength = Result.Val.getInt(); 18102 return CATy->getSize().getSExtValue() != ConstLength.getSExtValue(); 18103 } 18104 18105 // Return true if it can be proven that the provided array expression (array 18106 // section or array subscript) does NOT specify a single element of the array 18107 // whose base type is \a BaseQTy. 18108 static bool checkArrayExpressionDoesNotReferToUnitySize(Sema &SemaRef, 18109 const Expr *E, 18110 QualType BaseQTy) { 18111 const auto *OASE = dyn_cast<OMPArraySectionExpr>(E); 18112 18113 // An array subscript always refer to a single element. Also, an array section 18114 // assumes the format of an array subscript if no colon is used. 18115 if (isa<ArraySubscriptExpr>(E) || 18116 (OASE && OASE->getColonLocFirst().isInvalid())) 18117 return false; 18118 18119 assert(OASE && "Expecting array section if not an array subscript."); 18120 const Expr *Length = OASE->getLength(); 18121 18122 // If we don't have a length we have to check if the array has unitary size 18123 // for this dimension. Also, we should always expect a length if the base type 18124 // is pointer. 18125 if (!Length) { 18126 if (const auto *ATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr())) 18127 return ATy->getSize().getSExtValue() != 1; 18128 // We cannot assume anything. 18129 return false; 18130 } 18131 18132 // Check if the length evaluates to 1. 18133 Expr::EvalResult Result; 18134 if (!Length->EvaluateAsInt(Result, SemaRef.getASTContext())) 18135 return false; // Can't get the integer value as a constant. 18136 18137 llvm::APSInt ConstLength = Result.Val.getInt(); 18138 return ConstLength.getSExtValue() != 1; 18139 } 18140 18141 // The base of elements of list in a map clause have to be either: 18142 // - a reference to variable or field. 18143 // - a member expression. 18144 // - an array expression. 18145 // 18146 // E.g. if we have the expression 'r.S.Arr[:12]', we want to retrieve the 18147 // reference to 'r'. 18148 // 18149 // If we have: 18150 // 18151 // struct SS { 18152 // Bla S; 18153 // foo() { 18154 // #pragma omp target map (S.Arr[:12]); 18155 // } 18156 // } 18157 // 18158 // We want to retrieve the member expression 'this->S'; 18159 18160 // OpenMP 5.0 [2.19.7.1, map Clause, Restrictions, p.2] 18161 // If a list item is an array section, it must specify contiguous storage. 18162 // 18163 // For this restriction it is sufficient that we make sure only references 18164 // to variables or fields and array expressions, and that no array sections 18165 // exist except in the rightmost expression (unless they cover the whole 18166 // dimension of the array). E.g. these would be invalid: 18167 // 18168 // r.ArrS[3:5].Arr[6:7] 18169 // 18170 // r.ArrS[3:5].x 18171 // 18172 // but these would be valid: 18173 // r.ArrS[3].Arr[6:7] 18174 // 18175 // r.ArrS[3].x 18176 namespace { 18177 class MapBaseChecker final : public StmtVisitor<MapBaseChecker, bool> { 18178 Sema &SemaRef; 18179 OpenMPClauseKind CKind = OMPC_unknown; 18180 OpenMPDirectiveKind DKind = OMPD_unknown; 18181 OMPClauseMappableExprCommon::MappableExprComponentList &Components; 18182 bool IsNonContiguous = false; 18183 bool NoDiagnose = false; 18184 const Expr *RelevantExpr = nullptr; 18185 bool AllowUnitySizeArraySection = true; 18186 bool AllowWholeSizeArraySection = true; 18187 bool AllowAnotherPtr = true; 18188 SourceLocation ELoc; 18189 SourceRange ERange; 18190 18191 void emitErrorMsg() { 18192 // If nothing else worked, this is not a valid map clause expression. 18193 if (SemaRef.getLangOpts().OpenMP < 50) { 18194 SemaRef.Diag(ELoc, 18195 diag::err_omp_expected_named_var_member_or_array_expression) 18196 << ERange; 18197 } else { 18198 SemaRef.Diag(ELoc, diag::err_omp_non_lvalue_in_map_or_motion_clauses) 18199 << getOpenMPClauseName(CKind) << ERange; 18200 } 18201 } 18202 18203 public: 18204 bool VisitDeclRefExpr(DeclRefExpr *DRE) { 18205 if (!isa<VarDecl>(DRE->getDecl())) { 18206 emitErrorMsg(); 18207 return false; 18208 } 18209 assert(!RelevantExpr && "RelevantExpr is expected to be nullptr"); 18210 RelevantExpr = DRE; 18211 // Record the component. 18212 Components.emplace_back(DRE, DRE->getDecl(), IsNonContiguous); 18213 return true; 18214 } 18215 18216 bool VisitMemberExpr(MemberExpr *ME) { 18217 Expr *E = ME; 18218 Expr *BaseE = ME->getBase()->IgnoreParenCasts(); 18219 18220 if (isa<CXXThisExpr>(BaseE)) { 18221 assert(!RelevantExpr && "RelevantExpr is expected to be nullptr"); 18222 // We found a base expression: this->Val. 18223 RelevantExpr = ME; 18224 } else { 18225 E = BaseE; 18226 } 18227 18228 if (!isa<FieldDecl>(ME->getMemberDecl())) { 18229 if (!NoDiagnose) { 18230 SemaRef.Diag(ELoc, diag::err_omp_expected_access_to_data_field) 18231 << ME->getSourceRange(); 18232 return false; 18233 } 18234 if (RelevantExpr) 18235 return false; 18236 return Visit(E); 18237 } 18238 18239 auto *FD = cast<FieldDecl>(ME->getMemberDecl()); 18240 18241 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.3] 18242 // A bit-field cannot appear in a map clause. 18243 // 18244 if (FD->isBitField()) { 18245 if (!NoDiagnose) { 18246 SemaRef.Diag(ELoc, diag::err_omp_bit_fields_forbidden_in_clause) 18247 << ME->getSourceRange() << getOpenMPClauseName(CKind); 18248 return false; 18249 } 18250 if (RelevantExpr) 18251 return false; 18252 return Visit(E); 18253 } 18254 18255 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1] 18256 // If the type of a list item is a reference to a type T then the type 18257 // will be considered to be T for all purposes of this clause. 18258 QualType CurType = BaseE->getType().getNonReferenceType(); 18259 18260 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.2] 18261 // A list item cannot be a variable that is a member of a structure with 18262 // a union type. 18263 // 18264 if (CurType->isUnionType()) { 18265 if (!NoDiagnose) { 18266 SemaRef.Diag(ELoc, diag::err_omp_union_type_not_allowed) 18267 << ME->getSourceRange(); 18268 return false; 18269 } 18270 return RelevantExpr || Visit(E); 18271 } 18272 18273 // If we got a member expression, we should not expect any array section 18274 // before that: 18275 // 18276 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.7] 18277 // If a list item is an element of a structure, only the rightmost symbol 18278 // of the variable reference can be an array section. 18279 // 18280 AllowUnitySizeArraySection = false; 18281 AllowWholeSizeArraySection = false; 18282 18283 // Record the component. 18284 Components.emplace_back(ME, FD, IsNonContiguous); 18285 return RelevantExpr || Visit(E); 18286 } 18287 18288 bool VisitArraySubscriptExpr(ArraySubscriptExpr *AE) { 18289 Expr *E = AE->getBase()->IgnoreParenImpCasts(); 18290 18291 if (!E->getType()->isAnyPointerType() && !E->getType()->isArrayType()) { 18292 if (!NoDiagnose) { 18293 SemaRef.Diag(ELoc, diag::err_omp_expected_base_var_name) 18294 << 0 << AE->getSourceRange(); 18295 return false; 18296 } 18297 return RelevantExpr || Visit(E); 18298 } 18299 18300 // If we got an array subscript that express the whole dimension we 18301 // can have any array expressions before. If it only expressing part of 18302 // the dimension, we can only have unitary-size array expressions. 18303 if (checkArrayExpressionDoesNotReferToWholeSize(SemaRef, AE, 18304 E->getType())) 18305 AllowWholeSizeArraySection = false; 18306 18307 if (const auto *TE = dyn_cast<CXXThisExpr>(E->IgnoreParenCasts())) { 18308 Expr::EvalResult Result; 18309 if (!AE->getIdx()->isValueDependent() && 18310 AE->getIdx()->EvaluateAsInt(Result, SemaRef.getASTContext()) && 18311 !Result.Val.getInt().isNullValue()) { 18312 SemaRef.Diag(AE->getIdx()->getExprLoc(), 18313 diag::err_omp_invalid_map_this_expr); 18314 SemaRef.Diag(AE->getIdx()->getExprLoc(), 18315 diag::note_omp_invalid_subscript_on_this_ptr_map); 18316 } 18317 assert(!RelevantExpr && "RelevantExpr is expected to be nullptr"); 18318 RelevantExpr = TE; 18319 } 18320 18321 // Record the component - we don't have any declaration associated. 18322 Components.emplace_back(AE, nullptr, IsNonContiguous); 18323 18324 return RelevantExpr || Visit(E); 18325 } 18326 18327 bool VisitOMPArraySectionExpr(OMPArraySectionExpr *OASE) { 18328 assert(!NoDiagnose && "Array sections cannot be implicitly mapped."); 18329 Expr *E = OASE->getBase()->IgnoreParenImpCasts(); 18330 QualType CurType = 18331 OMPArraySectionExpr::getBaseOriginalType(E).getCanonicalType(); 18332 18333 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1] 18334 // If the type of a list item is a reference to a type T then the type 18335 // will be considered to be T for all purposes of this clause. 18336 if (CurType->isReferenceType()) 18337 CurType = CurType->getPointeeType(); 18338 18339 bool IsPointer = CurType->isAnyPointerType(); 18340 18341 if (!IsPointer && !CurType->isArrayType()) { 18342 SemaRef.Diag(ELoc, diag::err_omp_expected_base_var_name) 18343 << 0 << OASE->getSourceRange(); 18344 return false; 18345 } 18346 18347 bool NotWhole = 18348 checkArrayExpressionDoesNotReferToWholeSize(SemaRef, OASE, CurType); 18349 bool NotUnity = 18350 checkArrayExpressionDoesNotReferToUnitySize(SemaRef, OASE, CurType); 18351 18352 if (AllowWholeSizeArraySection) { 18353 // Any array section is currently allowed. Allowing a whole size array 18354 // section implies allowing a unity array section as well. 18355 // 18356 // If this array section refers to the whole dimension we can still 18357 // accept other array sections before this one, except if the base is a 18358 // pointer. Otherwise, only unitary sections are accepted. 18359 if (NotWhole || IsPointer) 18360 AllowWholeSizeArraySection = false; 18361 } else if (DKind == OMPD_target_update && 18362 SemaRef.getLangOpts().OpenMP >= 50) { 18363 if (IsPointer && !AllowAnotherPtr) 18364 SemaRef.Diag(ELoc, diag::err_omp_section_length_undefined) 18365 << /*array of unknown bound */ 1; 18366 else 18367 IsNonContiguous = true; 18368 } else if (AllowUnitySizeArraySection && NotUnity) { 18369 // A unity or whole array section is not allowed and that is not 18370 // compatible with the properties of the current array section. 18371 SemaRef.Diag( 18372 ELoc, diag::err_array_section_does_not_specify_contiguous_storage) 18373 << OASE->getSourceRange(); 18374 return false; 18375 } 18376 18377 if (IsPointer) 18378 AllowAnotherPtr = false; 18379 18380 if (const auto *TE = dyn_cast<CXXThisExpr>(E)) { 18381 Expr::EvalResult ResultR; 18382 Expr::EvalResult ResultL; 18383 if (!OASE->getLength()->isValueDependent() && 18384 OASE->getLength()->EvaluateAsInt(ResultR, SemaRef.getASTContext()) && 18385 !ResultR.Val.getInt().isOneValue()) { 18386 SemaRef.Diag(OASE->getLength()->getExprLoc(), 18387 diag::err_omp_invalid_map_this_expr); 18388 SemaRef.Diag(OASE->getLength()->getExprLoc(), 18389 diag::note_omp_invalid_length_on_this_ptr_mapping); 18390 } 18391 if (OASE->getLowerBound() && !OASE->getLowerBound()->isValueDependent() && 18392 OASE->getLowerBound()->EvaluateAsInt(ResultL, 18393 SemaRef.getASTContext()) && 18394 !ResultL.Val.getInt().isNullValue()) { 18395 SemaRef.Diag(OASE->getLowerBound()->getExprLoc(), 18396 diag::err_omp_invalid_map_this_expr); 18397 SemaRef.Diag(OASE->getLowerBound()->getExprLoc(), 18398 diag::note_omp_invalid_lower_bound_on_this_ptr_mapping); 18399 } 18400 assert(!RelevantExpr && "RelevantExpr is expected to be nullptr"); 18401 RelevantExpr = TE; 18402 } 18403 18404 // Record the component - we don't have any declaration associated. 18405 Components.emplace_back(OASE, nullptr, /*IsNonContiguous=*/false); 18406 return RelevantExpr || Visit(E); 18407 } 18408 bool VisitOMPArrayShapingExpr(OMPArrayShapingExpr *E) { 18409 Expr *Base = E->getBase(); 18410 18411 // Record the component - we don't have any declaration associated. 18412 Components.emplace_back(E, nullptr, IsNonContiguous); 18413 18414 return Visit(Base->IgnoreParenImpCasts()); 18415 } 18416 18417 bool VisitUnaryOperator(UnaryOperator *UO) { 18418 if (SemaRef.getLangOpts().OpenMP < 50 || !UO->isLValue() || 18419 UO->getOpcode() != UO_Deref) { 18420 emitErrorMsg(); 18421 return false; 18422 } 18423 if (!RelevantExpr) { 18424 // Record the component if haven't found base decl. 18425 Components.emplace_back(UO, nullptr, /*IsNonContiguous=*/false); 18426 } 18427 return RelevantExpr || Visit(UO->getSubExpr()->IgnoreParenImpCasts()); 18428 } 18429 bool VisitBinaryOperator(BinaryOperator *BO) { 18430 if (SemaRef.getLangOpts().OpenMP < 50 || !BO->getType()->isPointerType()) { 18431 emitErrorMsg(); 18432 return false; 18433 } 18434 18435 // Pointer arithmetic is the only thing we expect to happen here so after we 18436 // make sure the binary operator is a pointer type, the we only thing need 18437 // to to is to visit the subtree that has the same type as root (so that we 18438 // know the other subtree is just an offset) 18439 Expr *LE = BO->getLHS()->IgnoreParenImpCasts(); 18440 Expr *RE = BO->getRHS()->IgnoreParenImpCasts(); 18441 Components.emplace_back(BO, nullptr, false); 18442 assert((LE->getType().getTypePtr() == BO->getType().getTypePtr() || 18443 RE->getType().getTypePtr() == BO->getType().getTypePtr()) && 18444 "Either LHS or RHS have base decl inside"); 18445 if (BO->getType().getTypePtr() == LE->getType().getTypePtr()) 18446 return RelevantExpr || Visit(LE); 18447 return RelevantExpr || Visit(RE); 18448 } 18449 bool VisitCXXThisExpr(CXXThisExpr *CTE) { 18450 assert(!RelevantExpr && "RelevantExpr is expected to be nullptr"); 18451 RelevantExpr = CTE; 18452 Components.emplace_back(CTE, nullptr, IsNonContiguous); 18453 return true; 18454 } 18455 bool VisitCXXOperatorCallExpr(CXXOperatorCallExpr *COCE) { 18456 assert(!RelevantExpr && "RelevantExpr is expected to be nullptr"); 18457 Components.emplace_back(COCE, nullptr, IsNonContiguous); 18458 return true; 18459 } 18460 bool VisitOpaqueValueExpr(OpaqueValueExpr *E) { 18461 Expr *Source = E->getSourceExpr(); 18462 if (!Source) { 18463 emitErrorMsg(); 18464 return false; 18465 } 18466 return Visit(Source); 18467 } 18468 bool VisitStmt(Stmt *) { 18469 emitErrorMsg(); 18470 return false; 18471 } 18472 const Expr *getFoundBase() const { 18473 return RelevantExpr; 18474 } 18475 explicit MapBaseChecker( 18476 Sema &SemaRef, OpenMPClauseKind CKind, OpenMPDirectiveKind DKind, 18477 OMPClauseMappableExprCommon::MappableExprComponentList &Components, 18478 bool NoDiagnose, SourceLocation &ELoc, SourceRange &ERange) 18479 : SemaRef(SemaRef), CKind(CKind), DKind(DKind), Components(Components), 18480 NoDiagnose(NoDiagnose), ELoc(ELoc), ERange(ERange) {} 18481 }; 18482 } // namespace 18483 18484 /// Return the expression of the base of the mappable expression or null if it 18485 /// cannot be determined and do all the necessary checks to see if the expression 18486 /// is valid as a standalone mappable expression. In the process, record all the 18487 /// components of the expression. 18488 static const Expr *checkMapClauseExpressionBase( 18489 Sema &SemaRef, Expr *E, 18490 OMPClauseMappableExprCommon::MappableExprComponentList &CurComponents, 18491 OpenMPClauseKind CKind, OpenMPDirectiveKind DKind, bool NoDiagnose) { 18492 SourceLocation ELoc = E->getExprLoc(); 18493 SourceRange ERange = E->getSourceRange(); 18494 MapBaseChecker Checker(SemaRef, CKind, DKind, CurComponents, NoDiagnose, ELoc, 18495 ERange); 18496 if (Checker.Visit(E->IgnoreParens())) { 18497 // Check if the highest dimension array section has length specified 18498 if (SemaRef.getLangOpts().OpenMP >= 50 && !CurComponents.empty() && 18499 (CKind == OMPC_to || CKind == OMPC_from)) { 18500 auto CI = CurComponents.rbegin(); 18501 auto CE = CurComponents.rend(); 18502 for (; CI != CE; ++CI) { 18503 const auto *OASE = 18504 dyn_cast<OMPArraySectionExpr>(CI->getAssociatedExpression()); 18505 if (!OASE) 18506 continue; 18507 if (OASE && OASE->getLength()) 18508 break; 18509 SemaRef.Diag(ELoc, diag::err_array_section_does_not_specify_length) 18510 << ERange; 18511 } 18512 } 18513 return Checker.getFoundBase(); 18514 } 18515 return nullptr; 18516 } 18517 18518 // Return true if expression E associated with value VD has conflicts with other 18519 // map information. 18520 static bool checkMapConflicts( 18521 Sema &SemaRef, DSAStackTy *DSAS, const ValueDecl *VD, const Expr *E, 18522 bool CurrentRegionOnly, 18523 OMPClauseMappableExprCommon::MappableExprComponentListRef CurComponents, 18524 OpenMPClauseKind CKind) { 18525 assert(VD && E); 18526 SourceLocation ELoc = E->getExprLoc(); 18527 SourceRange ERange = E->getSourceRange(); 18528 18529 // In order to easily check the conflicts we need to match each component of 18530 // the expression under test with the components of the expressions that are 18531 // already in the stack. 18532 18533 assert(!CurComponents.empty() && "Map clause expression with no components!"); 18534 assert(CurComponents.back().getAssociatedDeclaration() == VD && 18535 "Map clause expression with unexpected base!"); 18536 18537 // Variables to help detecting enclosing problems in data environment nests. 18538 bool IsEnclosedByDataEnvironmentExpr = false; 18539 const Expr *EnclosingExpr = nullptr; 18540 18541 bool FoundError = DSAS->checkMappableExprComponentListsForDecl( 18542 VD, CurrentRegionOnly, 18543 [&IsEnclosedByDataEnvironmentExpr, &SemaRef, VD, CurrentRegionOnly, ELoc, 18544 ERange, CKind, &EnclosingExpr, 18545 CurComponents](OMPClauseMappableExprCommon::MappableExprComponentListRef 18546 StackComponents, 18547 OpenMPClauseKind Kind) { 18548 if (CKind == Kind && SemaRef.LangOpts.OpenMP >= 50) 18549 return false; 18550 assert(!StackComponents.empty() && 18551 "Map clause expression with no components!"); 18552 assert(StackComponents.back().getAssociatedDeclaration() == VD && 18553 "Map clause expression with unexpected base!"); 18554 (void)VD; 18555 18556 // The whole expression in the stack. 18557 const Expr *RE = StackComponents.front().getAssociatedExpression(); 18558 18559 // Expressions must start from the same base. Here we detect at which 18560 // point both expressions diverge from each other and see if we can 18561 // detect if the memory referred to both expressions is contiguous and 18562 // do not overlap. 18563 auto CI = CurComponents.rbegin(); 18564 auto CE = CurComponents.rend(); 18565 auto SI = StackComponents.rbegin(); 18566 auto SE = StackComponents.rend(); 18567 for (; CI != CE && SI != SE; ++CI, ++SI) { 18568 18569 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.3] 18570 // At most one list item can be an array item derived from a given 18571 // variable in map clauses of the same construct. 18572 if (CurrentRegionOnly && 18573 (isa<ArraySubscriptExpr>(CI->getAssociatedExpression()) || 18574 isa<OMPArraySectionExpr>(CI->getAssociatedExpression()) || 18575 isa<OMPArrayShapingExpr>(CI->getAssociatedExpression())) && 18576 (isa<ArraySubscriptExpr>(SI->getAssociatedExpression()) || 18577 isa<OMPArraySectionExpr>(SI->getAssociatedExpression()) || 18578 isa<OMPArrayShapingExpr>(SI->getAssociatedExpression()))) { 18579 SemaRef.Diag(CI->getAssociatedExpression()->getExprLoc(), 18580 diag::err_omp_multiple_array_items_in_map_clause) 18581 << CI->getAssociatedExpression()->getSourceRange(); 18582 SemaRef.Diag(SI->getAssociatedExpression()->getExprLoc(), 18583 diag::note_used_here) 18584 << SI->getAssociatedExpression()->getSourceRange(); 18585 return true; 18586 } 18587 18588 // Do both expressions have the same kind? 18589 if (CI->getAssociatedExpression()->getStmtClass() != 18590 SI->getAssociatedExpression()->getStmtClass()) 18591 break; 18592 18593 // Are we dealing with different variables/fields? 18594 if (CI->getAssociatedDeclaration() != SI->getAssociatedDeclaration()) 18595 break; 18596 } 18597 // Check if the extra components of the expressions in the enclosing 18598 // data environment are redundant for the current base declaration. 18599 // If they are, the maps completely overlap, which is legal. 18600 for (; SI != SE; ++SI) { 18601 QualType Type; 18602 if (const auto *ASE = 18603 dyn_cast<ArraySubscriptExpr>(SI->getAssociatedExpression())) { 18604 Type = ASE->getBase()->IgnoreParenImpCasts()->getType(); 18605 } else if (const auto *OASE = dyn_cast<OMPArraySectionExpr>( 18606 SI->getAssociatedExpression())) { 18607 const Expr *E = OASE->getBase()->IgnoreParenImpCasts(); 18608 Type = 18609 OMPArraySectionExpr::getBaseOriginalType(E).getCanonicalType(); 18610 } else if (const auto *OASE = dyn_cast<OMPArrayShapingExpr>( 18611 SI->getAssociatedExpression())) { 18612 Type = OASE->getBase()->getType()->getPointeeType(); 18613 } 18614 if (Type.isNull() || Type->isAnyPointerType() || 18615 checkArrayExpressionDoesNotReferToWholeSize( 18616 SemaRef, SI->getAssociatedExpression(), Type)) 18617 break; 18618 } 18619 18620 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.4] 18621 // List items of map clauses in the same construct must not share 18622 // original storage. 18623 // 18624 // If the expressions are exactly the same or one is a subset of the 18625 // other, it means they are sharing storage. 18626 if (CI == CE && SI == SE) { 18627 if (CurrentRegionOnly) { 18628 if (CKind == OMPC_map) { 18629 SemaRef.Diag(ELoc, diag::err_omp_map_shared_storage) << ERange; 18630 } else { 18631 assert(CKind == OMPC_to || CKind == OMPC_from); 18632 SemaRef.Diag(ELoc, diag::err_omp_once_referenced_in_target_update) 18633 << ERange; 18634 } 18635 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here) 18636 << RE->getSourceRange(); 18637 return true; 18638 } 18639 // If we find the same expression in the enclosing data environment, 18640 // that is legal. 18641 IsEnclosedByDataEnvironmentExpr = true; 18642 return false; 18643 } 18644 18645 QualType DerivedType = 18646 std::prev(CI)->getAssociatedDeclaration()->getType(); 18647 SourceLocation DerivedLoc = 18648 std::prev(CI)->getAssociatedExpression()->getExprLoc(); 18649 18650 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1] 18651 // If the type of a list item is a reference to a type T then the type 18652 // will be considered to be T for all purposes of this clause. 18653 DerivedType = DerivedType.getNonReferenceType(); 18654 18655 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.1] 18656 // A variable for which the type is pointer and an array section 18657 // derived from that variable must not appear as list items of map 18658 // clauses of the same construct. 18659 // 18660 // Also, cover one of the cases in: 18661 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.5] 18662 // If any part of the original storage of a list item has corresponding 18663 // storage in the device data environment, all of the original storage 18664 // must have corresponding storage in the device data environment. 18665 // 18666 if (DerivedType->isAnyPointerType()) { 18667 if (CI == CE || SI == SE) { 18668 SemaRef.Diag( 18669 DerivedLoc, 18670 diag::err_omp_pointer_mapped_along_with_derived_section) 18671 << DerivedLoc; 18672 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here) 18673 << RE->getSourceRange(); 18674 return true; 18675 } 18676 if (CI->getAssociatedExpression()->getStmtClass() != 18677 SI->getAssociatedExpression()->getStmtClass() || 18678 CI->getAssociatedDeclaration()->getCanonicalDecl() == 18679 SI->getAssociatedDeclaration()->getCanonicalDecl()) { 18680 assert(CI != CE && SI != SE); 18681 SemaRef.Diag(DerivedLoc, diag::err_omp_same_pointer_dereferenced) 18682 << DerivedLoc; 18683 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here) 18684 << RE->getSourceRange(); 18685 return true; 18686 } 18687 } 18688 18689 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.4] 18690 // List items of map clauses in the same construct must not share 18691 // original storage. 18692 // 18693 // An expression is a subset of the other. 18694 if (CurrentRegionOnly && (CI == CE || SI == SE)) { 18695 if (CKind == OMPC_map) { 18696 if (CI != CE || SI != SE) { 18697 // Allow constructs like this: map(s, s.ptr[0:1]), where s.ptr is 18698 // a pointer. 18699 auto Begin = 18700 CI != CE ? CurComponents.begin() : StackComponents.begin(); 18701 auto End = CI != CE ? CurComponents.end() : StackComponents.end(); 18702 auto It = Begin; 18703 while (It != End && !It->getAssociatedDeclaration()) 18704 std::advance(It, 1); 18705 assert(It != End && 18706 "Expected at least one component with the declaration."); 18707 if (It != Begin && It->getAssociatedDeclaration() 18708 ->getType() 18709 .getCanonicalType() 18710 ->isAnyPointerType()) { 18711 IsEnclosedByDataEnvironmentExpr = false; 18712 EnclosingExpr = nullptr; 18713 return false; 18714 } 18715 } 18716 SemaRef.Diag(ELoc, diag::err_omp_map_shared_storage) << ERange; 18717 } else { 18718 assert(CKind == OMPC_to || CKind == OMPC_from); 18719 SemaRef.Diag(ELoc, diag::err_omp_once_referenced_in_target_update) 18720 << ERange; 18721 } 18722 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here) 18723 << RE->getSourceRange(); 18724 return true; 18725 } 18726 18727 // The current expression uses the same base as other expression in the 18728 // data environment but does not contain it completely. 18729 if (!CurrentRegionOnly && SI != SE) 18730 EnclosingExpr = RE; 18731 18732 // The current expression is a subset of the expression in the data 18733 // environment. 18734 IsEnclosedByDataEnvironmentExpr |= 18735 (!CurrentRegionOnly && CI != CE && SI == SE); 18736 18737 return false; 18738 }); 18739 18740 if (CurrentRegionOnly) 18741 return FoundError; 18742 18743 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.5] 18744 // If any part of the original storage of a list item has corresponding 18745 // storage in the device data environment, all of the original storage must 18746 // have corresponding storage in the device data environment. 18747 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.6] 18748 // If a list item is an element of a structure, and a different element of 18749 // the structure has a corresponding list item in the device data environment 18750 // prior to a task encountering the construct associated with the map clause, 18751 // then the list item must also have a corresponding list item in the device 18752 // data environment prior to the task encountering the construct. 18753 // 18754 if (EnclosingExpr && !IsEnclosedByDataEnvironmentExpr) { 18755 SemaRef.Diag(ELoc, 18756 diag::err_omp_original_storage_is_shared_and_does_not_contain) 18757 << ERange; 18758 SemaRef.Diag(EnclosingExpr->getExprLoc(), diag::note_used_here) 18759 << EnclosingExpr->getSourceRange(); 18760 return true; 18761 } 18762 18763 return FoundError; 18764 } 18765 18766 // Look up the user-defined mapper given the mapper name and mapped type, and 18767 // build a reference to it. 18768 static ExprResult buildUserDefinedMapperRef(Sema &SemaRef, Scope *S, 18769 CXXScopeSpec &MapperIdScopeSpec, 18770 const DeclarationNameInfo &MapperId, 18771 QualType Type, 18772 Expr *UnresolvedMapper) { 18773 if (MapperIdScopeSpec.isInvalid()) 18774 return ExprError(); 18775 // Get the actual type for the array type. 18776 if (Type->isArrayType()) { 18777 assert(Type->getAsArrayTypeUnsafe() && "Expect to get a valid array type"); 18778 Type = Type->getAsArrayTypeUnsafe()->getElementType().getCanonicalType(); 18779 } 18780 // Find all user-defined mappers with the given MapperId. 18781 SmallVector<UnresolvedSet<8>, 4> Lookups; 18782 LookupResult Lookup(SemaRef, MapperId, Sema::LookupOMPMapperName); 18783 Lookup.suppressDiagnostics(); 18784 if (S) { 18785 while (S && SemaRef.LookupParsedName(Lookup, S, &MapperIdScopeSpec)) { 18786 NamedDecl *D = Lookup.getRepresentativeDecl(); 18787 while (S && !S->isDeclScope(D)) 18788 S = S->getParent(); 18789 if (S) 18790 S = S->getParent(); 18791 Lookups.emplace_back(); 18792 Lookups.back().append(Lookup.begin(), Lookup.end()); 18793 Lookup.clear(); 18794 } 18795 } else if (auto *ULE = cast_or_null<UnresolvedLookupExpr>(UnresolvedMapper)) { 18796 // Extract the user-defined mappers with the given MapperId. 18797 Lookups.push_back(UnresolvedSet<8>()); 18798 for (NamedDecl *D : ULE->decls()) { 18799 auto *DMD = cast<OMPDeclareMapperDecl>(D); 18800 assert(DMD && "Expect valid OMPDeclareMapperDecl during instantiation."); 18801 Lookups.back().addDecl(DMD); 18802 } 18803 } 18804 // Defer the lookup for dependent types. The results will be passed through 18805 // UnresolvedMapper on instantiation. 18806 if (SemaRef.CurContext->isDependentContext() || Type->isDependentType() || 18807 Type->isInstantiationDependentType() || 18808 Type->containsUnexpandedParameterPack() || 18809 filterLookupForUDReductionAndMapper<bool>(Lookups, [](ValueDecl *D) { 18810 return !D->isInvalidDecl() && 18811 (D->getType()->isDependentType() || 18812 D->getType()->isInstantiationDependentType() || 18813 D->getType()->containsUnexpandedParameterPack()); 18814 })) { 18815 UnresolvedSet<8> URS; 18816 for (const UnresolvedSet<8> &Set : Lookups) { 18817 if (Set.empty()) 18818 continue; 18819 URS.append(Set.begin(), Set.end()); 18820 } 18821 return UnresolvedLookupExpr::Create( 18822 SemaRef.Context, /*NamingClass=*/nullptr, 18823 MapperIdScopeSpec.getWithLocInContext(SemaRef.Context), MapperId, 18824 /*ADL=*/false, /*Overloaded=*/true, URS.begin(), URS.end()); 18825 } 18826 SourceLocation Loc = MapperId.getLoc(); 18827 // [OpenMP 5.0], 2.19.7.3 declare mapper Directive, Restrictions 18828 // The type must be of struct, union or class type in C and C++ 18829 if (!Type->isStructureOrClassType() && !Type->isUnionType() && 18830 (MapperIdScopeSpec.isSet() || MapperId.getAsString() != "default")) { 18831 SemaRef.Diag(Loc, diag::err_omp_mapper_wrong_type); 18832 return ExprError(); 18833 } 18834 // Perform argument dependent lookup. 18835 if (SemaRef.getLangOpts().CPlusPlus && !MapperIdScopeSpec.isSet()) 18836 argumentDependentLookup(SemaRef, MapperId, Loc, Type, Lookups); 18837 // Return the first user-defined mapper with the desired type. 18838 if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>( 18839 Lookups, [&SemaRef, Type](ValueDecl *D) -> ValueDecl * { 18840 if (!D->isInvalidDecl() && 18841 SemaRef.Context.hasSameType(D->getType(), Type)) 18842 return D; 18843 return nullptr; 18844 })) 18845 return SemaRef.BuildDeclRefExpr(VD, Type, VK_LValue, Loc); 18846 // Find the first user-defined mapper with a type derived from the desired 18847 // type. 18848 if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>( 18849 Lookups, [&SemaRef, Type, Loc](ValueDecl *D) -> ValueDecl * { 18850 if (!D->isInvalidDecl() && 18851 SemaRef.IsDerivedFrom(Loc, Type, D->getType()) && 18852 !Type.isMoreQualifiedThan(D->getType())) 18853 return D; 18854 return nullptr; 18855 })) { 18856 CXXBasePaths Paths(/*FindAmbiguities=*/true, /*RecordPaths=*/true, 18857 /*DetectVirtual=*/false); 18858 if (SemaRef.IsDerivedFrom(Loc, Type, VD->getType(), Paths)) { 18859 if (!Paths.isAmbiguous(SemaRef.Context.getCanonicalType( 18860 VD->getType().getUnqualifiedType()))) { 18861 if (SemaRef.CheckBaseClassAccess( 18862 Loc, VD->getType(), Type, Paths.front(), 18863 /*DiagID=*/0) != Sema::AR_inaccessible) { 18864 return SemaRef.BuildDeclRefExpr(VD, Type, VK_LValue, Loc); 18865 } 18866 } 18867 } 18868 } 18869 // Report error if a mapper is specified, but cannot be found. 18870 if (MapperIdScopeSpec.isSet() || MapperId.getAsString() != "default") { 18871 SemaRef.Diag(Loc, diag::err_omp_invalid_mapper) 18872 << Type << MapperId.getName(); 18873 return ExprError(); 18874 } 18875 return ExprEmpty(); 18876 } 18877 18878 namespace { 18879 // Utility struct that gathers all the related lists associated with a mappable 18880 // expression. 18881 struct MappableVarListInfo { 18882 // The list of expressions. 18883 ArrayRef<Expr *> VarList; 18884 // The list of processed expressions. 18885 SmallVector<Expr *, 16> ProcessedVarList; 18886 // The mappble components for each expression. 18887 OMPClauseMappableExprCommon::MappableExprComponentLists VarComponents; 18888 // The base declaration of the variable. 18889 SmallVector<ValueDecl *, 16> VarBaseDeclarations; 18890 // The reference to the user-defined mapper associated with every expression. 18891 SmallVector<Expr *, 16> UDMapperList; 18892 18893 MappableVarListInfo(ArrayRef<Expr *> VarList) : VarList(VarList) { 18894 // We have a list of components and base declarations for each entry in the 18895 // variable list. 18896 VarComponents.reserve(VarList.size()); 18897 VarBaseDeclarations.reserve(VarList.size()); 18898 } 18899 }; 18900 } 18901 18902 // Check the validity of the provided variable list for the provided clause kind 18903 // \a CKind. In the check process the valid expressions, mappable expression 18904 // components, variables, and user-defined mappers are extracted and used to 18905 // fill \a ProcessedVarList, \a VarComponents, \a VarBaseDeclarations, and \a 18906 // UDMapperList in MVLI. \a MapType, \a IsMapTypeImplicit, \a MapperIdScopeSpec, 18907 // and \a MapperId are expected to be valid if the clause kind is 'map'. 18908 static void checkMappableExpressionList( 18909 Sema &SemaRef, DSAStackTy *DSAS, OpenMPClauseKind CKind, 18910 MappableVarListInfo &MVLI, SourceLocation StartLoc, 18911 CXXScopeSpec &MapperIdScopeSpec, DeclarationNameInfo MapperId, 18912 ArrayRef<Expr *> UnresolvedMappers, 18913 OpenMPMapClauseKind MapType = OMPC_MAP_unknown, 18914 bool IsMapTypeImplicit = false) { 18915 // We only expect mappable expressions in 'to', 'from', and 'map' clauses. 18916 assert((CKind == OMPC_map || CKind == OMPC_to || CKind == OMPC_from) && 18917 "Unexpected clause kind with mappable expressions!"); 18918 18919 // If the identifier of user-defined mapper is not specified, it is "default". 18920 // We do not change the actual name in this clause to distinguish whether a 18921 // mapper is specified explicitly, i.e., it is not explicitly specified when 18922 // MapperId.getName() is empty. 18923 if (!MapperId.getName() || MapperId.getName().isEmpty()) { 18924 auto &DeclNames = SemaRef.getASTContext().DeclarationNames; 18925 MapperId.setName(DeclNames.getIdentifier( 18926 &SemaRef.getASTContext().Idents.get("default"))); 18927 MapperId.setLoc(StartLoc); 18928 } 18929 18930 // Iterators to find the current unresolved mapper expression. 18931 auto UMIt = UnresolvedMappers.begin(), UMEnd = UnresolvedMappers.end(); 18932 bool UpdateUMIt = false; 18933 Expr *UnresolvedMapper = nullptr; 18934 18935 // Keep track of the mappable components and base declarations in this clause. 18936 // Each entry in the list is going to have a list of components associated. We 18937 // record each set of the components so that we can build the clause later on. 18938 // In the end we should have the same amount of declarations and component 18939 // lists. 18940 18941 for (Expr *RE : MVLI.VarList) { 18942 assert(RE && "Null expr in omp to/from/map clause"); 18943 SourceLocation ELoc = RE->getExprLoc(); 18944 18945 // Find the current unresolved mapper expression. 18946 if (UpdateUMIt && UMIt != UMEnd) { 18947 UMIt++; 18948 assert( 18949 UMIt != UMEnd && 18950 "Expect the size of UnresolvedMappers to match with that of VarList"); 18951 } 18952 UpdateUMIt = true; 18953 if (UMIt != UMEnd) 18954 UnresolvedMapper = *UMIt; 18955 18956 const Expr *VE = RE->IgnoreParenLValueCasts(); 18957 18958 if (VE->isValueDependent() || VE->isTypeDependent() || 18959 VE->isInstantiationDependent() || 18960 VE->containsUnexpandedParameterPack()) { 18961 // Try to find the associated user-defined mapper. 18962 ExprResult ER = buildUserDefinedMapperRef( 18963 SemaRef, DSAS->getCurScope(), MapperIdScopeSpec, MapperId, 18964 VE->getType().getCanonicalType(), UnresolvedMapper); 18965 if (ER.isInvalid()) 18966 continue; 18967 MVLI.UDMapperList.push_back(ER.get()); 18968 // We can only analyze this information once the missing information is 18969 // resolved. 18970 MVLI.ProcessedVarList.push_back(RE); 18971 continue; 18972 } 18973 18974 Expr *SimpleExpr = RE->IgnoreParenCasts(); 18975 18976 if (!RE->isLValue()) { 18977 if (SemaRef.getLangOpts().OpenMP < 50) { 18978 SemaRef.Diag( 18979 ELoc, diag::err_omp_expected_named_var_member_or_array_expression) 18980 << RE->getSourceRange(); 18981 } else { 18982 SemaRef.Diag(ELoc, diag::err_omp_non_lvalue_in_map_or_motion_clauses) 18983 << getOpenMPClauseName(CKind) << RE->getSourceRange(); 18984 } 18985 continue; 18986 } 18987 18988 OMPClauseMappableExprCommon::MappableExprComponentList CurComponents; 18989 ValueDecl *CurDeclaration = nullptr; 18990 18991 // Obtain the array or member expression bases if required. Also, fill the 18992 // components array with all the components identified in the process. 18993 const Expr *BE = checkMapClauseExpressionBase( 18994 SemaRef, SimpleExpr, CurComponents, CKind, DSAS->getCurrentDirective(), 18995 /*NoDiagnose=*/false); 18996 if (!BE) 18997 continue; 18998 18999 assert(!CurComponents.empty() && 19000 "Invalid mappable expression information."); 19001 19002 if (const auto *TE = dyn_cast<CXXThisExpr>(BE)) { 19003 // Add store "this" pointer to class in DSAStackTy for future checking 19004 DSAS->addMappedClassesQualTypes(TE->getType()); 19005 // Try to find the associated user-defined mapper. 19006 ExprResult ER = buildUserDefinedMapperRef( 19007 SemaRef, DSAS->getCurScope(), MapperIdScopeSpec, MapperId, 19008 VE->getType().getCanonicalType(), UnresolvedMapper); 19009 if (ER.isInvalid()) 19010 continue; 19011 MVLI.UDMapperList.push_back(ER.get()); 19012 // Skip restriction checking for variable or field declarations 19013 MVLI.ProcessedVarList.push_back(RE); 19014 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1); 19015 MVLI.VarComponents.back().append(CurComponents.begin(), 19016 CurComponents.end()); 19017 MVLI.VarBaseDeclarations.push_back(nullptr); 19018 continue; 19019 } 19020 19021 // For the following checks, we rely on the base declaration which is 19022 // expected to be associated with the last component. The declaration is 19023 // expected to be a variable or a field (if 'this' is being mapped). 19024 CurDeclaration = CurComponents.back().getAssociatedDeclaration(); 19025 assert(CurDeclaration && "Null decl on map clause."); 19026 assert( 19027 CurDeclaration->isCanonicalDecl() && 19028 "Expecting components to have associated only canonical declarations."); 19029 19030 auto *VD = dyn_cast<VarDecl>(CurDeclaration); 19031 const auto *FD = dyn_cast<FieldDecl>(CurDeclaration); 19032 19033 assert((VD || FD) && "Only variables or fields are expected here!"); 19034 (void)FD; 19035 19036 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.10] 19037 // threadprivate variables cannot appear in a map clause. 19038 // OpenMP 4.5 [2.10.5, target update Construct] 19039 // threadprivate variables cannot appear in a from clause. 19040 if (VD && DSAS->isThreadPrivate(VD)) { 19041 DSAStackTy::DSAVarData DVar = DSAS->getTopDSA(VD, /*FromParent=*/false); 19042 SemaRef.Diag(ELoc, diag::err_omp_threadprivate_in_clause) 19043 << getOpenMPClauseName(CKind); 19044 reportOriginalDsa(SemaRef, DSAS, VD, DVar); 19045 continue; 19046 } 19047 19048 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.9] 19049 // A list item cannot appear in both a map clause and a data-sharing 19050 // attribute clause on the same construct. 19051 19052 // Check conflicts with other map clause expressions. We check the conflicts 19053 // with the current construct separately from the enclosing data 19054 // environment, because the restrictions are different. We only have to 19055 // check conflicts across regions for the map clauses. 19056 if (checkMapConflicts(SemaRef, DSAS, CurDeclaration, SimpleExpr, 19057 /*CurrentRegionOnly=*/true, CurComponents, CKind)) 19058 break; 19059 if (CKind == OMPC_map && 19060 (SemaRef.getLangOpts().OpenMP <= 45 || StartLoc.isValid()) && 19061 checkMapConflicts(SemaRef, DSAS, CurDeclaration, SimpleExpr, 19062 /*CurrentRegionOnly=*/false, CurComponents, CKind)) 19063 break; 19064 19065 // OpenMP 4.5 [2.10.5, target update Construct] 19066 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1] 19067 // If the type of a list item is a reference to a type T then the type will 19068 // be considered to be T for all purposes of this clause. 19069 auto I = llvm::find_if( 19070 CurComponents, 19071 [](const OMPClauseMappableExprCommon::MappableComponent &MC) { 19072 return MC.getAssociatedDeclaration(); 19073 }); 19074 assert(I != CurComponents.end() && "Null decl on map clause."); 19075 (void)I; 19076 QualType Type; 19077 auto *ASE = dyn_cast<ArraySubscriptExpr>(VE->IgnoreParens()); 19078 auto *OASE = dyn_cast<OMPArraySectionExpr>(VE->IgnoreParens()); 19079 auto *OAShE = dyn_cast<OMPArrayShapingExpr>(VE->IgnoreParens()); 19080 if (ASE) { 19081 Type = ASE->getType().getNonReferenceType(); 19082 } else if (OASE) { 19083 QualType BaseType = 19084 OMPArraySectionExpr::getBaseOriginalType(OASE->getBase()); 19085 if (const auto *ATy = BaseType->getAsArrayTypeUnsafe()) 19086 Type = ATy->getElementType(); 19087 else 19088 Type = BaseType->getPointeeType(); 19089 Type = Type.getNonReferenceType(); 19090 } else if (OAShE) { 19091 Type = OAShE->getBase()->getType()->getPointeeType(); 19092 } else { 19093 Type = VE->getType(); 19094 } 19095 19096 // OpenMP 4.5 [2.10.5, target update Construct, Restrictions, p.4] 19097 // A list item in a to or from clause must have a mappable type. 19098 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.9] 19099 // A list item must have a mappable type. 19100 if (!checkTypeMappable(VE->getExprLoc(), VE->getSourceRange(), SemaRef, 19101 DSAS, Type)) 19102 continue; 19103 19104 if (CKind == OMPC_map) { 19105 // target enter data 19106 // OpenMP [2.10.2, Restrictions, p. 99] 19107 // A map-type must be specified in all map clauses and must be either 19108 // to or alloc. 19109 OpenMPDirectiveKind DKind = DSAS->getCurrentDirective(); 19110 if (DKind == OMPD_target_enter_data && 19111 !(MapType == OMPC_MAP_to || MapType == OMPC_MAP_alloc)) { 19112 SemaRef.Diag(StartLoc, diag::err_omp_invalid_map_type_for_directive) 19113 << (IsMapTypeImplicit ? 1 : 0) 19114 << getOpenMPSimpleClauseTypeName(OMPC_map, MapType) 19115 << getOpenMPDirectiveName(DKind); 19116 continue; 19117 } 19118 19119 // target exit_data 19120 // OpenMP [2.10.3, Restrictions, p. 102] 19121 // A map-type must be specified in all map clauses and must be either 19122 // from, release, or delete. 19123 if (DKind == OMPD_target_exit_data && 19124 !(MapType == OMPC_MAP_from || MapType == OMPC_MAP_release || 19125 MapType == OMPC_MAP_delete)) { 19126 SemaRef.Diag(StartLoc, diag::err_omp_invalid_map_type_for_directive) 19127 << (IsMapTypeImplicit ? 1 : 0) 19128 << getOpenMPSimpleClauseTypeName(OMPC_map, MapType) 19129 << getOpenMPDirectiveName(DKind); 19130 continue; 19131 } 19132 19133 // target, target data 19134 // OpenMP 5.0 [2.12.2, Restrictions, p. 163] 19135 // OpenMP 5.0 [2.12.5, Restrictions, p. 174] 19136 // A map-type in a map clause must be to, from, tofrom or alloc 19137 if ((DKind == OMPD_target_data || 19138 isOpenMPTargetExecutionDirective(DKind)) && 19139 !(MapType == OMPC_MAP_to || MapType == OMPC_MAP_from || 19140 MapType == OMPC_MAP_tofrom || MapType == OMPC_MAP_alloc)) { 19141 SemaRef.Diag(StartLoc, diag::err_omp_invalid_map_type_for_directive) 19142 << (IsMapTypeImplicit ? 1 : 0) 19143 << getOpenMPSimpleClauseTypeName(OMPC_map, MapType) 19144 << getOpenMPDirectiveName(DKind); 19145 continue; 19146 } 19147 19148 // OpenMP 4.5 [2.15.5.1, Restrictions, p.3] 19149 // A list item cannot appear in both a map clause and a data-sharing 19150 // attribute clause on the same construct 19151 // 19152 // OpenMP 5.0 [2.19.7.1, Restrictions, p.7] 19153 // A list item cannot appear in both a map clause and a data-sharing 19154 // attribute clause on the same construct unless the construct is a 19155 // combined construct. 19156 if (VD && ((SemaRef.LangOpts.OpenMP <= 45 && 19157 isOpenMPTargetExecutionDirective(DKind)) || 19158 DKind == OMPD_target)) { 19159 DSAStackTy::DSAVarData DVar = DSAS->getTopDSA(VD, /*FromParent=*/false); 19160 if (isOpenMPPrivate(DVar.CKind)) { 19161 SemaRef.Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa) 19162 << getOpenMPClauseName(DVar.CKind) 19163 << getOpenMPClauseName(OMPC_map) 19164 << getOpenMPDirectiveName(DSAS->getCurrentDirective()); 19165 reportOriginalDsa(SemaRef, DSAS, CurDeclaration, DVar); 19166 continue; 19167 } 19168 } 19169 } 19170 19171 // Try to find the associated user-defined mapper. 19172 ExprResult ER = buildUserDefinedMapperRef( 19173 SemaRef, DSAS->getCurScope(), MapperIdScopeSpec, MapperId, 19174 Type.getCanonicalType(), UnresolvedMapper); 19175 if (ER.isInvalid()) 19176 continue; 19177 MVLI.UDMapperList.push_back(ER.get()); 19178 19179 // Save the current expression. 19180 MVLI.ProcessedVarList.push_back(RE); 19181 19182 // Store the components in the stack so that they can be used to check 19183 // against other clauses later on. 19184 DSAS->addMappableExpressionComponents(CurDeclaration, CurComponents, 19185 /*WhereFoundClauseKind=*/OMPC_map); 19186 19187 // Save the components and declaration to create the clause. For purposes of 19188 // the clause creation, any component list that has has base 'this' uses 19189 // null as base declaration. 19190 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1); 19191 MVLI.VarComponents.back().append(CurComponents.begin(), 19192 CurComponents.end()); 19193 MVLI.VarBaseDeclarations.push_back(isa<MemberExpr>(BE) ? nullptr 19194 : CurDeclaration); 19195 } 19196 } 19197 19198 OMPClause *Sema::ActOnOpenMPMapClause( 19199 ArrayRef<OpenMPMapModifierKind> MapTypeModifiers, 19200 ArrayRef<SourceLocation> MapTypeModifiersLoc, 19201 CXXScopeSpec &MapperIdScopeSpec, DeclarationNameInfo &MapperId, 19202 OpenMPMapClauseKind MapType, bool IsMapTypeImplicit, SourceLocation MapLoc, 19203 SourceLocation ColonLoc, ArrayRef<Expr *> VarList, 19204 const OMPVarListLocTy &Locs, ArrayRef<Expr *> UnresolvedMappers) { 19205 OpenMPMapModifierKind Modifiers[] = { 19206 OMPC_MAP_MODIFIER_unknown, OMPC_MAP_MODIFIER_unknown, 19207 OMPC_MAP_MODIFIER_unknown, OMPC_MAP_MODIFIER_unknown}; 19208 SourceLocation ModifiersLoc[NumberOfOMPMapClauseModifiers]; 19209 19210 // Process map-type-modifiers, flag errors for duplicate modifiers. 19211 unsigned Count = 0; 19212 for (unsigned I = 0, E = MapTypeModifiers.size(); I < E; ++I) { 19213 if (MapTypeModifiers[I] != OMPC_MAP_MODIFIER_unknown && 19214 llvm::find(Modifiers, MapTypeModifiers[I]) != std::end(Modifiers)) { 19215 Diag(MapTypeModifiersLoc[I], diag::err_omp_duplicate_map_type_modifier); 19216 continue; 19217 } 19218 assert(Count < NumberOfOMPMapClauseModifiers && 19219 "Modifiers exceed the allowed number of map type modifiers"); 19220 Modifiers[Count] = MapTypeModifiers[I]; 19221 ModifiersLoc[Count] = MapTypeModifiersLoc[I]; 19222 ++Count; 19223 } 19224 19225 MappableVarListInfo MVLI(VarList); 19226 checkMappableExpressionList(*this, DSAStack, OMPC_map, MVLI, Locs.StartLoc, 19227 MapperIdScopeSpec, MapperId, UnresolvedMappers, 19228 MapType, IsMapTypeImplicit); 19229 19230 // We need to produce a map clause even if we don't have variables so that 19231 // other diagnostics related with non-existing map clauses are accurate. 19232 return OMPMapClause::Create(Context, Locs, MVLI.ProcessedVarList, 19233 MVLI.VarBaseDeclarations, MVLI.VarComponents, 19234 MVLI.UDMapperList, Modifiers, ModifiersLoc, 19235 MapperIdScopeSpec.getWithLocInContext(Context), 19236 MapperId, MapType, IsMapTypeImplicit, MapLoc); 19237 } 19238 19239 QualType Sema::ActOnOpenMPDeclareReductionType(SourceLocation TyLoc, 19240 TypeResult ParsedType) { 19241 assert(ParsedType.isUsable()); 19242 19243 QualType ReductionType = GetTypeFromParser(ParsedType.get()); 19244 if (ReductionType.isNull()) 19245 return QualType(); 19246 19247 // [OpenMP 4.0], 2.15 declare reduction Directive, Restrictions, C\C++ 19248 // A type name in a declare reduction directive cannot be a function type, an 19249 // array type, a reference type, or a type qualified with const, volatile or 19250 // restrict. 19251 if (ReductionType.hasQualifiers()) { 19252 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 0; 19253 return QualType(); 19254 } 19255 19256 if (ReductionType->isFunctionType()) { 19257 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 1; 19258 return QualType(); 19259 } 19260 if (ReductionType->isReferenceType()) { 19261 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 2; 19262 return QualType(); 19263 } 19264 if (ReductionType->isArrayType()) { 19265 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 3; 19266 return QualType(); 19267 } 19268 return ReductionType; 19269 } 19270 19271 Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareReductionDirectiveStart( 19272 Scope *S, DeclContext *DC, DeclarationName Name, 19273 ArrayRef<std::pair<QualType, SourceLocation>> ReductionTypes, 19274 AccessSpecifier AS, Decl *PrevDeclInScope) { 19275 SmallVector<Decl *, 8> Decls; 19276 Decls.reserve(ReductionTypes.size()); 19277 19278 LookupResult Lookup(*this, Name, SourceLocation(), LookupOMPReductionName, 19279 forRedeclarationInCurContext()); 19280 // [OpenMP 4.0], 2.15 declare reduction Directive, Restrictions 19281 // A reduction-identifier may not be re-declared in the current scope for the 19282 // same type or for a type that is compatible according to the base language 19283 // rules. 19284 llvm::DenseMap<QualType, SourceLocation> PreviousRedeclTypes; 19285 OMPDeclareReductionDecl *PrevDRD = nullptr; 19286 bool InCompoundScope = true; 19287 if (S != nullptr) { 19288 // Find previous declaration with the same name not referenced in other 19289 // declarations. 19290 FunctionScopeInfo *ParentFn = getEnclosingFunction(); 19291 InCompoundScope = 19292 (ParentFn != nullptr) && !ParentFn->CompoundScopes.empty(); 19293 LookupName(Lookup, S); 19294 FilterLookupForScope(Lookup, DC, S, /*ConsiderLinkage=*/false, 19295 /*AllowInlineNamespace=*/false); 19296 llvm::DenseMap<OMPDeclareReductionDecl *, bool> UsedAsPrevious; 19297 LookupResult::Filter Filter = Lookup.makeFilter(); 19298 while (Filter.hasNext()) { 19299 auto *PrevDecl = cast<OMPDeclareReductionDecl>(Filter.next()); 19300 if (InCompoundScope) { 19301 auto I = UsedAsPrevious.find(PrevDecl); 19302 if (I == UsedAsPrevious.end()) 19303 UsedAsPrevious[PrevDecl] = false; 19304 if (OMPDeclareReductionDecl *D = PrevDecl->getPrevDeclInScope()) 19305 UsedAsPrevious[D] = true; 19306 } 19307 PreviousRedeclTypes[PrevDecl->getType().getCanonicalType()] = 19308 PrevDecl->getLocation(); 19309 } 19310 Filter.done(); 19311 if (InCompoundScope) { 19312 for (const auto &PrevData : UsedAsPrevious) { 19313 if (!PrevData.second) { 19314 PrevDRD = PrevData.first; 19315 break; 19316 } 19317 } 19318 } 19319 } else if (PrevDeclInScope != nullptr) { 19320 auto *PrevDRDInScope = PrevDRD = 19321 cast<OMPDeclareReductionDecl>(PrevDeclInScope); 19322 do { 19323 PreviousRedeclTypes[PrevDRDInScope->getType().getCanonicalType()] = 19324 PrevDRDInScope->getLocation(); 19325 PrevDRDInScope = PrevDRDInScope->getPrevDeclInScope(); 19326 } while (PrevDRDInScope != nullptr); 19327 } 19328 for (const auto &TyData : ReductionTypes) { 19329 const auto I = PreviousRedeclTypes.find(TyData.first.getCanonicalType()); 19330 bool Invalid = false; 19331 if (I != PreviousRedeclTypes.end()) { 19332 Diag(TyData.second, diag::err_omp_declare_reduction_redefinition) 19333 << TyData.first; 19334 Diag(I->second, diag::note_previous_definition); 19335 Invalid = true; 19336 } 19337 PreviousRedeclTypes[TyData.first.getCanonicalType()] = TyData.second; 19338 auto *DRD = OMPDeclareReductionDecl::Create(Context, DC, TyData.second, 19339 Name, TyData.first, PrevDRD); 19340 DC->addDecl(DRD); 19341 DRD->setAccess(AS); 19342 Decls.push_back(DRD); 19343 if (Invalid) 19344 DRD->setInvalidDecl(); 19345 else 19346 PrevDRD = DRD; 19347 } 19348 19349 return DeclGroupPtrTy::make( 19350 DeclGroupRef::Create(Context, Decls.begin(), Decls.size())); 19351 } 19352 19353 void Sema::ActOnOpenMPDeclareReductionCombinerStart(Scope *S, Decl *D) { 19354 auto *DRD = cast<OMPDeclareReductionDecl>(D); 19355 19356 // Enter new function scope. 19357 PushFunctionScope(); 19358 setFunctionHasBranchProtectedScope(); 19359 getCurFunction()->setHasOMPDeclareReductionCombiner(); 19360 19361 if (S != nullptr) 19362 PushDeclContext(S, DRD); 19363 else 19364 CurContext = DRD; 19365 19366 PushExpressionEvaluationContext( 19367 ExpressionEvaluationContext::PotentiallyEvaluated); 19368 19369 QualType ReductionType = DRD->getType(); 19370 // Create 'T* omp_parm;T omp_in;'. All references to 'omp_in' will 19371 // be replaced by '*omp_parm' during codegen. This required because 'omp_in' 19372 // uses semantics of argument handles by value, but it should be passed by 19373 // reference. C lang does not support references, so pass all parameters as 19374 // pointers. 19375 // Create 'T omp_in;' variable. 19376 VarDecl *OmpInParm = 19377 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_in"); 19378 // Create 'T* omp_parm;T omp_out;'. All references to 'omp_out' will 19379 // be replaced by '*omp_parm' during codegen. This required because 'omp_out' 19380 // uses semantics of argument handles by value, but it should be passed by 19381 // reference. C lang does not support references, so pass all parameters as 19382 // pointers. 19383 // Create 'T omp_out;' variable. 19384 VarDecl *OmpOutParm = 19385 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_out"); 19386 if (S != nullptr) { 19387 PushOnScopeChains(OmpInParm, S); 19388 PushOnScopeChains(OmpOutParm, S); 19389 } else { 19390 DRD->addDecl(OmpInParm); 19391 DRD->addDecl(OmpOutParm); 19392 } 19393 Expr *InE = 19394 ::buildDeclRefExpr(*this, OmpInParm, ReductionType, D->getLocation()); 19395 Expr *OutE = 19396 ::buildDeclRefExpr(*this, OmpOutParm, ReductionType, D->getLocation()); 19397 DRD->setCombinerData(InE, OutE); 19398 } 19399 19400 void Sema::ActOnOpenMPDeclareReductionCombinerEnd(Decl *D, Expr *Combiner) { 19401 auto *DRD = cast<OMPDeclareReductionDecl>(D); 19402 DiscardCleanupsInEvaluationContext(); 19403 PopExpressionEvaluationContext(); 19404 19405 PopDeclContext(); 19406 PopFunctionScopeInfo(); 19407 19408 if (Combiner != nullptr) 19409 DRD->setCombiner(Combiner); 19410 else 19411 DRD->setInvalidDecl(); 19412 } 19413 19414 VarDecl *Sema::ActOnOpenMPDeclareReductionInitializerStart(Scope *S, Decl *D) { 19415 auto *DRD = cast<OMPDeclareReductionDecl>(D); 19416 19417 // Enter new function scope. 19418 PushFunctionScope(); 19419 setFunctionHasBranchProtectedScope(); 19420 19421 if (S != nullptr) 19422 PushDeclContext(S, DRD); 19423 else 19424 CurContext = DRD; 19425 19426 PushExpressionEvaluationContext( 19427 ExpressionEvaluationContext::PotentiallyEvaluated); 19428 19429 QualType ReductionType = DRD->getType(); 19430 // Create 'T* omp_parm;T omp_priv;'. All references to 'omp_priv' will 19431 // be replaced by '*omp_parm' during codegen. This required because 'omp_priv' 19432 // uses semantics of argument handles by value, but it should be passed by 19433 // reference. C lang does not support references, so pass all parameters as 19434 // pointers. 19435 // Create 'T omp_priv;' variable. 19436 VarDecl *OmpPrivParm = 19437 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_priv"); 19438 // Create 'T* omp_parm;T omp_orig;'. All references to 'omp_orig' will 19439 // be replaced by '*omp_parm' during codegen. This required because 'omp_orig' 19440 // uses semantics of argument handles by value, but it should be passed by 19441 // reference. C lang does not support references, so pass all parameters as 19442 // pointers. 19443 // Create 'T omp_orig;' variable. 19444 VarDecl *OmpOrigParm = 19445 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_orig"); 19446 if (S != nullptr) { 19447 PushOnScopeChains(OmpPrivParm, S); 19448 PushOnScopeChains(OmpOrigParm, S); 19449 } else { 19450 DRD->addDecl(OmpPrivParm); 19451 DRD->addDecl(OmpOrigParm); 19452 } 19453 Expr *OrigE = 19454 ::buildDeclRefExpr(*this, OmpOrigParm, ReductionType, D->getLocation()); 19455 Expr *PrivE = 19456 ::buildDeclRefExpr(*this, OmpPrivParm, ReductionType, D->getLocation()); 19457 DRD->setInitializerData(OrigE, PrivE); 19458 return OmpPrivParm; 19459 } 19460 19461 void Sema::ActOnOpenMPDeclareReductionInitializerEnd(Decl *D, Expr *Initializer, 19462 VarDecl *OmpPrivParm) { 19463 auto *DRD = cast<OMPDeclareReductionDecl>(D); 19464 DiscardCleanupsInEvaluationContext(); 19465 PopExpressionEvaluationContext(); 19466 19467 PopDeclContext(); 19468 PopFunctionScopeInfo(); 19469 19470 if (Initializer != nullptr) { 19471 DRD->setInitializer(Initializer, OMPDeclareReductionDecl::CallInit); 19472 } else if (OmpPrivParm->hasInit()) { 19473 DRD->setInitializer(OmpPrivParm->getInit(), 19474 OmpPrivParm->isDirectInit() 19475 ? OMPDeclareReductionDecl::DirectInit 19476 : OMPDeclareReductionDecl::CopyInit); 19477 } else { 19478 DRD->setInvalidDecl(); 19479 } 19480 } 19481 19482 Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareReductionDirectiveEnd( 19483 Scope *S, DeclGroupPtrTy DeclReductions, bool IsValid) { 19484 for (Decl *D : DeclReductions.get()) { 19485 if (IsValid) { 19486 if (S) 19487 PushOnScopeChains(cast<OMPDeclareReductionDecl>(D), S, 19488 /*AddToContext=*/false); 19489 } else { 19490 D->setInvalidDecl(); 19491 } 19492 } 19493 return DeclReductions; 19494 } 19495 19496 TypeResult Sema::ActOnOpenMPDeclareMapperVarDecl(Scope *S, Declarator &D) { 19497 TypeSourceInfo *TInfo = GetTypeForDeclarator(D, S); 19498 QualType T = TInfo->getType(); 19499 if (D.isInvalidType()) 19500 return true; 19501 19502 if (getLangOpts().CPlusPlus) { 19503 // Check that there are no default arguments (C++ only). 19504 CheckExtraCXXDefaultArguments(D); 19505 } 19506 19507 return CreateParsedType(T, TInfo); 19508 } 19509 19510 QualType Sema::ActOnOpenMPDeclareMapperType(SourceLocation TyLoc, 19511 TypeResult ParsedType) { 19512 assert(ParsedType.isUsable() && "Expect usable parsed mapper type"); 19513 19514 QualType MapperType = GetTypeFromParser(ParsedType.get()); 19515 assert(!MapperType.isNull() && "Expect valid mapper type"); 19516 19517 // [OpenMP 5.0], 2.19.7.3 declare mapper Directive, Restrictions 19518 // The type must be of struct, union or class type in C and C++ 19519 if (!MapperType->isStructureOrClassType() && !MapperType->isUnionType()) { 19520 Diag(TyLoc, diag::err_omp_mapper_wrong_type); 19521 return QualType(); 19522 } 19523 return MapperType; 19524 } 19525 19526 Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareMapperDirective( 19527 Scope *S, DeclContext *DC, DeclarationName Name, QualType MapperType, 19528 SourceLocation StartLoc, DeclarationName VN, AccessSpecifier AS, 19529 Expr *MapperVarRef, ArrayRef<OMPClause *> Clauses, Decl *PrevDeclInScope) { 19530 LookupResult Lookup(*this, Name, SourceLocation(), LookupOMPMapperName, 19531 forRedeclarationInCurContext()); 19532 // [OpenMP 5.0], 2.19.7.3 declare mapper Directive, Restrictions 19533 // A mapper-identifier may not be redeclared in the current scope for the 19534 // same type or for a type that is compatible according to the base language 19535 // rules. 19536 llvm::DenseMap<QualType, SourceLocation> PreviousRedeclTypes; 19537 OMPDeclareMapperDecl *PrevDMD = nullptr; 19538 bool InCompoundScope = true; 19539 if (S != nullptr) { 19540 // Find previous declaration with the same name not referenced in other 19541 // declarations. 19542 FunctionScopeInfo *ParentFn = getEnclosingFunction(); 19543 InCompoundScope = 19544 (ParentFn != nullptr) && !ParentFn->CompoundScopes.empty(); 19545 LookupName(Lookup, S); 19546 FilterLookupForScope(Lookup, DC, S, /*ConsiderLinkage=*/false, 19547 /*AllowInlineNamespace=*/false); 19548 llvm::DenseMap<OMPDeclareMapperDecl *, bool> UsedAsPrevious; 19549 LookupResult::Filter Filter = Lookup.makeFilter(); 19550 while (Filter.hasNext()) { 19551 auto *PrevDecl = cast<OMPDeclareMapperDecl>(Filter.next()); 19552 if (InCompoundScope) { 19553 auto I = UsedAsPrevious.find(PrevDecl); 19554 if (I == UsedAsPrevious.end()) 19555 UsedAsPrevious[PrevDecl] = false; 19556 if (OMPDeclareMapperDecl *D = PrevDecl->getPrevDeclInScope()) 19557 UsedAsPrevious[D] = true; 19558 } 19559 PreviousRedeclTypes[PrevDecl->getType().getCanonicalType()] = 19560 PrevDecl->getLocation(); 19561 } 19562 Filter.done(); 19563 if (InCompoundScope) { 19564 for (const auto &PrevData : UsedAsPrevious) { 19565 if (!PrevData.second) { 19566 PrevDMD = PrevData.first; 19567 break; 19568 } 19569 } 19570 } 19571 } else if (PrevDeclInScope) { 19572 auto *PrevDMDInScope = PrevDMD = 19573 cast<OMPDeclareMapperDecl>(PrevDeclInScope); 19574 do { 19575 PreviousRedeclTypes[PrevDMDInScope->getType().getCanonicalType()] = 19576 PrevDMDInScope->getLocation(); 19577 PrevDMDInScope = PrevDMDInScope->getPrevDeclInScope(); 19578 } while (PrevDMDInScope != nullptr); 19579 } 19580 const auto I = PreviousRedeclTypes.find(MapperType.getCanonicalType()); 19581 bool Invalid = false; 19582 if (I != PreviousRedeclTypes.end()) { 19583 Diag(StartLoc, diag::err_omp_declare_mapper_redefinition) 19584 << MapperType << Name; 19585 Diag(I->second, diag::note_previous_definition); 19586 Invalid = true; 19587 } 19588 // Build expressions for implicit maps of data members with 'default' 19589 // mappers. 19590 SmallVector<OMPClause *, 4> ClausesWithImplicit(Clauses.begin(), 19591 Clauses.end()); 19592 if (LangOpts.OpenMP >= 50) 19593 processImplicitMapsWithDefaultMappers(*this, DSAStack, ClausesWithImplicit); 19594 auto *DMD = 19595 OMPDeclareMapperDecl::Create(Context, DC, StartLoc, Name, MapperType, VN, 19596 ClausesWithImplicit, PrevDMD); 19597 if (S) 19598 PushOnScopeChains(DMD, S); 19599 else 19600 DC->addDecl(DMD); 19601 DMD->setAccess(AS); 19602 if (Invalid) 19603 DMD->setInvalidDecl(); 19604 19605 auto *VD = cast<DeclRefExpr>(MapperVarRef)->getDecl(); 19606 VD->setDeclContext(DMD); 19607 VD->setLexicalDeclContext(DMD); 19608 DMD->addDecl(VD); 19609 DMD->setMapperVarRef(MapperVarRef); 19610 19611 return DeclGroupPtrTy::make(DeclGroupRef(DMD)); 19612 } 19613 19614 ExprResult 19615 Sema::ActOnOpenMPDeclareMapperDirectiveVarDecl(Scope *S, QualType MapperType, 19616 SourceLocation StartLoc, 19617 DeclarationName VN) { 19618 TypeSourceInfo *TInfo = 19619 Context.getTrivialTypeSourceInfo(MapperType, StartLoc); 19620 auto *VD = VarDecl::Create(Context, Context.getTranslationUnitDecl(), 19621 StartLoc, StartLoc, VN.getAsIdentifierInfo(), 19622 MapperType, TInfo, SC_None); 19623 if (S) 19624 PushOnScopeChains(VD, S, /*AddToContext=*/false); 19625 Expr *E = buildDeclRefExpr(*this, VD, MapperType, StartLoc); 19626 DSAStack->addDeclareMapperVarRef(E); 19627 return E; 19628 } 19629 19630 bool Sema::isOpenMPDeclareMapperVarDeclAllowed(const VarDecl *VD) const { 19631 assert(LangOpts.OpenMP && "Expected OpenMP mode."); 19632 const Expr *Ref = DSAStack->getDeclareMapperVarRef(); 19633 if (const auto *DRE = cast_or_null<DeclRefExpr>(Ref)) 19634 return VD->getCanonicalDecl() == DRE->getDecl()->getCanonicalDecl(); 19635 return true; 19636 } 19637 19638 const ValueDecl *Sema::getOpenMPDeclareMapperVarName() const { 19639 assert(LangOpts.OpenMP && "Expected OpenMP mode."); 19640 return cast<DeclRefExpr>(DSAStack->getDeclareMapperVarRef())->getDecl(); 19641 } 19642 19643 OMPClause *Sema::ActOnOpenMPNumTeamsClause(Expr *NumTeams, 19644 SourceLocation StartLoc, 19645 SourceLocation LParenLoc, 19646 SourceLocation EndLoc) { 19647 Expr *ValExpr = NumTeams; 19648 Stmt *HelperValStmt = nullptr; 19649 19650 // OpenMP [teams Constrcut, Restrictions] 19651 // The num_teams expression must evaluate to a positive integer value. 19652 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_num_teams, 19653 /*StrictlyPositive=*/true)) 19654 return nullptr; 19655 19656 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 19657 OpenMPDirectiveKind CaptureRegion = 19658 getOpenMPCaptureRegionForClause(DKind, OMPC_num_teams, LangOpts.OpenMP); 19659 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 19660 ValExpr = MakeFullExpr(ValExpr).get(); 19661 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 19662 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 19663 HelperValStmt = buildPreInits(Context, Captures); 19664 } 19665 19666 return new (Context) OMPNumTeamsClause(ValExpr, HelperValStmt, CaptureRegion, 19667 StartLoc, LParenLoc, EndLoc); 19668 } 19669 19670 OMPClause *Sema::ActOnOpenMPThreadLimitClause(Expr *ThreadLimit, 19671 SourceLocation StartLoc, 19672 SourceLocation LParenLoc, 19673 SourceLocation EndLoc) { 19674 Expr *ValExpr = ThreadLimit; 19675 Stmt *HelperValStmt = nullptr; 19676 19677 // OpenMP [teams Constrcut, Restrictions] 19678 // The thread_limit expression must evaluate to a positive integer value. 19679 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_thread_limit, 19680 /*StrictlyPositive=*/true)) 19681 return nullptr; 19682 19683 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 19684 OpenMPDirectiveKind CaptureRegion = getOpenMPCaptureRegionForClause( 19685 DKind, OMPC_thread_limit, LangOpts.OpenMP); 19686 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 19687 ValExpr = MakeFullExpr(ValExpr).get(); 19688 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 19689 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 19690 HelperValStmt = buildPreInits(Context, Captures); 19691 } 19692 19693 return new (Context) OMPThreadLimitClause( 19694 ValExpr, HelperValStmt, CaptureRegion, StartLoc, LParenLoc, EndLoc); 19695 } 19696 19697 OMPClause *Sema::ActOnOpenMPPriorityClause(Expr *Priority, 19698 SourceLocation StartLoc, 19699 SourceLocation LParenLoc, 19700 SourceLocation EndLoc) { 19701 Expr *ValExpr = Priority; 19702 Stmt *HelperValStmt = nullptr; 19703 OpenMPDirectiveKind CaptureRegion = OMPD_unknown; 19704 19705 // OpenMP [2.9.1, task Constrcut] 19706 // The priority-value is a non-negative numerical scalar expression. 19707 if (!isNonNegativeIntegerValue( 19708 ValExpr, *this, OMPC_priority, 19709 /*StrictlyPositive=*/false, /*BuildCapture=*/true, 19710 DSAStack->getCurrentDirective(), &CaptureRegion, &HelperValStmt)) 19711 return nullptr; 19712 19713 return new (Context) OMPPriorityClause(ValExpr, HelperValStmt, CaptureRegion, 19714 StartLoc, LParenLoc, EndLoc); 19715 } 19716 19717 OMPClause *Sema::ActOnOpenMPGrainsizeClause(Expr *Grainsize, 19718 SourceLocation StartLoc, 19719 SourceLocation LParenLoc, 19720 SourceLocation EndLoc) { 19721 Expr *ValExpr = Grainsize; 19722 Stmt *HelperValStmt = nullptr; 19723 OpenMPDirectiveKind CaptureRegion = OMPD_unknown; 19724 19725 // OpenMP [2.9.2, taskloop Constrcut] 19726 // The parameter of the grainsize clause must be a positive integer 19727 // expression. 19728 if (!isNonNegativeIntegerValue( 19729 ValExpr, *this, OMPC_grainsize, 19730 /*StrictlyPositive=*/true, /*BuildCapture=*/true, 19731 DSAStack->getCurrentDirective(), &CaptureRegion, &HelperValStmt)) 19732 return nullptr; 19733 19734 return new (Context) OMPGrainsizeClause(ValExpr, HelperValStmt, CaptureRegion, 19735 StartLoc, LParenLoc, EndLoc); 19736 } 19737 19738 OMPClause *Sema::ActOnOpenMPNumTasksClause(Expr *NumTasks, 19739 SourceLocation StartLoc, 19740 SourceLocation LParenLoc, 19741 SourceLocation EndLoc) { 19742 Expr *ValExpr = NumTasks; 19743 Stmt *HelperValStmt = nullptr; 19744 OpenMPDirectiveKind CaptureRegion = OMPD_unknown; 19745 19746 // OpenMP [2.9.2, taskloop Constrcut] 19747 // The parameter of the num_tasks clause must be a positive integer 19748 // expression. 19749 if (!isNonNegativeIntegerValue( 19750 ValExpr, *this, OMPC_num_tasks, 19751 /*StrictlyPositive=*/true, /*BuildCapture=*/true, 19752 DSAStack->getCurrentDirective(), &CaptureRegion, &HelperValStmt)) 19753 return nullptr; 19754 19755 return new (Context) OMPNumTasksClause(ValExpr, HelperValStmt, CaptureRegion, 19756 StartLoc, LParenLoc, EndLoc); 19757 } 19758 19759 OMPClause *Sema::ActOnOpenMPHintClause(Expr *Hint, SourceLocation StartLoc, 19760 SourceLocation LParenLoc, 19761 SourceLocation EndLoc) { 19762 // OpenMP [2.13.2, critical construct, Description] 19763 // ... where hint-expression is an integer constant expression that evaluates 19764 // to a valid lock hint. 19765 ExprResult HintExpr = VerifyPositiveIntegerConstantInClause(Hint, OMPC_hint); 19766 if (HintExpr.isInvalid()) 19767 return nullptr; 19768 return new (Context) 19769 OMPHintClause(HintExpr.get(), StartLoc, LParenLoc, EndLoc); 19770 } 19771 19772 /// Tries to find omp_event_handle_t type. 19773 static bool findOMPEventHandleT(Sema &S, SourceLocation Loc, 19774 DSAStackTy *Stack) { 19775 QualType OMPEventHandleT = Stack->getOMPEventHandleT(); 19776 if (!OMPEventHandleT.isNull()) 19777 return true; 19778 IdentifierInfo *II = &S.PP.getIdentifierTable().get("omp_event_handle_t"); 19779 ParsedType PT = S.getTypeName(*II, Loc, S.getCurScope()); 19780 if (!PT.getAsOpaquePtr() || PT.get().isNull()) { 19781 S.Diag(Loc, diag::err_omp_implied_type_not_found) << "omp_event_handle_t"; 19782 return false; 19783 } 19784 Stack->setOMPEventHandleT(PT.get()); 19785 return true; 19786 } 19787 19788 OMPClause *Sema::ActOnOpenMPDetachClause(Expr *Evt, SourceLocation StartLoc, 19789 SourceLocation LParenLoc, 19790 SourceLocation EndLoc) { 19791 if (!Evt->isValueDependent() && !Evt->isTypeDependent() && 19792 !Evt->isInstantiationDependent() && 19793 !Evt->containsUnexpandedParameterPack()) { 19794 if (!findOMPEventHandleT(*this, Evt->getExprLoc(), DSAStack)) 19795 return nullptr; 19796 // OpenMP 5.0, 2.10.1 task Construct. 19797 // event-handle is a variable of the omp_event_handle_t type. 19798 auto *Ref = dyn_cast<DeclRefExpr>(Evt->IgnoreParenImpCasts()); 19799 if (!Ref) { 19800 Diag(Evt->getExprLoc(), diag::err_omp_var_expected) 19801 << "omp_event_handle_t" << 0 << Evt->getSourceRange(); 19802 return nullptr; 19803 } 19804 auto *VD = dyn_cast_or_null<VarDecl>(Ref->getDecl()); 19805 if (!VD) { 19806 Diag(Evt->getExprLoc(), diag::err_omp_var_expected) 19807 << "omp_event_handle_t" << 0 << Evt->getSourceRange(); 19808 return nullptr; 19809 } 19810 if (!Context.hasSameUnqualifiedType(DSAStack->getOMPEventHandleT(), 19811 VD->getType()) || 19812 VD->getType().isConstant(Context)) { 19813 Diag(Evt->getExprLoc(), diag::err_omp_var_expected) 19814 << "omp_event_handle_t" << 1 << VD->getType() 19815 << Evt->getSourceRange(); 19816 return nullptr; 19817 } 19818 // OpenMP 5.0, 2.10.1 task Construct 19819 // [detach clause]... The event-handle will be considered as if it was 19820 // specified on a firstprivate clause. 19821 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(VD, /*FromParent=*/false); 19822 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_firstprivate && 19823 DVar.RefExpr) { 19824 Diag(Evt->getExprLoc(), diag::err_omp_wrong_dsa) 19825 << getOpenMPClauseName(DVar.CKind) 19826 << getOpenMPClauseName(OMPC_firstprivate); 19827 reportOriginalDsa(*this, DSAStack, VD, DVar); 19828 return nullptr; 19829 } 19830 } 19831 19832 return new (Context) OMPDetachClause(Evt, StartLoc, LParenLoc, EndLoc); 19833 } 19834 19835 OMPClause *Sema::ActOnOpenMPDistScheduleClause( 19836 OpenMPDistScheduleClauseKind Kind, Expr *ChunkSize, SourceLocation StartLoc, 19837 SourceLocation LParenLoc, SourceLocation KindLoc, SourceLocation CommaLoc, 19838 SourceLocation EndLoc) { 19839 if (Kind == OMPC_DIST_SCHEDULE_unknown) { 19840 std::string Values; 19841 Values += "'"; 19842 Values += getOpenMPSimpleClauseTypeName(OMPC_dist_schedule, 0); 19843 Values += "'"; 19844 Diag(KindLoc, diag::err_omp_unexpected_clause_value) 19845 << Values << getOpenMPClauseName(OMPC_dist_schedule); 19846 return nullptr; 19847 } 19848 Expr *ValExpr = ChunkSize; 19849 Stmt *HelperValStmt = nullptr; 19850 if (ChunkSize) { 19851 if (!ChunkSize->isValueDependent() && !ChunkSize->isTypeDependent() && 19852 !ChunkSize->isInstantiationDependent() && 19853 !ChunkSize->containsUnexpandedParameterPack()) { 19854 SourceLocation ChunkSizeLoc = ChunkSize->getBeginLoc(); 19855 ExprResult Val = 19856 PerformOpenMPImplicitIntegerConversion(ChunkSizeLoc, ChunkSize); 19857 if (Val.isInvalid()) 19858 return nullptr; 19859 19860 ValExpr = Val.get(); 19861 19862 // OpenMP [2.7.1, Restrictions] 19863 // chunk_size must be a loop invariant integer expression with a positive 19864 // value. 19865 if (Optional<llvm::APSInt> Result = 19866 ValExpr->getIntegerConstantExpr(Context)) { 19867 if (Result->isSigned() && !Result->isStrictlyPositive()) { 19868 Diag(ChunkSizeLoc, diag::err_omp_negative_expression_in_clause) 19869 << "dist_schedule" << ChunkSize->getSourceRange(); 19870 return nullptr; 19871 } 19872 } else if (getOpenMPCaptureRegionForClause( 19873 DSAStack->getCurrentDirective(), OMPC_dist_schedule, 19874 LangOpts.OpenMP) != OMPD_unknown && 19875 !CurContext->isDependentContext()) { 19876 ValExpr = MakeFullExpr(ValExpr).get(); 19877 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 19878 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 19879 HelperValStmt = buildPreInits(Context, Captures); 19880 } 19881 } 19882 } 19883 19884 return new (Context) 19885 OMPDistScheduleClause(StartLoc, LParenLoc, KindLoc, CommaLoc, EndLoc, 19886 Kind, ValExpr, HelperValStmt); 19887 } 19888 19889 OMPClause *Sema::ActOnOpenMPDefaultmapClause( 19890 OpenMPDefaultmapClauseModifier M, OpenMPDefaultmapClauseKind Kind, 19891 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation MLoc, 19892 SourceLocation KindLoc, SourceLocation EndLoc) { 19893 if (getLangOpts().OpenMP < 50) { 19894 if (M != OMPC_DEFAULTMAP_MODIFIER_tofrom || 19895 Kind != OMPC_DEFAULTMAP_scalar) { 19896 std::string Value; 19897 SourceLocation Loc; 19898 Value += "'"; 19899 if (M != OMPC_DEFAULTMAP_MODIFIER_tofrom) { 19900 Value += getOpenMPSimpleClauseTypeName(OMPC_defaultmap, 19901 OMPC_DEFAULTMAP_MODIFIER_tofrom); 19902 Loc = MLoc; 19903 } else { 19904 Value += getOpenMPSimpleClauseTypeName(OMPC_defaultmap, 19905 OMPC_DEFAULTMAP_scalar); 19906 Loc = KindLoc; 19907 } 19908 Value += "'"; 19909 Diag(Loc, diag::err_omp_unexpected_clause_value) 19910 << Value << getOpenMPClauseName(OMPC_defaultmap); 19911 return nullptr; 19912 } 19913 } else { 19914 bool isDefaultmapModifier = (M != OMPC_DEFAULTMAP_MODIFIER_unknown); 19915 bool isDefaultmapKind = (Kind != OMPC_DEFAULTMAP_unknown) || 19916 (LangOpts.OpenMP >= 50 && KindLoc.isInvalid()); 19917 if (!isDefaultmapKind || !isDefaultmapModifier) { 19918 StringRef KindValue = "'scalar', 'aggregate', 'pointer'"; 19919 if (LangOpts.OpenMP == 50) { 19920 StringRef ModifierValue = "'alloc', 'from', 'to', 'tofrom', " 19921 "'firstprivate', 'none', 'default'"; 19922 if (!isDefaultmapKind && isDefaultmapModifier) { 19923 Diag(KindLoc, diag::err_omp_unexpected_clause_value) 19924 << KindValue << getOpenMPClauseName(OMPC_defaultmap); 19925 } else if (isDefaultmapKind && !isDefaultmapModifier) { 19926 Diag(MLoc, diag::err_omp_unexpected_clause_value) 19927 << ModifierValue << getOpenMPClauseName(OMPC_defaultmap); 19928 } else { 19929 Diag(MLoc, diag::err_omp_unexpected_clause_value) 19930 << ModifierValue << getOpenMPClauseName(OMPC_defaultmap); 19931 Diag(KindLoc, diag::err_omp_unexpected_clause_value) 19932 << KindValue << getOpenMPClauseName(OMPC_defaultmap); 19933 } 19934 } else { 19935 StringRef ModifierValue = 19936 "'alloc', 'from', 'to', 'tofrom', " 19937 "'firstprivate', 'none', 'default', 'present'"; 19938 if (!isDefaultmapKind && isDefaultmapModifier) { 19939 Diag(KindLoc, diag::err_omp_unexpected_clause_value) 19940 << KindValue << getOpenMPClauseName(OMPC_defaultmap); 19941 } else if (isDefaultmapKind && !isDefaultmapModifier) { 19942 Diag(MLoc, diag::err_omp_unexpected_clause_value) 19943 << ModifierValue << getOpenMPClauseName(OMPC_defaultmap); 19944 } else { 19945 Diag(MLoc, diag::err_omp_unexpected_clause_value) 19946 << ModifierValue << getOpenMPClauseName(OMPC_defaultmap); 19947 Diag(KindLoc, diag::err_omp_unexpected_clause_value) 19948 << KindValue << getOpenMPClauseName(OMPC_defaultmap); 19949 } 19950 } 19951 return nullptr; 19952 } 19953 19954 // OpenMP [5.0, 2.12.5, Restrictions, p. 174] 19955 // At most one defaultmap clause for each category can appear on the 19956 // directive. 19957 if (DSAStack->checkDefaultmapCategory(Kind)) { 19958 Diag(StartLoc, diag::err_omp_one_defaultmap_each_category); 19959 return nullptr; 19960 } 19961 } 19962 if (Kind == OMPC_DEFAULTMAP_unknown) { 19963 // Variable category is not specified - mark all categories. 19964 DSAStack->setDefaultDMAAttr(M, OMPC_DEFAULTMAP_aggregate, StartLoc); 19965 DSAStack->setDefaultDMAAttr(M, OMPC_DEFAULTMAP_scalar, StartLoc); 19966 DSAStack->setDefaultDMAAttr(M, OMPC_DEFAULTMAP_pointer, StartLoc); 19967 } else { 19968 DSAStack->setDefaultDMAAttr(M, Kind, StartLoc); 19969 } 19970 19971 return new (Context) 19972 OMPDefaultmapClause(StartLoc, LParenLoc, MLoc, KindLoc, EndLoc, Kind, M); 19973 } 19974 19975 bool Sema::ActOnStartOpenMPDeclareTargetDirective(SourceLocation Loc) { 19976 DeclContext *CurLexicalContext = getCurLexicalContext(); 19977 if (!CurLexicalContext->isFileContext() && 19978 !CurLexicalContext->isExternCContext() && 19979 !CurLexicalContext->isExternCXXContext() && 19980 !isa<CXXRecordDecl>(CurLexicalContext) && 19981 !isa<ClassTemplateDecl>(CurLexicalContext) && 19982 !isa<ClassTemplatePartialSpecializationDecl>(CurLexicalContext) && 19983 !isa<ClassTemplateSpecializationDecl>(CurLexicalContext)) { 19984 Diag(Loc, diag::err_omp_region_not_file_context); 19985 return false; 19986 } 19987 DeclareTargetNesting.push_back(Loc); 19988 return true; 19989 } 19990 19991 void Sema::ActOnFinishOpenMPDeclareTargetDirective() { 19992 assert(!DeclareTargetNesting.empty() && 19993 "Unexpected ActOnFinishOpenMPDeclareTargetDirective"); 19994 DeclareTargetNesting.pop_back(); 19995 } 19996 19997 NamedDecl * 19998 Sema::lookupOpenMPDeclareTargetName(Scope *CurScope, CXXScopeSpec &ScopeSpec, 19999 const DeclarationNameInfo &Id, 20000 NamedDeclSetType &SameDirectiveDecls) { 20001 LookupResult Lookup(*this, Id, LookupOrdinaryName); 20002 LookupParsedName(Lookup, CurScope, &ScopeSpec, true); 20003 20004 if (Lookup.isAmbiguous()) 20005 return nullptr; 20006 Lookup.suppressDiagnostics(); 20007 20008 if (!Lookup.isSingleResult()) { 20009 VarOrFuncDeclFilterCCC CCC(*this); 20010 if (TypoCorrection Corrected = 20011 CorrectTypo(Id, LookupOrdinaryName, CurScope, nullptr, CCC, 20012 CTK_ErrorRecovery)) { 20013 diagnoseTypo(Corrected, PDiag(diag::err_undeclared_var_use_suggest) 20014 << Id.getName()); 20015 checkDeclIsAllowedInOpenMPTarget(nullptr, Corrected.getCorrectionDecl()); 20016 return nullptr; 20017 } 20018 20019 Diag(Id.getLoc(), diag::err_undeclared_var_use) << Id.getName(); 20020 return nullptr; 20021 } 20022 20023 NamedDecl *ND = Lookup.getAsSingle<NamedDecl>(); 20024 if (!isa<VarDecl>(ND) && !isa<FunctionDecl>(ND) && 20025 !isa<FunctionTemplateDecl>(ND)) { 20026 Diag(Id.getLoc(), diag::err_omp_invalid_target_decl) << Id.getName(); 20027 return nullptr; 20028 } 20029 if (!SameDirectiveDecls.insert(cast<NamedDecl>(ND->getCanonicalDecl()))) 20030 Diag(Id.getLoc(), diag::err_omp_declare_target_multiple) << Id.getName(); 20031 return ND; 20032 } 20033 20034 void Sema::ActOnOpenMPDeclareTargetName( 20035 NamedDecl *ND, SourceLocation Loc, OMPDeclareTargetDeclAttr::MapTypeTy MT, 20036 OMPDeclareTargetDeclAttr::DevTypeTy DT) { 20037 assert((isa<VarDecl>(ND) || isa<FunctionDecl>(ND) || 20038 isa<FunctionTemplateDecl>(ND)) && 20039 "Expected variable, function or function template."); 20040 20041 // Diagnose marking after use as it may lead to incorrect diagnosis and 20042 // codegen. 20043 if (LangOpts.OpenMP >= 50 && 20044 (ND->isUsed(/*CheckUsedAttr=*/false) || ND->isReferenced())) 20045 Diag(Loc, diag::warn_omp_declare_target_after_first_use); 20046 20047 auto *VD = cast<ValueDecl>(ND); 20048 Optional<OMPDeclareTargetDeclAttr::DevTypeTy> DevTy = 20049 OMPDeclareTargetDeclAttr::getDeviceType(VD); 20050 Optional<SourceLocation> AttrLoc = OMPDeclareTargetDeclAttr::getLocation(VD); 20051 if (DevTy.hasValue() && *DevTy != DT && 20052 (DeclareTargetNesting.empty() || 20053 *AttrLoc != DeclareTargetNesting.back())) { 20054 Diag(Loc, diag::err_omp_device_type_mismatch) 20055 << OMPDeclareTargetDeclAttr::ConvertDevTypeTyToStr(DT) 20056 << OMPDeclareTargetDeclAttr::ConvertDevTypeTyToStr(*DevTy); 20057 return; 20058 } 20059 Optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res = 20060 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD); 20061 if (!Res || (!DeclareTargetNesting.empty() && 20062 *AttrLoc == DeclareTargetNesting.back())) { 20063 auto *A = OMPDeclareTargetDeclAttr::CreateImplicit( 20064 Context, MT, DT, DeclareTargetNesting.size() + 1, 20065 SourceRange(Loc, Loc)); 20066 ND->addAttr(A); 20067 if (ASTMutationListener *ML = Context.getASTMutationListener()) 20068 ML->DeclarationMarkedOpenMPDeclareTarget(ND, A); 20069 checkDeclIsAllowedInOpenMPTarget(nullptr, ND, Loc); 20070 } else if (*Res != MT) { 20071 Diag(Loc, diag::err_omp_declare_target_to_and_link) << ND; 20072 } 20073 } 20074 20075 static void checkDeclInTargetContext(SourceLocation SL, SourceRange SR, 20076 Sema &SemaRef, Decl *D) { 20077 if (!D || !isa<VarDecl>(D)) 20078 return; 20079 auto *VD = cast<VarDecl>(D); 20080 Optional<OMPDeclareTargetDeclAttr::MapTypeTy> MapTy = 20081 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD); 20082 if (SemaRef.LangOpts.OpenMP >= 50 && 20083 (SemaRef.getCurLambda(/*IgnoreNonLambdaCapturingScope=*/true) || 20084 SemaRef.getCurBlock() || SemaRef.getCurCapturedRegion()) && 20085 VD->hasGlobalStorage()) { 20086 llvm::Optional<OMPDeclareTargetDeclAttr::MapTypeTy> MapTy = 20087 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD); 20088 if (!MapTy || *MapTy != OMPDeclareTargetDeclAttr::MT_To) { 20089 // OpenMP 5.0, 2.12.7 declare target Directive, Restrictions 20090 // If a lambda declaration and definition appears between a 20091 // declare target directive and the matching end declare target 20092 // directive, all variables that are captured by the lambda 20093 // expression must also appear in a to clause. 20094 SemaRef.Diag(VD->getLocation(), 20095 diag::err_omp_lambda_capture_in_declare_target_not_to); 20096 SemaRef.Diag(SL, diag::note_var_explicitly_captured_here) 20097 << VD << 0 << SR; 20098 return; 20099 } 20100 } 20101 if (MapTy.hasValue()) 20102 return; 20103 SemaRef.Diag(VD->getLocation(), diag::warn_omp_not_in_target_context); 20104 SemaRef.Diag(SL, diag::note_used_here) << SR; 20105 } 20106 20107 static bool checkValueDeclInTarget(SourceLocation SL, SourceRange SR, 20108 Sema &SemaRef, DSAStackTy *Stack, 20109 ValueDecl *VD) { 20110 return OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD) || 20111 checkTypeMappable(SL, SR, SemaRef, Stack, VD->getType(), 20112 /*FullCheck=*/false); 20113 } 20114 20115 void Sema::checkDeclIsAllowedInOpenMPTarget(Expr *E, Decl *D, 20116 SourceLocation IdLoc) { 20117 if (!D || D->isInvalidDecl()) 20118 return; 20119 SourceRange SR = E ? E->getSourceRange() : D->getSourceRange(); 20120 SourceLocation SL = E ? E->getBeginLoc() : D->getLocation(); 20121 if (auto *VD = dyn_cast<VarDecl>(D)) { 20122 // Only global variables can be marked as declare target. 20123 if (!VD->isFileVarDecl() && !VD->isStaticLocal() && 20124 !VD->isStaticDataMember()) 20125 return; 20126 // 2.10.6: threadprivate variable cannot appear in a declare target 20127 // directive. 20128 if (DSAStack->isThreadPrivate(VD)) { 20129 Diag(SL, diag::err_omp_threadprivate_in_target); 20130 reportOriginalDsa(*this, DSAStack, VD, DSAStack->getTopDSA(VD, false)); 20131 return; 20132 } 20133 } 20134 if (const auto *FTD = dyn_cast<FunctionTemplateDecl>(D)) 20135 D = FTD->getTemplatedDecl(); 20136 if (auto *FD = dyn_cast<FunctionDecl>(D)) { 20137 llvm::Optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res = 20138 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(FD); 20139 if (IdLoc.isValid() && Res && *Res == OMPDeclareTargetDeclAttr::MT_Link) { 20140 Diag(IdLoc, diag::err_omp_function_in_link_clause); 20141 Diag(FD->getLocation(), diag::note_defined_here) << FD; 20142 return; 20143 } 20144 } 20145 if (auto *VD = dyn_cast<ValueDecl>(D)) { 20146 // Problem if any with var declared with incomplete type will be reported 20147 // as normal, so no need to check it here. 20148 if ((E || !VD->getType()->isIncompleteType()) && 20149 !checkValueDeclInTarget(SL, SR, *this, DSAStack, VD)) 20150 return; 20151 if (!E && !OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD)) { 20152 // Checking declaration inside declare target region. 20153 if (isa<VarDecl>(D) || isa<FunctionDecl>(D) || 20154 isa<FunctionTemplateDecl>(D)) { 20155 auto *A = OMPDeclareTargetDeclAttr::CreateImplicit( 20156 Context, OMPDeclareTargetDeclAttr::MT_To, 20157 OMPDeclareTargetDeclAttr::DT_Any, DeclareTargetNesting.size(), 20158 SourceRange(DeclareTargetNesting.back(), 20159 DeclareTargetNesting.back())); 20160 D->addAttr(A); 20161 if (ASTMutationListener *ML = Context.getASTMutationListener()) 20162 ML->DeclarationMarkedOpenMPDeclareTarget(D, A); 20163 } 20164 return; 20165 } 20166 } 20167 if (!E) 20168 return; 20169 checkDeclInTargetContext(E->getExprLoc(), E->getSourceRange(), *this, D); 20170 } 20171 20172 OMPClause *Sema::ActOnOpenMPToClause( 20173 ArrayRef<OpenMPMotionModifierKind> MotionModifiers, 20174 ArrayRef<SourceLocation> MotionModifiersLoc, 20175 CXXScopeSpec &MapperIdScopeSpec, DeclarationNameInfo &MapperId, 20176 SourceLocation ColonLoc, ArrayRef<Expr *> VarList, 20177 const OMPVarListLocTy &Locs, ArrayRef<Expr *> UnresolvedMappers) { 20178 OpenMPMotionModifierKind Modifiers[] = {OMPC_MOTION_MODIFIER_unknown, 20179 OMPC_MOTION_MODIFIER_unknown}; 20180 SourceLocation ModifiersLoc[NumberOfOMPMotionModifiers]; 20181 20182 // Process motion-modifiers, flag errors for duplicate modifiers. 20183 unsigned Count = 0; 20184 for (unsigned I = 0, E = MotionModifiers.size(); I < E; ++I) { 20185 if (MotionModifiers[I] != OMPC_MOTION_MODIFIER_unknown && 20186 llvm::find(Modifiers, MotionModifiers[I]) != std::end(Modifiers)) { 20187 Diag(MotionModifiersLoc[I], diag::err_omp_duplicate_motion_modifier); 20188 continue; 20189 } 20190 assert(Count < NumberOfOMPMotionModifiers && 20191 "Modifiers exceed the allowed number of motion modifiers"); 20192 Modifiers[Count] = MotionModifiers[I]; 20193 ModifiersLoc[Count] = MotionModifiersLoc[I]; 20194 ++Count; 20195 } 20196 20197 MappableVarListInfo MVLI(VarList); 20198 checkMappableExpressionList(*this, DSAStack, OMPC_to, MVLI, Locs.StartLoc, 20199 MapperIdScopeSpec, MapperId, UnresolvedMappers); 20200 if (MVLI.ProcessedVarList.empty()) 20201 return nullptr; 20202 20203 return OMPToClause::Create( 20204 Context, Locs, MVLI.ProcessedVarList, MVLI.VarBaseDeclarations, 20205 MVLI.VarComponents, MVLI.UDMapperList, Modifiers, ModifiersLoc, 20206 MapperIdScopeSpec.getWithLocInContext(Context), MapperId); 20207 } 20208 20209 OMPClause *Sema::ActOnOpenMPFromClause( 20210 ArrayRef<OpenMPMotionModifierKind> MotionModifiers, 20211 ArrayRef<SourceLocation> MotionModifiersLoc, 20212 CXXScopeSpec &MapperIdScopeSpec, DeclarationNameInfo &MapperId, 20213 SourceLocation ColonLoc, ArrayRef<Expr *> VarList, 20214 const OMPVarListLocTy &Locs, ArrayRef<Expr *> UnresolvedMappers) { 20215 OpenMPMotionModifierKind Modifiers[] = {OMPC_MOTION_MODIFIER_unknown, 20216 OMPC_MOTION_MODIFIER_unknown}; 20217 SourceLocation ModifiersLoc[NumberOfOMPMotionModifiers]; 20218 20219 // Process motion-modifiers, flag errors for duplicate modifiers. 20220 unsigned Count = 0; 20221 for (unsigned I = 0, E = MotionModifiers.size(); I < E; ++I) { 20222 if (MotionModifiers[I] != OMPC_MOTION_MODIFIER_unknown && 20223 llvm::find(Modifiers, MotionModifiers[I]) != std::end(Modifiers)) { 20224 Diag(MotionModifiersLoc[I], diag::err_omp_duplicate_motion_modifier); 20225 continue; 20226 } 20227 assert(Count < NumberOfOMPMotionModifiers && 20228 "Modifiers exceed the allowed number of motion modifiers"); 20229 Modifiers[Count] = MotionModifiers[I]; 20230 ModifiersLoc[Count] = MotionModifiersLoc[I]; 20231 ++Count; 20232 } 20233 20234 MappableVarListInfo MVLI(VarList); 20235 checkMappableExpressionList(*this, DSAStack, OMPC_from, MVLI, Locs.StartLoc, 20236 MapperIdScopeSpec, MapperId, UnresolvedMappers); 20237 if (MVLI.ProcessedVarList.empty()) 20238 return nullptr; 20239 20240 return OMPFromClause::Create( 20241 Context, Locs, MVLI.ProcessedVarList, MVLI.VarBaseDeclarations, 20242 MVLI.VarComponents, MVLI.UDMapperList, Modifiers, ModifiersLoc, 20243 MapperIdScopeSpec.getWithLocInContext(Context), MapperId); 20244 } 20245 20246 OMPClause *Sema::ActOnOpenMPUseDevicePtrClause(ArrayRef<Expr *> VarList, 20247 const OMPVarListLocTy &Locs) { 20248 MappableVarListInfo MVLI(VarList); 20249 SmallVector<Expr *, 8> PrivateCopies; 20250 SmallVector<Expr *, 8> Inits; 20251 20252 for (Expr *RefExpr : VarList) { 20253 assert(RefExpr && "NULL expr in OpenMP use_device_ptr clause."); 20254 SourceLocation ELoc; 20255 SourceRange ERange; 20256 Expr *SimpleRefExpr = RefExpr; 20257 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 20258 if (Res.second) { 20259 // It will be analyzed later. 20260 MVLI.ProcessedVarList.push_back(RefExpr); 20261 PrivateCopies.push_back(nullptr); 20262 Inits.push_back(nullptr); 20263 } 20264 ValueDecl *D = Res.first; 20265 if (!D) 20266 continue; 20267 20268 QualType Type = D->getType(); 20269 Type = Type.getNonReferenceType().getUnqualifiedType(); 20270 20271 auto *VD = dyn_cast<VarDecl>(D); 20272 20273 // Item should be a pointer or reference to pointer. 20274 if (!Type->isPointerType()) { 20275 Diag(ELoc, diag::err_omp_usedeviceptr_not_a_pointer) 20276 << 0 << RefExpr->getSourceRange(); 20277 continue; 20278 } 20279 20280 // Build the private variable and the expression that refers to it. 20281 auto VDPrivate = 20282 buildVarDecl(*this, ELoc, Type, D->getName(), 20283 D->hasAttrs() ? &D->getAttrs() : nullptr, 20284 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr); 20285 if (VDPrivate->isInvalidDecl()) 20286 continue; 20287 20288 CurContext->addDecl(VDPrivate); 20289 DeclRefExpr *VDPrivateRefExpr = buildDeclRefExpr( 20290 *this, VDPrivate, RefExpr->getType().getUnqualifiedType(), ELoc); 20291 20292 // Add temporary variable to initialize the private copy of the pointer. 20293 VarDecl *VDInit = 20294 buildVarDecl(*this, RefExpr->getExprLoc(), Type, ".devptr.temp"); 20295 DeclRefExpr *VDInitRefExpr = buildDeclRefExpr( 20296 *this, VDInit, RefExpr->getType(), RefExpr->getExprLoc()); 20297 AddInitializerToDecl(VDPrivate, 20298 DefaultLvalueConversion(VDInitRefExpr).get(), 20299 /*DirectInit=*/false); 20300 20301 // If required, build a capture to implement the privatization initialized 20302 // with the current list item value. 20303 DeclRefExpr *Ref = nullptr; 20304 if (!VD) 20305 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true); 20306 MVLI.ProcessedVarList.push_back(VD ? RefExpr->IgnoreParens() : Ref); 20307 PrivateCopies.push_back(VDPrivateRefExpr); 20308 Inits.push_back(VDInitRefExpr); 20309 20310 // We need to add a data sharing attribute for this variable to make sure it 20311 // is correctly captured. A variable that shows up in a use_device_ptr has 20312 // similar properties of a first private variable. 20313 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_firstprivate, Ref); 20314 20315 // Create a mappable component for the list item. List items in this clause 20316 // only need a component. 20317 MVLI.VarBaseDeclarations.push_back(D); 20318 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1); 20319 MVLI.VarComponents.back().emplace_back(SimpleRefExpr, D, 20320 /*IsNonContiguous=*/false); 20321 } 20322 20323 if (MVLI.ProcessedVarList.empty()) 20324 return nullptr; 20325 20326 return OMPUseDevicePtrClause::Create( 20327 Context, Locs, MVLI.ProcessedVarList, PrivateCopies, Inits, 20328 MVLI.VarBaseDeclarations, MVLI.VarComponents); 20329 } 20330 20331 OMPClause *Sema::ActOnOpenMPUseDeviceAddrClause(ArrayRef<Expr *> VarList, 20332 const OMPVarListLocTy &Locs) { 20333 MappableVarListInfo MVLI(VarList); 20334 20335 for (Expr *RefExpr : VarList) { 20336 assert(RefExpr && "NULL expr in OpenMP use_device_addr clause."); 20337 SourceLocation ELoc; 20338 SourceRange ERange; 20339 Expr *SimpleRefExpr = RefExpr; 20340 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange, 20341 /*AllowArraySection=*/true); 20342 if (Res.second) { 20343 // It will be analyzed later. 20344 MVLI.ProcessedVarList.push_back(RefExpr); 20345 } 20346 ValueDecl *D = Res.first; 20347 if (!D) 20348 continue; 20349 auto *VD = dyn_cast<VarDecl>(D); 20350 20351 // If required, build a capture to implement the privatization initialized 20352 // with the current list item value. 20353 DeclRefExpr *Ref = nullptr; 20354 if (!VD) 20355 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true); 20356 MVLI.ProcessedVarList.push_back(VD ? RefExpr->IgnoreParens() : Ref); 20357 20358 // We need to add a data sharing attribute for this variable to make sure it 20359 // is correctly captured. A variable that shows up in a use_device_addr has 20360 // similar properties of a first private variable. 20361 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_firstprivate, Ref); 20362 20363 // Create a mappable component for the list item. List items in this clause 20364 // only need a component. 20365 MVLI.VarBaseDeclarations.push_back(D); 20366 MVLI.VarComponents.emplace_back(); 20367 Expr *Component = SimpleRefExpr; 20368 if (VD && (isa<OMPArraySectionExpr>(RefExpr->IgnoreParenImpCasts()) || 20369 isa<ArraySubscriptExpr>(RefExpr->IgnoreParenImpCasts()))) 20370 Component = DefaultFunctionArrayLvalueConversion(SimpleRefExpr).get(); 20371 MVLI.VarComponents.back().emplace_back(Component, D, 20372 /*IsNonContiguous=*/false); 20373 } 20374 20375 if (MVLI.ProcessedVarList.empty()) 20376 return nullptr; 20377 20378 return OMPUseDeviceAddrClause::Create(Context, Locs, MVLI.ProcessedVarList, 20379 MVLI.VarBaseDeclarations, 20380 MVLI.VarComponents); 20381 } 20382 20383 OMPClause *Sema::ActOnOpenMPIsDevicePtrClause(ArrayRef<Expr *> VarList, 20384 const OMPVarListLocTy &Locs) { 20385 MappableVarListInfo MVLI(VarList); 20386 for (Expr *RefExpr : VarList) { 20387 assert(RefExpr && "NULL expr in OpenMP is_device_ptr clause."); 20388 SourceLocation ELoc; 20389 SourceRange ERange; 20390 Expr *SimpleRefExpr = RefExpr; 20391 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 20392 if (Res.second) { 20393 // It will be analyzed later. 20394 MVLI.ProcessedVarList.push_back(RefExpr); 20395 } 20396 ValueDecl *D = Res.first; 20397 if (!D) 20398 continue; 20399 20400 QualType Type = D->getType(); 20401 // item should be a pointer or array or reference to pointer or array 20402 if (!Type.getNonReferenceType()->isPointerType() && 20403 !Type.getNonReferenceType()->isArrayType()) { 20404 Diag(ELoc, diag::err_omp_argument_type_isdeviceptr) 20405 << 0 << RefExpr->getSourceRange(); 20406 continue; 20407 } 20408 20409 // Check if the declaration in the clause does not show up in any data 20410 // sharing attribute. 20411 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false); 20412 if (isOpenMPPrivate(DVar.CKind)) { 20413 Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa) 20414 << getOpenMPClauseName(DVar.CKind) 20415 << getOpenMPClauseName(OMPC_is_device_ptr) 20416 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 20417 reportOriginalDsa(*this, DSAStack, D, DVar); 20418 continue; 20419 } 20420 20421 const Expr *ConflictExpr; 20422 if (DSAStack->checkMappableExprComponentListsForDecl( 20423 D, /*CurrentRegionOnly=*/true, 20424 [&ConflictExpr]( 20425 OMPClauseMappableExprCommon::MappableExprComponentListRef R, 20426 OpenMPClauseKind) -> bool { 20427 ConflictExpr = R.front().getAssociatedExpression(); 20428 return true; 20429 })) { 20430 Diag(ELoc, diag::err_omp_map_shared_storage) << RefExpr->getSourceRange(); 20431 Diag(ConflictExpr->getExprLoc(), diag::note_used_here) 20432 << ConflictExpr->getSourceRange(); 20433 continue; 20434 } 20435 20436 // Store the components in the stack so that they can be used to check 20437 // against other clauses later on. 20438 OMPClauseMappableExprCommon::MappableComponent MC( 20439 SimpleRefExpr, D, /*IsNonContiguous=*/false); 20440 DSAStack->addMappableExpressionComponents( 20441 D, MC, /*WhereFoundClauseKind=*/OMPC_is_device_ptr); 20442 20443 // Record the expression we've just processed. 20444 MVLI.ProcessedVarList.push_back(SimpleRefExpr); 20445 20446 // Create a mappable component for the list item. List items in this clause 20447 // only need a component. We use a null declaration to signal fields in 20448 // 'this'. 20449 assert((isa<DeclRefExpr>(SimpleRefExpr) || 20450 isa<CXXThisExpr>(cast<MemberExpr>(SimpleRefExpr)->getBase())) && 20451 "Unexpected device pointer expression!"); 20452 MVLI.VarBaseDeclarations.push_back( 20453 isa<DeclRefExpr>(SimpleRefExpr) ? D : nullptr); 20454 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1); 20455 MVLI.VarComponents.back().push_back(MC); 20456 } 20457 20458 if (MVLI.ProcessedVarList.empty()) 20459 return nullptr; 20460 20461 return OMPIsDevicePtrClause::Create(Context, Locs, MVLI.ProcessedVarList, 20462 MVLI.VarBaseDeclarations, 20463 MVLI.VarComponents); 20464 } 20465 20466 OMPClause *Sema::ActOnOpenMPAllocateClause( 20467 Expr *Allocator, ArrayRef<Expr *> VarList, SourceLocation StartLoc, 20468 SourceLocation ColonLoc, SourceLocation LParenLoc, SourceLocation EndLoc) { 20469 if (Allocator) { 20470 // OpenMP [2.11.4 allocate Clause, Description] 20471 // allocator is an expression of omp_allocator_handle_t type. 20472 if (!findOMPAllocatorHandleT(*this, Allocator->getExprLoc(), DSAStack)) 20473 return nullptr; 20474 20475 ExprResult AllocatorRes = DefaultLvalueConversion(Allocator); 20476 if (AllocatorRes.isInvalid()) 20477 return nullptr; 20478 AllocatorRes = PerformImplicitConversion(AllocatorRes.get(), 20479 DSAStack->getOMPAllocatorHandleT(), 20480 Sema::AA_Initializing, 20481 /*AllowExplicit=*/true); 20482 if (AllocatorRes.isInvalid()) 20483 return nullptr; 20484 Allocator = AllocatorRes.get(); 20485 } else { 20486 // OpenMP 5.0, 2.11.4 allocate Clause, Restrictions. 20487 // allocate clauses that appear on a target construct or on constructs in a 20488 // target region must specify an allocator expression unless a requires 20489 // directive with the dynamic_allocators clause is present in the same 20490 // compilation unit. 20491 if (LangOpts.OpenMPIsDevice && 20492 !DSAStack->hasRequiresDeclWithClause<OMPDynamicAllocatorsClause>()) 20493 targetDiag(StartLoc, diag::err_expected_allocator_expression); 20494 } 20495 // Analyze and build list of variables. 20496 SmallVector<Expr *, 8> Vars; 20497 for (Expr *RefExpr : VarList) { 20498 assert(RefExpr && "NULL expr in OpenMP private clause."); 20499 SourceLocation ELoc; 20500 SourceRange ERange; 20501 Expr *SimpleRefExpr = RefExpr; 20502 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 20503 if (Res.second) { 20504 // It will be analyzed later. 20505 Vars.push_back(RefExpr); 20506 } 20507 ValueDecl *D = Res.first; 20508 if (!D) 20509 continue; 20510 20511 auto *VD = dyn_cast<VarDecl>(D); 20512 DeclRefExpr *Ref = nullptr; 20513 if (!VD && !CurContext->isDependentContext()) 20514 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false); 20515 Vars.push_back((VD || CurContext->isDependentContext()) 20516 ? RefExpr->IgnoreParens() 20517 : Ref); 20518 } 20519 20520 if (Vars.empty()) 20521 return nullptr; 20522 20523 if (Allocator) 20524 DSAStack->addInnerAllocatorExpr(Allocator); 20525 return OMPAllocateClause::Create(Context, StartLoc, LParenLoc, Allocator, 20526 ColonLoc, EndLoc, Vars); 20527 } 20528 20529 OMPClause *Sema::ActOnOpenMPNontemporalClause(ArrayRef<Expr *> VarList, 20530 SourceLocation StartLoc, 20531 SourceLocation LParenLoc, 20532 SourceLocation EndLoc) { 20533 SmallVector<Expr *, 8> Vars; 20534 for (Expr *RefExpr : VarList) { 20535 assert(RefExpr && "NULL expr in OpenMP nontemporal clause."); 20536 SourceLocation ELoc; 20537 SourceRange ERange; 20538 Expr *SimpleRefExpr = RefExpr; 20539 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 20540 if (Res.second) 20541 // It will be analyzed later. 20542 Vars.push_back(RefExpr); 20543 ValueDecl *D = Res.first; 20544 if (!D) 20545 continue; 20546 20547 // OpenMP 5.0, 2.9.3.1 simd Construct, Restrictions. 20548 // A list-item cannot appear in more than one nontemporal clause. 20549 if (const Expr *PrevRef = 20550 DSAStack->addUniqueNontemporal(D, SimpleRefExpr)) { 20551 Diag(ELoc, diag::err_omp_used_in_clause_twice) 20552 << 0 << getOpenMPClauseName(OMPC_nontemporal) << ERange; 20553 Diag(PrevRef->getExprLoc(), diag::note_omp_explicit_dsa) 20554 << getOpenMPClauseName(OMPC_nontemporal); 20555 continue; 20556 } 20557 20558 Vars.push_back(RefExpr); 20559 } 20560 20561 if (Vars.empty()) 20562 return nullptr; 20563 20564 return OMPNontemporalClause::Create(Context, StartLoc, LParenLoc, EndLoc, 20565 Vars); 20566 } 20567 20568 OMPClause *Sema::ActOnOpenMPInclusiveClause(ArrayRef<Expr *> VarList, 20569 SourceLocation StartLoc, 20570 SourceLocation LParenLoc, 20571 SourceLocation EndLoc) { 20572 SmallVector<Expr *, 8> Vars; 20573 for (Expr *RefExpr : VarList) { 20574 assert(RefExpr && "NULL expr in OpenMP nontemporal clause."); 20575 SourceLocation ELoc; 20576 SourceRange ERange; 20577 Expr *SimpleRefExpr = RefExpr; 20578 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange, 20579 /*AllowArraySection=*/true); 20580 if (Res.second) 20581 // It will be analyzed later. 20582 Vars.push_back(RefExpr); 20583 ValueDecl *D = Res.first; 20584 if (!D) 20585 continue; 20586 20587 const DSAStackTy::DSAVarData DVar = 20588 DSAStack->getTopDSA(D, /*FromParent=*/true); 20589 // OpenMP 5.0, 2.9.6, scan Directive, Restrictions. 20590 // A list item that appears in the inclusive or exclusive clause must appear 20591 // in a reduction clause with the inscan modifier on the enclosing 20592 // worksharing-loop, worksharing-loop SIMD, or simd construct. 20593 if (DVar.CKind != OMPC_reduction || 20594 DVar.Modifier != OMPC_REDUCTION_inscan) 20595 Diag(ELoc, diag::err_omp_inclusive_exclusive_not_reduction) 20596 << RefExpr->getSourceRange(); 20597 20598 if (DSAStack->getParentDirective() != OMPD_unknown) 20599 DSAStack->markDeclAsUsedInScanDirective(D); 20600 Vars.push_back(RefExpr); 20601 } 20602 20603 if (Vars.empty()) 20604 return nullptr; 20605 20606 return OMPInclusiveClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars); 20607 } 20608 20609 OMPClause *Sema::ActOnOpenMPExclusiveClause(ArrayRef<Expr *> VarList, 20610 SourceLocation StartLoc, 20611 SourceLocation LParenLoc, 20612 SourceLocation EndLoc) { 20613 SmallVector<Expr *, 8> Vars; 20614 for (Expr *RefExpr : VarList) { 20615 assert(RefExpr && "NULL expr in OpenMP nontemporal clause."); 20616 SourceLocation ELoc; 20617 SourceRange ERange; 20618 Expr *SimpleRefExpr = RefExpr; 20619 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange, 20620 /*AllowArraySection=*/true); 20621 if (Res.second) 20622 // It will be analyzed later. 20623 Vars.push_back(RefExpr); 20624 ValueDecl *D = Res.first; 20625 if (!D) 20626 continue; 20627 20628 OpenMPDirectiveKind ParentDirective = DSAStack->getParentDirective(); 20629 DSAStackTy::DSAVarData DVar; 20630 if (ParentDirective != OMPD_unknown) 20631 DVar = DSAStack->getTopDSA(D, /*FromParent=*/true); 20632 // OpenMP 5.0, 2.9.6, scan Directive, Restrictions. 20633 // A list item that appears in the inclusive or exclusive clause must appear 20634 // in a reduction clause with the inscan modifier on the enclosing 20635 // worksharing-loop, worksharing-loop SIMD, or simd construct. 20636 if (ParentDirective == OMPD_unknown || DVar.CKind != OMPC_reduction || 20637 DVar.Modifier != OMPC_REDUCTION_inscan) { 20638 Diag(ELoc, diag::err_omp_inclusive_exclusive_not_reduction) 20639 << RefExpr->getSourceRange(); 20640 } else { 20641 DSAStack->markDeclAsUsedInScanDirective(D); 20642 } 20643 Vars.push_back(RefExpr); 20644 } 20645 20646 if (Vars.empty()) 20647 return nullptr; 20648 20649 return OMPExclusiveClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars); 20650 } 20651 20652 /// Tries to find omp_alloctrait_t type. 20653 static bool findOMPAlloctraitT(Sema &S, SourceLocation Loc, DSAStackTy *Stack) { 20654 QualType OMPAlloctraitT = Stack->getOMPAlloctraitT(); 20655 if (!OMPAlloctraitT.isNull()) 20656 return true; 20657 IdentifierInfo &II = S.PP.getIdentifierTable().get("omp_alloctrait_t"); 20658 ParsedType PT = S.getTypeName(II, Loc, S.getCurScope()); 20659 if (!PT.getAsOpaquePtr() || PT.get().isNull()) { 20660 S.Diag(Loc, diag::err_omp_implied_type_not_found) << "omp_alloctrait_t"; 20661 return false; 20662 } 20663 Stack->setOMPAlloctraitT(PT.get()); 20664 return true; 20665 } 20666 20667 OMPClause *Sema::ActOnOpenMPUsesAllocatorClause( 20668 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc, 20669 ArrayRef<UsesAllocatorsData> Data) { 20670 // OpenMP [2.12.5, target Construct] 20671 // allocator is an identifier of omp_allocator_handle_t type. 20672 if (!findOMPAllocatorHandleT(*this, StartLoc, DSAStack)) 20673 return nullptr; 20674 // OpenMP [2.12.5, target Construct] 20675 // allocator-traits-array is an identifier of const omp_alloctrait_t * type. 20676 if (llvm::any_of( 20677 Data, 20678 [](const UsesAllocatorsData &D) { return D.AllocatorTraits; }) && 20679 !findOMPAlloctraitT(*this, StartLoc, DSAStack)) 20680 return nullptr; 20681 llvm::SmallPtrSet<CanonicalDeclPtr<Decl>, 4> PredefinedAllocators; 20682 for (int I = 0; I < OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; ++I) { 20683 auto AllocatorKind = static_cast<OMPAllocateDeclAttr::AllocatorTypeTy>(I); 20684 StringRef Allocator = 20685 OMPAllocateDeclAttr::ConvertAllocatorTypeTyToStr(AllocatorKind); 20686 DeclarationName AllocatorName = &Context.Idents.get(Allocator); 20687 PredefinedAllocators.insert(LookupSingleName( 20688 TUScope, AllocatorName, StartLoc, Sema::LookupAnyName)); 20689 } 20690 20691 SmallVector<OMPUsesAllocatorsClause::Data, 4> NewData; 20692 for (const UsesAllocatorsData &D : Data) { 20693 Expr *AllocatorExpr = nullptr; 20694 // Check allocator expression. 20695 if (D.Allocator->isTypeDependent()) { 20696 AllocatorExpr = D.Allocator; 20697 } else { 20698 // Traits were specified - need to assign new allocator to the specified 20699 // allocator, so it must be an lvalue. 20700 AllocatorExpr = D.Allocator->IgnoreParenImpCasts(); 20701 auto *DRE = dyn_cast<DeclRefExpr>(AllocatorExpr); 20702 bool IsPredefinedAllocator = false; 20703 if (DRE) 20704 IsPredefinedAllocator = PredefinedAllocators.count(DRE->getDecl()); 20705 if (!DRE || 20706 !(Context.hasSameUnqualifiedType( 20707 AllocatorExpr->getType(), DSAStack->getOMPAllocatorHandleT()) || 20708 Context.typesAreCompatible(AllocatorExpr->getType(), 20709 DSAStack->getOMPAllocatorHandleT(), 20710 /*CompareUnqualified=*/true)) || 20711 (!IsPredefinedAllocator && 20712 (AllocatorExpr->getType().isConstant(Context) || 20713 !AllocatorExpr->isLValue()))) { 20714 Diag(D.Allocator->getExprLoc(), diag::err_omp_var_expected) 20715 << "omp_allocator_handle_t" << (DRE ? 1 : 0) 20716 << AllocatorExpr->getType() << D.Allocator->getSourceRange(); 20717 continue; 20718 } 20719 // OpenMP [2.12.5, target Construct] 20720 // Predefined allocators appearing in a uses_allocators clause cannot have 20721 // traits specified. 20722 if (IsPredefinedAllocator && D.AllocatorTraits) { 20723 Diag(D.AllocatorTraits->getExprLoc(), 20724 diag::err_omp_predefined_allocator_with_traits) 20725 << D.AllocatorTraits->getSourceRange(); 20726 Diag(D.Allocator->getExprLoc(), diag::note_omp_predefined_allocator) 20727 << cast<NamedDecl>(DRE->getDecl())->getName() 20728 << D.Allocator->getSourceRange(); 20729 continue; 20730 } 20731 // OpenMP [2.12.5, target Construct] 20732 // Non-predefined allocators appearing in a uses_allocators clause must 20733 // have traits specified. 20734 if (!IsPredefinedAllocator && !D.AllocatorTraits) { 20735 Diag(D.Allocator->getExprLoc(), 20736 diag::err_omp_nonpredefined_allocator_without_traits); 20737 continue; 20738 } 20739 // No allocator traits - just convert it to rvalue. 20740 if (!D.AllocatorTraits) 20741 AllocatorExpr = DefaultLvalueConversion(AllocatorExpr).get(); 20742 DSAStack->addUsesAllocatorsDecl( 20743 DRE->getDecl(), 20744 IsPredefinedAllocator 20745 ? DSAStackTy::UsesAllocatorsDeclKind::PredefinedAllocator 20746 : DSAStackTy::UsesAllocatorsDeclKind::UserDefinedAllocator); 20747 } 20748 Expr *AllocatorTraitsExpr = nullptr; 20749 if (D.AllocatorTraits) { 20750 if (D.AllocatorTraits->isTypeDependent()) { 20751 AllocatorTraitsExpr = D.AllocatorTraits; 20752 } else { 20753 // OpenMP [2.12.5, target Construct] 20754 // Arrays that contain allocator traits that appear in a uses_allocators 20755 // clause must be constant arrays, have constant values and be defined 20756 // in the same scope as the construct in which the clause appears. 20757 AllocatorTraitsExpr = D.AllocatorTraits->IgnoreParenImpCasts(); 20758 // Check that traits expr is a constant array. 20759 QualType TraitTy; 20760 if (const ArrayType *Ty = 20761 AllocatorTraitsExpr->getType()->getAsArrayTypeUnsafe()) 20762 if (const auto *ConstArrayTy = dyn_cast<ConstantArrayType>(Ty)) 20763 TraitTy = ConstArrayTy->getElementType(); 20764 if (TraitTy.isNull() || 20765 !(Context.hasSameUnqualifiedType(TraitTy, 20766 DSAStack->getOMPAlloctraitT()) || 20767 Context.typesAreCompatible(TraitTy, DSAStack->getOMPAlloctraitT(), 20768 /*CompareUnqualified=*/true))) { 20769 Diag(D.AllocatorTraits->getExprLoc(), 20770 diag::err_omp_expected_array_alloctraits) 20771 << AllocatorTraitsExpr->getType(); 20772 continue; 20773 } 20774 // Do not map by default allocator traits if it is a standalone 20775 // variable. 20776 if (auto *DRE = dyn_cast<DeclRefExpr>(AllocatorTraitsExpr)) 20777 DSAStack->addUsesAllocatorsDecl( 20778 DRE->getDecl(), 20779 DSAStackTy::UsesAllocatorsDeclKind::AllocatorTrait); 20780 } 20781 } 20782 OMPUsesAllocatorsClause::Data &NewD = NewData.emplace_back(); 20783 NewD.Allocator = AllocatorExpr; 20784 NewD.AllocatorTraits = AllocatorTraitsExpr; 20785 NewD.LParenLoc = D.LParenLoc; 20786 NewD.RParenLoc = D.RParenLoc; 20787 } 20788 return OMPUsesAllocatorsClause::Create(Context, StartLoc, LParenLoc, EndLoc, 20789 NewData); 20790 } 20791 20792 OMPClause *Sema::ActOnOpenMPAffinityClause( 20793 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation ColonLoc, 20794 SourceLocation EndLoc, Expr *Modifier, ArrayRef<Expr *> Locators) { 20795 SmallVector<Expr *, 8> Vars; 20796 for (Expr *RefExpr : Locators) { 20797 assert(RefExpr && "NULL expr in OpenMP shared clause."); 20798 if (isa<DependentScopeDeclRefExpr>(RefExpr) || RefExpr->isTypeDependent()) { 20799 // It will be analyzed later. 20800 Vars.push_back(RefExpr); 20801 continue; 20802 } 20803 20804 SourceLocation ELoc = RefExpr->getExprLoc(); 20805 Expr *SimpleExpr = RefExpr->IgnoreParenImpCasts(); 20806 20807 if (!SimpleExpr->isLValue()) { 20808 Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item) 20809 << 1 << 0 << RefExpr->getSourceRange(); 20810 continue; 20811 } 20812 20813 ExprResult Res; 20814 { 20815 Sema::TentativeAnalysisScope Trap(*this); 20816 Res = CreateBuiltinUnaryOp(ELoc, UO_AddrOf, SimpleExpr); 20817 } 20818 if (!Res.isUsable() && !isa<OMPArraySectionExpr>(SimpleExpr) && 20819 !isa<OMPArrayShapingExpr>(SimpleExpr)) { 20820 Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item) 20821 << 1 << 0 << RefExpr->getSourceRange(); 20822 continue; 20823 } 20824 Vars.push_back(SimpleExpr); 20825 } 20826 20827 return OMPAffinityClause::Create(Context, StartLoc, LParenLoc, ColonLoc, 20828 EndLoc, Modifier, Vars); 20829 } 20830