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/Frontend/OpenMP/OMPConstants.h" 39 #include <set> 40 41 using namespace clang; 42 using namespace llvm::omp; 43 44 //===----------------------------------------------------------------------===// 45 // Stack of data-sharing attributes for variables 46 //===----------------------------------------------------------------------===// 47 48 static const Expr *checkMapClauseExpressionBase( 49 Sema &SemaRef, Expr *E, 50 OMPClauseMappableExprCommon::MappableExprComponentList &CurComponents, 51 OpenMPClauseKind CKind, bool NoDiagnose); 52 53 namespace { 54 /// Default data sharing attributes, which can be applied to directive. 55 enum DefaultDataSharingAttributes { 56 DSA_unspecified = 0, /// Data sharing attribute not specified. 57 DSA_none = 1 << 0, /// Default data sharing attribute 'none'. 58 DSA_shared = 1 << 1, /// Default data sharing attribute 'shared'. 59 DSA_firstprivate = 1 << 2, /// Default data sharing attribute 'firstprivate'. 60 }; 61 62 /// Stack for tracking declarations used in OpenMP directives and 63 /// clauses and their data-sharing attributes. 64 class DSAStackTy { 65 public: 66 struct DSAVarData { 67 OpenMPDirectiveKind DKind = OMPD_unknown; 68 OpenMPClauseKind CKind = OMPC_unknown; 69 unsigned Modifier = 0; 70 const Expr *RefExpr = nullptr; 71 DeclRefExpr *PrivateCopy = nullptr; 72 SourceLocation ImplicitDSALoc; 73 bool AppliedToPointee = false; 74 DSAVarData() = default; 75 DSAVarData(OpenMPDirectiveKind DKind, OpenMPClauseKind CKind, 76 const Expr *RefExpr, DeclRefExpr *PrivateCopy, 77 SourceLocation ImplicitDSALoc, unsigned Modifier, 78 bool AppliedToPointee) 79 : DKind(DKind), CKind(CKind), Modifier(Modifier), RefExpr(RefExpr), 80 PrivateCopy(PrivateCopy), ImplicitDSALoc(ImplicitDSALoc), 81 AppliedToPointee(AppliedToPointee) {} 82 }; 83 using OperatorOffsetTy = 84 llvm::SmallVector<std::pair<Expr *, OverloadedOperatorKind>, 4>; 85 using DoacrossDependMapTy = 86 llvm::DenseMap<OMPDependClause *, OperatorOffsetTy>; 87 /// Kind of the declaration used in the uses_allocators clauses. 88 enum class UsesAllocatorsDeclKind { 89 /// Predefined allocator 90 PredefinedAllocator, 91 /// User-defined allocator 92 UserDefinedAllocator, 93 /// The declaration that represent allocator trait 94 AllocatorTrait, 95 }; 96 97 private: 98 struct DSAInfo { 99 OpenMPClauseKind Attributes = OMPC_unknown; 100 unsigned Modifier = 0; 101 /// Pointer to a reference expression and a flag which shows that the 102 /// variable is marked as lastprivate(true) or not (false). 103 llvm::PointerIntPair<const Expr *, 1, bool> RefExpr; 104 DeclRefExpr *PrivateCopy = nullptr; 105 /// true if the attribute is applied to the pointee, not the variable 106 /// itself. 107 bool AppliedToPointee = false; 108 }; 109 using DeclSAMapTy = llvm::SmallDenseMap<const ValueDecl *, DSAInfo, 8>; 110 using UsedRefMapTy = llvm::SmallDenseMap<const ValueDecl *, const Expr *, 8>; 111 using LCDeclInfo = std::pair<unsigned, VarDecl *>; 112 using LoopControlVariablesMapTy = 113 llvm::SmallDenseMap<const ValueDecl *, LCDeclInfo, 8>; 114 /// Struct that associates a component with the clause kind where they are 115 /// found. 116 struct MappedExprComponentTy { 117 OMPClauseMappableExprCommon::MappableExprComponentLists Components; 118 OpenMPClauseKind Kind = OMPC_unknown; 119 }; 120 using MappedExprComponentsTy = 121 llvm::DenseMap<const ValueDecl *, MappedExprComponentTy>; 122 using CriticalsWithHintsTy = 123 llvm::StringMap<std::pair<const OMPCriticalDirective *, llvm::APSInt>>; 124 struct ReductionData { 125 using BOKPtrType = llvm::PointerEmbeddedInt<BinaryOperatorKind, 16>; 126 SourceRange ReductionRange; 127 llvm::PointerUnion<const Expr *, BOKPtrType> ReductionOp; 128 ReductionData() = default; 129 void set(BinaryOperatorKind BO, SourceRange RR) { 130 ReductionRange = RR; 131 ReductionOp = BO; 132 } 133 void set(const Expr *RefExpr, SourceRange RR) { 134 ReductionRange = RR; 135 ReductionOp = RefExpr; 136 } 137 }; 138 using DeclReductionMapTy = 139 llvm::SmallDenseMap<const ValueDecl *, ReductionData, 4>; 140 struct DefaultmapInfo { 141 OpenMPDefaultmapClauseModifier ImplicitBehavior = 142 OMPC_DEFAULTMAP_MODIFIER_unknown; 143 SourceLocation SLoc; 144 DefaultmapInfo() = default; 145 DefaultmapInfo(OpenMPDefaultmapClauseModifier M, SourceLocation Loc) 146 : ImplicitBehavior(M), SLoc(Loc) {} 147 }; 148 149 struct SharingMapTy { 150 DeclSAMapTy SharingMap; 151 DeclReductionMapTy ReductionMap; 152 UsedRefMapTy AlignedMap; 153 UsedRefMapTy NontemporalMap; 154 MappedExprComponentsTy MappedExprComponents; 155 LoopControlVariablesMapTy LCVMap; 156 DefaultDataSharingAttributes DefaultAttr = DSA_unspecified; 157 SourceLocation DefaultAttrLoc; 158 DefaultmapInfo DefaultmapMap[OMPC_DEFAULTMAP_unknown]; 159 OpenMPDirectiveKind Directive = OMPD_unknown; 160 DeclarationNameInfo DirectiveName; 161 Scope *CurScope = nullptr; 162 DeclContext *Context = nullptr; 163 SourceLocation ConstructLoc; 164 /// Set of 'depend' clauses with 'sink|source' dependence kind. Required to 165 /// get the data (loop counters etc.) about enclosing loop-based construct. 166 /// This data is required during codegen. 167 DoacrossDependMapTy DoacrossDepends; 168 /// First argument (Expr *) contains optional argument of the 169 /// 'ordered' clause, the second one is true if the regions has 'ordered' 170 /// clause, false otherwise. 171 llvm::Optional<std::pair<const Expr *, OMPOrderedClause *>> OrderedRegion; 172 unsigned AssociatedLoops = 1; 173 bool HasMutipleLoops = false; 174 const Decl *PossiblyLoopCounter = nullptr; 175 bool NowaitRegion = false; 176 bool CancelRegion = false; 177 bool LoopStart = false; 178 bool BodyComplete = false; 179 SourceLocation PrevScanLocation; 180 SourceLocation PrevOrderedLocation; 181 SourceLocation InnerTeamsRegionLoc; 182 /// Reference to the taskgroup task_reduction reference expression. 183 Expr *TaskgroupReductionRef = nullptr; 184 llvm::DenseSet<QualType> MappedClassesQualTypes; 185 SmallVector<Expr *, 4> InnerUsedAllocators; 186 llvm::DenseSet<CanonicalDeclPtr<Decl>> ImplicitTaskFirstprivates; 187 /// List of globals marked as declare target link in this target region 188 /// (isOpenMPTargetExecutionDirective(Directive) == true). 189 llvm::SmallVector<DeclRefExpr *, 4> DeclareTargetLinkVarDecls; 190 /// List of decls used in inclusive/exclusive clauses of the scan directive. 191 llvm::DenseSet<CanonicalDeclPtr<Decl>> UsedInScanDirective; 192 llvm::DenseMap<CanonicalDeclPtr<const Decl>, UsesAllocatorsDeclKind> 193 UsesAllocatorsDecls; 194 Expr *DeclareMapperVar = nullptr; 195 SharingMapTy(OpenMPDirectiveKind DKind, DeclarationNameInfo Name, 196 Scope *CurScope, SourceLocation Loc) 197 : Directive(DKind), DirectiveName(Name), CurScope(CurScope), 198 ConstructLoc(Loc) {} 199 SharingMapTy() = default; 200 }; 201 202 using StackTy = SmallVector<SharingMapTy, 4>; 203 204 /// Stack of used declaration and their data-sharing attributes. 205 DeclSAMapTy Threadprivates; 206 const FunctionScopeInfo *CurrentNonCapturingFunctionScope = nullptr; 207 SmallVector<std::pair<StackTy, const FunctionScopeInfo *>, 4> Stack; 208 /// true, if check for DSA must be from parent directive, false, if 209 /// from current directive. 210 OpenMPClauseKind ClauseKindMode = OMPC_unknown; 211 Sema &SemaRef; 212 bool ForceCapturing = false; 213 /// true if all the variables in the target executable directives must be 214 /// captured by reference. 215 bool ForceCaptureByReferenceInTargetExecutable = false; 216 CriticalsWithHintsTy Criticals; 217 unsigned IgnoredStackElements = 0; 218 219 /// Iterators over the stack iterate in order from innermost to outermost 220 /// directive. 221 using const_iterator = StackTy::const_reverse_iterator; 222 const_iterator begin() const { 223 return Stack.empty() ? const_iterator() 224 : Stack.back().first.rbegin() + IgnoredStackElements; 225 } 226 const_iterator end() const { 227 return Stack.empty() ? const_iterator() : Stack.back().first.rend(); 228 } 229 using iterator = StackTy::reverse_iterator; 230 iterator begin() { 231 return Stack.empty() ? iterator() 232 : Stack.back().first.rbegin() + IgnoredStackElements; 233 } 234 iterator end() { 235 return Stack.empty() ? iterator() : Stack.back().first.rend(); 236 } 237 238 // Convenience operations to get at the elements of the stack. 239 240 bool isStackEmpty() const { 241 return Stack.empty() || 242 Stack.back().second != CurrentNonCapturingFunctionScope || 243 Stack.back().first.size() <= IgnoredStackElements; 244 } 245 size_t getStackSize() const { 246 return isStackEmpty() ? 0 247 : Stack.back().first.size() - IgnoredStackElements; 248 } 249 250 SharingMapTy *getTopOfStackOrNull() { 251 size_t Size = getStackSize(); 252 if (Size == 0) 253 return nullptr; 254 return &Stack.back().first[Size - 1]; 255 } 256 const SharingMapTy *getTopOfStackOrNull() const { 257 return const_cast<DSAStackTy&>(*this).getTopOfStackOrNull(); 258 } 259 SharingMapTy &getTopOfStack() { 260 assert(!isStackEmpty() && "no current directive"); 261 return *getTopOfStackOrNull(); 262 } 263 const SharingMapTy &getTopOfStack() const { 264 return const_cast<DSAStackTy&>(*this).getTopOfStack(); 265 } 266 267 SharingMapTy *getSecondOnStackOrNull() { 268 size_t Size = getStackSize(); 269 if (Size <= 1) 270 return nullptr; 271 return &Stack.back().first[Size - 2]; 272 } 273 const SharingMapTy *getSecondOnStackOrNull() const { 274 return const_cast<DSAStackTy&>(*this).getSecondOnStackOrNull(); 275 } 276 277 /// Get the stack element at a certain level (previously returned by 278 /// \c getNestingLevel). 279 /// 280 /// Note that nesting levels count from outermost to innermost, and this is 281 /// the reverse of our iteration order where new inner levels are pushed at 282 /// the front of the stack. 283 SharingMapTy &getStackElemAtLevel(unsigned Level) { 284 assert(Level < getStackSize() && "no such stack element"); 285 return Stack.back().first[Level]; 286 } 287 const SharingMapTy &getStackElemAtLevel(unsigned Level) const { 288 return const_cast<DSAStackTy&>(*this).getStackElemAtLevel(Level); 289 } 290 291 DSAVarData getDSA(const_iterator &Iter, ValueDecl *D) const; 292 293 /// Checks if the variable is a local for OpenMP region. 294 bool isOpenMPLocal(VarDecl *D, const_iterator Iter) const; 295 296 /// Vector of previously declared requires directives 297 SmallVector<const OMPRequiresDecl *, 2> RequiresDecls; 298 /// omp_allocator_handle_t type. 299 QualType OMPAllocatorHandleT; 300 /// omp_depend_t type. 301 QualType OMPDependT; 302 /// omp_event_handle_t type. 303 QualType OMPEventHandleT; 304 /// omp_alloctrait_t type. 305 QualType OMPAlloctraitT; 306 /// Expression for the predefined allocators. 307 Expr *OMPPredefinedAllocators[OMPAllocateDeclAttr::OMPUserDefinedMemAlloc] = { 308 nullptr}; 309 /// Vector of previously encountered target directives 310 SmallVector<SourceLocation, 2> TargetLocations; 311 SourceLocation AtomicLocation; 312 313 public: 314 explicit DSAStackTy(Sema &S) : SemaRef(S) {} 315 316 /// Sets omp_allocator_handle_t type. 317 void setOMPAllocatorHandleT(QualType Ty) { OMPAllocatorHandleT = Ty; } 318 /// Gets omp_allocator_handle_t type. 319 QualType getOMPAllocatorHandleT() const { return OMPAllocatorHandleT; } 320 /// Sets omp_alloctrait_t type. 321 void setOMPAlloctraitT(QualType Ty) { OMPAlloctraitT = Ty; } 322 /// Gets omp_alloctrait_t type. 323 QualType getOMPAlloctraitT() const { return OMPAlloctraitT; } 324 /// Sets the given default allocator. 325 void setAllocator(OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind, 326 Expr *Allocator) { 327 OMPPredefinedAllocators[AllocatorKind] = Allocator; 328 } 329 /// Returns the specified default allocator. 330 Expr *getAllocator(OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind) const { 331 return OMPPredefinedAllocators[AllocatorKind]; 332 } 333 /// Sets omp_depend_t type. 334 void setOMPDependT(QualType Ty) { OMPDependT = Ty; } 335 /// Gets omp_depend_t type. 336 QualType getOMPDependT() const { return OMPDependT; } 337 338 /// Sets omp_event_handle_t type. 339 void setOMPEventHandleT(QualType Ty) { OMPEventHandleT = Ty; } 340 /// Gets omp_event_handle_t type. 341 QualType getOMPEventHandleT() const { return OMPEventHandleT; } 342 343 bool isClauseParsingMode() const { return ClauseKindMode != OMPC_unknown; } 344 OpenMPClauseKind getClauseParsingMode() const { 345 assert(isClauseParsingMode() && "Must be in clause parsing mode."); 346 return ClauseKindMode; 347 } 348 void setClauseParsingMode(OpenMPClauseKind K) { ClauseKindMode = K; } 349 350 bool isBodyComplete() const { 351 const SharingMapTy *Top = getTopOfStackOrNull(); 352 return Top && Top->BodyComplete; 353 } 354 void setBodyComplete() { 355 getTopOfStack().BodyComplete = true; 356 } 357 358 bool isForceVarCapturing() const { return ForceCapturing; } 359 void setForceVarCapturing(bool V) { ForceCapturing = V; } 360 361 void setForceCaptureByReferenceInTargetExecutable(bool V) { 362 ForceCaptureByReferenceInTargetExecutable = V; 363 } 364 bool isForceCaptureByReferenceInTargetExecutable() const { 365 return ForceCaptureByReferenceInTargetExecutable; 366 } 367 368 void push(OpenMPDirectiveKind DKind, const DeclarationNameInfo &DirName, 369 Scope *CurScope, SourceLocation Loc) { 370 assert(!IgnoredStackElements && 371 "cannot change stack while ignoring elements"); 372 if (Stack.empty() || 373 Stack.back().second != CurrentNonCapturingFunctionScope) 374 Stack.emplace_back(StackTy(), CurrentNonCapturingFunctionScope); 375 Stack.back().first.emplace_back(DKind, DirName, CurScope, Loc); 376 Stack.back().first.back().DefaultAttrLoc = Loc; 377 } 378 379 void pop() { 380 assert(!IgnoredStackElements && 381 "cannot change stack while ignoring elements"); 382 assert(!Stack.back().first.empty() && 383 "Data-sharing attributes stack is empty!"); 384 Stack.back().first.pop_back(); 385 } 386 387 /// RAII object to temporarily leave the scope of a directive when we want to 388 /// logically operate in its parent. 389 class ParentDirectiveScope { 390 DSAStackTy &Self; 391 bool Active; 392 public: 393 ParentDirectiveScope(DSAStackTy &Self, bool Activate) 394 : Self(Self), Active(false) { 395 if (Activate) 396 enable(); 397 } 398 ~ParentDirectiveScope() { disable(); } 399 void disable() { 400 if (Active) { 401 --Self.IgnoredStackElements; 402 Active = false; 403 } 404 } 405 void enable() { 406 if (!Active) { 407 ++Self.IgnoredStackElements; 408 Active = true; 409 } 410 } 411 }; 412 413 /// Marks that we're started loop parsing. 414 void loopInit() { 415 assert(isOpenMPLoopDirective(getCurrentDirective()) && 416 "Expected loop-based directive."); 417 getTopOfStack().LoopStart = true; 418 } 419 /// Start capturing of the variables in the loop context. 420 void loopStart() { 421 assert(isOpenMPLoopDirective(getCurrentDirective()) && 422 "Expected loop-based directive."); 423 getTopOfStack().LoopStart = false; 424 } 425 /// true, if variables are captured, false otherwise. 426 bool isLoopStarted() const { 427 assert(isOpenMPLoopDirective(getCurrentDirective()) && 428 "Expected loop-based directive."); 429 return !getTopOfStack().LoopStart; 430 } 431 /// Marks (or clears) declaration as possibly loop counter. 432 void resetPossibleLoopCounter(const Decl *D = nullptr) { 433 getTopOfStack().PossiblyLoopCounter = 434 D ? D->getCanonicalDecl() : D; 435 } 436 /// Gets the possible loop counter decl. 437 const Decl *getPossiblyLoopCunter() const { 438 return getTopOfStack().PossiblyLoopCounter; 439 } 440 /// Start new OpenMP region stack in new non-capturing function. 441 void pushFunction() { 442 assert(!IgnoredStackElements && 443 "cannot change stack while ignoring elements"); 444 const FunctionScopeInfo *CurFnScope = SemaRef.getCurFunction(); 445 assert(!isa<CapturingScopeInfo>(CurFnScope)); 446 CurrentNonCapturingFunctionScope = CurFnScope; 447 } 448 /// Pop region stack for non-capturing function. 449 void popFunction(const FunctionScopeInfo *OldFSI) { 450 assert(!IgnoredStackElements && 451 "cannot change stack while ignoring elements"); 452 if (!Stack.empty() && Stack.back().second == OldFSI) { 453 assert(Stack.back().first.empty()); 454 Stack.pop_back(); 455 } 456 CurrentNonCapturingFunctionScope = nullptr; 457 for (const FunctionScopeInfo *FSI : llvm::reverse(SemaRef.FunctionScopes)) { 458 if (!isa<CapturingScopeInfo>(FSI)) { 459 CurrentNonCapturingFunctionScope = FSI; 460 break; 461 } 462 } 463 } 464 465 void addCriticalWithHint(const OMPCriticalDirective *D, llvm::APSInt Hint) { 466 Criticals.try_emplace(D->getDirectiveName().getAsString(), D, Hint); 467 } 468 const std::pair<const OMPCriticalDirective *, llvm::APSInt> 469 getCriticalWithHint(const DeclarationNameInfo &Name) const { 470 auto I = Criticals.find(Name.getAsString()); 471 if (I != Criticals.end()) 472 return I->second; 473 return std::make_pair(nullptr, llvm::APSInt()); 474 } 475 /// If 'aligned' declaration for given variable \a D was not seen yet, 476 /// add it and return NULL; otherwise return previous occurrence's expression 477 /// for diagnostics. 478 const Expr *addUniqueAligned(const ValueDecl *D, const Expr *NewDE); 479 /// If 'nontemporal' declaration for given variable \a D was not seen yet, 480 /// add it and return NULL; otherwise return previous occurrence's expression 481 /// for diagnostics. 482 const Expr *addUniqueNontemporal(const ValueDecl *D, const Expr *NewDE); 483 484 /// Register specified variable as loop control variable. 485 void addLoopControlVariable(const ValueDecl *D, VarDecl *Capture); 486 /// Check if the specified variable is a loop control variable for 487 /// current region. 488 /// \return The index of the loop control variable in the list of associated 489 /// for-loops (from outer to inner). 490 const LCDeclInfo isLoopControlVariable(const ValueDecl *D) const; 491 /// Check if the specified variable is a loop control variable for 492 /// parent region. 493 /// \return The index of the loop control variable in the list of associated 494 /// for-loops (from outer to inner). 495 const LCDeclInfo isParentLoopControlVariable(const ValueDecl *D) const; 496 /// Check if the specified variable is a loop control variable for 497 /// current region. 498 /// \return The index of the loop control variable in the list of associated 499 /// for-loops (from outer to inner). 500 const LCDeclInfo isLoopControlVariable(const ValueDecl *D, 501 unsigned Level) const; 502 /// Get the loop control variable for the I-th loop (or nullptr) in 503 /// parent directive. 504 const ValueDecl *getParentLoopControlVariable(unsigned I) const; 505 506 /// Marks the specified decl \p D as used in scan directive. 507 void markDeclAsUsedInScanDirective(ValueDecl *D) { 508 if (SharingMapTy *Stack = getSecondOnStackOrNull()) 509 Stack->UsedInScanDirective.insert(D); 510 } 511 512 /// Checks if the specified declaration was used in the inner scan directive. 513 bool isUsedInScanDirective(ValueDecl *D) const { 514 if (const SharingMapTy *Stack = getTopOfStackOrNull()) 515 return Stack->UsedInScanDirective.count(D) > 0; 516 return false; 517 } 518 519 /// Adds explicit data sharing attribute to the specified declaration. 520 void addDSA(const ValueDecl *D, const Expr *E, OpenMPClauseKind A, 521 DeclRefExpr *PrivateCopy = nullptr, unsigned Modifier = 0, 522 bool AppliedToPointee = false); 523 524 /// Adds additional information for the reduction items with the reduction id 525 /// represented as an operator. 526 void addTaskgroupReductionData(const ValueDecl *D, SourceRange SR, 527 BinaryOperatorKind BOK); 528 /// Adds additional information for the reduction items with the reduction id 529 /// represented as reduction identifier. 530 void addTaskgroupReductionData(const ValueDecl *D, SourceRange SR, 531 const Expr *ReductionRef); 532 /// Returns the location and reduction operation from the innermost parent 533 /// region for the given \p D. 534 const DSAVarData 535 getTopMostTaskgroupReductionData(const ValueDecl *D, SourceRange &SR, 536 BinaryOperatorKind &BOK, 537 Expr *&TaskgroupDescriptor) const; 538 /// Returns the location and reduction operation from the innermost parent 539 /// region for the given \p D. 540 const DSAVarData 541 getTopMostTaskgroupReductionData(const ValueDecl *D, SourceRange &SR, 542 const Expr *&ReductionRef, 543 Expr *&TaskgroupDescriptor) const; 544 /// Return reduction reference expression for the current taskgroup or 545 /// parallel/worksharing directives with task reductions. 546 Expr *getTaskgroupReductionRef() const { 547 assert((getTopOfStack().Directive == OMPD_taskgroup || 548 ((isOpenMPParallelDirective(getTopOfStack().Directive) || 549 isOpenMPWorksharingDirective(getTopOfStack().Directive)) && 550 !isOpenMPSimdDirective(getTopOfStack().Directive))) && 551 "taskgroup reference expression requested for non taskgroup or " 552 "parallel/worksharing directive."); 553 return getTopOfStack().TaskgroupReductionRef; 554 } 555 /// Checks if the given \p VD declaration is actually a taskgroup reduction 556 /// descriptor variable at the \p Level of OpenMP regions. 557 bool isTaskgroupReductionRef(const ValueDecl *VD, unsigned Level) const { 558 return getStackElemAtLevel(Level).TaskgroupReductionRef && 559 cast<DeclRefExpr>(getStackElemAtLevel(Level).TaskgroupReductionRef) 560 ->getDecl() == VD; 561 } 562 563 /// Returns data sharing attributes from top of the stack for the 564 /// specified declaration. 565 const DSAVarData getTopDSA(ValueDecl *D, bool FromParent); 566 /// Returns data-sharing attributes for the specified declaration. 567 const DSAVarData getImplicitDSA(ValueDecl *D, bool FromParent) const; 568 /// Returns data-sharing attributes for the specified declaration. 569 const DSAVarData getImplicitDSA(ValueDecl *D, unsigned Level) const; 570 /// Checks if the specified variables has data-sharing attributes which 571 /// match specified \a CPred predicate in any directive which matches \a DPred 572 /// predicate. 573 const DSAVarData 574 hasDSA(ValueDecl *D, 575 const llvm::function_ref<bool(OpenMPClauseKind, bool)> CPred, 576 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred, 577 bool FromParent) const; 578 /// Checks if the specified variables has data-sharing attributes which 579 /// match specified \a CPred predicate in any innermost directive which 580 /// matches \a DPred predicate. 581 const DSAVarData 582 hasInnermostDSA(ValueDecl *D, 583 const llvm::function_ref<bool(OpenMPClauseKind, bool)> CPred, 584 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred, 585 bool FromParent) const; 586 /// Checks if the specified variables has explicit data-sharing 587 /// attributes which match specified \a CPred predicate at the specified 588 /// OpenMP region. 589 bool 590 hasExplicitDSA(const ValueDecl *D, 591 const llvm::function_ref<bool(OpenMPClauseKind, bool)> CPred, 592 unsigned Level, bool NotLastprivate = false) const; 593 594 /// Returns true if the directive at level \Level matches in the 595 /// specified \a DPred predicate. 596 bool hasExplicitDirective( 597 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred, 598 unsigned Level) const; 599 600 /// Finds a directive which matches specified \a DPred predicate. 601 bool hasDirective( 602 const llvm::function_ref<bool( 603 OpenMPDirectiveKind, const DeclarationNameInfo &, SourceLocation)> 604 DPred, 605 bool FromParent) const; 606 607 /// Returns currently analyzed directive. 608 OpenMPDirectiveKind getCurrentDirective() const { 609 const SharingMapTy *Top = getTopOfStackOrNull(); 610 return Top ? Top->Directive : OMPD_unknown; 611 } 612 /// Returns directive kind at specified level. 613 OpenMPDirectiveKind getDirective(unsigned Level) const { 614 assert(!isStackEmpty() && "No directive at specified level."); 615 return getStackElemAtLevel(Level).Directive; 616 } 617 /// Returns the capture region at the specified level. 618 OpenMPDirectiveKind getCaptureRegion(unsigned Level, 619 unsigned OpenMPCaptureLevel) const { 620 SmallVector<OpenMPDirectiveKind, 4> CaptureRegions; 621 getOpenMPCaptureRegions(CaptureRegions, getDirective(Level)); 622 return CaptureRegions[OpenMPCaptureLevel]; 623 } 624 /// Returns parent directive. 625 OpenMPDirectiveKind getParentDirective() const { 626 const SharingMapTy *Parent = getSecondOnStackOrNull(); 627 return Parent ? Parent->Directive : OMPD_unknown; 628 } 629 630 /// Add requires decl to internal vector 631 void addRequiresDecl(OMPRequiresDecl *RD) { 632 RequiresDecls.push_back(RD); 633 } 634 635 /// Checks if the defined 'requires' directive has specified type of clause. 636 template <typename ClauseType> 637 bool hasRequiresDeclWithClause() const { 638 return llvm::any_of(RequiresDecls, [](const OMPRequiresDecl *D) { 639 return llvm::any_of(D->clauselists(), [](const OMPClause *C) { 640 return isa<ClauseType>(C); 641 }); 642 }); 643 } 644 645 /// Checks for a duplicate clause amongst previously declared requires 646 /// directives 647 bool hasDuplicateRequiresClause(ArrayRef<OMPClause *> ClauseList) const { 648 bool IsDuplicate = false; 649 for (OMPClause *CNew : ClauseList) { 650 for (const OMPRequiresDecl *D : RequiresDecls) { 651 for (const OMPClause *CPrev : D->clauselists()) { 652 if (CNew->getClauseKind() == CPrev->getClauseKind()) { 653 SemaRef.Diag(CNew->getBeginLoc(), 654 diag::err_omp_requires_clause_redeclaration) 655 << getOpenMPClauseName(CNew->getClauseKind()); 656 SemaRef.Diag(CPrev->getBeginLoc(), 657 diag::note_omp_requires_previous_clause) 658 << getOpenMPClauseName(CPrev->getClauseKind()); 659 IsDuplicate = true; 660 } 661 } 662 } 663 } 664 return IsDuplicate; 665 } 666 667 /// Add location of previously encountered target to internal vector 668 void addTargetDirLocation(SourceLocation LocStart) { 669 TargetLocations.push_back(LocStart); 670 } 671 672 /// Add location for the first encountered atomicc directive. 673 void addAtomicDirectiveLoc(SourceLocation Loc) { 674 if (AtomicLocation.isInvalid()) 675 AtomicLocation = Loc; 676 } 677 678 /// Returns the location of the first encountered atomic directive in the 679 /// module. 680 SourceLocation getAtomicDirectiveLoc() const { 681 return AtomicLocation; 682 } 683 684 // Return previously encountered target region locations. 685 ArrayRef<SourceLocation> getEncounteredTargetLocs() const { 686 return TargetLocations; 687 } 688 689 /// Set default data sharing attribute to none. 690 void setDefaultDSANone(SourceLocation Loc) { 691 getTopOfStack().DefaultAttr = DSA_none; 692 getTopOfStack().DefaultAttrLoc = Loc; 693 } 694 /// Set default data sharing attribute to shared. 695 void setDefaultDSAShared(SourceLocation Loc) { 696 getTopOfStack().DefaultAttr = DSA_shared; 697 getTopOfStack().DefaultAttrLoc = Loc; 698 } 699 /// Set default data sharing attribute to firstprivate. 700 void setDefaultDSAFirstPrivate(SourceLocation Loc) { 701 getTopOfStack().DefaultAttr = DSA_firstprivate; 702 getTopOfStack().DefaultAttrLoc = Loc; 703 } 704 /// Set default data mapping attribute to Modifier:Kind 705 void setDefaultDMAAttr(OpenMPDefaultmapClauseModifier M, 706 OpenMPDefaultmapClauseKind Kind, 707 SourceLocation Loc) { 708 DefaultmapInfo &DMI = getTopOfStack().DefaultmapMap[Kind]; 709 DMI.ImplicitBehavior = M; 710 DMI.SLoc = Loc; 711 } 712 /// Check whether the implicit-behavior has been set in defaultmap 713 bool checkDefaultmapCategory(OpenMPDefaultmapClauseKind VariableCategory) { 714 if (VariableCategory == OMPC_DEFAULTMAP_unknown) 715 return getTopOfStack() 716 .DefaultmapMap[OMPC_DEFAULTMAP_aggregate] 717 .ImplicitBehavior != OMPC_DEFAULTMAP_MODIFIER_unknown || 718 getTopOfStack() 719 .DefaultmapMap[OMPC_DEFAULTMAP_scalar] 720 .ImplicitBehavior != OMPC_DEFAULTMAP_MODIFIER_unknown || 721 getTopOfStack() 722 .DefaultmapMap[OMPC_DEFAULTMAP_pointer] 723 .ImplicitBehavior != OMPC_DEFAULTMAP_MODIFIER_unknown; 724 return getTopOfStack().DefaultmapMap[VariableCategory].ImplicitBehavior != 725 OMPC_DEFAULTMAP_MODIFIER_unknown; 726 } 727 728 DefaultDataSharingAttributes getDefaultDSA(unsigned Level) const { 729 return getStackSize() <= Level ? DSA_unspecified 730 : getStackElemAtLevel(Level).DefaultAttr; 731 } 732 DefaultDataSharingAttributes getDefaultDSA() const { 733 return isStackEmpty() ? DSA_unspecified 734 : getTopOfStack().DefaultAttr; 735 } 736 SourceLocation getDefaultDSALocation() const { 737 return isStackEmpty() ? SourceLocation() 738 : getTopOfStack().DefaultAttrLoc; 739 } 740 OpenMPDefaultmapClauseModifier 741 getDefaultmapModifier(OpenMPDefaultmapClauseKind Kind) const { 742 return isStackEmpty() 743 ? OMPC_DEFAULTMAP_MODIFIER_unknown 744 : getTopOfStack().DefaultmapMap[Kind].ImplicitBehavior; 745 } 746 OpenMPDefaultmapClauseModifier 747 getDefaultmapModifierAtLevel(unsigned Level, 748 OpenMPDefaultmapClauseKind Kind) const { 749 return getStackElemAtLevel(Level).DefaultmapMap[Kind].ImplicitBehavior; 750 } 751 bool isDefaultmapCapturedByRef(unsigned Level, 752 OpenMPDefaultmapClauseKind Kind) const { 753 OpenMPDefaultmapClauseModifier M = 754 getDefaultmapModifierAtLevel(Level, Kind); 755 if (Kind == OMPC_DEFAULTMAP_scalar || Kind == OMPC_DEFAULTMAP_pointer) { 756 return (M == OMPC_DEFAULTMAP_MODIFIER_alloc) || 757 (M == OMPC_DEFAULTMAP_MODIFIER_to) || 758 (M == OMPC_DEFAULTMAP_MODIFIER_from) || 759 (M == OMPC_DEFAULTMAP_MODIFIER_tofrom); 760 } 761 return true; 762 } 763 static bool mustBeFirstprivateBase(OpenMPDefaultmapClauseModifier M, 764 OpenMPDefaultmapClauseKind Kind) { 765 switch (Kind) { 766 case OMPC_DEFAULTMAP_scalar: 767 case OMPC_DEFAULTMAP_pointer: 768 return (M == OMPC_DEFAULTMAP_MODIFIER_unknown) || 769 (M == OMPC_DEFAULTMAP_MODIFIER_firstprivate) || 770 (M == OMPC_DEFAULTMAP_MODIFIER_default); 771 case OMPC_DEFAULTMAP_aggregate: 772 return M == OMPC_DEFAULTMAP_MODIFIER_firstprivate; 773 default: 774 break; 775 } 776 llvm_unreachable("Unexpected OpenMPDefaultmapClauseKind enum"); 777 } 778 bool mustBeFirstprivateAtLevel(unsigned Level, 779 OpenMPDefaultmapClauseKind Kind) const { 780 OpenMPDefaultmapClauseModifier M = 781 getDefaultmapModifierAtLevel(Level, Kind); 782 return mustBeFirstprivateBase(M, Kind); 783 } 784 bool mustBeFirstprivate(OpenMPDefaultmapClauseKind Kind) const { 785 OpenMPDefaultmapClauseModifier M = getDefaultmapModifier(Kind); 786 return mustBeFirstprivateBase(M, Kind); 787 } 788 789 /// Checks if the specified variable is a threadprivate. 790 bool isThreadPrivate(VarDecl *D) { 791 const DSAVarData DVar = getTopDSA(D, false); 792 return isOpenMPThreadPrivate(DVar.CKind); 793 } 794 795 /// Marks current region as ordered (it has an 'ordered' clause). 796 void setOrderedRegion(bool IsOrdered, const Expr *Param, 797 OMPOrderedClause *Clause) { 798 if (IsOrdered) 799 getTopOfStack().OrderedRegion.emplace(Param, Clause); 800 else 801 getTopOfStack().OrderedRegion.reset(); 802 } 803 /// Returns true, if region is ordered (has associated 'ordered' clause), 804 /// false - otherwise. 805 bool isOrderedRegion() const { 806 if (const SharingMapTy *Top = getTopOfStackOrNull()) 807 return Top->OrderedRegion.hasValue(); 808 return false; 809 } 810 /// Returns optional parameter for the ordered region. 811 std::pair<const Expr *, OMPOrderedClause *> getOrderedRegionParam() const { 812 if (const SharingMapTy *Top = getTopOfStackOrNull()) 813 if (Top->OrderedRegion.hasValue()) 814 return Top->OrderedRegion.getValue(); 815 return std::make_pair(nullptr, nullptr); 816 } 817 /// Returns true, if parent region is ordered (has associated 818 /// 'ordered' clause), false - otherwise. 819 bool isParentOrderedRegion() const { 820 if (const SharingMapTy *Parent = getSecondOnStackOrNull()) 821 return Parent->OrderedRegion.hasValue(); 822 return false; 823 } 824 /// Returns optional parameter for the ordered region. 825 std::pair<const Expr *, OMPOrderedClause *> 826 getParentOrderedRegionParam() const { 827 if (const SharingMapTy *Parent = getSecondOnStackOrNull()) 828 if (Parent->OrderedRegion.hasValue()) 829 return Parent->OrderedRegion.getValue(); 830 return std::make_pair(nullptr, nullptr); 831 } 832 /// Marks current region as nowait (it has a 'nowait' clause). 833 void setNowaitRegion(bool IsNowait = true) { 834 getTopOfStack().NowaitRegion = IsNowait; 835 } 836 /// Returns true, if parent region is nowait (has associated 837 /// 'nowait' clause), false - otherwise. 838 bool isParentNowaitRegion() const { 839 if (const SharingMapTy *Parent = getSecondOnStackOrNull()) 840 return Parent->NowaitRegion; 841 return false; 842 } 843 /// Marks parent region as cancel region. 844 void setParentCancelRegion(bool Cancel = true) { 845 if (SharingMapTy *Parent = getSecondOnStackOrNull()) 846 Parent->CancelRegion |= Cancel; 847 } 848 /// Return true if current region has inner cancel construct. 849 bool isCancelRegion() const { 850 const SharingMapTy *Top = getTopOfStackOrNull(); 851 return Top ? Top->CancelRegion : false; 852 } 853 854 /// Mark that parent region already has scan directive. 855 void setParentHasScanDirective(SourceLocation Loc) { 856 if (SharingMapTy *Parent = getSecondOnStackOrNull()) 857 Parent->PrevScanLocation = Loc; 858 } 859 /// Return true if current region has inner cancel construct. 860 bool doesParentHasScanDirective() const { 861 const SharingMapTy *Top = getSecondOnStackOrNull(); 862 return Top ? Top->PrevScanLocation.isValid() : false; 863 } 864 /// Return true if current region has inner cancel construct. 865 SourceLocation getParentScanDirectiveLoc() const { 866 const SharingMapTy *Top = getSecondOnStackOrNull(); 867 return Top ? Top->PrevScanLocation : SourceLocation(); 868 } 869 /// Mark that parent region already has ordered directive. 870 void setParentHasOrderedDirective(SourceLocation Loc) { 871 if (SharingMapTy *Parent = getSecondOnStackOrNull()) 872 Parent->PrevOrderedLocation = Loc; 873 } 874 /// Return true if current region has inner ordered construct. 875 bool doesParentHasOrderedDirective() const { 876 const SharingMapTy *Top = getSecondOnStackOrNull(); 877 return Top ? Top->PrevOrderedLocation.isValid() : false; 878 } 879 /// Returns the location of the previously specified ordered directive. 880 SourceLocation getParentOrderedDirectiveLoc() const { 881 const SharingMapTy *Top = getSecondOnStackOrNull(); 882 return Top ? Top->PrevOrderedLocation : SourceLocation(); 883 } 884 885 /// Set collapse value for the region. 886 void setAssociatedLoops(unsigned Val) { 887 getTopOfStack().AssociatedLoops = Val; 888 if (Val > 1) 889 getTopOfStack().HasMutipleLoops = true; 890 } 891 /// Return collapse value for region. 892 unsigned getAssociatedLoops() const { 893 const SharingMapTy *Top = getTopOfStackOrNull(); 894 return Top ? Top->AssociatedLoops : 0; 895 } 896 /// Returns true if the construct is associated with multiple loops. 897 bool hasMutipleLoops() const { 898 const SharingMapTy *Top = getTopOfStackOrNull(); 899 return Top ? Top->HasMutipleLoops : false; 900 } 901 902 /// Marks current target region as one with closely nested teams 903 /// region. 904 void setParentTeamsRegionLoc(SourceLocation TeamsRegionLoc) { 905 if (SharingMapTy *Parent = getSecondOnStackOrNull()) 906 Parent->InnerTeamsRegionLoc = TeamsRegionLoc; 907 } 908 /// Returns true, if current region has closely nested teams region. 909 bool hasInnerTeamsRegion() const { 910 return getInnerTeamsRegionLoc().isValid(); 911 } 912 /// Returns location of the nested teams region (if any). 913 SourceLocation getInnerTeamsRegionLoc() const { 914 const SharingMapTy *Top = getTopOfStackOrNull(); 915 return Top ? Top->InnerTeamsRegionLoc : SourceLocation(); 916 } 917 918 Scope *getCurScope() const { 919 const SharingMapTy *Top = getTopOfStackOrNull(); 920 return Top ? Top->CurScope : nullptr; 921 } 922 void setContext(DeclContext *DC) { getTopOfStack().Context = DC; } 923 SourceLocation getConstructLoc() const { 924 const SharingMapTy *Top = getTopOfStackOrNull(); 925 return Top ? Top->ConstructLoc : SourceLocation(); 926 } 927 928 /// Do the check specified in \a Check to all component lists and return true 929 /// if any issue is found. 930 bool checkMappableExprComponentListsForDecl( 931 const ValueDecl *VD, bool CurrentRegionOnly, 932 const llvm::function_ref< 933 bool(OMPClauseMappableExprCommon::MappableExprComponentListRef, 934 OpenMPClauseKind)> 935 Check) const { 936 if (isStackEmpty()) 937 return false; 938 auto SI = begin(); 939 auto SE = end(); 940 941 if (SI == SE) 942 return false; 943 944 if (CurrentRegionOnly) 945 SE = std::next(SI); 946 else 947 std::advance(SI, 1); 948 949 for (; SI != SE; ++SI) { 950 auto MI = SI->MappedExprComponents.find(VD); 951 if (MI != SI->MappedExprComponents.end()) 952 for (OMPClauseMappableExprCommon::MappableExprComponentListRef L : 953 MI->second.Components) 954 if (Check(L, MI->second.Kind)) 955 return true; 956 } 957 return false; 958 } 959 960 /// Do the check specified in \a Check to all component lists at a given level 961 /// and return true if any issue is found. 962 bool checkMappableExprComponentListsForDeclAtLevel( 963 const ValueDecl *VD, unsigned Level, 964 const llvm::function_ref< 965 bool(OMPClauseMappableExprCommon::MappableExprComponentListRef, 966 OpenMPClauseKind)> 967 Check) const { 968 if (getStackSize() <= Level) 969 return false; 970 971 const SharingMapTy &StackElem = getStackElemAtLevel(Level); 972 auto MI = StackElem.MappedExprComponents.find(VD); 973 if (MI != StackElem.MappedExprComponents.end()) 974 for (OMPClauseMappableExprCommon::MappableExprComponentListRef L : 975 MI->second.Components) 976 if (Check(L, MI->second.Kind)) 977 return true; 978 return false; 979 } 980 981 /// Create a new mappable expression component list associated with a given 982 /// declaration and initialize it with the provided list of components. 983 void addMappableExpressionComponents( 984 const ValueDecl *VD, 985 OMPClauseMappableExprCommon::MappableExprComponentListRef Components, 986 OpenMPClauseKind WhereFoundClauseKind) { 987 MappedExprComponentTy &MEC = getTopOfStack().MappedExprComponents[VD]; 988 // Create new entry and append the new components there. 989 MEC.Components.resize(MEC.Components.size() + 1); 990 MEC.Components.back().append(Components.begin(), Components.end()); 991 MEC.Kind = WhereFoundClauseKind; 992 } 993 994 unsigned getNestingLevel() const { 995 assert(!isStackEmpty()); 996 return getStackSize() - 1; 997 } 998 void addDoacrossDependClause(OMPDependClause *C, 999 const OperatorOffsetTy &OpsOffs) { 1000 SharingMapTy *Parent = getSecondOnStackOrNull(); 1001 assert(Parent && isOpenMPWorksharingDirective(Parent->Directive)); 1002 Parent->DoacrossDepends.try_emplace(C, OpsOffs); 1003 } 1004 llvm::iterator_range<DoacrossDependMapTy::const_iterator> 1005 getDoacrossDependClauses() const { 1006 const SharingMapTy &StackElem = getTopOfStack(); 1007 if (isOpenMPWorksharingDirective(StackElem.Directive)) { 1008 const DoacrossDependMapTy &Ref = StackElem.DoacrossDepends; 1009 return llvm::make_range(Ref.begin(), Ref.end()); 1010 } 1011 return llvm::make_range(StackElem.DoacrossDepends.end(), 1012 StackElem.DoacrossDepends.end()); 1013 } 1014 1015 // Store types of classes which have been explicitly mapped 1016 void addMappedClassesQualTypes(QualType QT) { 1017 SharingMapTy &StackElem = getTopOfStack(); 1018 StackElem.MappedClassesQualTypes.insert(QT); 1019 } 1020 1021 // Return set of mapped classes types 1022 bool isClassPreviouslyMapped(QualType QT) const { 1023 const SharingMapTy &StackElem = getTopOfStack(); 1024 return StackElem.MappedClassesQualTypes.count(QT) != 0; 1025 } 1026 1027 /// Adds global declare target to the parent target region. 1028 void addToParentTargetRegionLinkGlobals(DeclRefExpr *E) { 1029 assert(*OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration( 1030 E->getDecl()) == OMPDeclareTargetDeclAttr::MT_Link && 1031 "Expected declare target link global."); 1032 for (auto &Elem : *this) { 1033 if (isOpenMPTargetExecutionDirective(Elem.Directive)) { 1034 Elem.DeclareTargetLinkVarDecls.push_back(E); 1035 return; 1036 } 1037 } 1038 } 1039 1040 /// Returns the list of globals with declare target link if current directive 1041 /// is target. 1042 ArrayRef<DeclRefExpr *> getLinkGlobals() const { 1043 assert(isOpenMPTargetExecutionDirective(getCurrentDirective()) && 1044 "Expected target executable directive."); 1045 return getTopOfStack().DeclareTargetLinkVarDecls; 1046 } 1047 1048 /// Adds list of allocators expressions. 1049 void addInnerAllocatorExpr(Expr *E) { 1050 getTopOfStack().InnerUsedAllocators.push_back(E); 1051 } 1052 /// Return list of used allocators. 1053 ArrayRef<Expr *> getInnerAllocators() const { 1054 return getTopOfStack().InnerUsedAllocators; 1055 } 1056 /// Marks the declaration as implicitly firstprivate nin the task-based 1057 /// regions. 1058 void addImplicitTaskFirstprivate(unsigned Level, Decl *D) { 1059 getStackElemAtLevel(Level).ImplicitTaskFirstprivates.insert(D); 1060 } 1061 /// Checks if the decl is implicitly firstprivate in the task-based region. 1062 bool isImplicitTaskFirstprivate(Decl *D) const { 1063 return getTopOfStack().ImplicitTaskFirstprivates.count(D) > 0; 1064 } 1065 1066 /// Marks decl as used in uses_allocators clause as the allocator. 1067 void addUsesAllocatorsDecl(const Decl *D, UsesAllocatorsDeclKind Kind) { 1068 getTopOfStack().UsesAllocatorsDecls.try_emplace(D, Kind); 1069 } 1070 /// Checks if specified decl is used in uses allocator clause as the 1071 /// allocator. 1072 Optional<UsesAllocatorsDeclKind> isUsesAllocatorsDecl(unsigned Level, 1073 const Decl *D) const { 1074 const SharingMapTy &StackElem = getTopOfStack(); 1075 auto I = StackElem.UsesAllocatorsDecls.find(D); 1076 if (I == StackElem.UsesAllocatorsDecls.end()) 1077 return None; 1078 return I->getSecond(); 1079 } 1080 Optional<UsesAllocatorsDeclKind> isUsesAllocatorsDecl(const Decl *D) const { 1081 const SharingMapTy &StackElem = getTopOfStack(); 1082 auto I = StackElem.UsesAllocatorsDecls.find(D); 1083 if (I == StackElem.UsesAllocatorsDecls.end()) 1084 return None; 1085 return I->getSecond(); 1086 } 1087 1088 void addDeclareMapperVarRef(Expr *Ref) { 1089 SharingMapTy &StackElem = getTopOfStack(); 1090 StackElem.DeclareMapperVar = Ref; 1091 } 1092 const Expr *getDeclareMapperVarRef() const { 1093 const SharingMapTy *Top = getTopOfStackOrNull(); 1094 return Top ? Top->DeclareMapperVar : nullptr; 1095 } 1096 }; 1097 1098 bool isImplicitTaskingRegion(OpenMPDirectiveKind DKind) { 1099 return isOpenMPParallelDirective(DKind) || isOpenMPTeamsDirective(DKind); 1100 } 1101 1102 bool isImplicitOrExplicitTaskingRegion(OpenMPDirectiveKind DKind) { 1103 return isImplicitTaskingRegion(DKind) || isOpenMPTaskingDirective(DKind) || 1104 DKind == OMPD_unknown; 1105 } 1106 1107 } // namespace 1108 1109 static const Expr *getExprAsWritten(const Expr *E) { 1110 if (const auto *FE = dyn_cast<FullExpr>(E)) 1111 E = FE->getSubExpr(); 1112 1113 if (const auto *MTE = dyn_cast<MaterializeTemporaryExpr>(E)) 1114 E = MTE->getSubExpr(); 1115 1116 while (const auto *Binder = dyn_cast<CXXBindTemporaryExpr>(E)) 1117 E = Binder->getSubExpr(); 1118 1119 if (const auto *ICE = dyn_cast<ImplicitCastExpr>(E)) 1120 E = ICE->getSubExprAsWritten(); 1121 return E->IgnoreParens(); 1122 } 1123 1124 static Expr *getExprAsWritten(Expr *E) { 1125 return const_cast<Expr *>(getExprAsWritten(const_cast<const Expr *>(E))); 1126 } 1127 1128 static const ValueDecl *getCanonicalDecl(const ValueDecl *D) { 1129 if (const auto *CED = dyn_cast<OMPCapturedExprDecl>(D)) 1130 if (const auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit()))) 1131 D = ME->getMemberDecl(); 1132 const auto *VD = dyn_cast<VarDecl>(D); 1133 const auto *FD = dyn_cast<FieldDecl>(D); 1134 if (VD != nullptr) { 1135 VD = VD->getCanonicalDecl(); 1136 D = VD; 1137 } else { 1138 assert(FD); 1139 FD = FD->getCanonicalDecl(); 1140 D = FD; 1141 } 1142 return D; 1143 } 1144 1145 static ValueDecl *getCanonicalDecl(ValueDecl *D) { 1146 return const_cast<ValueDecl *>( 1147 getCanonicalDecl(const_cast<const ValueDecl *>(D))); 1148 } 1149 1150 DSAStackTy::DSAVarData DSAStackTy::getDSA(const_iterator &Iter, 1151 ValueDecl *D) const { 1152 D = getCanonicalDecl(D); 1153 auto *VD = dyn_cast<VarDecl>(D); 1154 const auto *FD = dyn_cast<FieldDecl>(D); 1155 DSAVarData DVar; 1156 if (Iter == end()) { 1157 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 1158 // in a region but not in construct] 1159 // File-scope or namespace-scope variables referenced in called routines 1160 // in the region are shared unless they appear in a threadprivate 1161 // directive. 1162 if (VD && !VD->isFunctionOrMethodVarDecl() && !isa<ParmVarDecl>(VD)) 1163 DVar.CKind = OMPC_shared; 1164 1165 // OpenMP [2.9.1.2, Data-sharing Attribute Rules for Variables Referenced 1166 // in a region but not in construct] 1167 // Variables with static storage duration that are declared in called 1168 // routines in the region are shared. 1169 if (VD && VD->hasGlobalStorage()) 1170 DVar.CKind = OMPC_shared; 1171 1172 // Non-static data members are shared by default. 1173 if (FD) 1174 DVar.CKind = OMPC_shared; 1175 1176 return DVar; 1177 } 1178 1179 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 1180 // in a Construct, C/C++, predetermined, p.1] 1181 // Variables with automatic storage duration that are declared in a scope 1182 // inside the construct are private. 1183 if (VD && isOpenMPLocal(VD, Iter) && VD->isLocalVarDecl() && 1184 (VD->getStorageClass() == SC_Auto || VD->getStorageClass() == SC_None)) { 1185 DVar.CKind = OMPC_private; 1186 return DVar; 1187 } 1188 1189 DVar.DKind = Iter->Directive; 1190 // Explicitly specified attributes and local variables with predetermined 1191 // attributes. 1192 if (Iter->SharingMap.count(D)) { 1193 const DSAInfo &Data = Iter->SharingMap.lookup(D); 1194 DVar.RefExpr = Data.RefExpr.getPointer(); 1195 DVar.PrivateCopy = Data.PrivateCopy; 1196 DVar.CKind = Data.Attributes; 1197 DVar.ImplicitDSALoc = Iter->DefaultAttrLoc; 1198 DVar.Modifier = Data.Modifier; 1199 DVar.AppliedToPointee = Data.AppliedToPointee; 1200 return DVar; 1201 } 1202 1203 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 1204 // in a Construct, C/C++, implicitly determined, p.1] 1205 // In a parallel or task construct, the data-sharing attributes of these 1206 // variables are determined by the default clause, if present. 1207 switch (Iter->DefaultAttr) { 1208 case DSA_shared: 1209 DVar.CKind = OMPC_shared; 1210 DVar.ImplicitDSALoc = Iter->DefaultAttrLoc; 1211 return DVar; 1212 case DSA_none: 1213 return DVar; 1214 case DSA_firstprivate: 1215 if (VD->getStorageDuration() == SD_Static && 1216 VD->getDeclContext()->isFileContext()) { 1217 DVar.CKind = OMPC_unknown; 1218 } else { 1219 DVar.CKind = OMPC_firstprivate; 1220 } 1221 DVar.ImplicitDSALoc = Iter->DefaultAttrLoc; 1222 return DVar; 1223 case DSA_unspecified: 1224 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 1225 // in a Construct, implicitly determined, p.2] 1226 // In a parallel construct, if no default clause is present, these 1227 // variables are shared. 1228 DVar.ImplicitDSALoc = Iter->DefaultAttrLoc; 1229 if ((isOpenMPParallelDirective(DVar.DKind) && 1230 !isOpenMPTaskLoopDirective(DVar.DKind)) || 1231 isOpenMPTeamsDirective(DVar.DKind)) { 1232 DVar.CKind = OMPC_shared; 1233 return DVar; 1234 } 1235 1236 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 1237 // in a Construct, implicitly determined, p.4] 1238 // In a task construct, if no default clause is present, a variable that in 1239 // the enclosing context is determined to be shared by all implicit tasks 1240 // bound to the current team is shared. 1241 if (isOpenMPTaskingDirective(DVar.DKind)) { 1242 DSAVarData DVarTemp; 1243 const_iterator I = Iter, E = end(); 1244 do { 1245 ++I; 1246 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables 1247 // Referenced in a Construct, implicitly determined, p.6] 1248 // In a task construct, if no default clause is present, a variable 1249 // whose data-sharing attribute is not determined by the rules above is 1250 // firstprivate. 1251 DVarTemp = getDSA(I, D); 1252 if (DVarTemp.CKind != OMPC_shared) { 1253 DVar.RefExpr = nullptr; 1254 DVar.CKind = OMPC_firstprivate; 1255 return DVar; 1256 } 1257 } while (I != E && !isImplicitTaskingRegion(I->Directive)); 1258 DVar.CKind = 1259 (DVarTemp.CKind == OMPC_unknown) ? OMPC_firstprivate : OMPC_shared; 1260 return DVar; 1261 } 1262 } 1263 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 1264 // in a Construct, implicitly determined, p.3] 1265 // For constructs other than task, if no default clause is present, these 1266 // variables inherit their data-sharing attributes from the enclosing 1267 // context. 1268 return getDSA(++Iter, D); 1269 } 1270 1271 const Expr *DSAStackTy::addUniqueAligned(const ValueDecl *D, 1272 const Expr *NewDE) { 1273 assert(!isStackEmpty() && "Data sharing attributes stack is empty"); 1274 D = getCanonicalDecl(D); 1275 SharingMapTy &StackElem = getTopOfStack(); 1276 auto It = StackElem.AlignedMap.find(D); 1277 if (It == StackElem.AlignedMap.end()) { 1278 assert(NewDE && "Unexpected nullptr expr to be added into aligned map"); 1279 StackElem.AlignedMap[D] = NewDE; 1280 return nullptr; 1281 } 1282 assert(It->second && "Unexpected nullptr expr in the aligned map"); 1283 return It->second; 1284 } 1285 1286 const Expr *DSAStackTy::addUniqueNontemporal(const ValueDecl *D, 1287 const Expr *NewDE) { 1288 assert(!isStackEmpty() && "Data sharing attributes stack is empty"); 1289 D = getCanonicalDecl(D); 1290 SharingMapTy &StackElem = getTopOfStack(); 1291 auto It = StackElem.NontemporalMap.find(D); 1292 if (It == StackElem.NontemporalMap.end()) { 1293 assert(NewDE && "Unexpected nullptr expr to be added into aligned map"); 1294 StackElem.NontemporalMap[D] = NewDE; 1295 return nullptr; 1296 } 1297 assert(It->second && "Unexpected nullptr expr in the aligned map"); 1298 return It->second; 1299 } 1300 1301 void DSAStackTy::addLoopControlVariable(const ValueDecl *D, VarDecl *Capture) { 1302 assert(!isStackEmpty() && "Data-sharing attributes stack is empty"); 1303 D = getCanonicalDecl(D); 1304 SharingMapTy &StackElem = getTopOfStack(); 1305 StackElem.LCVMap.try_emplace( 1306 D, LCDeclInfo(StackElem.LCVMap.size() + 1, Capture)); 1307 } 1308 1309 const DSAStackTy::LCDeclInfo 1310 DSAStackTy::isLoopControlVariable(const ValueDecl *D) const { 1311 assert(!isStackEmpty() && "Data-sharing attributes stack is empty"); 1312 D = getCanonicalDecl(D); 1313 const SharingMapTy &StackElem = getTopOfStack(); 1314 auto It = StackElem.LCVMap.find(D); 1315 if (It != StackElem.LCVMap.end()) 1316 return It->second; 1317 return {0, nullptr}; 1318 } 1319 1320 const DSAStackTy::LCDeclInfo 1321 DSAStackTy::isLoopControlVariable(const ValueDecl *D, unsigned Level) const { 1322 assert(!isStackEmpty() && "Data-sharing attributes stack is empty"); 1323 D = getCanonicalDecl(D); 1324 for (unsigned I = Level + 1; I > 0; --I) { 1325 const SharingMapTy &StackElem = getStackElemAtLevel(I - 1); 1326 auto It = StackElem.LCVMap.find(D); 1327 if (It != StackElem.LCVMap.end()) 1328 return It->second; 1329 } 1330 return {0, nullptr}; 1331 } 1332 1333 const DSAStackTy::LCDeclInfo 1334 DSAStackTy::isParentLoopControlVariable(const ValueDecl *D) const { 1335 const SharingMapTy *Parent = getSecondOnStackOrNull(); 1336 assert(Parent && "Data-sharing attributes stack is empty"); 1337 D = getCanonicalDecl(D); 1338 auto It = Parent->LCVMap.find(D); 1339 if (It != Parent->LCVMap.end()) 1340 return It->second; 1341 return {0, nullptr}; 1342 } 1343 1344 const ValueDecl *DSAStackTy::getParentLoopControlVariable(unsigned I) const { 1345 const SharingMapTy *Parent = getSecondOnStackOrNull(); 1346 assert(Parent && "Data-sharing attributes stack is empty"); 1347 if (Parent->LCVMap.size() < I) 1348 return nullptr; 1349 for (const auto &Pair : Parent->LCVMap) 1350 if (Pair.second.first == I) 1351 return Pair.first; 1352 return nullptr; 1353 } 1354 1355 void DSAStackTy::addDSA(const ValueDecl *D, const Expr *E, OpenMPClauseKind A, 1356 DeclRefExpr *PrivateCopy, unsigned Modifier, 1357 bool AppliedToPointee) { 1358 D = getCanonicalDecl(D); 1359 if (A == OMPC_threadprivate) { 1360 DSAInfo &Data = Threadprivates[D]; 1361 Data.Attributes = A; 1362 Data.RefExpr.setPointer(E); 1363 Data.PrivateCopy = nullptr; 1364 Data.Modifier = Modifier; 1365 } else { 1366 DSAInfo &Data = getTopOfStack().SharingMap[D]; 1367 assert(Data.Attributes == OMPC_unknown || (A == Data.Attributes) || 1368 (A == OMPC_firstprivate && Data.Attributes == OMPC_lastprivate) || 1369 (A == OMPC_lastprivate && Data.Attributes == OMPC_firstprivate) || 1370 (isLoopControlVariable(D).first && A == OMPC_private)); 1371 Data.Modifier = Modifier; 1372 if (A == OMPC_lastprivate && Data.Attributes == OMPC_firstprivate) { 1373 Data.RefExpr.setInt(/*IntVal=*/true); 1374 return; 1375 } 1376 const bool IsLastprivate = 1377 A == OMPC_lastprivate || Data.Attributes == OMPC_lastprivate; 1378 Data.Attributes = A; 1379 Data.RefExpr.setPointerAndInt(E, IsLastprivate); 1380 Data.PrivateCopy = PrivateCopy; 1381 Data.AppliedToPointee = AppliedToPointee; 1382 if (PrivateCopy) { 1383 DSAInfo &Data = getTopOfStack().SharingMap[PrivateCopy->getDecl()]; 1384 Data.Modifier = Modifier; 1385 Data.Attributes = A; 1386 Data.RefExpr.setPointerAndInt(PrivateCopy, IsLastprivate); 1387 Data.PrivateCopy = nullptr; 1388 Data.AppliedToPointee = AppliedToPointee; 1389 } 1390 } 1391 } 1392 1393 /// Build a variable declaration for OpenMP loop iteration variable. 1394 static VarDecl *buildVarDecl(Sema &SemaRef, SourceLocation Loc, QualType Type, 1395 StringRef Name, const AttrVec *Attrs = nullptr, 1396 DeclRefExpr *OrigRef = nullptr) { 1397 DeclContext *DC = SemaRef.CurContext; 1398 IdentifierInfo *II = &SemaRef.PP.getIdentifierTable().get(Name); 1399 TypeSourceInfo *TInfo = SemaRef.Context.getTrivialTypeSourceInfo(Type, Loc); 1400 auto *Decl = 1401 VarDecl::Create(SemaRef.Context, DC, Loc, Loc, II, Type, TInfo, SC_None); 1402 if (Attrs) { 1403 for (specific_attr_iterator<AlignedAttr> I(Attrs->begin()), E(Attrs->end()); 1404 I != E; ++I) 1405 Decl->addAttr(*I); 1406 } 1407 Decl->setImplicit(); 1408 if (OrigRef) { 1409 Decl->addAttr( 1410 OMPReferencedVarAttr::CreateImplicit(SemaRef.Context, OrigRef)); 1411 } 1412 return Decl; 1413 } 1414 1415 static DeclRefExpr *buildDeclRefExpr(Sema &S, VarDecl *D, QualType Ty, 1416 SourceLocation Loc, 1417 bool RefersToCapture = false) { 1418 D->setReferenced(); 1419 D->markUsed(S.Context); 1420 return DeclRefExpr::Create(S.getASTContext(), NestedNameSpecifierLoc(), 1421 SourceLocation(), D, RefersToCapture, Loc, Ty, 1422 VK_LValue); 1423 } 1424 1425 void DSAStackTy::addTaskgroupReductionData(const ValueDecl *D, SourceRange SR, 1426 BinaryOperatorKind BOK) { 1427 D = getCanonicalDecl(D); 1428 assert(!isStackEmpty() && "Data-sharing attributes stack is empty"); 1429 assert( 1430 getTopOfStack().SharingMap[D].Attributes == OMPC_reduction && 1431 "Additional reduction info may be specified only for reduction items."); 1432 ReductionData &ReductionData = getTopOfStack().ReductionMap[D]; 1433 assert(ReductionData.ReductionRange.isInvalid() && 1434 (getTopOfStack().Directive == OMPD_taskgroup || 1435 ((isOpenMPParallelDirective(getTopOfStack().Directive) || 1436 isOpenMPWorksharingDirective(getTopOfStack().Directive)) && 1437 !isOpenMPSimdDirective(getTopOfStack().Directive))) && 1438 "Additional reduction info may be specified only once for reduction " 1439 "items."); 1440 ReductionData.set(BOK, SR); 1441 Expr *&TaskgroupReductionRef = 1442 getTopOfStack().TaskgroupReductionRef; 1443 if (!TaskgroupReductionRef) { 1444 VarDecl *VD = buildVarDecl(SemaRef, SR.getBegin(), 1445 SemaRef.Context.VoidPtrTy, ".task_red."); 1446 TaskgroupReductionRef = 1447 buildDeclRefExpr(SemaRef, VD, SemaRef.Context.VoidPtrTy, SR.getBegin()); 1448 } 1449 } 1450 1451 void DSAStackTy::addTaskgroupReductionData(const ValueDecl *D, SourceRange SR, 1452 const Expr *ReductionRef) { 1453 D = getCanonicalDecl(D); 1454 assert(!isStackEmpty() && "Data-sharing attributes stack is empty"); 1455 assert( 1456 getTopOfStack().SharingMap[D].Attributes == OMPC_reduction && 1457 "Additional reduction info may be specified only for reduction items."); 1458 ReductionData &ReductionData = getTopOfStack().ReductionMap[D]; 1459 assert(ReductionData.ReductionRange.isInvalid() && 1460 (getTopOfStack().Directive == OMPD_taskgroup || 1461 ((isOpenMPParallelDirective(getTopOfStack().Directive) || 1462 isOpenMPWorksharingDirective(getTopOfStack().Directive)) && 1463 !isOpenMPSimdDirective(getTopOfStack().Directive))) && 1464 "Additional reduction info may be specified only once for reduction " 1465 "items."); 1466 ReductionData.set(ReductionRef, SR); 1467 Expr *&TaskgroupReductionRef = 1468 getTopOfStack().TaskgroupReductionRef; 1469 if (!TaskgroupReductionRef) { 1470 VarDecl *VD = buildVarDecl(SemaRef, SR.getBegin(), 1471 SemaRef.Context.VoidPtrTy, ".task_red."); 1472 TaskgroupReductionRef = 1473 buildDeclRefExpr(SemaRef, VD, SemaRef.Context.VoidPtrTy, SR.getBegin()); 1474 } 1475 } 1476 1477 const DSAStackTy::DSAVarData DSAStackTy::getTopMostTaskgroupReductionData( 1478 const ValueDecl *D, SourceRange &SR, BinaryOperatorKind &BOK, 1479 Expr *&TaskgroupDescriptor) const { 1480 D = getCanonicalDecl(D); 1481 assert(!isStackEmpty() && "Data-sharing attributes stack is empty."); 1482 for (const_iterator I = begin() + 1, E = end(); I != E; ++I) { 1483 const DSAInfo &Data = I->SharingMap.lookup(D); 1484 if (Data.Attributes != OMPC_reduction || 1485 Data.Modifier != OMPC_REDUCTION_task) 1486 continue; 1487 const ReductionData &ReductionData = I->ReductionMap.lookup(D); 1488 if (!ReductionData.ReductionOp || 1489 ReductionData.ReductionOp.is<const Expr *>()) 1490 return DSAVarData(); 1491 SR = ReductionData.ReductionRange; 1492 BOK = ReductionData.ReductionOp.get<ReductionData::BOKPtrType>(); 1493 assert(I->TaskgroupReductionRef && "taskgroup reduction reference " 1494 "expression for the descriptor is not " 1495 "set."); 1496 TaskgroupDescriptor = I->TaskgroupReductionRef; 1497 return DSAVarData(I->Directive, OMPC_reduction, Data.RefExpr.getPointer(), 1498 Data.PrivateCopy, I->DefaultAttrLoc, OMPC_REDUCTION_task, 1499 /*AppliedToPointee=*/false); 1500 } 1501 return DSAVarData(); 1502 } 1503 1504 const DSAStackTy::DSAVarData DSAStackTy::getTopMostTaskgroupReductionData( 1505 const ValueDecl *D, SourceRange &SR, const Expr *&ReductionRef, 1506 Expr *&TaskgroupDescriptor) const { 1507 D = getCanonicalDecl(D); 1508 assert(!isStackEmpty() && "Data-sharing attributes stack is empty."); 1509 for (const_iterator I = begin() + 1, E = end(); I != E; ++I) { 1510 const DSAInfo &Data = I->SharingMap.lookup(D); 1511 if (Data.Attributes != OMPC_reduction || 1512 Data.Modifier != OMPC_REDUCTION_task) 1513 continue; 1514 const ReductionData &ReductionData = I->ReductionMap.lookup(D); 1515 if (!ReductionData.ReductionOp || 1516 !ReductionData.ReductionOp.is<const Expr *>()) 1517 return DSAVarData(); 1518 SR = ReductionData.ReductionRange; 1519 ReductionRef = ReductionData.ReductionOp.get<const Expr *>(); 1520 assert(I->TaskgroupReductionRef && "taskgroup reduction reference " 1521 "expression for the descriptor is not " 1522 "set."); 1523 TaskgroupDescriptor = I->TaskgroupReductionRef; 1524 return DSAVarData(I->Directive, OMPC_reduction, Data.RefExpr.getPointer(), 1525 Data.PrivateCopy, I->DefaultAttrLoc, OMPC_REDUCTION_task, 1526 /*AppliedToPointee=*/false); 1527 } 1528 return DSAVarData(); 1529 } 1530 1531 bool DSAStackTy::isOpenMPLocal(VarDecl *D, const_iterator I) const { 1532 D = D->getCanonicalDecl(); 1533 for (const_iterator E = end(); I != E; ++I) { 1534 if (isImplicitOrExplicitTaskingRegion(I->Directive) || 1535 isOpenMPTargetExecutionDirective(I->Directive)) { 1536 if (I->CurScope) { 1537 Scope *TopScope = I->CurScope->getParent(); 1538 Scope *CurScope = getCurScope(); 1539 while (CurScope && CurScope != TopScope && !CurScope->isDeclScope(D)) 1540 CurScope = CurScope->getParent(); 1541 return CurScope != TopScope; 1542 } 1543 for (DeclContext *DC = D->getDeclContext(); DC; DC = DC->getParent()) 1544 if (I->Context == DC) 1545 return true; 1546 return false; 1547 } 1548 } 1549 return false; 1550 } 1551 1552 static bool isConstNotMutableType(Sema &SemaRef, QualType Type, 1553 bool AcceptIfMutable = true, 1554 bool *IsClassType = nullptr) { 1555 ASTContext &Context = SemaRef.getASTContext(); 1556 Type = Type.getNonReferenceType().getCanonicalType(); 1557 bool IsConstant = Type.isConstant(Context); 1558 Type = Context.getBaseElementType(Type); 1559 const CXXRecordDecl *RD = AcceptIfMutable && SemaRef.getLangOpts().CPlusPlus 1560 ? Type->getAsCXXRecordDecl() 1561 : nullptr; 1562 if (const auto *CTSD = dyn_cast_or_null<ClassTemplateSpecializationDecl>(RD)) 1563 if (const ClassTemplateDecl *CTD = CTSD->getSpecializedTemplate()) 1564 RD = CTD->getTemplatedDecl(); 1565 if (IsClassType) 1566 *IsClassType = RD; 1567 return IsConstant && !(SemaRef.getLangOpts().CPlusPlus && RD && 1568 RD->hasDefinition() && RD->hasMutableFields()); 1569 } 1570 1571 static bool rejectConstNotMutableType(Sema &SemaRef, const ValueDecl *D, 1572 QualType Type, OpenMPClauseKind CKind, 1573 SourceLocation ELoc, 1574 bool AcceptIfMutable = true, 1575 bool ListItemNotVar = false) { 1576 ASTContext &Context = SemaRef.getASTContext(); 1577 bool IsClassType; 1578 if (isConstNotMutableType(SemaRef, Type, AcceptIfMutable, &IsClassType)) { 1579 unsigned Diag = ListItemNotVar 1580 ? diag::err_omp_const_list_item 1581 : IsClassType ? diag::err_omp_const_not_mutable_variable 1582 : diag::err_omp_const_variable; 1583 SemaRef.Diag(ELoc, Diag) << getOpenMPClauseName(CKind); 1584 if (!ListItemNotVar && D) { 1585 const VarDecl *VD = dyn_cast<VarDecl>(D); 1586 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) == 1587 VarDecl::DeclarationOnly; 1588 SemaRef.Diag(D->getLocation(), 1589 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 1590 << D; 1591 } 1592 return true; 1593 } 1594 return false; 1595 } 1596 1597 const DSAStackTy::DSAVarData DSAStackTy::getTopDSA(ValueDecl *D, 1598 bool FromParent) { 1599 D = getCanonicalDecl(D); 1600 DSAVarData DVar; 1601 1602 auto *VD = dyn_cast<VarDecl>(D); 1603 auto TI = Threadprivates.find(D); 1604 if (TI != Threadprivates.end()) { 1605 DVar.RefExpr = TI->getSecond().RefExpr.getPointer(); 1606 DVar.CKind = OMPC_threadprivate; 1607 DVar.Modifier = TI->getSecond().Modifier; 1608 return DVar; 1609 } 1610 if (VD && VD->hasAttr<OMPThreadPrivateDeclAttr>()) { 1611 DVar.RefExpr = buildDeclRefExpr( 1612 SemaRef, VD, D->getType().getNonReferenceType(), 1613 VD->getAttr<OMPThreadPrivateDeclAttr>()->getLocation()); 1614 DVar.CKind = OMPC_threadprivate; 1615 addDSA(D, DVar.RefExpr, OMPC_threadprivate); 1616 return DVar; 1617 } 1618 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 1619 // in a Construct, C/C++, predetermined, p.1] 1620 // Variables appearing in threadprivate directives are threadprivate. 1621 if ((VD && VD->getTLSKind() != VarDecl::TLS_None && 1622 !(VD->hasAttr<OMPThreadPrivateDeclAttr>() && 1623 SemaRef.getLangOpts().OpenMPUseTLS && 1624 SemaRef.getASTContext().getTargetInfo().isTLSSupported())) || 1625 (VD && VD->getStorageClass() == SC_Register && 1626 VD->hasAttr<AsmLabelAttr>() && !VD->isLocalVarDecl())) { 1627 DVar.RefExpr = buildDeclRefExpr( 1628 SemaRef, VD, D->getType().getNonReferenceType(), D->getLocation()); 1629 DVar.CKind = OMPC_threadprivate; 1630 addDSA(D, DVar.RefExpr, OMPC_threadprivate); 1631 return DVar; 1632 } 1633 if (SemaRef.getLangOpts().OpenMPCUDAMode && VD && 1634 VD->isLocalVarDeclOrParm() && !isStackEmpty() && 1635 !isLoopControlVariable(D).first) { 1636 const_iterator IterTarget = 1637 std::find_if(begin(), end(), [](const SharingMapTy &Data) { 1638 return isOpenMPTargetExecutionDirective(Data.Directive); 1639 }); 1640 if (IterTarget != end()) { 1641 const_iterator ParentIterTarget = IterTarget + 1; 1642 for (const_iterator Iter = begin(); 1643 Iter != ParentIterTarget; ++Iter) { 1644 if (isOpenMPLocal(VD, Iter)) { 1645 DVar.RefExpr = 1646 buildDeclRefExpr(SemaRef, VD, D->getType().getNonReferenceType(), 1647 D->getLocation()); 1648 DVar.CKind = OMPC_threadprivate; 1649 return DVar; 1650 } 1651 } 1652 if (!isClauseParsingMode() || IterTarget != begin()) { 1653 auto DSAIter = IterTarget->SharingMap.find(D); 1654 if (DSAIter != IterTarget->SharingMap.end() && 1655 isOpenMPPrivate(DSAIter->getSecond().Attributes)) { 1656 DVar.RefExpr = DSAIter->getSecond().RefExpr.getPointer(); 1657 DVar.CKind = OMPC_threadprivate; 1658 return DVar; 1659 } 1660 const_iterator End = end(); 1661 if (!SemaRef.isOpenMPCapturedByRef( 1662 D, std::distance(ParentIterTarget, End), 1663 /*OpenMPCaptureLevel=*/0)) { 1664 DVar.RefExpr = 1665 buildDeclRefExpr(SemaRef, VD, D->getType().getNonReferenceType(), 1666 IterTarget->ConstructLoc); 1667 DVar.CKind = OMPC_threadprivate; 1668 return DVar; 1669 } 1670 } 1671 } 1672 } 1673 1674 if (isStackEmpty()) 1675 // Not in OpenMP execution region and top scope was already checked. 1676 return DVar; 1677 1678 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 1679 // in a Construct, C/C++, predetermined, p.4] 1680 // Static data members are shared. 1681 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 1682 // in a Construct, C/C++, predetermined, p.7] 1683 // Variables with static storage duration that are declared in a scope 1684 // inside the construct are shared. 1685 if (VD && VD->isStaticDataMember()) { 1686 // Check for explicitly specified attributes. 1687 const_iterator I = begin(); 1688 const_iterator EndI = end(); 1689 if (FromParent && I != EndI) 1690 ++I; 1691 if (I != EndI) { 1692 auto It = I->SharingMap.find(D); 1693 if (It != I->SharingMap.end()) { 1694 const DSAInfo &Data = It->getSecond(); 1695 DVar.RefExpr = Data.RefExpr.getPointer(); 1696 DVar.PrivateCopy = Data.PrivateCopy; 1697 DVar.CKind = Data.Attributes; 1698 DVar.ImplicitDSALoc = I->DefaultAttrLoc; 1699 DVar.DKind = I->Directive; 1700 DVar.Modifier = Data.Modifier; 1701 DVar.AppliedToPointee = Data.AppliedToPointee; 1702 return DVar; 1703 } 1704 } 1705 1706 DVar.CKind = OMPC_shared; 1707 return DVar; 1708 } 1709 1710 auto &&MatchesAlways = [](OpenMPDirectiveKind) { return true; }; 1711 // The predetermined shared attribute for const-qualified types having no 1712 // mutable members was removed after OpenMP 3.1. 1713 if (SemaRef.LangOpts.OpenMP <= 31) { 1714 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 1715 // in a Construct, C/C++, predetermined, p.6] 1716 // Variables with const qualified type having no mutable member are 1717 // shared. 1718 if (isConstNotMutableType(SemaRef, D->getType())) { 1719 // Variables with const-qualified type having no mutable member may be 1720 // listed in a firstprivate clause, even if they are static data members. 1721 DSAVarData DVarTemp = hasInnermostDSA( 1722 D, 1723 [](OpenMPClauseKind C, bool) { 1724 return C == OMPC_firstprivate || C == OMPC_shared; 1725 }, 1726 MatchesAlways, FromParent); 1727 if (DVarTemp.CKind != OMPC_unknown && DVarTemp.RefExpr) 1728 return DVarTemp; 1729 1730 DVar.CKind = OMPC_shared; 1731 return DVar; 1732 } 1733 } 1734 1735 // Explicitly specified attributes and local variables with predetermined 1736 // attributes. 1737 const_iterator I = begin(); 1738 const_iterator EndI = end(); 1739 if (FromParent && I != EndI) 1740 ++I; 1741 if (I == EndI) 1742 return DVar; 1743 auto It = I->SharingMap.find(D); 1744 if (It != I->SharingMap.end()) { 1745 const DSAInfo &Data = It->getSecond(); 1746 DVar.RefExpr = Data.RefExpr.getPointer(); 1747 DVar.PrivateCopy = Data.PrivateCopy; 1748 DVar.CKind = Data.Attributes; 1749 DVar.ImplicitDSALoc = I->DefaultAttrLoc; 1750 DVar.DKind = I->Directive; 1751 DVar.Modifier = Data.Modifier; 1752 DVar.AppliedToPointee = Data.AppliedToPointee; 1753 } 1754 1755 return DVar; 1756 } 1757 1758 const DSAStackTy::DSAVarData DSAStackTy::getImplicitDSA(ValueDecl *D, 1759 bool FromParent) const { 1760 if (isStackEmpty()) { 1761 const_iterator I; 1762 return getDSA(I, D); 1763 } 1764 D = getCanonicalDecl(D); 1765 const_iterator StartI = begin(); 1766 const_iterator EndI = end(); 1767 if (FromParent && StartI != EndI) 1768 ++StartI; 1769 return getDSA(StartI, D); 1770 } 1771 1772 const DSAStackTy::DSAVarData DSAStackTy::getImplicitDSA(ValueDecl *D, 1773 unsigned Level) const { 1774 if (getStackSize() <= Level) 1775 return DSAVarData(); 1776 D = getCanonicalDecl(D); 1777 const_iterator StartI = std::next(begin(), getStackSize() - 1 - Level); 1778 return getDSA(StartI, D); 1779 } 1780 1781 const DSAStackTy::DSAVarData 1782 DSAStackTy::hasDSA(ValueDecl *D, 1783 const llvm::function_ref<bool(OpenMPClauseKind, bool)> CPred, 1784 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred, 1785 bool FromParent) const { 1786 if (isStackEmpty()) 1787 return {}; 1788 D = getCanonicalDecl(D); 1789 const_iterator I = begin(); 1790 const_iterator EndI = end(); 1791 if (FromParent && I != EndI) 1792 ++I; 1793 for (; I != EndI; ++I) { 1794 if (!DPred(I->Directive) && 1795 !isImplicitOrExplicitTaskingRegion(I->Directive)) 1796 continue; 1797 const_iterator NewI = I; 1798 DSAVarData DVar = getDSA(NewI, D); 1799 if (I == NewI && CPred(DVar.CKind, DVar.AppliedToPointee)) 1800 return DVar; 1801 } 1802 return {}; 1803 } 1804 1805 const DSAStackTy::DSAVarData DSAStackTy::hasInnermostDSA( 1806 ValueDecl *D, const llvm::function_ref<bool(OpenMPClauseKind, bool)> CPred, 1807 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred, 1808 bool FromParent) const { 1809 if (isStackEmpty()) 1810 return {}; 1811 D = getCanonicalDecl(D); 1812 const_iterator StartI = begin(); 1813 const_iterator EndI = end(); 1814 if (FromParent && StartI != EndI) 1815 ++StartI; 1816 if (StartI == EndI || !DPred(StartI->Directive)) 1817 return {}; 1818 const_iterator NewI = StartI; 1819 DSAVarData DVar = getDSA(NewI, D); 1820 return (NewI == StartI && CPred(DVar.CKind, DVar.AppliedToPointee)) 1821 ? DVar 1822 : DSAVarData(); 1823 } 1824 1825 bool DSAStackTy::hasExplicitDSA( 1826 const ValueDecl *D, 1827 const llvm::function_ref<bool(OpenMPClauseKind, bool)> CPred, 1828 unsigned Level, bool NotLastprivate) const { 1829 if (getStackSize() <= Level) 1830 return false; 1831 D = getCanonicalDecl(D); 1832 const SharingMapTy &StackElem = getStackElemAtLevel(Level); 1833 auto I = StackElem.SharingMap.find(D); 1834 if (I != StackElem.SharingMap.end() && I->getSecond().RefExpr.getPointer() && 1835 CPred(I->getSecond().Attributes, I->getSecond().AppliedToPointee) && 1836 (!NotLastprivate || !I->getSecond().RefExpr.getInt())) 1837 return true; 1838 // Check predetermined rules for the loop control variables. 1839 auto LI = StackElem.LCVMap.find(D); 1840 if (LI != StackElem.LCVMap.end()) 1841 return CPred(OMPC_private, /*AppliedToPointee=*/false); 1842 return false; 1843 } 1844 1845 bool DSAStackTy::hasExplicitDirective( 1846 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred, 1847 unsigned Level) const { 1848 if (getStackSize() <= Level) 1849 return false; 1850 const SharingMapTy &StackElem = getStackElemAtLevel(Level); 1851 return DPred(StackElem.Directive); 1852 } 1853 1854 bool DSAStackTy::hasDirective( 1855 const llvm::function_ref<bool(OpenMPDirectiveKind, 1856 const DeclarationNameInfo &, SourceLocation)> 1857 DPred, 1858 bool FromParent) const { 1859 // We look only in the enclosing region. 1860 size_t Skip = FromParent ? 2 : 1; 1861 for (const_iterator I = begin() + std::min(Skip, getStackSize()), E = end(); 1862 I != E; ++I) { 1863 if (DPred(I->Directive, I->DirectiveName, I->ConstructLoc)) 1864 return true; 1865 } 1866 return false; 1867 } 1868 1869 void Sema::InitDataSharingAttributesStack() { 1870 VarDataSharingAttributesStack = new DSAStackTy(*this); 1871 } 1872 1873 #define DSAStack static_cast<DSAStackTy *>(VarDataSharingAttributesStack) 1874 1875 void Sema::pushOpenMPFunctionRegion() { 1876 DSAStack->pushFunction(); 1877 } 1878 1879 void Sema::popOpenMPFunctionRegion(const FunctionScopeInfo *OldFSI) { 1880 DSAStack->popFunction(OldFSI); 1881 } 1882 1883 static bool isOpenMPDeviceDelayedContext(Sema &S) { 1884 assert(S.LangOpts.OpenMP && S.LangOpts.OpenMPIsDevice && 1885 "Expected OpenMP device compilation."); 1886 return !S.isInOpenMPTargetExecutionDirective() && 1887 !S.isInOpenMPDeclareTargetContext(); 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::DeviceDiagBuilder Sema::diagIfOpenMPDeviceCode(SourceLocation Loc, 1900 unsigned DiagID) { 1901 assert(LangOpts.OpenMP && LangOpts.OpenMPIsDevice && 1902 "Expected OpenMP device compilation."); 1903 1904 FunctionDecl *FD = getCurFunctionDecl(); 1905 DeviceDiagBuilder::Kind Kind = DeviceDiagBuilder::K_Nop; 1906 if (FD) { 1907 FunctionEmissionStatus FES = getEmissionStatus(FD); 1908 switch (FES) { 1909 case FunctionEmissionStatus::Emitted: 1910 Kind = DeviceDiagBuilder::K_Immediate; 1911 break; 1912 case FunctionEmissionStatus::Unknown: 1913 Kind = isOpenMPDeviceDelayedContext(*this) 1914 ? DeviceDiagBuilder::K_Deferred 1915 : DeviceDiagBuilder::K_Immediate; 1916 break; 1917 case FunctionEmissionStatus::TemplateDiscarded: 1918 case FunctionEmissionStatus::OMPDiscarded: 1919 Kind = DeviceDiagBuilder::K_Nop; 1920 break; 1921 case FunctionEmissionStatus::CUDADiscarded: 1922 llvm_unreachable("CUDADiscarded unexpected in OpenMP device compilation"); 1923 break; 1924 } 1925 } 1926 1927 return DeviceDiagBuilder(Kind, Loc, DiagID, getCurFunctionDecl(), *this); 1928 } 1929 1930 Sema::DeviceDiagBuilder Sema::diagIfOpenMPHostCode(SourceLocation Loc, 1931 unsigned DiagID) { 1932 assert(LangOpts.OpenMP && !LangOpts.OpenMPIsDevice && 1933 "Expected OpenMP host compilation."); 1934 FunctionEmissionStatus FES = getEmissionStatus(getCurFunctionDecl()); 1935 DeviceDiagBuilder::Kind Kind = DeviceDiagBuilder::K_Nop; 1936 switch (FES) { 1937 case FunctionEmissionStatus::Emitted: 1938 Kind = DeviceDiagBuilder::K_Immediate; 1939 break; 1940 case FunctionEmissionStatus::Unknown: 1941 Kind = DeviceDiagBuilder::K_Deferred; 1942 break; 1943 case FunctionEmissionStatus::TemplateDiscarded: 1944 case FunctionEmissionStatus::OMPDiscarded: 1945 case FunctionEmissionStatus::CUDADiscarded: 1946 Kind = DeviceDiagBuilder::K_Nop; 1947 break; 1948 } 1949 1950 return DeviceDiagBuilder(Kind, Loc, DiagID, getCurFunctionDecl(), *this); 1951 } 1952 1953 static OpenMPDefaultmapClauseKind 1954 getVariableCategoryFromDecl(const LangOptions &LO, const ValueDecl *VD) { 1955 if (LO.OpenMP <= 45) { 1956 if (VD->getType().getNonReferenceType()->isScalarType()) 1957 return OMPC_DEFAULTMAP_scalar; 1958 return OMPC_DEFAULTMAP_aggregate; 1959 } 1960 if (VD->getType().getNonReferenceType()->isAnyPointerType()) 1961 return OMPC_DEFAULTMAP_pointer; 1962 if (VD->getType().getNonReferenceType()->isScalarType()) 1963 return OMPC_DEFAULTMAP_scalar; 1964 return OMPC_DEFAULTMAP_aggregate; 1965 } 1966 1967 bool Sema::isOpenMPCapturedByRef(const ValueDecl *D, unsigned Level, 1968 unsigned OpenMPCaptureLevel) const { 1969 assert(LangOpts.OpenMP && "OpenMP is not allowed"); 1970 1971 ASTContext &Ctx = getASTContext(); 1972 bool IsByRef = true; 1973 1974 // Find the directive that is associated with the provided scope. 1975 D = cast<ValueDecl>(D->getCanonicalDecl()); 1976 QualType Ty = D->getType(); 1977 1978 bool IsVariableUsedInMapClause = false; 1979 if (DSAStack->hasExplicitDirective(isOpenMPTargetExecutionDirective, Level)) { 1980 // This table summarizes how a given variable should be passed to the device 1981 // given its type and the clauses where it appears. This table is based on 1982 // the description in OpenMP 4.5 [2.10.4, target Construct] and 1983 // OpenMP 4.5 [2.15.5, Data-mapping Attribute Rules and Clauses]. 1984 // 1985 // ========================================================================= 1986 // | type | defaultmap | pvt | first | is_device_ptr | map | res. | 1987 // | |(tofrom:scalar)| | pvt | | | | 1988 // ========================================================================= 1989 // | scl | | | | - | | bycopy| 1990 // | scl | | - | x | - | - | bycopy| 1991 // | scl | | x | - | - | - | null | 1992 // | scl | x | | | - | | byref | 1993 // | scl | x | - | x | - | - | bycopy| 1994 // | scl | x | x | - | - | - | null | 1995 // | scl | | - | - | - | x | byref | 1996 // | scl | x | - | - | - | x | byref | 1997 // 1998 // | agg | n.a. | | | - | | byref | 1999 // | agg | n.a. | - | x | - | - | byref | 2000 // | agg | n.a. | x | - | - | - | null | 2001 // | agg | n.a. | - | - | - | x | byref | 2002 // | agg | n.a. | - | - | - | x[] | byref | 2003 // 2004 // | ptr | n.a. | | | - | | bycopy| 2005 // | ptr | n.a. | - | x | - | - | bycopy| 2006 // | ptr | n.a. | x | - | - | - | null | 2007 // | ptr | n.a. | - | - | - | x | byref | 2008 // | ptr | n.a. | - | - | - | x[] | bycopy| 2009 // | ptr | n.a. | - | - | x | | bycopy| 2010 // | ptr | n.a. | - | - | x | x | bycopy| 2011 // | ptr | n.a. | - | - | x | x[] | bycopy| 2012 // ========================================================================= 2013 // Legend: 2014 // scl - scalar 2015 // ptr - pointer 2016 // agg - aggregate 2017 // x - applies 2018 // - - invalid in this combination 2019 // [] - mapped with an array section 2020 // byref - should be mapped by reference 2021 // byval - should be mapped by value 2022 // null - initialize a local variable to null on the device 2023 // 2024 // Observations: 2025 // - All scalar declarations that show up in a map clause have to be passed 2026 // by reference, because they may have been mapped in the enclosing data 2027 // environment. 2028 // - If the scalar value does not fit the size of uintptr, it has to be 2029 // passed by reference, regardless the result in the table above. 2030 // - For pointers mapped by value that have either an implicit map or an 2031 // array section, the runtime library may pass the NULL value to the 2032 // device instead of the value passed to it by the compiler. 2033 2034 if (Ty->isReferenceType()) 2035 Ty = Ty->castAs<ReferenceType>()->getPointeeType(); 2036 2037 // Locate map clauses and see if the variable being captured is referred to 2038 // in any of those clauses. Here we only care about variables, not fields, 2039 // because fields are part of aggregates. 2040 bool IsVariableAssociatedWithSection = false; 2041 2042 DSAStack->checkMappableExprComponentListsForDeclAtLevel( 2043 D, Level, 2044 [&IsVariableUsedInMapClause, &IsVariableAssociatedWithSection, D]( 2045 OMPClauseMappableExprCommon::MappableExprComponentListRef 2046 MapExprComponents, 2047 OpenMPClauseKind WhereFoundClauseKind) { 2048 // Only the map clause information influences how a variable is 2049 // captured. E.g. is_device_ptr does not require changing the default 2050 // behavior. 2051 if (WhereFoundClauseKind != OMPC_map) 2052 return false; 2053 2054 auto EI = MapExprComponents.rbegin(); 2055 auto EE = MapExprComponents.rend(); 2056 2057 assert(EI != EE && "Invalid map expression!"); 2058 2059 if (isa<DeclRefExpr>(EI->getAssociatedExpression())) 2060 IsVariableUsedInMapClause |= EI->getAssociatedDeclaration() == D; 2061 2062 ++EI; 2063 if (EI == EE) 2064 return false; 2065 2066 if (isa<ArraySubscriptExpr>(EI->getAssociatedExpression()) || 2067 isa<OMPArraySectionExpr>(EI->getAssociatedExpression()) || 2068 isa<MemberExpr>(EI->getAssociatedExpression()) || 2069 isa<OMPArrayShapingExpr>(EI->getAssociatedExpression())) { 2070 IsVariableAssociatedWithSection = true; 2071 // There is nothing more we need to know about this variable. 2072 return true; 2073 } 2074 2075 // Keep looking for more map info. 2076 return false; 2077 }); 2078 2079 if (IsVariableUsedInMapClause) { 2080 // If variable is identified in a map clause it is always captured by 2081 // reference except if it is a pointer that is dereferenced somehow. 2082 IsByRef = !(Ty->isPointerType() && IsVariableAssociatedWithSection); 2083 } else { 2084 // By default, all the data that has a scalar type is mapped by copy 2085 // (except for reduction variables). 2086 // Defaultmap scalar is mutual exclusive to defaultmap pointer 2087 IsByRef = (DSAStack->isForceCaptureByReferenceInTargetExecutable() && 2088 !Ty->isAnyPointerType()) || 2089 !Ty->isScalarType() || 2090 DSAStack->isDefaultmapCapturedByRef( 2091 Level, getVariableCategoryFromDecl(LangOpts, D)) || 2092 DSAStack->hasExplicitDSA( 2093 D, 2094 [](OpenMPClauseKind K, bool AppliedToPointee) { 2095 return K == OMPC_reduction && !AppliedToPointee; 2096 }, 2097 Level); 2098 } 2099 } 2100 2101 if (IsByRef && Ty.getNonReferenceType()->isScalarType()) { 2102 IsByRef = 2103 ((IsVariableUsedInMapClause && 2104 DSAStack->getCaptureRegion(Level, OpenMPCaptureLevel) == 2105 OMPD_target) || 2106 !(DSAStack->hasExplicitDSA( 2107 D, 2108 [](OpenMPClauseKind K, bool AppliedToPointee) -> bool { 2109 return K == OMPC_firstprivate || 2110 (K == OMPC_reduction && AppliedToPointee); 2111 }, 2112 Level, /*NotLastprivate=*/true) || 2113 DSAStack->isUsesAllocatorsDecl(Level, D))) && 2114 // If the variable is artificial and must be captured by value - try to 2115 // capture by value. 2116 !(isa<OMPCapturedExprDecl>(D) && !D->hasAttr<OMPCaptureNoInitAttr>() && 2117 !cast<OMPCapturedExprDecl>(D)->getInit()->isGLValue()) && 2118 // If the variable is implicitly firstprivate and scalar - capture by 2119 // copy 2120 !(DSAStack->getDefaultDSA() == DSA_firstprivate && 2121 !DSAStack->hasExplicitDSA( 2122 D, [](OpenMPClauseKind K, bool) { return K != OMPC_unknown; }, 2123 Level) && 2124 !DSAStack->isLoopControlVariable(D, Level).first); 2125 } 2126 2127 // When passing data by copy, we need to make sure it fits the uintptr size 2128 // and alignment, because the runtime library only deals with uintptr types. 2129 // If it does not fit the uintptr size, we need to pass the data by reference 2130 // instead. 2131 if (!IsByRef && 2132 (Ctx.getTypeSizeInChars(Ty) > 2133 Ctx.getTypeSizeInChars(Ctx.getUIntPtrType()) || 2134 Ctx.getDeclAlign(D) > Ctx.getTypeAlignInChars(Ctx.getUIntPtrType()))) { 2135 IsByRef = true; 2136 } 2137 2138 return IsByRef; 2139 } 2140 2141 unsigned Sema::getOpenMPNestingLevel() const { 2142 assert(getLangOpts().OpenMP); 2143 return DSAStack->getNestingLevel(); 2144 } 2145 2146 bool Sema::isInOpenMPTargetExecutionDirective() const { 2147 return (isOpenMPTargetExecutionDirective(DSAStack->getCurrentDirective()) && 2148 !DSAStack->isClauseParsingMode()) || 2149 DSAStack->hasDirective( 2150 [](OpenMPDirectiveKind K, const DeclarationNameInfo &, 2151 SourceLocation) -> bool { 2152 return isOpenMPTargetExecutionDirective(K); 2153 }, 2154 false); 2155 } 2156 2157 VarDecl *Sema::isOpenMPCapturedDecl(ValueDecl *D, bool CheckScopeInfo, 2158 unsigned StopAt) { 2159 assert(LangOpts.OpenMP && "OpenMP is not allowed"); 2160 D = getCanonicalDecl(D); 2161 2162 auto *VD = dyn_cast<VarDecl>(D); 2163 // Do not capture constexpr variables. 2164 if (VD && VD->isConstexpr()) 2165 return nullptr; 2166 2167 // If we want to determine whether the variable should be captured from the 2168 // perspective of the current capturing scope, and we've already left all the 2169 // capturing scopes of the top directive on the stack, check from the 2170 // perspective of its parent directive (if any) instead. 2171 DSAStackTy::ParentDirectiveScope InParentDirectiveRAII( 2172 *DSAStack, CheckScopeInfo && DSAStack->isBodyComplete()); 2173 2174 // If we are attempting to capture a global variable in a directive with 2175 // 'target' we return true so that this global is also mapped to the device. 2176 // 2177 if (VD && !VD->hasLocalStorage() && 2178 (getCurCapturedRegion() || getCurBlock() || getCurLambda())) { 2179 if (isInOpenMPDeclareTargetContext()) { 2180 // Try to mark variable as declare target if it is used in capturing 2181 // regions. 2182 if (LangOpts.OpenMP <= 45 && 2183 !OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD)) 2184 checkDeclIsAllowedInOpenMPTarget(nullptr, VD); 2185 return nullptr; 2186 } 2187 if (isInOpenMPTargetExecutionDirective()) { 2188 // If the declaration is enclosed in a 'declare target' directive, 2189 // then it should not be captured. 2190 // 2191 if (OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD)) 2192 return nullptr; 2193 CapturedRegionScopeInfo *CSI = nullptr; 2194 for (FunctionScopeInfo *FSI : llvm::drop_begin( 2195 llvm::reverse(FunctionScopes), 2196 CheckScopeInfo ? (FunctionScopes.size() - (StopAt + 1)) : 0)) { 2197 if (!isa<CapturingScopeInfo>(FSI)) 2198 return nullptr; 2199 if (auto *RSI = dyn_cast<CapturedRegionScopeInfo>(FSI)) 2200 if (RSI->CapRegionKind == CR_OpenMP) { 2201 CSI = RSI; 2202 break; 2203 } 2204 } 2205 assert(CSI && "Failed to find CapturedRegionScopeInfo"); 2206 SmallVector<OpenMPDirectiveKind, 4> Regions; 2207 getOpenMPCaptureRegions(Regions, 2208 DSAStack->getDirective(CSI->OpenMPLevel)); 2209 if (Regions[CSI->OpenMPCaptureLevel] != OMPD_task) 2210 return VD; 2211 } 2212 } 2213 2214 if (CheckScopeInfo) { 2215 bool OpenMPFound = false; 2216 for (unsigned I = StopAt + 1; I > 0; --I) { 2217 FunctionScopeInfo *FSI = FunctionScopes[I - 1]; 2218 if(!isa<CapturingScopeInfo>(FSI)) 2219 return nullptr; 2220 if (auto *RSI = dyn_cast<CapturedRegionScopeInfo>(FSI)) 2221 if (RSI->CapRegionKind == CR_OpenMP) { 2222 OpenMPFound = true; 2223 break; 2224 } 2225 } 2226 if (!OpenMPFound) 2227 return nullptr; 2228 } 2229 2230 if (DSAStack->getCurrentDirective() != OMPD_unknown && 2231 (!DSAStack->isClauseParsingMode() || 2232 DSAStack->getParentDirective() != OMPD_unknown)) { 2233 auto &&Info = DSAStack->isLoopControlVariable(D); 2234 if (Info.first || 2235 (VD && VD->hasLocalStorage() && 2236 isImplicitOrExplicitTaskingRegion(DSAStack->getCurrentDirective())) || 2237 (VD && DSAStack->isForceVarCapturing())) 2238 return VD ? VD : Info.second; 2239 DSAStackTy::DSAVarData DVarTop = 2240 DSAStack->getTopDSA(D, DSAStack->isClauseParsingMode()); 2241 if (DVarTop.CKind != OMPC_unknown && isOpenMPPrivate(DVarTop.CKind) && 2242 (!VD || VD->hasLocalStorage() || !DVarTop.AppliedToPointee)) 2243 return VD ? VD : cast<VarDecl>(DVarTop.PrivateCopy->getDecl()); 2244 // Threadprivate variables must not be captured. 2245 if (isOpenMPThreadPrivate(DVarTop.CKind)) 2246 return nullptr; 2247 // The variable is not private or it is the variable in the directive with 2248 // default(none) clause and not used in any clause. 2249 DSAStackTy::DSAVarData DVarPrivate = DSAStack->hasDSA( 2250 D, 2251 [](OpenMPClauseKind C, bool AppliedToPointee) { 2252 return isOpenMPPrivate(C) && !AppliedToPointee; 2253 }, 2254 [](OpenMPDirectiveKind) { return true; }, 2255 DSAStack->isClauseParsingMode()); 2256 // Global shared must not be captured. 2257 if (VD && !VD->hasLocalStorage() && DVarPrivate.CKind == OMPC_unknown && 2258 ((DSAStack->getDefaultDSA() != DSA_none && 2259 DSAStack->getDefaultDSA() != DSA_firstprivate) || 2260 DVarTop.CKind == OMPC_shared)) 2261 return nullptr; 2262 if (DVarPrivate.CKind != OMPC_unknown || 2263 (VD && (DSAStack->getDefaultDSA() == DSA_none || 2264 DSAStack->getDefaultDSA() == DSA_firstprivate))) 2265 return VD ? VD : cast<VarDecl>(DVarPrivate.PrivateCopy->getDecl()); 2266 } 2267 return nullptr; 2268 } 2269 2270 void Sema::adjustOpenMPTargetScopeIndex(unsigned &FunctionScopesIndex, 2271 unsigned Level) const { 2272 FunctionScopesIndex -= getOpenMPCaptureLevels(DSAStack->getDirective(Level)); 2273 } 2274 2275 void Sema::startOpenMPLoop() { 2276 assert(LangOpts.OpenMP && "OpenMP must be enabled."); 2277 if (isOpenMPLoopDirective(DSAStack->getCurrentDirective())) 2278 DSAStack->loopInit(); 2279 } 2280 2281 void Sema::startOpenMPCXXRangeFor() { 2282 assert(LangOpts.OpenMP && "OpenMP must be enabled."); 2283 if (isOpenMPLoopDirective(DSAStack->getCurrentDirective())) { 2284 DSAStack->resetPossibleLoopCounter(); 2285 DSAStack->loopStart(); 2286 } 2287 } 2288 2289 OpenMPClauseKind Sema::isOpenMPPrivateDecl(ValueDecl *D, unsigned Level, 2290 unsigned CapLevel) const { 2291 assert(LangOpts.OpenMP && "OpenMP is not allowed"); 2292 if (DSAStack->hasExplicitDirective( 2293 [](OpenMPDirectiveKind K) { return isOpenMPTaskingDirective(K); }, 2294 Level)) { 2295 bool IsTriviallyCopyable = 2296 D->getType().getNonReferenceType().isTriviallyCopyableType(Context) && 2297 !D->getType() 2298 .getNonReferenceType() 2299 .getCanonicalType() 2300 ->getAsCXXRecordDecl(); 2301 OpenMPDirectiveKind DKind = DSAStack->getDirective(Level); 2302 SmallVector<OpenMPDirectiveKind, 4> CaptureRegions; 2303 getOpenMPCaptureRegions(CaptureRegions, DKind); 2304 if (isOpenMPTaskingDirective(CaptureRegions[CapLevel]) && 2305 (IsTriviallyCopyable || 2306 !isOpenMPTaskLoopDirective(CaptureRegions[CapLevel]))) { 2307 if (DSAStack->hasExplicitDSA( 2308 D, 2309 [](OpenMPClauseKind K, bool) { return K == OMPC_firstprivate; }, 2310 Level, /*NotLastprivate=*/true)) 2311 return OMPC_firstprivate; 2312 DSAStackTy::DSAVarData DVar = DSAStack->getImplicitDSA(D, Level); 2313 if (DVar.CKind != OMPC_shared && 2314 !DSAStack->isLoopControlVariable(D, Level).first && !DVar.RefExpr) { 2315 DSAStack->addImplicitTaskFirstprivate(Level, D); 2316 return OMPC_firstprivate; 2317 } 2318 } 2319 } 2320 if (isOpenMPLoopDirective(DSAStack->getCurrentDirective())) { 2321 if (DSAStack->getAssociatedLoops() > 0 && 2322 !DSAStack->isLoopStarted()) { 2323 DSAStack->resetPossibleLoopCounter(D); 2324 DSAStack->loopStart(); 2325 return OMPC_private; 2326 } 2327 if ((DSAStack->getPossiblyLoopCunter() == D->getCanonicalDecl() || 2328 DSAStack->isLoopControlVariable(D).first) && 2329 !DSAStack->hasExplicitDSA( 2330 D, [](OpenMPClauseKind K, bool) { return K != OMPC_private; }, 2331 Level) && 2332 !isOpenMPSimdDirective(DSAStack->getCurrentDirective())) 2333 return OMPC_private; 2334 } 2335 if (const auto *VD = dyn_cast<VarDecl>(D)) { 2336 if (DSAStack->isThreadPrivate(const_cast<VarDecl *>(VD)) && 2337 DSAStack->isForceVarCapturing() && 2338 !DSAStack->hasExplicitDSA( 2339 D, [](OpenMPClauseKind K, bool) { return K == OMPC_copyin; }, 2340 Level)) 2341 return OMPC_private; 2342 } 2343 // User-defined allocators are private since they must be defined in the 2344 // context of target region. 2345 if (DSAStack->hasExplicitDirective(isOpenMPTargetExecutionDirective, Level) && 2346 DSAStack->isUsesAllocatorsDecl(Level, D).getValueOr( 2347 DSAStackTy::UsesAllocatorsDeclKind::AllocatorTrait) == 2348 DSAStackTy::UsesAllocatorsDeclKind::UserDefinedAllocator) 2349 return OMPC_private; 2350 return (DSAStack->hasExplicitDSA( 2351 D, [](OpenMPClauseKind K, bool) { return K == OMPC_private; }, 2352 Level) || 2353 (DSAStack->isClauseParsingMode() && 2354 DSAStack->getClauseParsingMode() == OMPC_private) || 2355 // Consider taskgroup reduction descriptor variable a private 2356 // to avoid possible capture in the region. 2357 (DSAStack->hasExplicitDirective( 2358 [](OpenMPDirectiveKind K) { 2359 return K == OMPD_taskgroup || 2360 ((isOpenMPParallelDirective(K) || 2361 isOpenMPWorksharingDirective(K)) && 2362 !isOpenMPSimdDirective(K)); 2363 }, 2364 Level) && 2365 DSAStack->isTaskgroupReductionRef(D, Level))) 2366 ? OMPC_private 2367 : OMPC_unknown; 2368 } 2369 2370 void Sema::setOpenMPCaptureKind(FieldDecl *FD, const ValueDecl *D, 2371 unsigned Level) { 2372 assert(LangOpts.OpenMP && "OpenMP is not allowed"); 2373 D = getCanonicalDecl(D); 2374 OpenMPClauseKind OMPC = OMPC_unknown; 2375 for (unsigned I = DSAStack->getNestingLevel() + 1; I > Level; --I) { 2376 const unsigned NewLevel = I - 1; 2377 if (DSAStack->hasExplicitDSA( 2378 D, 2379 [&OMPC](const OpenMPClauseKind K, bool AppliedToPointee) { 2380 if (isOpenMPPrivate(K) && !AppliedToPointee) { 2381 OMPC = K; 2382 return true; 2383 } 2384 return false; 2385 }, 2386 NewLevel)) 2387 break; 2388 if (DSAStack->checkMappableExprComponentListsForDeclAtLevel( 2389 D, NewLevel, 2390 [](OMPClauseMappableExprCommon::MappableExprComponentListRef, 2391 OpenMPClauseKind) { return true; })) { 2392 OMPC = OMPC_map; 2393 break; 2394 } 2395 if (DSAStack->hasExplicitDirective(isOpenMPTargetExecutionDirective, 2396 NewLevel)) { 2397 OMPC = OMPC_map; 2398 if (DSAStack->mustBeFirstprivateAtLevel( 2399 NewLevel, getVariableCategoryFromDecl(LangOpts, D))) 2400 OMPC = OMPC_firstprivate; 2401 break; 2402 } 2403 } 2404 if (OMPC != OMPC_unknown) 2405 FD->addAttr(OMPCaptureKindAttr::CreateImplicit(Context, unsigned(OMPC))); 2406 } 2407 2408 bool Sema::isOpenMPTargetCapturedDecl(const ValueDecl *D, unsigned Level, 2409 unsigned CaptureLevel) const { 2410 assert(LangOpts.OpenMP && "OpenMP is not allowed"); 2411 // Return true if the current level is no longer enclosed in a target region. 2412 2413 SmallVector<OpenMPDirectiveKind, 4> Regions; 2414 getOpenMPCaptureRegions(Regions, DSAStack->getDirective(Level)); 2415 const auto *VD = dyn_cast<VarDecl>(D); 2416 return VD && !VD->hasLocalStorage() && 2417 DSAStack->hasExplicitDirective(isOpenMPTargetExecutionDirective, 2418 Level) && 2419 Regions[CaptureLevel] != OMPD_task; 2420 } 2421 2422 bool Sema::isOpenMPGlobalCapturedDecl(ValueDecl *D, unsigned Level, 2423 unsigned CaptureLevel) const { 2424 assert(LangOpts.OpenMP && "OpenMP is not allowed"); 2425 // Return true if the current level is no longer enclosed in a target region. 2426 2427 if (const auto *VD = dyn_cast<VarDecl>(D)) { 2428 if (!VD->hasLocalStorage()) { 2429 if (isInOpenMPTargetExecutionDirective()) 2430 return true; 2431 DSAStackTy::DSAVarData TopDVar = 2432 DSAStack->getTopDSA(D, /*FromParent=*/false); 2433 unsigned NumLevels = 2434 getOpenMPCaptureLevels(DSAStack->getDirective(Level)); 2435 if (Level == 0) 2436 return (NumLevels == CaptureLevel + 1) && TopDVar.CKind != OMPC_shared; 2437 do { 2438 --Level; 2439 DSAStackTy::DSAVarData DVar = DSAStack->getImplicitDSA(D, Level); 2440 if (DVar.CKind != OMPC_shared) 2441 return true; 2442 } while (Level > 0); 2443 } 2444 } 2445 return true; 2446 } 2447 2448 void Sema::DestroyDataSharingAttributesStack() { delete DSAStack; } 2449 2450 void Sema::ActOnOpenMPBeginDeclareVariant(SourceLocation Loc, 2451 OMPTraitInfo &TI) { 2452 OMPDeclareVariantScopes.push_back(OMPDeclareVariantScope(TI)); 2453 } 2454 2455 void Sema::ActOnOpenMPEndDeclareVariant() { 2456 assert(isInOpenMPDeclareVariantScope() && 2457 "Not in OpenMP declare variant scope!"); 2458 2459 OMPDeclareVariantScopes.pop_back(); 2460 } 2461 2462 void Sema::finalizeOpenMPDelayedAnalysis(const FunctionDecl *Caller, 2463 const FunctionDecl *Callee, 2464 SourceLocation Loc) { 2465 assert(LangOpts.OpenMP && "Expected OpenMP compilation mode."); 2466 Optional<OMPDeclareTargetDeclAttr::DevTypeTy> DevTy = 2467 OMPDeclareTargetDeclAttr::getDeviceType(Caller->getMostRecentDecl()); 2468 // Ignore host functions during device analyzis. 2469 if (LangOpts.OpenMPIsDevice && DevTy && 2470 *DevTy == OMPDeclareTargetDeclAttr::DT_Host) 2471 return; 2472 // Ignore nohost functions during host analyzis. 2473 if (!LangOpts.OpenMPIsDevice && DevTy && 2474 *DevTy == OMPDeclareTargetDeclAttr::DT_NoHost) 2475 return; 2476 const FunctionDecl *FD = Callee->getMostRecentDecl(); 2477 DevTy = OMPDeclareTargetDeclAttr::getDeviceType(FD); 2478 if (LangOpts.OpenMPIsDevice && DevTy && 2479 *DevTy == OMPDeclareTargetDeclAttr::DT_Host) { 2480 // Diagnose host function called during device codegen. 2481 StringRef HostDevTy = 2482 getOpenMPSimpleClauseTypeName(OMPC_device_type, OMPC_DEVICE_TYPE_host); 2483 Diag(Loc, diag::err_omp_wrong_device_function_call) << HostDevTy << 0; 2484 Diag(*OMPDeclareTargetDeclAttr::getLocation(FD), 2485 diag::note_omp_marked_device_type_here) 2486 << HostDevTy; 2487 return; 2488 } 2489 if (!LangOpts.OpenMPIsDevice && DevTy && 2490 *DevTy == OMPDeclareTargetDeclAttr::DT_NoHost) { 2491 // Diagnose nohost function called during host codegen. 2492 StringRef NoHostDevTy = getOpenMPSimpleClauseTypeName( 2493 OMPC_device_type, OMPC_DEVICE_TYPE_nohost); 2494 Diag(Loc, diag::err_omp_wrong_device_function_call) << NoHostDevTy << 1; 2495 Diag(*OMPDeclareTargetDeclAttr::getLocation(FD), 2496 diag::note_omp_marked_device_type_here) 2497 << NoHostDevTy; 2498 } 2499 } 2500 2501 void Sema::StartOpenMPDSABlock(OpenMPDirectiveKind DKind, 2502 const DeclarationNameInfo &DirName, 2503 Scope *CurScope, SourceLocation Loc) { 2504 DSAStack->push(DKind, DirName, CurScope, Loc); 2505 PushExpressionEvaluationContext( 2506 ExpressionEvaluationContext::PotentiallyEvaluated); 2507 } 2508 2509 void Sema::StartOpenMPClause(OpenMPClauseKind K) { 2510 DSAStack->setClauseParsingMode(K); 2511 } 2512 2513 void Sema::EndOpenMPClause() { 2514 DSAStack->setClauseParsingMode(/*K=*/OMPC_unknown); 2515 } 2516 2517 static std::pair<ValueDecl *, bool> 2518 getPrivateItem(Sema &S, Expr *&RefExpr, SourceLocation &ELoc, 2519 SourceRange &ERange, bool AllowArraySection = false); 2520 2521 /// Check consistency of the reduction clauses. 2522 static void checkReductionClauses(Sema &S, DSAStackTy *Stack, 2523 ArrayRef<OMPClause *> Clauses) { 2524 bool InscanFound = false; 2525 SourceLocation InscanLoc; 2526 // OpenMP 5.0, 2.19.5.4 reduction Clause, Restrictions. 2527 // A reduction clause without the inscan reduction-modifier may not appear on 2528 // a construct on which a reduction clause with the inscan reduction-modifier 2529 // appears. 2530 for (OMPClause *C : Clauses) { 2531 if (C->getClauseKind() != OMPC_reduction) 2532 continue; 2533 auto *RC = cast<OMPReductionClause>(C); 2534 if (RC->getModifier() == OMPC_REDUCTION_inscan) { 2535 InscanFound = true; 2536 InscanLoc = RC->getModifierLoc(); 2537 continue; 2538 } 2539 if (RC->getModifier() == OMPC_REDUCTION_task) { 2540 // OpenMP 5.0, 2.19.5.4 reduction Clause. 2541 // A reduction clause with the task reduction-modifier may only appear on 2542 // a parallel construct, a worksharing construct or a combined or 2543 // composite construct for which any of the aforementioned constructs is a 2544 // constituent construct and simd or loop are not constituent constructs. 2545 OpenMPDirectiveKind CurDir = Stack->getCurrentDirective(); 2546 if (!(isOpenMPParallelDirective(CurDir) || 2547 isOpenMPWorksharingDirective(CurDir)) || 2548 isOpenMPSimdDirective(CurDir)) 2549 S.Diag(RC->getModifierLoc(), 2550 diag::err_omp_reduction_task_not_parallel_or_worksharing); 2551 continue; 2552 } 2553 } 2554 if (InscanFound) { 2555 for (OMPClause *C : Clauses) { 2556 if (C->getClauseKind() != OMPC_reduction) 2557 continue; 2558 auto *RC = cast<OMPReductionClause>(C); 2559 if (RC->getModifier() != OMPC_REDUCTION_inscan) { 2560 S.Diag(RC->getModifier() == OMPC_REDUCTION_unknown 2561 ? RC->getBeginLoc() 2562 : RC->getModifierLoc(), 2563 diag::err_omp_inscan_reduction_expected); 2564 S.Diag(InscanLoc, diag::note_omp_previous_inscan_reduction); 2565 continue; 2566 } 2567 for (Expr *Ref : RC->varlists()) { 2568 assert(Ref && "NULL expr in OpenMP nontemporal clause."); 2569 SourceLocation ELoc; 2570 SourceRange ERange; 2571 Expr *SimpleRefExpr = Ref; 2572 auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange, 2573 /*AllowArraySection=*/true); 2574 ValueDecl *D = Res.first; 2575 if (!D) 2576 continue; 2577 if (!Stack->isUsedInScanDirective(getCanonicalDecl(D))) { 2578 S.Diag(Ref->getExprLoc(), 2579 diag::err_omp_reduction_not_inclusive_exclusive) 2580 << Ref->getSourceRange(); 2581 } 2582 } 2583 } 2584 } 2585 } 2586 2587 static void checkAllocateClauses(Sema &S, DSAStackTy *Stack, 2588 ArrayRef<OMPClause *> Clauses); 2589 static DeclRefExpr *buildCapture(Sema &S, ValueDecl *D, Expr *CaptureExpr, 2590 bool WithInit); 2591 2592 static void reportOriginalDsa(Sema &SemaRef, const DSAStackTy *Stack, 2593 const ValueDecl *D, 2594 const DSAStackTy::DSAVarData &DVar, 2595 bool IsLoopIterVar = false); 2596 2597 void Sema::EndOpenMPDSABlock(Stmt *CurDirective) { 2598 // OpenMP [2.14.3.5, Restrictions, C/C++, p.1] 2599 // A variable of class type (or array thereof) that appears in a lastprivate 2600 // clause requires an accessible, unambiguous default constructor for the 2601 // class type, unless the list item is also specified in a firstprivate 2602 // clause. 2603 if (const auto *D = dyn_cast_or_null<OMPExecutableDirective>(CurDirective)) { 2604 for (OMPClause *C : D->clauses()) { 2605 if (auto *Clause = dyn_cast<OMPLastprivateClause>(C)) { 2606 SmallVector<Expr *, 8> PrivateCopies; 2607 for (Expr *DE : Clause->varlists()) { 2608 if (DE->isValueDependent() || DE->isTypeDependent()) { 2609 PrivateCopies.push_back(nullptr); 2610 continue; 2611 } 2612 auto *DRE = cast<DeclRefExpr>(DE->IgnoreParens()); 2613 auto *VD = cast<VarDecl>(DRE->getDecl()); 2614 QualType Type = VD->getType().getNonReferenceType(); 2615 const DSAStackTy::DSAVarData DVar = 2616 DSAStack->getTopDSA(VD, /*FromParent=*/false); 2617 if (DVar.CKind == OMPC_lastprivate) { 2618 // Generate helper private variable and initialize it with the 2619 // default value. The address of the original variable is replaced 2620 // by the address of the new private variable in CodeGen. This new 2621 // variable is not added to IdResolver, so the code in the OpenMP 2622 // region uses original variable for proper diagnostics. 2623 VarDecl *VDPrivate = buildVarDecl( 2624 *this, DE->getExprLoc(), Type.getUnqualifiedType(), 2625 VD->getName(), VD->hasAttrs() ? &VD->getAttrs() : nullptr, DRE); 2626 ActOnUninitializedDecl(VDPrivate); 2627 if (VDPrivate->isInvalidDecl()) { 2628 PrivateCopies.push_back(nullptr); 2629 continue; 2630 } 2631 PrivateCopies.push_back(buildDeclRefExpr( 2632 *this, VDPrivate, DE->getType(), DE->getExprLoc())); 2633 } else { 2634 // The variable is also a firstprivate, so initialization sequence 2635 // for private copy is generated already. 2636 PrivateCopies.push_back(nullptr); 2637 } 2638 } 2639 Clause->setPrivateCopies(PrivateCopies); 2640 continue; 2641 } 2642 // Finalize nontemporal clause by handling private copies, if any. 2643 if (auto *Clause = dyn_cast<OMPNontemporalClause>(C)) { 2644 SmallVector<Expr *, 8> PrivateRefs; 2645 for (Expr *RefExpr : Clause->varlists()) { 2646 assert(RefExpr && "NULL expr in OpenMP nontemporal clause."); 2647 SourceLocation ELoc; 2648 SourceRange ERange; 2649 Expr *SimpleRefExpr = RefExpr; 2650 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 2651 if (Res.second) 2652 // It will be analyzed later. 2653 PrivateRefs.push_back(RefExpr); 2654 ValueDecl *D = Res.first; 2655 if (!D) 2656 continue; 2657 2658 const DSAStackTy::DSAVarData DVar = 2659 DSAStack->getTopDSA(D, /*FromParent=*/false); 2660 PrivateRefs.push_back(DVar.PrivateCopy ? DVar.PrivateCopy 2661 : SimpleRefExpr); 2662 } 2663 Clause->setPrivateRefs(PrivateRefs); 2664 continue; 2665 } 2666 if (auto *Clause = dyn_cast<OMPUsesAllocatorsClause>(C)) { 2667 for (unsigned I = 0, E = Clause->getNumberOfAllocators(); I < E; ++I) { 2668 OMPUsesAllocatorsClause::Data D = Clause->getAllocatorData(I); 2669 auto *DRE = dyn_cast<DeclRefExpr>(D.Allocator->IgnoreParenImpCasts()); 2670 if (!DRE) 2671 continue; 2672 ValueDecl *VD = DRE->getDecl(); 2673 if (!VD || !isa<VarDecl>(VD)) 2674 continue; 2675 DSAStackTy::DSAVarData DVar = 2676 DSAStack->getTopDSA(VD, /*FromParent=*/false); 2677 // OpenMP [2.12.5, target Construct] 2678 // Memory allocators that appear in a uses_allocators clause cannot 2679 // appear in other data-sharing attribute clauses or data-mapping 2680 // attribute clauses in the same construct. 2681 Expr *MapExpr = nullptr; 2682 if (DVar.RefExpr || 2683 DSAStack->checkMappableExprComponentListsForDecl( 2684 VD, /*CurrentRegionOnly=*/true, 2685 [VD, &MapExpr]( 2686 OMPClauseMappableExprCommon::MappableExprComponentListRef 2687 MapExprComponents, 2688 OpenMPClauseKind C) { 2689 auto MI = MapExprComponents.rbegin(); 2690 auto ME = MapExprComponents.rend(); 2691 if (MI != ME && 2692 MI->getAssociatedDeclaration()->getCanonicalDecl() == 2693 VD->getCanonicalDecl()) { 2694 MapExpr = MI->getAssociatedExpression(); 2695 return true; 2696 } 2697 return false; 2698 })) { 2699 Diag(D.Allocator->getExprLoc(), 2700 diag::err_omp_allocator_used_in_clauses) 2701 << D.Allocator->getSourceRange(); 2702 if (DVar.RefExpr) 2703 reportOriginalDsa(*this, DSAStack, VD, DVar); 2704 else 2705 Diag(MapExpr->getExprLoc(), diag::note_used_here) 2706 << MapExpr->getSourceRange(); 2707 } 2708 } 2709 continue; 2710 } 2711 } 2712 // Check allocate clauses. 2713 if (!CurContext->isDependentContext()) 2714 checkAllocateClauses(*this, DSAStack, D->clauses()); 2715 checkReductionClauses(*this, DSAStack, D->clauses()); 2716 } 2717 2718 DSAStack->pop(); 2719 DiscardCleanupsInEvaluationContext(); 2720 PopExpressionEvaluationContext(); 2721 } 2722 2723 static bool FinishOpenMPLinearClause(OMPLinearClause &Clause, DeclRefExpr *IV, 2724 Expr *NumIterations, Sema &SemaRef, 2725 Scope *S, DSAStackTy *Stack); 2726 2727 namespace { 2728 2729 class VarDeclFilterCCC final : public CorrectionCandidateCallback { 2730 private: 2731 Sema &SemaRef; 2732 2733 public: 2734 explicit VarDeclFilterCCC(Sema &S) : SemaRef(S) {} 2735 bool ValidateCandidate(const TypoCorrection &Candidate) override { 2736 NamedDecl *ND = Candidate.getCorrectionDecl(); 2737 if (const auto *VD = dyn_cast_or_null<VarDecl>(ND)) { 2738 return VD->hasGlobalStorage() && 2739 SemaRef.isDeclInScope(ND, SemaRef.getCurLexicalContext(), 2740 SemaRef.getCurScope()); 2741 } 2742 return false; 2743 } 2744 2745 std::unique_ptr<CorrectionCandidateCallback> clone() override { 2746 return std::make_unique<VarDeclFilterCCC>(*this); 2747 } 2748 2749 }; 2750 2751 class VarOrFuncDeclFilterCCC final : public CorrectionCandidateCallback { 2752 private: 2753 Sema &SemaRef; 2754 2755 public: 2756 explicit VarOrFuncDeclFilterCCC(Sema &S) : SemaRef(S) {} 2757 bool ValidateCandidate(const TypoCorrection &Candidate) override { 2758 NamedDecl *ND = Candidate.getCorrectionDecl(); 2759 if (ND && ((isa<VarDecl>(ND) && ND->getKind() == Decl::Var) || 2760 isa<FunctionDecl>(ND))) { 2761 return SemaRef.isDeclInScope(ND, SemaRef.getCurLexicalContext(), 2762 SemaRef.getCurScope()); 2763 } 2764 return false; 2765 } 2766 2767 std::unique_ptr<CorrectionCandidateCallback> clone() override { 2768 return std::make_unique<VarOrFuncDeclFilterCCC>(*this); 2769 } 2770 }; 2771 2772 } // namespace 2773 2774 ExprResult Sema::ActOnOpenMPIdExpression(Scope *CurScope, 2775 CXXScopeSpec &ScopeSpec, 2776 const DeclarationNameInfo &Id, 2777 OpenMPDirectiveKind Kind) { 2778 LookupResult Lookup(*this, Id, LookupOrdinaryName); 2779 LookupParsedName(Lookup, CurScope, &ScopeSpec, true); 2780 2781 if (Lookup.isAmbiguous()) 2782 return ExprError(); 2783 2784 VarDecl *VD; 2785 if (!Lookup.isSingleResult()) { 2786 VarDeclFilterCCC CCC(*this); 2787 if (TypoCorrection Corrected = 2788 CorrectTypo(Id, LookupOrdinaryName, CurScope, nullptr, CCC, 2789 CTK_ErrorRecovery)) { 2790 diagnoseTypo(Corrected, 2791 PDiag(Lookup.empty() 2792 ? diag::err_undeclared_var_use_suggest 2793 : diag::err_omp_expected_var_arg_suggest) 2794 << Id.getName()); 2795 VD = Corrected.getCorrectionDeclAs<VarDecl>(); 2796 } else { 2797 Diag(Id.getLoc(), Lookup.empty() ? diag::err_undeclared_var_use 2798 : diag::err_omp_expected_var_arg) 2799 << Id.getName(); 2800 return ExprError(); 2801 } 2802 } else if (!(VD = Lookup.getAsSingle<VarDecl>())) { 2803 Diag(Id.getLoc(), diag::err_omp_expected_var_arg) << Id.getName(); 2804 Diag(Lookup.getFoundDecl()->getLocation(), diag::note_declared_at); 2805 return ExprError(); 2806 } 2807 Lookup.suppressDiagnostics(); 2808 2809 // OpenMP [2.9.2, Syntax, C/C++] 2810 // Variables must be file-scope, namespace-scope, or static block-scope. 2811 if (Kind == OMPD_threadprivate && !VD->hasGlobalStorage()) { 2812 Diag(Id.getLoc(), diag::err_omp_global_var_arg) 2813 << getOpenMPDirectiveName(Kind) << !VD->isStaticLocal(); 2814 bool IsDecl = 2815 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 2816 Diag(VD->getLocation(), 2817 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 2818 << VD; 2819 return ExprError(); 2820 } 2821 2822 VarDecl *CanonicalVD = VD->getCanonicalDecl(); 2823 NamedDecl *ND = CanonicalVD; 2824 // OpenMP [2.9.2, Restrictions, C/C++, p.2] 2825 // A threadprivate directive for file-scope variables must appear outside 2826 // any definition or declaration. 2827 if (CanonicalVD->getDeclContext()->isTranslationUnit() && 2828 !getCurLexicalContext()->isTranslationUnit()) { 2829 Diag(Id.getLoc(), diag::err_omp_var_scope) 2830 << getOpenMPDirectiveName(Kind) << VD; 2831 bool IsDecl = 2832 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 2833 Diag(VD->getLocation(), 2834 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 2835 << VD; 2836 return ExprError(); 2837 } 2838 // OpenMP [2.9.2, Restrictions, C/C++, p.3] 2839 // A threadprivate directive for static class member variables must appear 2840 // in the class definition, in the same scope in which the member 2841 // variables are declared. 2842 if (CanonicalVD->isStaticDataMember() && 2843 !CanonicalVD->getDeclContext()->Equals(getCurLexicalContext())) { 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.4] 2854 // A threadprivate directive for namespace-scope variables must appear 2855 // outside any definition or declaration other than the namespace 2856 // definition itself. 2857 if (CanonicalVD->getDeclContext()->isNamespace() && 2858 (!getCurLexicalContext()->isFileContext() || 2859 !getCurLexicalContext()->Encloses(CanonicalVD->getDeclContext()))) { 2860 Diag(Id.getLoc(), diag::err_omp_var_scope) 2861 << getOpenMPDirectiveName(Kind) << VD; 2862 bool IsDecl = 2863 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 2864 Diag(VD->getLocation(), 2865 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 2866 << VD; 2867 return ExprError(); 2868 } 2869 // OpenMP [2.9.2, Restrictions, C/C++, p.6] 2870 // A threadprivate directive for static block-scope variables must appear 2871 // in the scope of the variable and not in a nested scope. 2872 if (CanonicalVD->isLocalVarDecl() && CurScope && 2873 !isDeclInScope(ND, getCurLexicalContext(), CurScope)) { 2874 Diag(Id.getLoc(), diag::err_omp_var_scope) 2875 << getOpenMPDirectiveName(Kind) << VD; 2876 bool IsDecl = 2877 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 2878 Diag(VD->getLocation(), 2879 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 2880 << VD; 2881 return ExprError(); 2882 } 2883 2884 // OpenMP [2.9.2, Restrictions, C/C++, p.2-6] 2885 // A threadprivate directive must lexically precede all references to any 2886 // of the variables in its list. 2887 if (Kind == OMPD_threadprivate && VD->isUsed() && 2888 !DSAStack->isThreadPrivate(VD)) { 2889 Diag(Id.getLoc(), diag::err_omp_var_used) 2890 << getOpenMPDirectiveName(Kind) << VD; 2891 return ExprError(); 2892 } 2893 2894 QualType ExprType = VD->getType().getNonReferenceType(); 2895 return DeclRefExpr::Create(Context, NestedNameSpecifierLoc(), 2896 SourceLocation(), VD, 2897 /*RefersToEnclosingVariableOrCapture=*/false, 2898 Id.getLoc(), ExprType, VK_LValue); 2899 } 2900 2901 Sema::DeclGroupPtrTy 2902 Sema::ActOnOpenMPThreadprivateDirective(SourceLocation Loc, 2903 ArrayRef<Expr *> VarList) { 2904 if (OMPThreadPrivateDecl *D = CheckOMPThreadPrivateDecl(Loc, VarList)) { 2905 CurContext->addDecl(D); 2906 return DeclGroupPtrTy::make(DeclGroupRef(D)); 2907 } 2908 return nullptr; 2909 } 2910 2911 namespace { 2912 class LocalVarRefChecker final 2913 : public ConstStmtVisitor<LocalVarRefChecker, bool> { 2914 Sema &SemaRef; 2915 2916 public: 2917 bool VisitDeclRefExpr(const DeclRefExpr *E) { 2918 if (const auto *VD = dyn_cast<VarDecl>(E->getDecl())) { 2919 if (VD->hasLocalStorage()) { 2920 SemaRef.Diag(E->getBeginLoc(), 2921 diag::err_omp_local_var_in_threadprivate_init) 2922 << E->getSourceRange(); 2923 SemaRef.Diag(VD->getLocation(), diag::note_defined_here) 2924 << VD << VD->getSourceRange(); 2925 return true; 2926 } 2927 } 2928 return false; 2929 } 2930 bool VisitStmt(const Stmt *S) { 2931 for (const Stmt *Child : S->children()) { 2932 if (Child && Visit(Child)) 2933 return true; 2934 } 2935 return false; 2936 } 2937 explicit LocalVarRefChecker(Sema &SemaRef) : SemaRef(SemaRef) {} 2938 }; 2939 } // namespace 2940 2941 OMPThreadPrivateDecl * 2942 Sema::CheckOMPThreadPrivateDecl(SourceLocation Loc, ArrayRef<Expr *> VarList) { 2943 SmallVector<Expr *, 8> Vars; 2944 for (Expr *RefExpr : VarList) { 2945 auto *DE = cast<DeclRefExpr>(RefExpr); 2946 auto *VD = cast<VarDecl>(DE->getDecl()); 2947 SourceLocation ILoc = DE->getExprLoc(); 2948 2949 // Mark variable as used. 2950 VD->setReferenced(); 2951 VD->markUsed(Context); 2952 2953 QualType QType = VD->getType(); 2954 if (QType->isDependentType() || QType->isInstantiationDependentType()) { 2955 // It will be analyzed later. 2956 Vars.push_back(DE); 2957 continue; 2958 } 2959 2960 // OpenMP [2.9.2, Restrictions, C/C++, p.10] 2961 // A threadprivate variable must not have an incomplete type. 2962 if (RequireCompleteType(ILoc, VD->getType(), 2963 diag::err_omp_threadprivate_incomplete_type)) { 2964 continue; 2965 } 2966 2967 // OpenMP [2.9.2, Restrictions, C/C++, p.10] 2968 // A threadprivate variable must not have a reference type. 2969 if (VD->getType()->isReferenceType()) { 2970 Diag(ILoc, diag::err_omp_ref_type_arg) 2971 << getOpenMPDirectiveName(OMPD_threadprivate) << VD->getType(); 2972 bool IsDecl = 2973 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 2974 Diag(VD->getLocation(), 2975 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 2976 << VD; 2977 continue; 2978 } 2979 2980 // Check if this is a TLS variable. If TLS is not being supported, produce 2981 // the corresponding diagnostic. 2982 if ((VD->getTLSKind() != VarDecl::TLS_None && 2983 !(VD->hasAttr<OMPThreadPrivateDeclAttr>() && 2984 getLangOpts().OpenMPUseTLS && 2985 getASTContext().getTargetInfo().isTLSSupported())) || 2986 (VD->getStorageClass() == SC_Register && VD->hasAttr<AsmLabelAttr>() && 2987 !VD->isLocalVarDecl())) { 2988 Diag(ILoc, diag::err_omp_var_thread_local) 2989 << VD << ((VD->getTLSKind() != VarDecl::TLS_None) ? 0 : 1); 2990 bool IsDecl = 2991 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 2992 Diag(VD->getLocation(), 2993 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 2994 << VD; 2995 continue; 2996 } 2997 2998 // Check if initial value of threadprivate variable reference variable with 2999 // local storage (it is not supported by runtime). 3000 if (const Expr *Init = VD->getAnyInitializer()) { 3001 LocalVarRefChecker Checker(*this); 3002 if (Checker.Visit(Init)) 3003 continue; 3004 } 3005 3006 Vars.push_back(RefExpr); 3007 DSAStack->addDSA(VD, DE, OMPC_threadprivate); 3008 VD->addAttr(OMPThreadPrivateDeclAttr::CreateImplicit( 3009 Context, SourceRange(Loc, Loc))); 3010 if (ASTMutationListener *ML = Context.getASTMutationListener()) 3011 ML->DeclarationMarkedOpenMPThreadPrivate(VD); 3012 } 3013 OMPThreadPrivateDecl *D = nullptr; 3014 if (!Vars.empty()) { 3015 D = OMPThreadPrivateDecl::Create(Context, getCurLexicalContext(), Loc, 3016 Vars); 3017 D->setAccess(AS_public); 3018 } 3019 return D; 3020 } 3021 3022 static OMPAllocateDeclAttr::AllocatorTypeTy 3023 getAllocatorKind(Sema &S, DSAStackTy *Stack, Expr *Allocator) { 3024 if (!Allocator) 3025 return OMPAllocateDeclAttr::OMPNullMemAlloc; 3026 if (Allocator->isTypeDependent() || Allocator->isValueDependent() || 3027 Allocator->isInstantiationDependent() || 3028 Allocator->containsUnexpandedParameterPack()) 3029 return OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; 3030 auto AllocatorKindRes = OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; 3031 const Expr *AE = Allocator->IgnoreParenImpCasts(); 3032 for (int I = 0; I < OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; ++I) { 3033 auto AllocatorKind = static_cast<OMPAllocateDeclAttr::AllocatorTypeTy>(I); 3034 const Expr *DefAllocator = Stack->getAllocator(AllocatorKind); 3035 llvm::FoldingSetNodeID AEId, DAEId; 3036 AE->Profile(AEId, S.getASTContext(), /*Canonical=*/true); 3037 DefAllocator->Profile(DAEId, S.getASTContext(), /*Canonical=*/true); 3038 if (AEId == DAEId) { 3039 AllocatorKindRes = AllocatorKind; 3040 break; 3041 } 3042 } 3043 return AllocatorKindRes; 3044 } 3045 3046 static bool checkPreviousOMPAllocateAttribute( 3047 Sema &S, DSAStackTy *Stack, Expr *RefExpr, VarDecl *VD, 3048 OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind, Expr *Allocator) { 3049 if (!VD->hasAttr<OMPAllocateDeclAttr>()) 3050 return false; 3051 const auto *A = VD->getAttr<OMPAllocateDeclAttr>(); 3052 Expr *PrevAllocator = A->getAllocator(); 3053 OMPAllocateDeclAttr::AllocatorTypeTy PrevAllocatorKind = 3054 getAllocatorKind(S, Stack, PrevAllocator); 3055 bool AllocatorsMatch = AllocatorKind == PrevAllocatorKind; 3056 if (AllocatorsMatch && 3057 AllocatorKind == OMPAllocateDeclAttr::OMPUserDefinedMemAlloc && 3058 Allocator && PrevAllocator) { 3059 const Expr *AE = Allocator->IgnoreParenImpCasts(); 3060 const Expr *PAE = PrevAllocator->IgnoreParenImpCasts(); 3061 llvm::FoldingSetNodeID AEId, PAEId; 3062 AE->Profile(AEId, S.Context, /*Canonical=*/true); 3063 PAE->Profile(PAEId, S.Context, /*Canonical=*/true); 3064 AllocatorsMatch = AEId == PAEId; 3065 } 3066 if (!AllocatorsMatch) { 3067 SmallString<256> AllocatorBuffer; 3068 llvm::raw_svector_ostream AllocatorStream(AllocatorBuffer); 3069 if (Allocator) 3070 Allocator->printPretty(AllocatorStream, nullptr, S.getPrintingPolicy()); 3071 SmallString<256> PrevAllocatorBuffer; 3072 llvm::raw_svector_ostream PrevAllocatorStream(PrevAllocatorBuffer); 3073 if (PrevAllocator) 3074 PrevAllocator->printPretty(PrevAllocatorStream, nullptr, 3075 S.getPrintingPolicy()); 3076 3077 SourceLocation AllocatorLoc = 3078 Allocator ? Allocator->getExprLoc() : RefExpr->getExprLoc(); 3079 SourceRange AllocatorRange = 3080 Allocator ? Allocator->getSourceRange() : RefExpr->getSourceRange(); 3081 SourceLocation PrevAllocatorLoc = 3082 PrevAllocator ? PrevAllocator->getExprLoc() : A->getLocation(); 3083 SourceRange PrevAllocatorRange = 3084 PrevAllocator ? PrevAllocator->getSourceRange() : A->getRange(); 3085 S.Diag(AllocatorLoc, diag::warn_omp_used_different_allocator) 3086 << (Allocator ? 1 : 0) << AllocatorStream.str() 3087 << (PrevAllocator ? 1 : 0) << PrevAllocatorStream.str() 3088 << AllocatorRange; 3089 S.Diag(PrevAllocatorLoc, diag::note_omp_previous_allocator) 3090 << PrevAllocatorRange; 3091 return true; 3092 } 3093 return false; 3094 } 3095 3096 static void 3097 applyOMPAllocateAttribute(Sema &S, VarDecl *VD, 3098 OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind, 3099 Expr *Allocator, SourceRange SR) { 3100 if (VD->hasAttr<OMPAllocateDeclAttr>()) 3101 return; 3102 if (Allocator && 3103 (Allocator->isTypeDependent() || Allocator->isValueDependent() || 3104 Allocator->isInstantiationDependent() || 3105 Allocator->containsUnexpandedParameterPack())) 3106 return; 3107 auto *A = OMPAllocateDeclAttr::CreateImplicit(S.Context, AllocatorKind, 3108 Allocator, SR); 3109 VD->addAttr(A); 3110 if (ASTMutationListener *ML = S.Context.getASTMutationListener()) 3111 ML->DeclarationMarkedOpenMPAllocate(VD, A); 3112 } 3113 3114 Sema::DeclGroupPtrTy Sema::ActOnOpenMPAllocateDirective( 3115 SourceLocation Loc, ArrayRef<Expr *> VarList, 3116 ArrayRef<OMPClause *> Clauses, DeclContext *Owner) { 3117 assert(Clauses.size() <= 1 && "Expected at most one clause."); 3118 Expr *Allocator = nullptr; 3119 if (Clauses.empty()) { 3120 // OpenMP 5.0, 2.11.3 allocate Directive, Restrictions. 3121 // allocate directives that appear in a target region must specify an 3122 // allocator clause unless a requires directive with the dynamic_allocators 3123 // clause is present in the same compilation unit. 3124 if (LangOpts.OpenMPIsDevice && 3125 !DSAStack->hasRequiresDeclWithClause<OMPDynamicAllocatorsClause>()) 3126 targetDiag(Loc, diag::err_expected_allocator_clause); 3127 } else { 3128 Allocator = cast<OMPAllocatorClause>(Clauses.back())->getAllocator(); 3129 } 3130 OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind = 3131 getAllocatorKind(*this, DSAStack, Allocator); 3132 SmallVector<Expr *, 8> Vars; 3133 for (Expr *RefExpr : VarList) { 3134 auto *DE = cast<DeclRefExpr>(RefExpr); 3135 auto *VD = cast<VarDecl>(DE->getDecl()); 3136 3137 // Check if this is a TLS variable or global register. 3138 if (VD->getTLSKind() != VarDecl::TLS_None || 3139 VD->hasAttr<OMPThreadPrivateDeclAttr>() || 3140 (VD->getStorageClass() == SC_Register && VD->hasAttr<AsmLabelAttr>() && 3141 !VD->isLocalVarDecl())) 3142 continue; 3143 3144 // If the used several times in the allocate directive, the same allocator 3145 // must be used. 3146 if (checkPreviousOMPAllocateAttribute(*this, DSAStack, RefExpr, VD, 3147 AllocatorKind, Allocator)) 3148 continue; 3149 3150 // OpenMP, 2.11.3 allocate Directive, Restrictions, C / C++ 3151 // If a list item has a static storage type, the allocator expression in the 3152 // allocator clause must be a constant expression that evaluates to one of 3153 // the predefined memory allocator values. 3154 if (Allocator && VD->hasGlobalStorage()) { 3155 if (AllocatorKind == OMPAllocateDeclAttr::OMPUserDefinedMemAlloc) { 3156 Diag(Allocator->getExprLoc(), 3157 diag::err_omp_expected_predefined_allocator) 3158 << Allocator->getSourceRange(); 3159 bool IsDecl = VD->isThisDeclarationADefinition(Context) == 3160 VarDecl::DeclarationOnly; 3161 Diag(VD->getLocation(), 3162 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 3163 << VD; 3164 continue; 3165 } 3166 } 3167 3168 Vars.push_back(RefExpr); 3169 applyOMPAllocateAttribute(*this, VD, AllocatorKind, Allocator, 3170 DE->getSourceRange()); 3171 } 3172 if (Vars.empty()) 3173 return nullptr; 3174 if (!Owner) 3175 Owner = getCurLexicalContext(); 3176 auto *D = OMPAllocateDecl::Create(Context, Owner, Loc, Vars, Clauses); 3177 D->setAccess(AS_public); 3178 Owner->addDecl(D); 3179 return DeclGroupPtrTy::make(DeclGroupRef(D)); 3180 } 3181 3182 Sema::DeclGroupPtrTy 3183 Sema::ActOnOpenMPRequiresDirective(SourceLocation Loc, 3184 ArrayRef<OMPClause *> ClauseList) { 3185 OMPRequiresDecl *D = nullptr; 3186 if (!CurContext->isFileContext()) { 3187 Diag(Loc, diag::err_omp_invalid_scope) << "requires"; 3188 } else { 3189 D = CheckOMPRequiresDecl(Loc, ClauseList); 3190 if (D) { 3191 CurContext->addDecl(D); 3192 DSAStack->addRequiresDecl(D); 3193 } 3194 } 3195 return DeclGroupPtrTy::make(DeclGroupRef(D)); 3196 } 3197 3198 OMPRequiresDecl *Sema::CheckOMPRequiresDecl(SourceLocation Loc, 3199 ArrayRef<OMPClause *> ClauseList) { 3200 /// For target specific clauses, the requires directive cannot be 3201 /// specified after the handling of any of the target regions in the 3202 /// current compilation unit. 3203 ArrayRef<SourceLocation> TargetLocations = 3204 DSAStack->getEncounteredTargetLocs(); 3205 SourceLocation AtomicLoc = DSAStack->getAtomicDirectiveLoc(); 3206 if (!TargetLocations.empty() || !AtomicLoc.isInvalid()) { 3207 for (const OMPClause *CNew : ClauseList) { 3208 // Check if any of the requires clauses affect target regions. 3209 if (isa<OMPUnifiedSharedMemoryClause>(CNew) || 3210 isa<OMPUnifiedAddressClause>(CNew) || 3211 isa<OMPReverseOffloadClause>(CNew) || 3212 isa<OMPDynamicAllocatorsClause>(CNew)) { 3213 Diag(Loc, diag::err_omp_directive_before_requires) 3214 << "target" << getOpenMPClauseName(CNew->getClauseKind()); 3215 for (SourceLocation TargetLoc : TargetLocations) { 3216 Diag(TargetLoc, diag::note_omp_requires_encountered_directive) 3217 << "target"; 3218 } 3219 } else if (!AtomicLoc.isInvalid() && 3220 isa<OMPAtomicDefaultMemOrderClause>(CNew)) { 3221 Diag(Loc, diag::err_omp_directive_before_requires) 3222 << "atomic" << getOpenMPClauseName(CNew->getClauseKind()); 3223 Diag(AtomicLoc, diag::note_omp_requires_encountered_directive) 3224 << "atomic"; 3225 } 3226 } 3227 } 3228 3229 if (!DSAStack->hasDuplicateRequiresClause(ClauseList)) 3230 return OMPRequiresDecl::Create(Context, getCurLexicalContext(), Loc, 3231 ClauseList); 3232 return nullptr; 3233 } 3234 3235 static void reportOriginalDsa(Sema &SemaRef, const DSAStackTy *Stack, 3236 const ValueDecl *D, 3237 const DSAStackTy::DSAVarData &DVar, 3238 bool IsLoopIterVar) { 3239 if (DVar.RefExpr) { 3240 SemaRef.Diag(DVar.RefExpr->getExprLoc(), diag::note_omp_explicit_dsa) 3241 << getOpenMPClauseName(DVar.CKind); 3242 return; 3243 } 3244 enum { 3245 PDSA_StaticMemberShared, 3246 PDSA_StaticLocalVarShared, 3247 PDSA_LoopIterVarPrivate, 3248 PDSA_LoopIterVarLinear, 3249 PDSA_LoopIterVarLastprivate, 3250 PDSA_ConstVarShared, 3251 PDSA_GlobalVarShared, 3252 PDSA_TaskVarFirstprivate, 3253 PDSA_LocalVarPrivate, 3254 PDSA_Implicit 3255 } Reason = PDSA_Implicit; 3256 bool ReportHint = false; 3257 auto ReportLoc = D->getLocation(); 3258 auto *VD = dyn_cast<VarDecl>(D); 3259 if (IsLoopIterVar) { 3260 if (DVar.CKind == OMPC_private) 3261 Reason = PDSA_LoopIterVarPrivate; 3262 else if (DVar.CKind == OMPC_lastprivate) 3263 Reason = PDSA_LoopIterVarLastprivate; 3264 else 3265 Reason = PDSA_LoopIterVarLinear; 3266 } else if (isOpenMPTaskingDirective(DVar.DKind) && 3267 DVar.CKind == OMPC_firstprivate) { 3268 Reason = PDSA_TaskVarFirstprivate; 3269 ReportLoc = DVar.ImplicitDSALoc; 3270 } else if (VD && VD->isStaticLocal()) 3271 Reason = PDSA_StaticLocalVarShared; 3272 else if (VD && VD->isStaticDataMember()) 3273 Reason = PDSA_StaticMemberShared; 3274 else if (VD && VD->isFileVarDecl()) 3275 Reason = PDSA_GlobalVarShared; 3276 else if (D->getType().isConstant(SemaRef.getASTContext())) 3277 Reason = PDSA_ConstVarShared; 3278 else if (VD && VD->isLocalVarDecl() && DVar.CKind == OMPC_private) { 3279 ReportHint = true; 3280 Reason = PDSA_LocalVarPrivate; 3281 } 3282 if (Reason != PDSA_Implicit) { 3283 SemaRef.Diag(ReportLoc, diag::note_omp_predetermined_dsa) 3284 << Reason << ReportHint 3285 << getOpenMPDirectiveName(Stack->getCurrentDirective()); 3286 } else if (DVar.ImplicitDSALoc.isValid()) { 3287 SemaRef.Diag(DVar.ImplicitDSALoc, diag::note_omp_implicit_dsa) 3288 << getOpenMPClauseName(DVar.CKind); 3289 } 3290 } 3291 3292 static OpenMPMapClauseKind 3293 getMapClauseKindFromModifier(OpenMPDefaultmapClauseModifier M, 3294 bool IsAggregateOrDeclareTarget) { 3295 OpenMPMapClauseKind Kind = OMPC_MAP_unknown; 3296 switch (M) { 3297 case OMPC_DEFAULTMAP_MODIFIER_alloc: 3298 Kind = OMPC_MAP_alloc; 3299 break; 3300 case OMPC_DEFAULTMAP_MODIFIER_to: 3301 Kind = OMPC_MAP_to; 3302 break; 3303 case OMPC_DEFAULTMAP_MODIFIER_from: 3304 Kind = OMPC_MAP_from; 3305 break; 3306 case OMPC_DEFAULTMAP_MODIFIER_tofrom: 3307 Kind = OMPC_MAP_tofrom; 3308 break; 3309 case OMPC_DEFAULTMAP_MODIFIER_firstprivate: 3310 case OMPC_DEFAULTMAP_MODIFIER_last: 3311 llvm_unreachable("Unexpected defaultmap implicit behavior"); 3312 case OMPC_DEFAULTMAP_MODIFIER_none: 3313 case OMPC_DEFAULTMAP_MODIFIER_default: 3314 case OMPC_DEFAULTMAP_MODIFIER_unknown: 3315 // IsAggregateOrDeclareTarget could be true if: 3316 // 1. the implicit behavior for aggregate is tofrom 3317 // 2. it's a declare target link 3318 if (IsAggregateOrDeclareTarget) { 3319 Kind = OMPC_MAP_tofrom; 3320 break; 3321 } 3322 llvm_unreachable("Unexpected defaultmap implicit behavior"); 3323 } 3324 assert(Kind != OMPC_MAP_unknown && "Expect map kind to be known"); 3325 return Kind; 3326 } 3327 3328 namespace { 3329 class DSAAttrChecker final : public StmtVisitor<DSAAttrChecker, void> { 3330 DSAStackTy *Stack; 3331 Sema &SemaRef; 3332 bool ErrorFound = false; 3333 bool TryCaptureCXXThisMembers = false; 3334 CapturedStmt *CS = nullptr; 3335 llvm::SmallVector<Expr *, 4> ImplicitFirstprivate; 3336 llvm::SmallVector<Expr *, 4> ImplicitMap[OMPC_MAP_delete]; 3337 Sema::VarsWithInheritedDSAType VarsWithInheritedDSA; 3338 llvm::SmallDenseSet<const ValueDecl *, 4> ImplicitDeclarations; 3339 3340 void VisitSubCaptures(OMPExecutableDirective *S) { 3341 // Check implicitly captured variables. 3342 if (!S->hasAssociatedStmt() || !S->getAssociatedStmt() || 3343 S->getDirectiveKind() == OMPD_atomic || 3344 S->getDirectiveKind() == OMPD_critical || 3345 S->getDirectiveKind() == OMPD_section || 3346 S->getDirectiveKind() == OMPD_master) 3347 return; 3348 visitSubCaptures(S->getInnermostCapturedStmt()); 3349 // Try to capture inner this->member references to generate correct mappings 3350 // and diagnostics. 3351 if (TryCaptureCXXThisMembers || 3352 (isOpenMPTargetExecutionDirective(Stack->getCurrentDirective()) && 3353 llvm::any_of(S->getInnermostCapturedStmt()->captures(), 3354 [](const CapturedStmt::Capture &C) { 3355 return C.capturesThis(); 3356 }))) { 3357 bool SavedTryCaptureCXXThisMembers = TryCaptureCXXThisMembers; 3358 TryCaptureCXXThisMembers = true; 3359 Visit(S->getInnermostCapturedStmt()->getCapturedStmt()); 3360 TryCaptureCXXThisMembers = SavedTryCaptureCXXThisMembers; 3361 } 3362 // In tasks firstprivates are not captured anymore, need to analyze them 3363 // explicitly. 3364 if (isOpenMPTaskingDirective(S->getDirectiveKind()) && 3365 !isOpenMPTaskLoopDirective(S->getDirectiveKind())) { 3366 for (OMPClause *C : S->clauses()) 3367 if (auto *FC = dyn_cast<OMPFirstprivateClause>(C)) { 3368 for (Expr *Ref : FC->varlists()) 3369 Visit(Ref); 3370 } 3371 } 3372 } 3373 3374 public: 3375 void VisitDeclRefExpr(DeclRefExpr *E) { 3376 if (TryCaptureCXXThisMembers || E->isTypeDependent() || 3377 E->isValueDependent() || E->containsUnexpandedParameterPack() || 3378 E->isInstantiationDependent()) 3379 return; 3380 if (auto *VD = dyn_cast<VarDecl>(E->getDecl())) { 3381 // Check the datasharing rules for the expressions in the clauses. 3382 if (!CS) { 3383 if (auto *CED = dyn_cast<OMPCapturedExprDecl>(VD)) 3384 if (!CED->hasAttr<OMPCaptureNoInitAttr>()) { 3385 Visit(CED->getInit()); 3386 return; 3387 } 3388 } else if (VD->isImplicit() || isa<OMPCapturedExprDecl>(VD)) 3389 // Do not analyze internal variables and do not enclose them into 3390 // implicit clauses. 3391 return; 3392 VD = VD->getCanonicalDecl(); 3393 // Skip internally declared variables. 3394 if (VD->hasLocalStorage() && CS && !CS->capturesVariable(VD) && 3395 !Stack->isImplicitTaskFirstprivate(VD)) 3396 return; 3397 // Skip allocators in uses_allocators clauses. 3398 if (Stack->isUsesAllocatorsDecl(VD).hasValue()) 3399 return; 3400 3401 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(VD, /*FromParent=*/false); 3402 // Check if the variable has explicit DSA set and stop analysis if it so. 3403 if (DVar.RefExpr || !ImplicitDeclarations.insert(VD).second) 3404 return; 3405 3406 // Skip internally declared static variables. 3407 llvm::Optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res = 3408 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD); 3409 if (VD->hasGlobalStorage() && CS && !CS->capturesVariable(VD) && 3410 (Stack->hasRequiresDeclWithClause<OMPUnifiedSharedMemoryClause>() || 3411 !Res || *Res != OMPDeclareTargetDeclAttr::MT_Link) && 3412 !Stack->isImplicitTaskFirstprivate(VD)) 3413 return; 3414 3415 SourceLocation ELoc = E->getExprLoc(); 3416 OpenMPDirectiveKind DKind = Stack->getCurrentDirective(); 3417 // The default(none) clause requires that each variable that is referenced 3418 // in the construct, and does not have a predetermined data-sharing 3419 // attribute, must have its data-sharing attribute explicitly determined 3420 // by being listed in a data-sharing attribute clause. 3421 if (DVar.CKind == OMPC_unknown && 3422 (Stack->getDefaultDSA() == DSA_none || 3423 Stack->getDefaultDSA() == DSA_firstprivate) && 3424 isImplicitOrExplicitTaskingRegion(DKind) && 3425 VarsWithInheritedDSA.count(VD) == 0) { 3426 bool InheritedDSA = Stack->getDefaultDSA() == DSA_none; 3427 if (!InheritedDSA && Stack->getDefaultDSA() == DSA_firstprivate) { 3428 DSAStackTy::DSAVarData DVar = 3429 Stack->getImplicitDSA(VD, /*FromParent=*/false); 3430 InheritedDSA = DVar.CKind == OMPC_unknown; 3431 } 3432 if (InheritedDSA) 3433 VarsWithInheritedDSA[VD] = E; 3434 return; 3435 } 3436 3437 // OpenMP 5.0 [2.19.7.2, defaultmap clause, Description] 3438 // If implicit-behavior is none, each variable referenced in the 3439 // construct that does not have a predetermined data-sharing attribute 3440 // and does not appear in a to or link clause on a declare target 3441 // directive must be listed in a data-mapping attribute clause, a 3442 // data-haring attribute clause (including a data-sharing attribute 3443 // clause on a combined construct where target. is one of the 3444 // constituent constructs), or an is_device_ptr clause. 3445 OpenMPDefaultmapClauseKind ClauseKind = 3446 getVariableCategoryFromDecl(SemaRef.getLangOpts(), VD); 3447 if (SemaRef.getLangOpts().OpenMP >= 50) { 3448 bool IsModifierNone = Stack->getDefaultmapModifier(ClauseKind) == 3449 OMPC_DEFAULTMAP_MODIFIER_none; 3450 if (DVar.CKind == OMPC_unknown && IsModifierNone && 3451 VarsWithInheritedDSA.count(VD) == 0 && !Res) { 3452 // Only check for data-mapping attribute and is_device_ptr here 3453 // since we have already make sure that the declaration does not 3454 // have a data-sharing attribute above 3455 if (!Stack->checkMappableExprComponentListsForDecl( 3456 VD, /*CurrentRegionOnly=*/true, 3457 [VD](OMPClauseMappableExprCommon::MappableExprComponentListRef 3458 MapExprComponents, 3459 OpenMPClauseKind) { 3460 auto MI = MapExprComponents.rbegin(); 3461 auto ME = MapExprComponents.rend(); 3462 return MI != ME && MI->getAssociatedDeclaration() == VD; 3463 })) { 3464 VarsWithInheritedDSA[VD] = E; 3465 return; 3466 } 3467 } 3468 } 3469 3470 if (isOpenMPTargetExecutionDirective(DKind) && 3471 !Stack->isLoopControlVariable(VD).first) { 3472 if (!Stack->checkMappableExprComponentListsForDecl( 3473 VD, /*CurrentRegionOnly=*/true, 3474 [](OMPClauseMappableExprCommon::MappableExprComponentListRef 3475 StackComponents, 3476 OpenMPClauseKind) { 3477 // Variable is used if it has been marked as an array, array 3478 // section, array shaping or the variable iself. 3479 return StackComponents.size() == 1 || 3480 std::all_of( 3481 std::next(StackComponents.rbegin()), 3482 StackComponents.rend(), 3483 [](const OMPClauseMappableExprCommon:: 3484 MappableComponent &MC) { 3485 return MC.getAssociatedDeclaration() == 3486 nullptr && 3487 (isa<OMPArraySectionExpr>( 3488 MC.getAssociatedExpression()) || 3489 isa<OMPArrayShapingExpr>( 3490 MC.getAssociatedExpression()) || 3491 isa<ArraySubscriptExpr>( 3492 MC.getAssociatedExpression())); 3493 }); 3494 })) { 3495 bool IsFirstprivate = false; 3496 // By default lambdas are captured as firstprivates. 3497 if (const auto *RD = 3498 VD->getType().getNonReferenceType()->getAsCXXRecordDecl()) 3499 IsFirstprivate = RD->isLambda(); 3500 IsFirstprivate = 3501 IsFirstprivate || (Stack->mustBeFirstprivate(ClauseKind) && !Res); 3502 if (IsFirstprivate) { 3503 ImplicitFirstprivate.emplace_back(E); 3504 } else { 3505 OpenMPDefaultmapClauseModifier M = 3506 Stack->getDefaultmapModifier(ClauseKind); 3507 OpenMPMapClauseKind Kind = getMapClauseKindFromModifier( 3508 M, ClauseKind == OMPC_DEFAULTMAP_aggregate || Res); 3509 ImplicitMap[Kind].emplace_back(E); 3510 } 3511 return; 3512 } 3513 } 3514 3515 // OpenMP [2.9.3.6, Restrictions, p.2] 3516 // A list item that appears in a reduction clause of the innermost 3517 // enclosing worksharing or parallel construct may not be accessed in an 3518 // explicit task. 3519 DVar = Stack->hasInnermostDSA( 3520 VD, 3521 [](OpenMPClauseKind C, bool AppliedToPointee) { 3522 return C == OMPC_reduction && !AppliedToPointee; 3523 }, 3524 [](OpenMPDirectiveKind K) { 3525 return isOpenMPParallelDirective(K) || 3526 isOpenMPWorksharingDirective(K) || isOpenMPTeamsDirective(K); 3527 }, 3528 /*FromParent=*/true); 3529 if (isOpenMPTaskingDirective(DKind) && DVar.CKind == OMPC_reduction) { 3530 ErrorFound = true; 3531 SemaRef.Diag(ELoc, diag::err_omp_reduction_in_task); 3532 reportOriginalDsa(SemaRef, Stack, VD, DVar); 3533 return; 3534 } 3535 3536 // Define implicit data-sharing attributes for task. 3537 DVar = Stack->getImplicitDSA(VD, /*FromParent=*/false); 3538 if (((isOpenMPTaskingDirective(DKind) && DVar.CKind != OMPC_shared) || 3539 (Stack->getDefaultDSA() == DSA_firstprivate && 3540 DVar.CKind == OMPC_firstprivate && !DVar.RefExpr)) && 3541 !Stack->isLoopControlVariable(VD).first) { 3542 ImplicitFirstprivate.push_back(E); 3543 return; 3544 } 3545 3546 // Store implicitly used globals with declare target link for parent 3547 // target. 3548 if (!isOpenMPTargetExecutionDirective(DKind) && Res && 3549 *Res == OMPDeclareTargetDeclAttr::MT_Link) { 3550 Stack->addToParentTargetRegionLinkGlobals(E); 3551 return; 3552 } 3553 } 3554 } 3555 void VisitMemberExpr(MemberExpr *E) { 3556 if (E->isTypeDependent() || E->isValueDependent() || 3557 E->containsUnexpandedParameterPack() || E->isInstantiationDependent()) 3558 return; 3559 auto *FD = dyn_cast<FieldDecl>(E->getMemberDecl()); 3560 OpenMPDirectiveKind DKind = Stack->getCurrentDirective(); 3561 if (auto *TE = dyn_cast<CXXThisExpr>(E->getBase()->IgnoreParenCasts())) { 3562 if (!FD) 3563 return; 3564 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(FD, /*FromParent=*/false); 3565 // Check if the variable has explicit DSA set and stop analysis if it 3566 // so. 3567 if (DVar.RefExpr || !ImplicitDeclarations.insert(FD).second) 3568 return; 3569 3570 if (isOpenMPTargetExecutionDirective(DKind) && 3571 !Stack->isLoopControlVariable(FD).first && 3572 !Stack->checkMappableExprComponentListsForDecl( 3573 FD, /*CurrentRegionOnly=*/true, 3574 [](OMPClauseMappableExprCommon::MappableExprComponentListRef 3575 StackComponents, 3576 OpenMPClauseKind) { 3577 return isa<CXXThisExpr>( 3578 cast<MemberExpr>( 3579 StackComponents.back().getAssociatedExpression()) 3580 ->getBase() 3581 ->IgnoreParens()); 3582 })) { 3583 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.3] 3584 // A bit-field cannot appear in a map clause. 3585 // 3586 if (FD->isBitField()) 3587 return; 3588 3589 // Check to see if the member expression is referencing a class that 3590 // has already been explicitly mapped 3591 if (Stack->isClassPreviouslyMapped(TE->getType())) 3592 return; 3593 3594 OpenMPDefaultmapClauseModifier Modifier = 3595 Stack->getDefaultmapModifier(OMPC_DEFAULTMAP_aggregate); 3596 OpenMPMapClauseKind Kind = getMapClauseKindFromModifier( 3597 Modifier, /*IsAggregateOrDeclareTarget*/ true); 3598 ImplicitMap[Kind].emplace_back(E); 3599 return; 3600 } 3601 3602 SourceLocation ELoc = E->getExprLoc(); 3603 // OpenMP [2.9.3.6, Restrictions, p.2] 3604 // A list item that appears in a reduction clause of the innermost 3605 // enclosing worksharing or parallel construct may not be accessed in 3606 // an explicit task. 3607 DVar = Stack->hasInnermostDSA( 3608 FD, 3609 [](OpenMPClauseKind C, bool AppliedToPointee) { 3610 return C == OMPC_reduction && !AppliedToPointee; 3611 }, 3612 [](OpenMPDirectiveKind K) { 3613 return isOpenMPParallelDirective(K) || 3614 isOpenMPWorksharingDirective(K) || isOpenMPTeamsDirective(K); 3615 }, 3616 /*FromParent=*/true); 3617 if (isOpenMPTaskingDirective(DKind) && DVar.CKind == OMPC_reduction) { 3618 ErrorFound = true; 3619 SemaRef.Diag(ELoc, diag::err_omp_reduction_in_task); 3620 reportOriginalDsa(SemaRef, Stack, FD, DVar); 3621 return; 3622 } 3623 3624 // Define implicit data-sharing attributes for task. 3625 DVar = Stack->getImplicitDSA(FD, /*FromParent=*/false); 3626 if (isOpenMPTaskingDirective(DKind) && DVar.CKind != OMPC_shared && 3627 !Stack->isLoopControlVariable(FD).first) { 3628 // Check if there is a captured expression for the current field in the 3629 // region. Do not mark it as firstprivate unless there is no captured 3630 // expression. 3631 // TODO: try to make it firstprivate. 3632 if (DVar.CKind != OMPC_unknown) 3633 ImplicitFirstprivate.push_back(E); 3634 } 3635 return; 3636 } 3637 if (isOpenMPTargetExecutionDirective(DKind)) { 3638 OMPClauseMappableExprCommon::MappableExprComponentList CurComponents; 3639 if (!checkMapClauseExpressionBase(SemaRef, E, CurComponents, OMPC_map, 3640 /*NoDiagnose=*/true)) 3641 return; 3642 const auto *VD = cast<ValueDecl>( 3643 CurComponents.back().getAssociatedDeclaration()->getCanonicalDecl()); 3644 if (!Stack->checkMappableExprComponentListsForDecl( 3645 VD, /*CurrentRegionOnly=*/true, 3646 [&CurComponents]( 3647 OMPClauseMappableExprCommon::MappableExprComponentListRef 3648 StackComponents, 3649 OpenMPClauseKind) { 3650 auto CCI = CurComponents.rbegin(); 3651 auto CCE = CurComponents.rend(); 3652 for (const auto &SC : llvm::reverse(StackComponents)) { 3653 // Do both expressions have the same kind? 3654 if (CCI->getAssociatedExpression()->getStmtClass() != 3655 SC.getAssociatedExpression()->getStmtClass()) 3656 if (!((isa<OMPArraySectionExpr>( 3657 SC.getAssociatedExpression()) || 3658 isa<OMPArrayShapingExpr>( 3659 SC.getAssociatedExpression())) && 3660 isa<ArraySubscriptExpr>( 3661 CCI->getAssociatedExpression()))) 3662 return false; 3663 3664 const Decl *CCD = CCI->getAssociatedDeclaration(); 3665 const Decl *SCD = SC.getAssociatedDeclaration(); 3666 CCD = CCD ? CCD->getCanonicalDecl() : nullptr; 3667 SCD = SCD ? SCD->getCanonicalDecl() : nullptr; 3668 if (SCD != CCD) 3669 return false; 3670 std::advance(CCI, 1); 3671 if (CCI == CCE) 3672 break; 3673 } 3674 return true; 3675 })) { 3676 Visit(E->getBase()); 3677 } 3678 } else if (!TryCaptureCXXThisMembers) { 3679 Visit(E->getBase()); 3680 } 3681 } 3682 void VisitOMPExecutableDirective(OMPExecutableDirective *S) { 3683 for (OMPClause *C : S->clauses()) { 3684 // Skip analysis of arguments of implicitly defined firstprivate clause 3685 // for task|target directives. 3686 // Skip analysis of arguments of implicitly defined map clause for target 3687 // directives. 3688 if (C && !((isa<OMPFirstprivateClause>(C) || isa<OMPMapClause>(C)) && 3689 C->isImplicit())) { 3690 for (Stmt *CC : C->children()) { 3691 if (CC) 3692 Visit(CC); 3693 } 3694 } 3695 } 3696 // Check implicitly captured variables. 3697 VisitSubCaptures(S); 3698 } 3699 void VisitStmt(Stmt *S) { 3700 for (Stmt *C : S->children()) { 3701 if (C) { 3702 // Check implicitly captured variables in the task-based directives to 3703 // check if they must be firstprivatized. 3704 Visit(C); 3705 } 3706 } 3707 } 3708 3709 void visitSubCaptures(CapturedStmt *S) { 3710 for (const CapturedStmt::Capture &Cap : S->captures()) { 3711 if (!Cap.capturesVariable() && !Cap.capturesVariableByCopy()) 3712 continue; 3713 VarDecl *VD = Cap.getCapturedVar(); 3714 // Do not try to map the variable if it or its sub-component was mapped 3715 // already. 3716 if (isOpenMPTargetExecutionDirective(Stack->getCurrentDirective()) && 3717 Stack->checkMappableExprComponentListsForDecl( 3718 VD, /*CurrentRegionOnly=*/true, 3719 [](OMPClauseMappableExprCommon::MappableExprComponentListRef, 3720 OpenMPClauseKind) { return true; })) 3721 continue; 3722 DeclRefExpr *DRE = buildDeclRefExpr( 3723 SemaRef, VD, VD->getType().getNonLValueExprType(SemaRef.Context), 3724 Cap.getLocation(), /*RefersToCapture=*/true); 3725 Visit(DRE); 3726 } 3727 } 3728 bool isErrorFound() const { return ErrorFound; } 3729 ArrayRef<Expr *> getImplicitFirstprivate() const { 3730 return ImplicitFirstprivate; 3731 } 3732 ArrayRef<Expr *> getImplicitMap(OpenMPDefaultmapClauseKind Kind) const { 3733 return ImplicitMap[Kind]; 3734 } 3735 const Sema::VarsWithInheritedDSAType &getVarsWithInheritedDSA() const { 3736 return VarsWithInheritedDSA; 3737 } 3738 3739 DSAAttrChecker(DSAStackTy *S, Sema &SemaRef, CapturedStmt *CS) 3740 : Stack(S), SemaRef(SemaRef), ErrorFound(false), CS(CS) { 3741 // Process declare target link variables for the target directives. 3742 if (isOpenMPTargetExecutionDirective(S->getCurrentDirective())) { 3743 for (DeclRefExpr *E : Stack->getLinkGlobals()) 3744 Visit(E); 3745 } 3746 } 3747 }; 3748 } // namespace 3749 3750 void Sema::ActOnOpenMPRegionStart(OpenMPDirectiveKind DKind, Scope *CurScope) { 3751 switch (DKind) { 3752 case OMPD_parallel: 3753 case OMPD_parallel_for: 3754 case OMPD_parallel_for_simd: 3755 case OMPD_parallel_sections: 3756 case OMPD_parallel_master: 3757 case OMPD_teams: 3758 case OMPD_teams_distribute: 3759 case OMPD_teams_distribute_simd: { 3760 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 3761 QualType KmpInt32PtrTy = 3762 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3763 Sema::CapturedParamNameType Params[] = { 3764 std::make_pair(".global_tid.", KmpInt32PtrTy), 3765 std::make_pair(".bound_tid.", KmpInt32PtrTy), 3766 std::make_pair(StringRef(), QualType()) // __context with shared vars 3767 }; 3768 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3769 Params); 3770 break; 3771 } 3772 case OMPD_target_teams: 3773 case OMPD_target_parallel: 3774 case OMPD_target_parallel_for: 3775 case OMPD_target_parallel_for_simd: 3776 case OMPD_target_teams_distribute: 3777 case OMPD_target_teams_distribute_simd: { 3778 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 3779 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 3780 QualType KmpInt32PtrTy = 3781 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3782 QualType Args[] = {VoidPtrTy}; 3783 FunctionProtoType::ExtProtoInfo EPI; 3784 EPI.Variadic = true; 3785 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 3786 Sema::CapturedParamNameType Params[] = { 3787 std::make_pair(".global_tid.", KmpInt32Ty), 3788 std::make_pair(".part_id.", KmpInt32PtrTy), 3789 std::make_pair(".privates.", VoidPtrTy), 3790 std::make_pair( 3791 ".copy_fn.", 3792 Context.getPointerType(CopyFnType).withConst().withRestrict()), 3793 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 3794 std::make_pair(StringRef(), QualType()) // __context with shared vars 3795 }; 3796 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3797 Params, /*OpenMPCaptureLevel=*/0); 3798 // Mark this captured region as inlined, because we don't use outlined 3799 // function directly. 3800 getCurCapturedRegion()->TheCapturedDecl->addAttr( 3801 AlwaysInlineAttr::CreateImplicit( 3802 Context, {}, AttributeCommonInfo::AS_Keyword, 3803 AlwaysInlineAttr::Keyword_forceinline)); 3804 Sema::CapturedParamNameType ParamsTarget[] = { 3805 std::make_pair(StringRef(), QualType()) // __context with shared vars 3806 }; 3807 // Start a captured region for 'target' with no implicit parameters. 3808 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3809 ParamsTarget, /*OpenMPCaptureLevel=*/1); 3810 Sema::CapturedParamNameType ParamsTeamsOrParallel[] = { 3811 std::make_pair(".global_tid.", KmpInt32PtrTy), 3812 std::make_pair(".bound_tid.", KmpInt32PtrTy), 3813 std::make_pair(StringRef(), QualType()) // __context with shared vars 3814 }; 3815 // Start a captured region for 'teams' or 'parallel'. Both regions have 3816 // the same implicit parameters. 3817 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3818 ParamsTeamsOrParallel, /*OpenMPCaptureLevel=*/2); 3819 break; 3820 } 3821 case OMPD_target: 3822 case OMPD_target_simd: { 3823 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 3824 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 3825 QualType KmpInt32PtrTy = 3826 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3827 QualType Args[] = {VoidPtrTy}; 3828 FunctionProtoType::ExtProtoInfo EPI; 3829 EPI.Variadic = true; 3830 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 3831 Sema::CapturedParamNameType Params[] = { 3832 std::make_pair(".global_tid.", KmpInt32Ty), 3833 std::make_pair(".part_id.", KmpInt32PtrTy), 3834 std::make_pair(".privates.", VoidPtrTy), 3835 std::make_pair( 3836 ".copy_fn.", 3837 Context.getPointerType(CopyFnType).withConst().withRestrict()), 3838 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 3839 std::make_pair(StringRef(), QualType()) // __context with shared vars 3840 }; 3841 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3842 Params, /*OpenMPCaptureLevel=*/0); 3843 // Mark this captured region as inlined, because we don't use outlined 3844 // function directly. 3845 getCurCapturedRegion()->TheCapturedDecl->addAttr( 3846 AlwaysInlineAttr::CreateImplicit( 3847 Context, {}, AttributeCommonInfo::AS_Keyword, 3848 AlwaysInlineAttr::Keyword_forceinline)); 3849 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3850 std::make_pair(StringRef(), QualType()), 3851 /*OpenMPCaptureLevel=*/1); 3852 break; 3853 } 3854 case OMPD_atomic: 3855 case OMPD_critical: 3856 case OMPD_section: 3857 case OMPD_master: 3858 break; 3859 case OMPD_simd: 3860 case OMPD_for: 3861 case OMPD_for_simd: 3862 case OMPD_sections: 3863 case OMPD_single: 3864 case OMPD_taskgroup: 3865 case OMPD_distribute: 3866 case OMPD_distribute_simd: 3867 case OMPD_ordered: 3868 case OMPD_target_data: { 3869 Sema::CapturedParamNameType Params[] = { 3870 std::make_pair(StringRef(), QualType()) // __context with shared vars 3871 }; 3872 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3873 Params); 3874 break; 3875 } 3876 case OMPD_task: { 3877 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 3878 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 3879 QualType KmpInt32PtrTy = 3880 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3881 QualType Args[] = {VoidPtrTy}; 3882 FunctionProtoType::ExtProtoInfo EPI; 3883 EPI.Variadic = true; 3884 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 3885 Sema::CapturedParamNameType Params[] = { 3886 std::make_pair(".global_tid.", KmpInt32Ty), 3887 std::make_pair(".part_id.", KmpInt32PtrTy), 3888 std::make_pair(".privates.", VoidPtrTy), 3889 std::make_pair( 3890 ".copy_fn.", 3891 Context.getPointerType(CopyFnType).withConst().withRestrict()), 3892 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 3893 std::make_pair(StringRef(), QualType()) // __context with shared vars 3894 }; 3895 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3896 Params); 3897 // Mark this captured region as inlined, because we don't use outlined 3898 // function directly. 3899 getCurCapturedRegion()->TheCapturedDecl->addAttr( 3900 AlwaysInlineAttr::CreateImplicit( 3901 Context, {}, AttributeCommonInfo::AS_Keyword, 3902 AlwaysInlineAttr::Keyword_forceinline)); 3903 break; 3904 } 3905 case OMPD_taskloop: 3906 case OMPD_taskloop_simd: 3907 case OMPD_master_taskloop: 3908 case OMPD_master_taskloop_simd: { 3909 QualType KmpInt32Ty = 3910 Context.getIntTypeForBitwidth(/*DestWidth=*/32, /*Signed=*/1) 3911 .withConst(); 3912 QualType KmpUInt64Ty = 3913 Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/0) 3914 .withConst(); 3915 QualType KmpInt64Ty = 3916 Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/1) 3917 .withConst(); 3918 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 3919 QualType KmpInt32PtrTy = 3920 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3921 QualType Args[] = {VoidPtrTy}; 3922 FunctionProtoType::ExtProtoInfo EPI; 3923 EPI.Variadic = true; 3924 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 3925 Sema::CapturedParamNameType Params[] = { 3926 std::make_pair(".global_tid.", KmpInt32Ty), 3927 std::make_pair(".part_id.", KmpInt32PtrTy), 3928 std::make_pair(".privates.", VoidPtrTy), 3929 std::make_pair( 3930 ".copy_fn.", 3931 Context.getPointerType(CopyFnType).withConst().withRestrict()), 3932 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 3933 std::make_pair(".lb.", KmpUInt64Ty), 3934 std::make_pair(".ub.", KmpUInt64Ty), 3935 std::make_pair(".st.", KmpInt64Ty), 3936 std::make_pair(".liter.", KmpInt32Ty), 3937 std::make_pair(".reductions.", VoidPtrTy), 3938 std::make_pair(StringRef(), QualType()) // __context with shared vars 3939 }; 3940 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3941 Params); 3942 // Mark this captured region as inlined, because we don't use outlined 3943 // function directly. 3944 getCurCapturedRegion()->TheCapturedDecl->addAttr( 3945 AlwaysInlineAttr::CreateImplicit( 3946 Context, {}, AttributeCommonInfo::AS_Keyword, 3947 AlwaysInlineAttr::Keyword_forceinline)); 3948 break; 3949 } 3950 case OMPD_parallel_master_taskloop: 3951 case OMPD_parallel_master_taskloop_simd: { 3952 QualType KmpInt32Ty = 3953 Context.getIntTypeForBitwidth(/*DestWidth=*/32, /*Signed=*/1) 3954 .withConst(); 3955 QualType KmpUInt64Ty = 3956 Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/0) 3957 .withConst(); 3958 QualType KmpInt64Ty = 3959 Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/1) 3960 .withConst(); 3961 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 3962 QualType KmpInt32PtrTy = 3963 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3964 Sema::CapturedParamNameType ParamsParallel[] = { 3965 std::make_pair(".global_tid.", KmpInt32PtrTy), 3966 std::make_pair(".bound_tid.", KmpInt32PtrTy), 3967 std::make_pair(StringRef(), QualType()) // __context with shared vars 3968 }; 3969 // Start a captured region for 'parallel'. 3970 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3971 ParamsParallel, /*OpenMPCaptureLevel=*/0); 3972 QualType Args[] = {VoidPtrTy}; 3973 FunctionProtoType::ExtProtoInfo EPI; 3974 EPI.Variadic = true; 3975 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 3976 Sema::CapturedParamNameType Params[] = { 3977 std::make_pair(".global_tid.", KmpInt32Ty), 3978 std::make_pair(".part_id.", KmpInt32PtrTy), 3979 std::make_pair(".privates.", VoidPtrTy), 3980 std::make_pair( 3981 ".copy_fn.", 3982 Context.getPointerType(CopyFnType).withConst().withRestrict()), 3983 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 3984 std::make_pair(".lb.", KmpUInt64Ty), 3985 std::make_pair(".ub.", KmpUInt64Ty), 3986 std::make_pair(".st.", KmpInt64Ty), 3987 std::make_pair(".liter.", KmpInt32Ty), 3988 std::make_pair(".reductions.", VoidPtrTy), 3989 std::make_pair(StringRef(), QualType()) // __context with shared vars 3990 }; 3991 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3992 Params, /*OpenMPCaptureLevel=*/1); 3993 // Mark this captured region as inlined, because we don't use outlined 3994 // function directly. 3995 getCurCapturedRegion()->TheCapturedDecl->addAttr( 3996 AlwaysInlineAttr::CreateImplicit( 3997 Context, {}, AttributeCommonInfo::AS_Keyword, 3998 AlwaysInlineAttr::Keyword_forceinline)); 3999 break; 4000 } 4001 case OMPD_distribute_parallel_for_simd: 4002 case OMPD_distribute_parallel_for: { 4003 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 4004 QualType KmpInt32PtrTy = 4005 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 4006 Sema::CapturedParamNameType Params[] = { 4007 std::make_pair(".global_tid.", KmpInt32PtrTy), 4008 std::make_pair(".bound_tid.", KmpInt32PtrTy), 4009 std::make_pair(".previous.lb.", Context.getSizeType().withConst()), 4010 std::make_pair(".previous.ub.", Context.getSizeType().withConst()), 4011 std::make_pair(StringRef(), QualType()) // __context with shared vars 4012 }; 4013 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 4014 Params); 4015 break; 4016 } 4017 case OMPD_target_teams_distribute_parallel_for: 4018 case OMPD_target_teams_distribute_parallel_for_simd: { 4019 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 4020 QualType KmpInt32PtrTy = 4021 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 4022 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 4023 4024 QualType Args[] = {VoidPtrTy}; 4025 FunctionProtoType::ExtProtoInfo EPI; 4026 EPI.Variadic = true; 4027 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 4028 Sema::CapturedParamNameType Params[] = { 4029 std::make_pair(".global_tid.", KmpInt32Ty), 4030 std::make_pair(".part_id.", KmpInt32PtrTy), 4031 std::make_pair(".privates.", VoidPtrTy), 4032 std::make_pair( 4033 ".copy_fn.", 4034 Context.getPointerType(CopyFnType).withConst().withRestrict()), 4035 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 4036 std::make_pair(StringRef(), QualType()) // __context with shared vars 4037 }; 4038 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 4039 Params, /*OpenMPCaptureLevel=*/0); 4040 // Mark this captured region as inlined, because we don't use outlined 4041 // function directly. 4042 getCurCapturedRegion()->TheCapturedDecl->addAttr( 4043 AlwaysInlineAttr::CreateImplicit( 4044 Context, {}, AttributeCommonInfo::AS_Keyword, 4045 AlwaysInlineAttr::Keyword_forceinline)); 4046 Sema::CapturedParamNameType ParamsTarget[] = { 4047 std::make_pair(StringRef(), QualType()) // __context with shared vars 4048 }; 4049 // Start a captured region for 'target' with no implicit parameters. 4050 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 4051 ParamsTarget, /*OpenMPCaptureLevel=*/1); 4052 4053 Sema::CapturedParamNameType ParamsTeams[] = { 4054 std::make_pair(".global_tid.", KmpInt32PtrTy), 4055 std::make_pair(".bound_tid.", KmpInt32PtrTy), 4056 std::make_pair(StringRef(), QualType()) // __context with shared vars 4057 }; 4058 // Start a captured region for 'target' with no implicit parameters. 4059 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 4060 ParamsTeams, /*OpenMPCaptureLevel=*/2); 4061 4062 Sema::CapturedParamNameType ParamsParallel[] = { 4063 std::make_pair(".global_tid.", KmpInt32PtrTy), 4064 std::make_pair(".bound_tid.", KmpInt32PtrTy), 4065 std::make_pair(".previous.lb.", Context.getSizeType().withConst()), 4066 std::make_pair(".previous.ub.", Context.getSizeType().withConst()), 4067 std::make_pair(StringRef(), QualType()) // __context with shared vars 4068 }; 4069 // Start a captured region for 'teams' or 'parallel'. Both regions have 4070 // the same implicit parameters. 4071 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 4072 ParamsParallel, /*OpenMPCaptureLevel=*/3); 4073 break; 4074 } 4075 4076 case OMPD_teams_distribute_parallel_for: 4077 case OMPD_teams_distribute_parallel_for_simd: { 4078 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 4079 QualType KmpInt32PtrTy = 4080 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 4081 4082 Sema::CapturedParamNameType ParamsTeams[] = { 4083 std::make_pair(".global_tid.", KmpInt32PtrTy), 4084 std::make_pair(".bound_tid.", KmpInt32PtrTy), 4085 std::make_pair(StringRef(), QualType()) // __context with shared vars 4086 }; 4087 // Start a captured region for 'target' with no implicit parameters. 4088 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 4089 ParamsTeams, /*OpenMPCaptureLevel=*/0); 4090 4091 Sema::CapturedParamNameType ParamsParallel[] = { 4092 std::make_pair(".global_tid.", KmpInt32PtrTy), 4093 std::make_pair(".bound_tid.", KmpInt32PtrTy), 4094 std::make_pair(".previous.lb.", Context.getSizeType().withConst()), 4095 std::make_pair(".previous.ub.", Context.getSizeType().withConst()), 4096 std::make_pair(StringRef(), QualType()) // __context with shared vars 4097 }; 4098 // Start a captured region for 'teams' or 'parallel'. Both regions have 4099 // the same implicit parameters. 4100 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 4101 ParamsParallel, /*OpenMPCaptureLevel=*/1); 4102 break; 4103 } 4104 case OMPD_target_update: 4105 case OMPD_target_enter_data: 4106 case OMPD_target_exit_data: { 4107 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 4108 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 4109 QualType KmpInt32PtrTy = 4110 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 4111 QualType Args[] = {VoidPtrTy}; 4112 FunctionProtoType::ExtProtoInfo EPI; 4113 EPI.Variadic = true; 4114 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 4115 Sema::CapturedParamNameType Params[] = { 4116 std::make_pair(".global_tid.", KmpInt32Ty), 4117 std::make_pair(".part_id.", KmpInt32PtrTy), 4118 std::make_pair(".privates.", VoidPtrTy), 4119 std::make_pair( 4120 ".copy_fn.", 4121 Context.getPointerType(CopyFnType).withConst().withRestrict()), 4122 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 4123 std::make_pair(StringRef(), QualType()) // __context with shared vars 4124 }; 4125 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 4126 Params); 4127 // Mark this captured region as inlined, because we don't use outlined 4128 // function directly. 4129 getCurCapturedRegion()->TheCapturedDecl->addAttr( 4130 AlwaysInlineAttr::CreateImplicit( 4131 Context, {}, AttributeCommonInfo::AS_Keyword, 4132 AlwaysInlineAttr::Keyword_forceinline)); 4133 break; 4134 } 4135 case OMPD_threadprivate: 4136 case OMPD_allocate: 4137 case OMPD_taskyield: 4138 case OMPD_barrier: 4139 case OMPD_taskwait: 4140 case OMPD_cancellation_point: 4141 case OMPD_cancel: 4142 case OMPD_flush: 4143 case OMPD_depobj: 4144 case OMPD_scan: 4145 case OMPD_declare_reduction: 4146 case OMPD_declare_mapper: 4147 case OMPD_declare_simd: 4148 case OMPD_declare_target: 4149 case OMPD_end_declare_target: 4150 case OMPD_requires: 4151 case OMPD_declare_variant: 4152 case OMPD_begin_declare_variant: 4153 case OMPD_end_declare_variant: 4154 llvm_unreachable("OpenMP Directive is not allowed"); 4155 case OMPD_unknown: 4156 default: 4157 llvm_unreachable("Unknown OpenMP directive"); 4158 } 4159 DSAStack->setContext(CurContext); 4160 } 4161 4162 int Sema::getNumberOfConstructScopes(unsigned Level) const { 4163 return getOpenMPCaptureLevels(DSAStack->getDirective(Level)); 4164 } 4165 4166 int Sema::getOpenMPCaptureLevels(OpenMPDirectiveKind DKind) { 4167 SmallVector<OpenMPDirectiveKind, 4> CaptureRegions; 4168 getOpenMPCaptureRegions(CaptureRegions, DKind); 4169 return CaptureRegions.size(); 4170 } 4171 4172 static OMPCapturedExprDecl *buildCaptureDecl(Sema &S, IdentifierInfo *Id, 4173 Expr *CaptureExpr, bool WithInit, 4174 bool AsExpression) { 4175 assert(CaptureExpr); 4176 ASTContext &C = S.getASTContext(); 4177 Expr *Init = AsExpression ? CaptureExpr : CaptureExpr->IgnoreImpCasts(); 4178 QualType Ty = Init->getType(); 4179 if (CaptureExpr->getObjectKind() == OK_Ordinary && CaptureExpr->isGLValue()) { 4180 if (S.getLangOpts().CPlusPlus) { 4181 Ty = C.getLValueReferenceType(Ty); 4182 } else { 4183 Ty = C.getPointerType(Ty); 4184 ExprResult Res = 4185 S.CreateBuiltinUnaryOp(CaptureExpr->getExprLoc(), UO_AddrOf, Init); 4186 if (!Res.isUsable()) 4187 return nullptr; 4188 Init = Res.get(); 4189 } 4190 WithInit = true; 4191 } 4192 auto *CED = OMPCapturedExprDecl::Create(C, S.CurContext, Id, Ty, 4193 CaptureExpr->getBeginLoc()); 4194 if (!WithInit) 4195 CED->addAttr(OMPCaptureNoInitAttr::CreateImplicit(C)); 4196 S.CurContext->addHiddenDecl(CED); 4197 S.AddInitializerToDecl(CED, Init, /*DirectInit=*/false); 4198 return CED; 4199 } 4200 4201 static DeclRefExpr *buildCapture(Sema &S, ValueDecl *D, Expr *CaptureExpr, 4202 bool WithInit) { 4203 OMPCapturedExprDecl *CD; 4204 if (VarDecl *VD = S.isOpenMPCapturedDecl(D)) 4205 CD = cast<OMPCapturedExprDecl>(VD); 4206 else 4207 CD = buildCaptureDecl(S, D->getIdentifier(), CaptureExpr, WithInit, 4208 /*AsExpression=*/false); 4209 return buildDeclRefExpr(S, CD, CD->getType().getNonReferenceType(), 4210 CaptureExpr->getExprLoc()); 4211 } 4212 4213 static ExprResult buildCapture(Sema &S, Expr *CaptureExpr, DeclRefExpr *&Ref) { 4214 CaptureExpr = S.DefaultLvalueConversion(CaptureExpr).get(); 4215 if (!Ref) { 4216 OMPCapturedExprDecl *CD = buildCaptureDecl( 4217 S, &S.getASTContext().Idents.get(".capture_expr."), CaptureExpr, 4218 /*WithInit=*/true, /*AsExpression=*/true); 4219 Ref = buildDeclRefExpr(S, CD, CD->getType().getNonReferenceType(), 4220 CaptureExpr->getExprLoc()); 4221 } 4222 ExprResult Res = Ref; 4223 if (!S.getLangOpts().CPlusPlus && 4224 CaptureExpr->getObjectKind() == OK_Ordinary && CaptureExpr->isGLValue() && 4225 Ref->getType()->isPointerType()) { 4226 Res = S.CreateBuiltinUnaryOp(CaptureExpr->getExprLoc(), UO_Deref, Ref); 4227 if (!Res.isUsable()) 4228 return ExprError(); 4229 } 4230 return S.DefaultLvalueConversion(Res.get()); 4231 } 4232 4233 namespace { 4234 // OpenMP directives parsed in this section are represented as a 4235 // CapturedStatement with an associated statement. If a syntax error 4236 // is detected during the parsing of the associated statement, the 4237 // compiler must abort processing and close the CapturedStatement. 4238 // 4239 // Combined directives such as 'target parallel' have more than one 4240 // nested CapturedStatements. This RAII ensures that we unwind out 4241 // of all the nested CapturedStatements when an error is found. 4242 class CaptureRegionUnwinderRAII { 4243 private: 4244 Sema &S; 4245 bool &ErrorFound; 4246 OpenMPDirectiveKind DKind = OMPD_unknown; 4247 4248 public: 4249 CaptureRegionUnwinderRAII(Sema &S, bool &ErrorFound, 4250 OpenMPDirectiveKind DKind) 4251 : S(S), ErrorFound(ErrorFound), DKind(DKind) {} 4252 ~CaptureRegionUnwinderRAII() { 4253 if (ErrorFound) { 4254 int ThisCaptureLevel = S.getOpenMPCaptureLevels(DKind); 4255 while (--ThisCaptureLevel >= 0) 4256 S.ActOnCapturedRegionError(); 4257 } 4258 } 4259 }; 4260 } // namespace 4261 4262 void Sema::tryCaptureOpenMPLambdas(ValueDecl *V) { 4263 // Capture variables captured by reference in lambdas for target-based 4264 // directives. 4265 if (!CurContext->isDependentContext() && 4266 (isOpenMPTargetExecutionDirective(DSAStack->getCurrentDirective()) || 4267 isOpenMPTargetDataManagementDirective( 4268 DSAStack->getCurrentDirective()))) { 4269 QualType Type = V->getType(); 4270 if (const auto *RD = Type.getCanonicalType() 4271 .getNonReferenceType() 4272 ->getAsCXXRecordDecl()) { 4273 bool SavedForceCaptureByReferenceInTargetExecutable = 4274 DSAStack->isForceCaptureByReferenceInTargetExecutable(); 4275 DSAStack->setForceCaptureByReferenceInTargetExecutable( 4276 /*V=*/true); 4277 if (RD->isLambda()) { 4278 llvm::DenseMap<const VarDecl *, FieldDecl *> Captures; 4279 FieldDecl *ThisCapture; 4280 RD->getCaptureFields(Captures, ThisCapture); 4281 for (const LambdaCapture &LC : RD->captures()) { 4282 if (LC.getCaptureKind() == LCK_ByRef) { 4283 VarDecl *VD = LC.getCapturedVar(); 4284 DeclContext *VDC = VD->getDeclContext(); 4285 if (!VDC->Encloses(CurContext)) 4286 continue; 4287 MarkVariableReferenced(LC.getLocation(), VD); 4288 } else if (LC.getCaptureKind() == LCK_This) { 4289 QualType ThisTy = getCurrentThisType(); 4290 if (!ThisTy.isNull() && 4291 Context.typesAreCompatible(ThisTy, ThisCapture->getType())) 4292 CheckCXXThisCapture(LC.getLocation()); 4293 } 4294 } 4295 } 4296 DSAStack->setForceCaptureByReferenceInTargetExecutable( 4297 SavedForceCaptureByReferenceInTargetExecutable); 4298 } 4299 } 4300 } 4301 4302 static bool checkOrderedOrderSpecified(Sema &S, 4303 const ArrayRef<OMPClause *> Clauses) { 4304 const OMPOrderedClause *Ordered = nullptr; 4305 const OMPOrderClause *Order = nullptr; 4306 4307 for (const OMPClause *Clause : Clauses) { 4308 if (Clause->getClauseKind() == OMPC_ordered) 4309 Ordered = cast<OMPOrderedClause>(Clause); 4310 else if (Clause->getClauseKind() == OMPC_order) { 4311 Order = cast<OMPOrderClause>(Clause); 4312 if (Order->getKind() != OMPC_ORDER_concurrent) 4313 Order = nullptr; 4314 } 4315 if (Ordered && Order) 4316 break; 4317 } 4318 4319 if (Ordered && Order) { 4320 S.Diag(Order->getKindKwLoc(), 4321 diag::err_omp_simple_clause_incompatible_with_ordered) 4322 << getOpenMPClauseName(OMPC_order) 4323 << getOpenMPSimpleClauseTypeName(OMPC_order, OMPC_ORDER_concurrent) 4324 << SourceRange(Order->getBeginLoc(), Order->getEndLoc()); 4325 S.Diag(Ordered->getBeginLoc(), diag::note_omp_ordered_param) 4326 << 0 << SourceRange(Ordered->getBeginLoc(), Ordered->getEndLoc()); 4327 return true; 4328 } 4329 return false; 4330 } 4331 4332 StmtResult Sema::ActOnOpenMPRegionEnd(StmtResult S, 4333 ArrayRef<OMPClause *> Clauses) { 4334 if (DSAStack->getCurrentDirective() == OMPD_atomic || 4335 DSAStack->getCurrentDirective() == OMPD_critical || 4336 DSAStack->getCurrentDirective() == OMPD_section || 4337 DSAStack->getCurrentDirective() == OMPD_master) 4338 return S; 4339 4340 bool ErrorFound = false; 4341 CaptureRegionUnwinderRAII CaptureRegionUnwinder( 4342 *this, ErrorFound, DSAStack->getCurrentDirective()); 4343 if (!S.isUsable()) { 4344 ErrorFound = true; 4345 return StmtError(); 4346 } 4347 4348 SmallVector<OpenMPDirectiveKind, 4> CaptureRegions; 4349 getOpenMPCaptureRegions(CaptureRegions, DSAStack->getCurrentDirective()); 4350 OMPOrderedClause *OC = nullptr; 4351 OMPScheduleClause *SC = nullptr; 4352 SmallVector<const OMPLinearClause *, 4> LCs; 4353 SmallVector<const OMPClauseWithPreInit *, 4> PICs; 4354 // This is required for proper codegen. 4355 for (OMPClause *Clause : Clauses) { 4356 if (!LangOpts.OpenMPSimd && 4357 isOpenMPTaskingDirective(DSAStack->getCurrentDirective()) && 4358 Clause->getClauseKind() == OMPC_in_reduction) { 4359 // Capture taskgroup task_reduction descriptors inside the tasking regions 4360 // with the corresponding in_reduction items. 4361 auto *IRC = cast<OMPInReductionClause>(Clause); 4362 for (Expr *E : IRC->taskgroup_descriptors()) 4363 if (E) 4364 MarkDeclarationsReferencedInExpr(E); 4365 } 4366 if (isOpenMPPrivate(Clause->getClauseKind()) || 4367 Clause->getClauseKind() == OMPC_copyprivate || 4368 (getLangOpts().OpenMPUseTLS && 4369 getASTContext().getTargetInfo().isTLSSupported() && 4370 Clause->getClauseKind() == OMPC_copyin)) { 4371 DSAStack->setForceVarCapturing(Clause->getClauseKind() == OMPC_copyin); 4372 // Mark all variables in private list clauses as used in inner region. 4373 for (Stmt *VarRef : Clause->children()) { 4374 if (auto *E = cast_or_null<Expr>(VarRef)) { 4375 MarkDeclarationsReferencedInExpr(E); 4376 } 4377 } 4378 DSAStack->setForceVarCapturing(/*V=*/false); 4379 } else if (CaptureRegions.size() > 1 || 4380 CaptureRegions.back() != OMPD_unknown) { 4381 if (auto *C = OMPClauseWithPreInit::get(Clause)) 4382 PICs.push_back(C); 4383 if (auto *C = OMPClauseWithPostUpdate::get(Clause)) { 4384 if (Expr *E = C->getPostUpdateExpr()) 4385 MarkDeclarationsReferencedInExpr(E); 4386 } 4387 } 4388 if (Clause->getClauseKind() == OMPC_schedule) 4389 SC = cast<OMPScheduleClause>(Clause); 4390 else if (Clause->getClauseKind() == OMPC_ordered) 4391 OC = cast<OMPOrderedClause>(Clause); 4392 else if (Clause->getClauseKind() == OMPC_linear) 4393 LCs.push_back(cast<OMPLinearClause>(Clause)); 4394 } 4395 // Capture allocator expressions if used. 4396 for (Expr *E : DSAStack->getInnerAllocators()) 4397 MarkDeclarationsReferencedInExpr(E); 4398 // OpenMP, 2.7.1 Loop Construct, Restrictions 4399 // The nonmonotonic modifier cannot be specified if an ordered clause is 4400 // specified. 4401 if (SC && 4402 (SC->getFirstScheduleModifier() == OMPC_SCHEDULE_MODIFIER_nonmonotonic || 4403 SC->getSecondScheduleModifier() == 4404 OMPC_SCHEDULE_MODIFIER_nonmonotonic) && 4405 OC) { 4406 Diag(SC->getFirstScheduleModifier() == OMPC_SCHEDULE_MODIFIER_nonmonotonic 4407 ? SC->getFirstScheduleModifierLoc() 4408 : SC->getSecondScheduleModifierLoc(), 4409 diag::err_omp_simple_clause_incompatible_with_ordered) 4410 << getOpenMPClauseName(OMPC_schedule) 4411 << getOpenMPSimpleClauseTypeName(OMPC_schedule, 4412 OMPC_SCHEDULE_MODIFIER_nonmonotonic) 4413 << SourceRange(OC->getBeginLoc(), OC->getEndLoc()); 4414 ErrorFound = true; 4415 } 4416 // OpenMP 5.0, 2.9.2 Worksharing-Loop Construct, Restrictions. 4417 // If an order(concurrent) clause is present, an ordered clause may not appear 4418 // on the same directive. 4419 if (checkOrderedOrderSpecified(*this, Clauses)) 4420 ErrorFound = true; 4421 if (!LCs.empty() && OC && OC->getNumForLoops()) { 4422 for (const OMPLinearClause *C : LCs) { 4423 Diag(C->getBeginLoc(), diag::err_omp_linear_ordered) 4424 << SourceRange(OC->getBeginLoc(), OC->getEndLoc()); 4425 } 4426 ErrorFound = true; 4427 } 4428 if (isOpenMPWorksharingDirective(DSAStack->getCurrentDirective()) && 4429 isOpenMPSimdDirective(DSAStack->getCurrentDirective()) && OC && 4430 OC->getNumForLoops()) { 4431 Diag(OC->getBeginLoc(), diag::err_omp_ordered_simd) 4432 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 4433 ErrorFound = true; 4434 } 4435 if (ErrorFound) { 4436 return StmtError(); 4437 } 4438 StmtResult SR = S; 4439 unsigned CompletedRegions = 0; 4440 for (OpenMPDirectiveKind ThisCaptureRegion : llvm::reverse(CaptureRegions)) { 4441 // Mark all variables in private list clauses as used in inner region. 4442 // Required for proper codegen of combined directives. 4443 // TODO: add processing for other clauses. 4444 if (ThisCaptureRegion != OMPD_unknown) { 4445 for (const clang::OMPClauseWithPreInit *C : PICs) { 4446 OpenMPDirectiveKind CaptureRegion = C->getCaptureRegion(); 4447 // Find the particular capture region for the clause if the 4448 // directive is a combined one with multiple capture regions. 4449 // If the directive is not a combined one, the capture region 4450 // associated with the clause is OMPD_unknown and is generated 4451 // only once. 4452 if (CaptureRegion == ThisCaptureRegion || 4453 CaptureRegion == OMPD_unknown) { 4454 if (auto *DS = cast_or_null<DeclStmt>(C->getPreInitStmt())) { 4455 for (Decl *D : DS->decls()) 4456 MarkVariableReferenced(D->getLocation(), cast<VarDecl>(D)); 4457 } 4458 } 4459 } 4460 } 4461 if (ThisCaptureRegion == OMPD_target) { 4462 // Capture allocator traits in the target region. They are used implicitly 4463 // and, thus, are not captured by default. 4464 for (OMPClause *C : Clauses) { 4465 if (const auto *UAC = dyn_cast<OMPUsesAllocatorsClause>(C)) { 4466 for (unsigned I = 0, End = UAC->getNumberOfAllocators(); I < End; 4467 ++I) { 4468 OMPUsesAllocatorsClause::Data D = UAC->getAllocatorData(I); 4469 if (Expr *E = D.AllocatorTraits) 4470 MarkDeclarationsReferencedInExpr(E); 4471 } 4472 continue; 4473 } 4474 } 4475 } 4476 if (++CompletedRegions == CaptureRegions.size()) 4477 DSAStack->setBodyComplete(); 4478 SR = ActOnCapturedRegionEnd(SR.get()); 4479 } 4480 return SR; 4481 } 4482 4483 static bool checkCancelRegion(Sema &SemaRef, OpenMPDirectiveKind CurrentRegion, 4484 OpenMPDirectiveKind CancelRegion, 4485 SourceLocation StartLoc) { 4486 // CancelRegion is only needed for cancel and cancellation_point. 4487 if (CurrentRegion != OMPD_cancel && CurrentRegion != OMPD_cancellation_point) 4488 return false; 4489 4490 if (CancelRegion == OMPD_parallel || CancelRegion == OMPD_for || 4491 CancelRegion == OMPD_sections || CancelRegion == OMPD_taskgroup) 4492 return false; 4493 4494 SemaRef.Diag(StartLoc, diag::err_omp_wrong_cancel_region) 4495 << getOpenMPDirectiveName(CancelRegion); 4496 return true; 4497 } 4498 4499 static bool checkNestingOfRegions(Sema &SemaRef, const DSAStackTy *Stack, 4500 OpenMPDirectiveKind CurrentRegion, 4501 const DeclarationNameInfo &CurrentName, 4502 OpenMPDirectiveKind CancelRegion, 4503 SourceLocation StartLoc) { 4504 if (Stack->getCurScope()) { 4505 OpenMPDirectiveKind ParentRegion = Stack->getParentDirective(); 4506 OpenMPDirectiveKind OffendingRegion = ParentRegion; 4507 bool NestingProhibited = false; 4508 bool CloseNesting = true; 4509 bool OrphanSeen = false; 4510 enum { 4511 NoRecommend, 4512 ShouldBeInParallelRegion, 4513 ShouldBeInOrderedRegion, 4514 ShouldBeInTargetRegion, 4515 ShouldBeInTeamsRegion, 4516 ShouldBeInLoopSimdRegion, 4517 } Recommend = NoRecommend; 4518 if (isOpenMPSimdDirective(ParentRegion) && 4519 ((SemaRef.LangOpts.OpenMP <= 45 && CurrentRegion != OMPD_ordered) || 4520 (SemaRef.LangOpts.OpenMP >= 50 && CurrentRegion != OMPD_ordered && 4521 CurrentRegion != OMPD_simd && CurrentRegion != OMPD_atomic && 4522 CurrentRegion != OMPD_scan))) { 4523 // OpenMP [2.16, Nesting of Regions] 4524 // OpenMP constructs may not be nested inside a simd region. 4525 // OpenMP [2.8.1,simd Construct, Restrictions] 4526 // An ordered construct with the simd clause is the only OpenMP 4527 // construct that can appear in the simd region. 4528 // Allowing a SIMD construct nested in another SIMD construct is an 4529 // extension. The OpenMP 4.5 spec does not allow it. Issue a warning 4530 // message. 4531 // OpenMP 5.0 [2.9.3.1, simd Construct, Restrictions] 4532 // The only OpenMP constructs that can be encountered during execution of 4533 // a simd region are the atomic construct, the loop construct, the simd 4534 // construct and the ordered construct with the simd clause. 4535 SemaRef.Diag(StartLoc, (CurrentRegion != OMPD_simd) 4536 ? diag::err_omp_prohibited_region_simd 4537 : diag::warn_omp_nesting_simd) 4538 << (SemaRef.LangOpts.OpenMP >= 50 ? 1 : 0); 4539 return CurrentRegion != OMPD_simd; 4540 } 4541 if (ParentRegion == OMPD_atomic) { 4542 // OpenMP [2.16, Nesting of Regions] 4543 // OpenMP constructs may not be nested inside an atomic region. 4544 SemaRef.Diag(StartLoc, diag::err_omp_prohibited_region_atomic); 4545 return true; 4546 } 4547 if (CurrentRegion == OMPD_section) { 4548 // OpenMP [2.7.2, sections Construct, Restrictions] 4549 // Orphaned section directives are prohibited. That is, the section 4550 // directives must appear within the sections construct and must not be 4551 // encountered elsewhere in the sections region. 4552 if (ParentRegion != OMPD_sections && 4553 ParentRegion != OMPD_parallel_sections) { 4554 SemaRef.Diag(StartLoc, diag::err_omp_orphaned_section_directive) 4555 << (ParentRegion != OMPD_unknown) 4556 << getOpenMPDirectiveName(ParentRegion); 4557 return true; 4558 } 4559 return false; 4560 } 4561 // Allow some constructs (except teams and cancellation constructs) to be 4562 // orphaned (they could be used in functions, called from OpenMP regions 4563 // with the required preconditions). 4564 if (ParentRegion == OMPD_unknown && 4565 !isOpenMPNestingTeamsDirective(CurrentRegion) && 4566 CurrentRegion != OMPD_cancellation_point && 4567 CurrentRegion != OMPD_cancel && CurrentRegion != OMPD_scan) 4568 return false; 4569 if (CurrentRegion == OMPD_cancellation_point || 4570 CurrentRegion == OMPD_cancel) { 4571 // OpenMP [2.16, Nesting of Regions] 4572 // A cancellation point construct for which construct-type-clause is 4573 // taskgroup must be nested inside a task construct. A cancellation 4574 // point construct for which construct-type-clause is not taskgroup must 4575 // be closely nested inside an OpenMP construct that matches the type 4576 // specified in construct-type-clause. 4577 // A cancel construct for which construct-type-clause is taskgroup must be 4578 // nested inside a task construct. A cancel construct for which 4579 // construct-type-clause is not taskgroup must be closely nested inside an 4580 // OpenMP construct that matches the type specified in 4581 // construct-type-clause. 4582 NestingProhibited = 4583 !((CancelRegion == OMPD_parallel && 4584 (ParentRegion == OMPD_parallel || 4585 ParentRegion == OMPD_target_parallel)) || 4586 (CancelRegion == OMPD_for && 4587 (ParentRegion == OMPD_for || ParentRegion == OMPD_parallel_for || 4588 ParentRegion == OMPD_target_parallel_for || 4589 ParentRegion == OMPD_distribute_parallel_for || 4590 ParentRegion == OMPD_teams_distribute_parallel_for || 4591 ParentRegion == OMPD_target_teams_distribute_parallel_for)) || 4592 (CancelRegion == OMPD_taskgroup && 4593 (ParentRegion == OMPD_task || 4594 (SemaRef.getLangOpts().OpenMP >= 50 && 4595 (ParentRegion == OMPD_taskloop || 4596 ParentRegion == OMPD_master_taskloop || 4597 ParentRegion == OMPD_parallel_master_taskloop)))) || 4598 (CancelRegion == OMPD_sections && 4599 (ParentRegion == OMPD_section || ParentRegion == OMPD_sections || 4600 ParentRegion == OMPD_parallel_sections))); 4601 OrphanSeen = ParentRegion == OMPD_unknown; 4602 } else if (CurrentRegion == OMPD_master) { 4603 // OpenMP [2.16, Nesting of Regions] 4604 // A master region may not be closely nested inside a worksharing, 4605 // atomic, or explicit task region. 4606 NestingProhibited = isOpenMPWorksharingDirective(ParentRegion) || 4607 isOpenMPTaskingDirective(ParentRegion); 4608 } else if (CurrentRegion == OMPD_critical && CurrentName.getName()) { 4609 // OpenMP [2.16, Nesting of Regions] 4610 // A critical region may not be nested (closely or otherwise) inside a 4611 // critical region with the same name. Note that this restriction is not 4612 // sufficient to prevent deadlock. 4613 SourceLocation PreviousCriticalLoc; 4614 bool DeadLock = Stack->hasDirective( 4615 [CurrentName, &PreviousCriticalLoc](OpenMPDirectiveKind K, 4616 const DeclarationNameInfo &DNI, 4617 SourceLocation Loc) { 4618 if (K == OMPD_critical && DNI.getName() == CurrentName.getName()) { 4619 PreviousCriticalLoc = Loc; 4620 return true; 4621 } 4622 return false; 4623 }, 4624 false /* skip top directive */); 4625 if (DeadLock) { 4626 SemaRef.Diag(StartLoc, 4627 diag::err_omp_prohibited_region_critical_same_name) 4628 << CurrentName.getName(); 4629 if (PreviousCriticalLoc.isValid()) 4630 SemaRef.Diag(PreviousCriticalLoc, 4631 diag::note_omp_previous_critical_region); 4632 return true; 4633 } 4634 } else if (CurrentRegion == OMPD_barrier) { 4635 // OpenMP [2.16, Nesting of Regions] 4636 // A barrier region may not be closely nested inside a worksharing, 4637 // explicit task, critical, ordered, atomic, or master region. 4638 NestingProhibited = isOpenMPWorksharingDirective(ParentRegion) || 4639 isOpenMPTaskingDirective(ParentRegion) || 4640 ParentRegion == OMPD_master || 4641 ParentRegion == OMPD_parallel_master || 4642 ParentRegion == OMPD_critical || 4643 ParentRegion == OMPD_ordered; 4644 } else if (isOpenMPWorksharingDirective(CurrentRegion) && 4645 !isOpenMPParallelDirective(CurrentRegion) && 4646 !isOpenMPTeamsDirective(CurrentRegion)) { 4647 // OpenMP [2.16, Nesting of Regions] 4648 // A worksharing region may not be closely nested inside a worksharing, 4649 // explicit task, critical, ordered, atomic, or master region. 4650 NestingProhibited = isOpenMPWorksharingDirective(ParentRegion) || 4651 isOpenMPTaskingDirective(ParentRegion) || 4652 ParentRegion == OMPD_master || 4653 ParentRegion == OMPD_parallel_master || 4654 ParentRegion == OMPD_critical || 4655 ParentRegion == OMPD_ordered; 4656 Recommend = ShouldBeInParallelRegion; 4657 } else if (CurrentRegion == OMPD_ordered) { 4658 // OpenMP [2.16, Nesting of Regions] 4659 // An ordered region may not be closely nested inside a critical, 4660 // atomic, or explicit task region. 4661 // An ordered region must be closely nested inside a loop region (or 4662 // parallel loop region) with an ordered clause. 4663 // OpenMP [2.8.1,simd Construct, Restrictions] 4664 // An ordered construct with the simd clause is the only OpenMP construct 4665 // that can appear in the simd region. 4666 NestingProhibited = ParentRegion == OMPD_critical || 4667 isOpenMPTaskingDirective(ParentRegion) || 4668 !(isOpenMPSimdDirective(ParentRegion) || 4669 Stack->isParentOrderedRegion()); 4670 Recommend = ShouldBeInOrderedRegion; 4671 } else if (isOpenMPNestingTeamsDirective(CurrentRegion)) { 4672 // OpenMP [2.16, Nesting of Regions] 4673 // If specified, a teams construct must be contained within a target 4674 // construct. 4675 NestingProhibited = 4676 (SemaRef.LangOpts.OpenMP <= 45 && ParentRegion != OMPD_target) || 4677 (SemaRef.LangOpts.OpenMP >= 50 && ParentRegion != OMPD_unknown && 4678 ParentRegion != OMPD_target); 4679 OrphanSeen = ParentRegion == OMPD_unknown; 4680 Recommend = ShouldBeInTargetRegion; 4681 } else if (CurrentRegion == OMPD_scan) { 4682 // OpenMP [2.16, Nesting of Regions] 4683 // If specified, a teams construct must be contained within a target 4684 // construct. 4685 NestingProhibited = 4686 SemaRef.LangOpts.OpenMP < 50 || 4687 (ParentRegion != OMPD_simd && ParentRegion != OMPD_for && 4688 ParentRegion != OMPD_for_simd && ParentRegion != OMPD_parallel_for && 4689 ParentRegion != OMPD_parallel_for_simd); 4690 OrphanSeen = ParentRegion == OMPD_unknown; 4691 Recommend = ShouldBeInLoopSimdRegion; 4692 } 4693 if (!NestingProhibited && 4694 !isOpenMPTargetExecutionDirective(CurrentRegion) && 4695 !isOpenMPTargetDataManagementDirective(CurrentRegion) && 4696 (ParentRegion == OMPD_teams || ParentRegion == OMPD_target_teams)) { 4697 // OpenMP [2.16, Nesting of Regions] 4698 // distribute, parallel, parallel sections, parallel workshare, and the 4699 // parallel loop and parallel loop SIMD constructs are the only OpenMP 4700 // constructs that can be closely nested in the teams region. 4701 NestingProhibited = !isOpenMPParallelDirective(CurrentRegion) && 4702 !isOpenMPDistributeDirective(CurrentRegion); 4703 Recommend = ShouldBeInParallelRegion; 4704 } 4705 if (!NestingProhibited && 4706 isOpenMPNestingDistributeDirective(CurrentRegion)) { 4707 // OpenMP 4.5 [2.17 Nesting of Regions] 4708 // The region associated with the distribute construct must be strictly 4709 // nested inside a teams region 4710 NestingProhibited = 4711 (ParentRegion != OMPD_teams && ParentRegion != OMPD_target_teams); 4712 Recommend = ShouldBeInTeamsRegion; 4713 } 4714 if (!NestingProhibited && 4715 (isOpenMPTargetExecutionDirective(CurrentRegion) || 4716 isOpenMPTargetDataManagementDirective(CurrentRegion))) { 4717 // OpenMP 4.5 [2.17 Nesting of Regions] 4718 // If a target, target update, target data, target enter data, or 4719 // target exit data construct is encountered during execution of a 4720 // target region, the behavior is unspecified. 4721 NestingProhibited = Stack->hasDirective( 4722 [&OffendingRegion](OpenMPDirectiveKind K, const DeclarationNameInfo &, 4723 SourceLocation) { 4724 if (isOpenMPTargetExecutionDirective(K)) { 4725 OffendingRegion = K; 4726 return true; 4727 } 4728 return false; 4729 }, 4730 false /* don't skip top directive */); 4731 CloseNesting = false; 4732 } 4733 if (NestingProhibited) { 4734 if (OrphanSeen) { 4735 SemaRef.Diag(StartLoc, diag::err_omp_orphaned_device_directive) 4736 << getOpenMPDirectiveName(CurrentRegion) << Recommend; 4737 } else { 4738 SemaRef.Diag(StartLoc, diag::err_omp_prohibited_region) 4739 << CloseNesting << getOpenMPDirectiveName(OffendingRegion) 4740 << Recommend << getOpenMPDirectiveName(CurrentRegion); 4741 } 4742 return true; 4743 } 4744 } 4745 return false; 4746 } 4747 4748 struct Kind2Unsigned { 4749 using argument_type = OpenMPDirectiveKind; 4750 unsigned operator()(argument_type DK) { return unsigned(DK); } 4751 }; 4752 static bool checkIfClauses(Sema &S, OpenMPDirectiveKind Kind, 4753 ArrayRef<OMPClause *> Clauses, 4754 ArrayRef<OpenMPDirectiveKind> AllowedNameModifiers) { 4755 bool ErrorFound = false; 4756 unsigned NamedModifiersNumber = 0; 4757 llvm::IndexedMap<const OMPIfClause *, Kind2Unsigned> FoundNameModifiers; 4758 FoundNameModifiers.resize(llvm::omp::Directive_enumSize + 1); 4759 SmallVector<SourceLocation, 4> NameModifierLoc; 4760 for (const OMPClause *C : Clauses) { 4761 if (const auto *IC = dyn_cast_or_null<OMPIfClause>(C)) { 4762 // At most one if clause without a directive-name-modifier can appear on 4763 // the directive. 4764 OpenMPDirectiveKind CurNM = IC->getNameModifier(); 4765 if (FoundNameModifiers[CurNM]) { 4766 S.Diag(C->getBeginLoc(), diag::err_omp_more_one_clause) 4767 << getOpenMPDirectiveName(Kind) << getOpenMPClauseName(OMPC_if) 4768 << (CurNM != OMPD_unknown) << getOpenMPDirectiveName(CurNM); 4769 ErrorFound = true; 4770 } else if (CurNM != OMPD_unknown) { 4771 NameModifierLoc.push_back(IC->getNameModifierLoc()); 4772 ++NamedModifiersNumber; 4773 } 4774 FoundNameModifiers[CurNM] = IC; 4775 if (CurNM == OMPD_unknown) 4776 continue; 4777 // Check if the specified name modifier is allowed for the current 4778 // directive. 4779 // At most one if clause with the particular directive-name-modifier can 4780 // appear on the directive. 4781 bool MatchFound = false; 4782 for (auto NM : AllowedNameModifiers) { 4783 if (CurNM == NM) { 4784 MatchFound = true; 4785 break; 4786 } 4787 } 4788 if (!MatchFound) { 4789 S.Diag(IC->getNameModifierLoc(), 4790 diag::err_omp_wrong_if_directive_name_modifier) 4791 << getOpenMPDirectiveName(CurNM) << getOpenMPDirectiveName(Kind); 4792 ErrorFound = true; 4793 } 4794 } 4795 } 4796 // If any if clause on the directive includes a directive-name-modifier then 4797 // all if clauses on the directive must include a directive-name-modifier. 4798 if (FoundNameModifiers[OMPD_unknown] && NamedModifiersNumber > 0) { 4799 if (NamedModifiersNumber == AllowedNameModifiers.size()) { 4800 S.Diag(FoundNameModifiers[OMPD_unknown]->getBeginLoc(), 4801 diag::err_omp_no_more_if_clause); 4802 } else { 4803 std::string Values; 4804 std::string Sep(", "); 4805 unsigned AllowedCnt = 0; 4806 unsigned TotalAllowedNum = 4807 AllowedNameModifiers.size() - NamedModifiersNumber; 4808 for (unsigned Cnt = 0, End = AllowedNameModifiers.size(); Cnt < End; 4809 ++Cnt) { 4810 OpenMPDirectiveKind NM = AllowedNameModifiers[Cnt]; 4811 if (!FoundNameModifiers[NM]) { 4812 Values += "'"; 4813 Values += getOpenMPDirectiveName(NM); 4814 Values += "'"; 4815 if (AllowedCnt + 2 == TotalAllowedNum) 4816 Values += " or "; 4817 else if (AllowedCnt + 1 != TotalAllowedNum) 4818 Values += Sep; 4819 ++AllowedCnt; 4820 } 4821 } 4822 S.Diag(FoundNameModifiers[OMPD_unknown]->getCondition()->getBeginLoc(), 4823 diag::err_omp_unnamed_if_clause) 4824 << (TotalAllowedNum > 1) << Values; 4825 } 4826 for (SourceLocation Loc : NameModifierLoc) { 4827 S.Diag(Loc, diag::note_omp_previous_named_if_clause); 4828 } 4829 ErrorFound = true; 4830 } 4831 return ErrorFound; 4832 } 4833 4834 static std::pair<ValueDecl *, bool> getPrivateItem(Sema &S, Expr *&RefExpr, 4835 SourceLocation &ELoc, 4836 SourceRange &ERange, 4837 bool AllowArraySection) { 4838 if (RefExpr->isTypeDependent() || RefExpr->isValueDependent() || 4839 RefExpr->containsUnexpandedParameterPack()) 4840 return std::make_pair(nullptr, true); 4841 4842 // OpenMP [3.1, C/C++] 4843 // A list item is a variable name. 4844 // OpenMP [2.9.3.3, Restrictions, p.1] 4845 // A variable that is part of another variable (as an array or 4846 // structure element) cannot appear in a private clause. 4847 RefExpr = RefExpr->IgnoreParens(); 4848 enum { 4849 NoArrayExpr = -1, 4850 ArraySubscript = 0, 4851 OMPArraySection = 1 4852 } IsArrayExpr = NoArrayExpr; 4853 if (AllowArraySection) { 4854 if (auto *ASE = dyn_cast_or_null<ArraySubscriptExpr>(RefExpr)) { 4855 Expr *Base = ASE->getBase()->IgnoreParenImpCasts(); 4856 while (auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base)) 4857 Base = TempASE->getBase()->IgnoreParenImpCasts(); 4858 RefExpr = Base; 4859 IsArrayExpr = ArraySubscript; 4860 } else if (auto *OASE = dyn_cast_or_null<OMPArraySectionExpr>(RefExpr)) { 4861 Expr *Base = OASE->getBase()->IgnoreParenImpCasts(); 4862 while (auto *TempOASE = dyn_cast<OMPArraySectionExpr>(Base)) 4863 Base = TempOASE->getBase()->IgnoreParenImpCasts(); 4864 while (auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base)) 4865 Base = TempASE->getBase()->IgnoreParenImpCasts(); 4866 RefExpr = Base; 4867 IsArrayExpr = OMPArraySection; 4868 } 4869 } 4870 ELoc = RefExpr->getExprLoc(); 4871 ERange = RefExpr->getSourceRange(); 4872 RefExpr = RefExpr->IgnoreParenImpCasts(); 4873 auto *DE = dyn_cast_or_null<DeclRefExpr>(RefExpr); 4874 auto *ME = dyn_cast_or_null<MemberExpr>(RefExpr); 4875 if ((!DE || !isa<VarDecl>(DE->getDecl())) && 4876 (S.getCurrentThisType().isNull() || !ME || 4877 !isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts()) || 4878 !isa<FieldDecl>(ME->getMemberDecl()))) { 4879 if (IsArrayExpr != NoArrayExpr) { 4880 S.Diag(ELoc, diag::err_omp_expected_base_var_name) << IsArrayExpr 4881 << ERange; 4882 } else { 4883 S.Diag(ELoc, 4884 AllowArraySection 4885 ? diag::err_omp_expected_var_name_member_expr_or_array_item 4886 : diag::err_omp_expected_var_name_member_expr) 4887 << (S.getCurrentThisType().isNull() ? 0 : 1) << ERange; 4888 } 4889 return std::make_pair(nullptr, false); 4890 } 4891 return std::make_pair( 4892 getCanonicalDecl(DE ? DE->getDecl() : ME->getMemberDecl()), false); 4893 } 4894 4895 namespace { 4896 /// Checks if the allocator is used in uses_allocators clause to be allowed in 4897 /// target regions. 4898 class AllocatorChecker final : public ConstStmtVisitor<AllocatorChecker, bool> { 4899 DSAStackTy *S = nullptr; 4900 4901 public: 4902 bool VisitDeclRefExpr(const DeclRefExpr *E) { 4903 return S->isUsesAllocatorsDecl(E->getDecl()) 4904 .getValueOr( 4905 DSAStackTy::UsesAllocatorsDeclKind::AllocatorTrait) == 4906 DSAStackTy::UsesAllocatorsDeclKind::AllocatorTrait; 4907 } 4908 bool VisitStmt(const Stmt *S) { 4909 for (const Stmt *Child : S->children()) { 4910 if (Child && Visit(Child)) 4911 return true; 4912 } 4913 return false; 4914 } 4915 explicit AllocatorChecker(DSAStackTy *S) : S(S) {} 4916 }; 4917 } // namespace 4918 4919 static void checkAllocateClauses(Sema &S, DSAStackTy *Stack, 4920 ArrayRef<OMPClause *> Clauses) { 4921 assert(!S.CurContext->isDependentContext() && 4922 "Expected non-dependent context."); 4923 auto AllocateRange = 4924 llvm::make_filter_range(Clauses, OMPAllocateClause::classof); 4925 llvm::DenseMap<CanonicalDeclPtr<Decl>, CanonicalDeclPtr<VarDecl>> 4926 DeclToCopy; 4927 auto PrivateRange = llvm::make_filter_range(Clauses, [](const OMPClause *C) { 4928 return isOpenMPPrivate(C->getClauseKind()); 4929 }); 4930 for (OMPClause *Cl : PrivateRange) { 4931 MutableArrayRef<Expr *>::iterator I, It, Et; 4932 if (Cl->getClauseKind() == OMPC_private) { 4933 auto *PC = cast<OMPPrivateClause>(Cl); 4934 I = PC->private_copies().begin(); 4935 It = PC->varlist_begin(); 4936 Et = PC->varlist_end(); 4937 } else if (Cl->getClauseKind() == OMPC_firstprivate) { 4938 auto *PC = cast<OMPFirstprivateClause>(Cl); 4939 I = PC->private_copies().begin(); 4940 It = PC->varlist_begin(); 4941 Et = PC->varlist_end(); 4942 } else if (Cl->getClauseKind() == OMPC_lastprivate) { 4943 auto *PC = cast<OMPLastprivateClause>(Cl); 4944 I = PC->private_copies().begin(); 4945 It = PC->varlist_begin(); 4946 Et = PC->varlist_end(); 4947 } else if (Cl->getClauseKind() == OMPC_linear) { 4948 auto *PC = cast<OMPLinearClause>(Cl); 4949 I = PC->privates().begin(); 4950 It = PC->varlist_begin(); 4951 Et = PC->varlist_end(); 4952 } else if (Cl->getClauseKind() == OMPC_reduction) { 4953 auto *PC = cast<OMPReductionClause>(Cl); 4954 I = PC->privates().begin(); 4955 It = PC->varlist_begin(); 4956 Et = PC->varlist_end(); 4957 } else if (Cl->getClauseKind() == OMPC_task_reduction) { 4958 auto *PC = cast<OMPTaskReductionClause>(Cl); 4959 I = PC->privates().begin(); 4960 It = PC->varlist_begin(); 4961 Et = PC->varlist_end(); 4962 } else if (Cl->getClauseKind() == OMPC_in_reduction) { 4963 auto *PC = cast<OMPInReductionClause>(Cl); 4964 I = PC->privates().begin(); 4965 It = PC->varlist_begin(); 4966 Et = PC->varlist_end(); 4967 } else { 4968 llvm_unreachable("Expected private clause."); 4969 } 4970 for (Expr *E : llvm::make_range(It, Et)) { 4971 if (!*I) { 4972 ++I; 4973 continue; 4974 } 4975 SourceLocation ELoc; 4976 SourceRange ERange; 4977 Expr *SimpleRefExpr = E; 4978 auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange, 4979 /*AllowArraySection=*/true); 4980 DeclToCopy.try_emplace(Res.first, 4981 cast<VarDecl>(cast<DeclRefExpr>(*I)->getDecl())); 4982 ++I; 4983 } 4984 } 4985 for (OMPClause *C : AllocateRange) { 4986 auto *AC = cast<OMPAllocateClause>(C); 4987 if (S.getLangOpts().OpenMP >= 50 && 4988 !Stack->hasRequiresDeclWithClause<OMPDynamicAllocatorsClause>() && 4989 isOpenMPTargetExecutionDirective(Stack->getCurrentDirective()) && 4990 AC->getAllocator()) { 4991 Expr *Allocator = AC->getAllocator(); 4992 // OpenMP, 2.12.5 target Construct 4993 // Memory allocators that do not appear in a uses_allocators clause cannot 4994 // appear as an allocator in an allocate clause or be used in the target 4995 // region unless a requires directive with the dynamic_allocators clause 4996 // is present in the same compilation unit. 4997 AllocatorChecker Checker(Stack); 4998 if (Checker.Visit(Allocator)) 4999 S.Diag(Allocator->getExprLoc(), 5000 diag::err_omp_allocator_not_in_uses_allocators) 5001 << Allocator->getSourceRange(); 5002 } 5003 OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind = 5004 getAllocatorKind(S, Stack, AC->getAllocator()); 5005 // OpenMP, 2.11.4 allocate Clause, Restrictions. 5006 // For task, taskloop or target directives, allocation requests to memory 5007 // allocators with the trait access set to thread result in unspecified 5008 // behavior. 5009 if (AllocatorKind == OMPAllocateDeclAttr::OMPThreadMemAlloc && 5010 (isOpenMPTaskingDirective(Stack->getCurrentDirective()) || 5011 isOpenMPTargetExecutionDirective(Stack->getCurrentDirective()))) { 5012 S.Diag(AC->getAllocator()->getExprLoc(), 5013 diag::warn_omp_allocate_thread_on_task_target_directive) 5014 << getOpenMPDirectiveName(Stack->getCurrentDirective()); 5015 } 5016 for (Expr *E : AC->varlists()) { 5017 SourceLocation ELoc; 5018 SourceRange ERange; 5019 Expr *SimpleRefExpr = E; 5020 auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange); 5021 ValueDecl *VD = Res.first; 5022 DSAStackTy::DSAVarData Data = Stack->getTopDSA(VD, /*FromParent=*/false); 5023 if (!isOpenMPPrivate(Data.CKind)) { 5024 S.Diag(E->getExprLoc(), 5025 diag::err_omp_expected_private_copy_for_allocate); 5026 continue; 5027 } 5028 VarDecl *PrivateVD = DeclToCopy[VD]; 5029 if (checkPreviousOMPAllocateAttribute(S, Stack, E, PrivateVD, 5030 AllocatorKind, AC->getAllocator())) 5031 continue; 5032 applyOMPAllocateAttribute(S, PrivateVD, AllocatorKind, AC->getAllocator(), 5033 E->getSourceRange()); 5034 } 5035 } 5036 } 5037 5038 StmtResult Sema::ActOnOpenMPExecutableDirective( 5039 OpenMPDirectiveKind Kind, const DeclarationNameInfo &DirName, 5040 OpenMPDirectiveKind CancelRegion, ArrayRef<OMPClause *> Clauses, 5041 Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc) { 5042 StmtResult Res = StmtError(); 5043 // First check CancelRegion which is then used in checkNestingOfRegions. 5044 if (checkCancelRegion(*this, Kind, CancelRegion, StartLoc) || 5045 checkNestingOfRegions(*this, DSAStack, Kind, DirName, CancelRegion, 5046 StartLoc)) 5047 return StmtError(); 5048 5049 llvm::SmallVector<OMPClause *, 8> ClausesWithImplicit; 5050 VarsWithInheritedDSAType VarsWithInheritedDSA; 5051 bool ErrorFound = false; 5052 ClausesWithImplicit.append(Clauses.begin(), Clauses.end()); 5053 if (AStmt && !CurContext->isDependentContext() && Kind != OMPD_atomic && 5054 Kind != OMPD_critical && Kind != OMPD_section && Kind != OMPD_master) { 5055 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 5056 5057 // Check default data sharing attributes for referenced variables. 5058 DSAAttrChecker DSAChecker(DSAStack, *this, cast<CapturedStmt>(AStmt)); 5059 int ThisCaptureLevel = getOpenMPCaptureLevels(Kind); 5060 Stmt *S = AStmt; 5061 while (--ThisCaptureLevel >= 0) 5062 S = cast<CapturedStmt>(S)->getCapturedStmt(); 5063 DSAChecker.Visit(S); 5064 if (!isOpenMPTargetDataManagementDirective(Kind) && 5065 !isOpenMPTaskingDirective(Kind)) { 5066 // Visit subcaptures to generate implicit clauses for captured vars. 5067 auto *CS = cast<CapturedStmt>(AStmt); 5068 SmallVector<OpenMPDirectiveKind, 4> CaptureRegions; 5069 getOpenMPCaptureRegions(CaptureRegions, Kind); 5070 // Ignore outer tasking regions for target directives. 5071 if (CaptureRegions.size() > 1 && CaptureRegions.front() == OMPD_task) 5072 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 5073 DSAChecker.visitSubCaptures(CS); 5074 } 5075 if (DSAChecker.isErrorFound()) 5076 return StmtError(); 5077 // Generate list of implicitly defined firstprivate variables. 5078 VarsWithInheritedDSA = DSAChecker.getVarsWithInheritedDSA(); 5079 5080 SmallVector<Expr *, 4> ImplicitFirstprivates( 5081 DSAChecker.getImplicitFirstprivate().begin(), 5082 DSAChecker.getImplicitFirstprivate().end()); 5083 SmallVector<Expr *, 4> ImplicitMaps[OMPC_MAP_delete]; 5084 for (unsigned I = 0; I < OMPC_MAP_delete; ++I) { 5085 ArrayRef<Expr *> ImplicitMap = 5086 DSAChecker.getImplicitMap(static_cast<OpenMPDefaultmapClauseKind>(I)); 5087 ImplicitMaps[I].append(ImplicitMap.begin(), ImplicitMap.end()); 5088 } 5089 // Mark taskgroup task_reduction descriptors as implicitly firstprivate. 5090 for (OMPClause *C : Clauses) { 5091 if (auto *IRC = dyn_cast<OMPInReductionClause>(C)) { 5092 for (Expr *E : IRC->taskgroup_descriptors()) 5093 if (E) 5094 ImplicitFirstprivates.emplace_back(E); 5095 } 5096 // OpenMP 5.0, 2.10.1 task Construct 5097 // [detach clause]... The event-handle will be considered as if it was 5098 // specified on a firstprivate clause. 5099 if (auto *DC = dyn_cast<OMPDetachClause>(C)) 5100 ImplicitFirstprivates.push_back(DC->getEventHandler()); 5101 } 5102 if (!ImplicitFirstprivates.empty()) { 5103 if (OMPClause *Implicit = ActOnOpenMPFirstprivateClause( 5104 ImplicitFirstprivates, SourceLocation(), SourceLocation(), 5105 SourceLocation())) { 5106 ClausesWithImplicit.push_back(Implicit); 5107 ErrorFound = cast<OMPFirstprivateClause>(Implicit)->varlist_size() != 5108 ImplicitFirstprivates.size(); 5109 } else { 5110 ErrorFound = true; 5111 } 5112 } 5113 int ClauseKindCnt = -1; 5114 for (ArrayRef<Expr *> ImplicitMap : ImplicitMaps) { 5115 ++ClauseKindCnt; 5116 if (ImplicitMap.empty()) 5117 continue; 5118 CXXScopeSpec MapperIdScopeSpec; 5119 DeclarationNameInfo MapperId; 5120 auto Kind = static_cast<OpenMPMapClauseKind>(ClauseKindCnt); 5121 if (OMPClause *Implicit = ActOnOpenMPMapClause( 5122 llvm::None, llvm::None, MapperIdScopeSpec, MapperId, Kind, 5123 /*IsMapTypeImplicit=*/true, SourceLocation(), SourceLocation(), 5124 ImplicitMap, OMPVarListLocTy())) { 5125 ClausesWithImplicit.emplace_back(Implicit); 5126 ErrorFound |= 5127 cast<OMPMapClause>(Implicit)->varlist_size() != ImplicitMap.size(); 5128 } else { 5129 ErrorFound = true; 5130 } 5131 } 5132 } 5133 5134 llvm::SmallVector<OpenMPDirectiveKind, 4> AllowedNameModifiers; 5135 switch (Kind) { 5136 case OMPD_parallel: 5137 Res = ActOnOpenMPParallelDirective(ClausesWithImplicit, AStmt, StartLoc, 5138 EndLoc); 5139 AllowedNameModifiers.push_back(OMPD_parallel); 5140 break; 5141 case OMPD_simd: 5142 Res = ActOnOpenMPSimdDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc, 5143 VarsWithInheritedDSA); 5144 if (LangOpts.OpenMP >= 50) 5145 AllowedNameModifiers.push_back(OMPD_simd); 5146 break; 5147 case OMPD_for: 5148 Res = ActOnOpenMPForDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc, 5149 VarsWithInheritedDSA); 5150 break; 5151 case OMPD_for_simd: 5152 Res = ActOnOpenMPForSimdDirective(ClausesWithImplicit, AStmt, StartLoc, 5153 EndLoc, VarsWithInheritedDSA); 5154 if (LangOpts.OpenMP >= 50) 5155 AllowedNameModifiers.push_back(OMPD_simd); 5156 break; 5157 case OMPD_sections: 5158 Res = ActOnOpenMPSectionsDirective(ClausesWithImplicit, AStmt, StartLoc, 5159 EndLoc); 5160 break; 5161 case OMPD_section: 5162 assert(ClausesWithImplicit.empty() && 5163 "No clauses are allowed for 'omp section' directive"); 5164 Res = ActOnOpenMPSectionDirective(AStmt, StartLoc, EndLoc); 5165 break; 5166 case OMPD_single: 5167 Res = ActOnOpenMPSingleDirective(ClausesWithImplicit, AStmt, StartLoc, 5168 EndLoc); 5169 break; 5170 case OMPD_master: 5171 assert(ClausesWithImplicit.empty() && 5172 "No clauses are allowed for 'omp master' directive"); 5173 Res = ActOnOpenMPMasterDirective(AStmt, StartLoc, EndLoc); 5174 break; 5175 case OMPD_critical: 5176 Res = ActOnOpenMPCriticalDirective(DirName, ClausesWithImplicit, AStmt, 5177 StartLoc, EndLoc); 5178 break; 5179 case OMPD_parallel_for: 5180 Res = ActOnOpenMPParallelForDirective(ClausesWithImplicit, AStmt, StartLoc, 5181 EndLoc, VarsWithInheritedDSA); 5182 AllowedNameModifiers.push_back(OMPD_parallel); 5183 break; 5184 case OMPD_parallel_for_simd: 5185 Res = ActOnOpenMPParallelForSimdDirective( 5186 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 5187 AllowedNameModifiers.push_back(OMPD_parallel); 5188 if (LangOpts.OpenMP >= 50) 5189 AllowedNameModifiers.push_back(OMPD_simd); 5190 break; 5191 case OMPD_parallel_master: 5192 Res = ActOnOpenMPParallelMasterDirective(ClausesWithImplicit, AStmt, 5193 StartLoc, EndLoc); 5194 AllowedNameModifiers.push_back(OMPD_parallel); 5195 break; 5196 case OMPD_parallel_sections: 5197 Res = ActOnOpenMPParallelSectionsDirective(ClausesWithImplicit, AStmt, 5198 StartLoc, EndLoc); 5199 AllowedNameModifiers.push_back(OMPD_parallel); 5200 break; 5201 case OMPD_task: 5202 Res = 5203 ActOnOpenMPTaskDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc); 5204 AllowedNameModifiers.push_back(OMPD_task); 5205 break; 5206 case OMPD_taskyield: 5207 assert(ClausesWithImplicit.empty() && 5208 "No clauses are allowed for 'omp taskyield' directive"); 5209 assert(AStmt == nullptr && 5210 "No associated statement allowed for 'omp taskyield' directive"); 5211 Res = ActOnOpenMPTaskyieldDirective(StartLoc, EndLoc); 5212 break; 5213 case OMPD_barrier: 5214 assert(ClausesWithImplicit.empty() && 5215 "No clauses are allowed for 'omp barrier' directive"); 5216 assert(AStmt == nullptr && 5217 "No associated statement allowed for 'omp barrier' directive"); 5218 Res = ActOnOpenMPBarrierDirective(StartLoc, EndLoc); 5219 break; 5220 case OMPD_taskwait: 5221 assert(ClausesWithImplicit.empty() && 5222 "No clauses are allowed for 'omp taskwait' directive"); 5223 assert(AStmt == nullptr && 5224 "No associated statement allowed for 'omp taskwait' directive"); 5225 Res = ActOnOpenMPTaskwaitDirective(StartLoc, EndLoc); 5226 break; 5227 case OMPD_taskgroup: 5228 Res = ActOnOpenMPTaskgroupDirective(ClausesWithImplicit, AStmt, StartLoc, 5229 EndLoc); 5230 break; 5231 case OMPD_flush: 5232 assert(AStmt == nullptr && 5233 "No associated statement allowed for 'omp flush' directive"); 5234 Res = ActOnOpenMPFlushDirective(ClausesWithImplicit, StartLoc, EndLoc); 5235 break; 5236 case OMPD_depobj: 5237 assert(AStmt == nullptr && 5238 "No associated statement allowed for 'omp depobj' directive"); 5239 Res = ActOnOpenMPDepobjDirective(ClausesWithImplicit, StartLoc, EndLoc); 5240 break; 5241 case OMPD_scan: 5242 assert(AStmt == nullptr && 5243 "No associated statement allowed for 'omp scan' directive"); 5244 Res = ActOnOpenMPScanDirective(ClausesWithImplicit, StartLoc, EndLoc); 5245 break; 5246 case OMPD_ordered: 5247 Res = ActOnOpenMPOrderedDirective(ClausesWithImplicit, AStmt, StartLoc, 5248 EndLoc); 5249 break; 5250 case OMPD_atomic: 5251 Res = ActOnOpenMPAtomicDirective(ClausesWithImplicit, AStmt, StartLoc, 5252 EndLoc); 5253 break; 5254 case OMPD_teams: 5255 Res = 5256 ActOnOpenMPTeamsDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc); 5257 break; 5258 case OMPD_target: 5259 Res = ActOnOpenMPTargetDirective(ClausesWithImplicit, AStmt, StartLoc, 5260 EndLoc); 5261 AllowedNameModifiers.push_back(OMPD_target); 5262 break; 5263 case OMPD_target_parallel: 5264 Res = ActOnOpenMPTargetParallelDirective(ClausesWithImplicit, AStmt, 5265 StartLoc, EndLoc); 5266 AllowedNameModifiers.push_back(OMPD_target); 5267 AllowedNameModifiers.push_back(OMPD_parallel); 5268 break; 5269 case OMPD_target_parallel_for: 5270 Res = ActOnOpenMPTargetParallelForDirective( 5271 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 5272 AllowedNameModifiers.push_back(OMPD_target); 5273 AllowedNameModifiers.push_back(OMPD_parallel); 5274 break; 5275 case OMPD_cancellation_point: 5276 assert(ClausesWithImplicit.empty() && 5277 "No clauses are allowed for 'omp cancellation point' directive"); 5278 assert(AStmt == nullptr && "No associated statement allowed for 'omp " 5279 "cancellation point' directive"); 5280 Res = ActOnOpenMPCancellationPointDirective(StartLoc, EndLoc, CancelRegion); 5281 break; 5282 case OMPD_cancel: 5283 assert(AStmt == nullptr && 5284 "No associated statement allowed for 'omp cancel' directive"); 5285 Res = ActOnOpenMPCancelDirective(ClausesWithImplicit, StartLoc, EndLoc, 5286 CancelRegion); 5287 AllowedNameModifiers.push_back(OMPD_cancel); 5288 break; 5289 case OMPD_target_data: 5290 Res = ActOnOpenMPTargetDataDirective(ClausesWithImplicit, AStmt, StartLoc, 5291 EndLoc); 5292 AllowedNameModifiers.push_back(OMPD_target_data); 5293 break; 5294 case OMPD_target_enter_data: 5295 Res = ActOnOpenMPTargetEnterDataDirective(ClausesWithImplicit, StartLoc, 5296 EndLoc, AStmt); 5297 AllowedNameModifiers.push_back(OMPD_target_enter_data); 5298 break; 5299 case OMPD_target_exit_data: 5300 Res = ActOnOpenMPTargetExitDataDirective(ClausesWithImplicit, StartLoc, 5301 EndLoc, AStmt); 5302 AllowedNameModifiers.push_back(OMPD_target_exit_data); 5303 break; 5304 case OMPD_taskloop: 5305 Res = ActOnOpenMPTaskLoopDirective(ClausesWithImplicit, AStmt, StartLoc, 5306 EndLoc, VarsWithInheritedDSA); 5307 AllowedNameModifiers.push_back(OMPD_taskloop); 5308 break; 5309 case OMPD_taskloop_simd: 5310 Res = ActOnOpenMPTaskLoopSimdDirective(ClausesWithImplicit, AStmt, StartLoc, 5311 EndLoc, VarsWithInheritedDSA); 5312 AllowedNameModifiers.push_back(OMPD_taskloop); 5313 if (LangOpts.OpenMP >= 50) 5314 AllowedNameModifiers.push_back(OMPD_simd); 5315 break; 5316 case OMPD_master_taskloop: 5317 Res = ActOnOpenMPMasterTaskLoopDirective( 5318 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 5319 AllowedNameModifiers.push_back(OMPD_taskloop); 5320 break; 5321 case OMPD_master_taskloop_simd: 5322 Res = ActOnOpenMPMasterTaskLoopSimdDirective( 5323 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 5324 AllowedNameModifiers.push_back(OMPD_taskloop); 5325 if (LangOpts.OpenMP >= 50) 5326 AllowedNameModifiers.push_back(OMPD_simd); 5327 break; 5328 case OMPD_parallel_master_taskloop: 5329 Res = ActOnOpenMPParallelMasterTaskLoopDirective( 5330 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 5331 AllowedNameModifiers.push_back(OMPD_taskloop); 5332 AllowedNameModifiers.push_back(OMPD_parallel); 5333 break; 5334 case OMPD_parallel_master_taskloop_simd: 5335 Res = ActOnOpenMPParallelMasterTaskLoopSimdDirective( 5336 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 5337 AllowedNameModifiers.push_back(OMPD_taskloop); 5338 AllowedNameModifiers.push_back(OMPD_parallel); 5339 if (LangOpts.OpenMP >= 50) 5340 AllowedNameModifiers.push_back(OMPD_simd); 5341 break; 5342 case OMPD_distribute: 5343 Res = ActOnOpenMPDistributeDirective(ClausesWithImplicit, AStmt, StartLoc, 5344 EndLoc, VarsWithInheritedDSA); 5345 break; 5346 case OMPD_target_update: 5347 Res = ActOnOpenMPTargetUpdateDirective(ClausesWithImplicit, StartLoc, 5348 EndLoc, AStmt); 5349 AllowedNameModifiers.push_back(OMPD_target_update); 5350 break; 5351 case OMPD_distribute_parallel_for: 5352 Res = ActOnOpenMPDistributeParallelForDirective( 5353 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 5354 AllowedNameModifiers.push_back(OMPD_parallel); 5355 break; 5356 case OMPD_distribute_parallel_for_simd: 5357 Res = ActOnOpenMPDistributeParallelForSimdDirective( 5358 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 5359 AllowedNameModifiers.push_back(OMPD_parallel); 5360 if (LangOpts.OpenMP >= 50) 5361 AllowedNameModifiers.push_back(OMPD_simd); 5362 break; 5363 case OMPD_distribute_simd: 5364 Res = ActOnOpenMPDistributeSimdDirective( 5365 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 5366 if (LangOpts.OpenMP >= 50) 5367 AllowedNameModifiers.push_back(OMPD_simd); 5368 break; 5369 case OMPD_target_parallel_for_simd: 5370 Res = ActOnOpenMPTargetParallelForSimdDirective( 5371 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 5372 AllowedNameModifiers.push_back(OMPD_target); 5373 AllowedNameModifiers.push_back(OMPD_parallel); 5374 if (LangOpts.OpenMP >= 50) 5375 AllowedNameModifiers.push_back(OMPD_simd); 5376 break; 5377 case OMPD_target_simd: 5378 Res = ActOnOpenMPTargetSimdDirective(ClausesWithImplicit, AStmt, StartLoc, 5379 EndLoc, VarsWithInheritedDSA); 5380 AllowedNameModifiers.push_back(OMPD_target); 5381 if (LangOpts.OpenMP >= 50) 5382 AllowedNameModifiers.push_back(OMPD_simd); 5383 break; 5384 case OMPD_teams_distribute: 5385 Res = ActOnOpenMPTeamsDistributeDirective( 5386 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 5387 break; 5388 case OMPD_teams_distribute_simd: 5389 Res = ActOnOpenMPTeamsDistributeSimdDirective( 5390 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 5391 if (LangOpts.OpenMP >= 50) 5392 AllowedNameModifiers.push_back(OMPD_simd); 5393 break; 5394 case OMPD_teams_distribute_parallel_for_simd: 5395 Res = ActOnOpenMPTeamsDistributeParallelForSimdDirective( 5396 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 5397 AllowedNameModifiers.push_back(OMPD_parallel); 5398 if (LangOpts.OpenMP >= 50) 5399 AllowedNameModifiers.push_back(OMPD_simd); 5400 break; 5401 case OMPD_teams_distribute_parallel_for: 5402 Res = ActOnOpenMPTeamsDistributeParallelForDirective( 5403 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 5404 AllowedNameModifiers.push_back(OMPD_parallel); 5405 break; 5406 case OMPD_target_teams: 5407 Res = ActOnOpenMPTargetTeamsDirective(ClausesWithImplicit, AStmt, StartLoc, 5408 EndLoc); 5409 AllowedNameModifiers.push_back(OMPD_target); 5410 break; 5411 case OMPD_target_teams_distribute: 5412 Res = ActOnOpenMPTargetTeamsDistributeDirective( 5413 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 5414 AllowedNameModifiers.push_back(OMPD_target); 5415 break; 5416 case OMPD_target_teams_distribute_parallel_for: 5417 Res = ActOnOpenMPTargetTeamsDistributeParallelForDirective( 5418 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 5419 AllowedNameModifiers.push_back(OMPD_target); 5420 AllowedNameModifiers.push_back(OMPD_parallel); 5421 break; 5422 case OMPD_target_teams_distribute_parallel_for_simd: 5423 Res = ActOnOpenMPTargetTeamsDistributeParallelForSimdDirective( 5424 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 5425 AllowedNameModifiers.push_back(OMPD_target); 5426 AllowedNameModifiers.push_back(OMPD_parallel); 5427 if (LangOpts.OpenMP >= 50) 5428 AllowedNameModifiers.push_back(OMPD_simd); 5429 break; 5430 case OMPD_target_teams_distribute_simd: 5431 Res = ActOnOpenMPTargetTeamsDistributeSimdDirective( 5432 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 5433 AllowedNameModifiers.push_back(OMPD_target); 5434 if (LangOpts.OpenMP >= 50) 5435 AllowedNameModifiers.push_back(OMPD_simd); 5436 break; 5437 case OMPD_declare_target: 5438 case OMPD_end_declare_target: 5439 case OMPD_threadprivate: 5440 case OMPD_allocate: 5441 case OMPD_declare_reduction: 5442 case OMPD_declare_mapper: 5443 case OMPD_declare_simd: 5444 case OMPD_requires: 5445 case OMPD_declare_variant: 5446 case OMPD_begin_declare_variant: 5447 case OMPD_end_declare_variant: 5448 llvm_unreachable("OpenMP Directive is not allowed"); 5449 case OMPD_unknown: 5450 default: 5451 llvm_unreachable("Unknown OpenMP directive"); 5452 } 5453 5454 ErrorFound = Res.isInvalid() || ErrorFound; 5455 5456 // Check variables in the clauses if default(none) or 5457 // default(firstprivate) was specified. 5458 if (DSAStack->getDefaultDSA() == DSA_none || 5459 DSAStack->getDefaultDSA() == DSA_firstprivate) { 5460 DSAAttrChecker DSAChecker(DSAStack, *this, nullptr); 5461 for (OMPClause *C : Clauses) { 5462 switch (C->getClauseKind()) { 5463 case OMPC_num_threads: 5464 case OMPC_dist_schedule: 5465 // Do not analyse if no parent teams directive. 5466 if (isOpenMPTeamsDirective(Kind)) 5467 break; 5468 continue; 5469 case OMPC_if: 5470 if (isOpenMPTeamsDirective(Kind) && 5471 cast<OMPIfClause>(C)->getNameModifier() != OMPD_target) 5472 break; 5473 if (isOpenMPParallelDirective(Kind) && 5474 isOpenMPTaskLoopDirective(Kind) && 5475 cast<OMPIfClause>(C)->getNameModifier() != OMPD_parallel) 5476 break; 5477 continue; 5478 case OMPC_schedule: 5479 case OMPC_detach: 5480 break; 5481 case OMPC_grainsize: 5482 case OMPC_num_tasks: 5483 case OMPC_final: 5484 case OMPC_priority: 5485 // Do not analyze if no parent parallel directive. 5486 if (isOpenMPParallelDirective(Kind)) 5487 break; 5488 continue; 5489 case OMPC_ordered: 5490 case OMPC_device: 5491 case OMPC_num_teams: 5492 case OMPC_thread_limit: 5493 case OMPC_hint: 5494 case OMPC_collapse: 5495 case OMPC_safelen: 5496 case OMPC_simdlen: 5497 case OMPC_default: 5498 case OMPC_proc_bind: 5499 case OMPC_private: 5500 case OMPC_firstprivate: 5501 case OMPC_lastprivate: 5502 case OMPC_shared: 5503 case OMPC_reduction: 5504 case OMPC_task_reduction: 5505 case OMPC_in_reduction: 5506 case OMPC_linear: 5507 case OMPC_aligned: 5508 case OMPC_copyin: 5509 case OMPC_copyprivate: 5510 case OMPC_nowait: 5511 case OMPC_untied: 5512 case OMPC_mergeable: 5513 case OMPC_allocate: 5514 case OMPC_read: 5515 case OMPC_write: 5516 case OMPC_update: 5517 case OMPC_capture: 5518 case OMPC_seq_cst: 5519 case OMPC_acq_rel: 5520 case OMPC_acquire: 5521 case OMPC_release: 5522 case OMPC_relaxed: 5523 case OMPC_depend: 5524 case OMPC_threads: 5525 case OMPC_simd: 5526 case OMPC_map: 5527 case OMPC_nogroup: 5528 case OMPC_defaultmap: 5529 case OMPC_to: 5530 case OMPC_from: 5531 case OMPC_use_device_ptr: 5532 case OMPC_use_device_addr: 5533 case OMPC_is_device_ptr: 5534 case OMPC_nontemporal: 5535 case OMPC_order: 5536 case OMPC_destroy: 5537 case OMPC_inclusive: 5538 case OMPC_exclusive: 5539 case OMPC_uses_allocators: 5540 case OMPC_affinity: 5541 continue; 5542 case OMPC_allocator: 5543 case OMPC_flush: 5544 case OMPC_depobj: 5545 case OMPC_threadprivate: 5546 case OMPC_uniform: 5547 case OMPC_unknown: 5548 case OMPC_unified_address: 5549 case OMPC_unified_shared_memory: 5550 case OMPC_reverse_offload: 5551 case OMPC_dynamic_allocators: 5552 case OMPC_atomic_default_mem_order: 5553 case OMPC_device_type: 5554 case OMPC_match: 5555 default: 5556 llvm_unreachable("Unexpected clause"); 5557 } 5558 for (Stmt *CC : C->children()) { 5559 if (CC) 5560 DSAChecker.Visit(CC); 5561 } 5562 } 5563 for (const auto &P : DSAChecker.getVarsWithInheritedDSA()) 5564 VarsWithInheritedDSA[P.getFirst()] = P.getSecond(); 5565 } 5566 for (const auto &P : VarsWithInheritedDSA) { 5567 if (P.getFirst()->isImplicit() || isa<OMPCapturedExprDecl>(P.getFirst())) 5568 continue; 5569 ErrorFound = true; 5570 if (DSAStack->getDefaultDSA() == DSA_none || 5571 DSAStack->getDefaultDSA() == DSA_firstprivate) { 5572 Diag(P.second->getExprLoc(), diag::err_omp_no_dsa_for_variable) 5573 << P.first << P.second->getSourceRange(); 5574 Diag(DSAStack->getDefaultDSALocation(), diag::note_omp_default_dsa_none); 5575 } else if (getLangOpts().OpenMP >= 50) { 5576 Diag(P.second->getExprLoc(), 5577 diag::err_omp_defaultmap_no_attr_for_variable) 5578 << P.first << P.second->getSourceRange(); 5579 Diag(DSAStack->getDefaultDSALocation(), 5580 diag::note_omp_defaultmap_attr_none); 5581 } 5582 } 5583 5584 if (!AllowedNameModifiers.empty()) 5585 ErrorFound = checkIfClauses(*this, Kind, Clauses, AllowedNameModifiers) || 5586 ErrorFound; 5587 5588 if (ErrorFound) 5589 return StmtError(); 5590 5591 if (!CurContext->isDependentContext() && 5592 isOpenMPTargetExecutionDirective(Kind) && 5593 !(DSAStack->hasRequiresDeclWithClause<OMPUnifiedSharedMemoryClause>() || 5594 DSAStack->hasRequiresDeclWithClause<OMPUnifiedAddressClause>() || 5595 DSAStack->hasRequiresDeclWithClause<OMPReverseOffloadClause>() || 5596 DSAStack->hasRequiresDeclWithClause<OMPDynamicAllocatorsClause>())) { 5597 // Register target to DSA Stack. 5598 DSAStack->addTargetDirLocation(StartLoc); 5599 } 5600 5601 return Res; 5602 } 5603 5604 Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareSimdDirective( 5605 DeclGroupPtrTy DG, OMPDeclareSimdDeclAttr::BranchStateTy BS, Expr *Simdlen, 5606 ArrayRef<Expr *> Uniforms, ArrayRef<Expr *> Aligneds, 5607 ArrayRef<Expr *> Alignments, ArrayRef<Expr *> Linears, 5608 ArrayRef<unsigned> LinModifiers, ArrayRef<Expr *> Steps, SourceRange SR) { 5609 assert(Aligneds.size() == Alignments.size()); 5610 assert(Linears.size() == LinModifiers.size()); 5611 assert(Linears.size() == Steps.size()); 5612 if (!DG || DG.get().isNull()) 5613 return DeclGroupPtrTy(); 5614 5615 const int SimdId = 0; 5616 if (!DG.get().isSingleDecl()) { 5617 Diag(SR.getBegin(), diag::err_omp_single_decl_in_declare_simd_variant) 5618 << SimdId; 5619 return DG; 5620 } 5621 Decl *ADecl = DG.get().getSingleDecl(); 5622 if (auto *FTD = dyn_cast<FunctionTemplateDecl>(ADecl)) 5623 ADecl = FTD->getTemplatedDecl(); 5624 5625 auto *FD = dyn_cast<FunctionDecl>(ADecl); 5626 if (!FD) { 5627 Diag(ADecl->getLocation(), diag::err_omp_function_expected) << SimdId; 5628 return DeclGroupPtrTy(); 5629 } 5630 5631 // OpenMP [2.8.2, declare simd construct, Description] 5632 // The parameter of the simdlen clause must be a constant positive integer 5633 // expression. 5634 ExprResult SL; 5635 if (Simdlen) 5636 SL = VerifyPositiveIntegerConstantInClause(Simdlen, OMPC_simdlen); 5637 // OpenMP [2.8.2, declare simd construct, Description] 5638 // The special this pointer can be used as if was one of the arguments to the 5639 // function in any of the linear, aligned, or uniform clauses. 5640 // The uniform clause declares one or more arguments to have an invariant 5641 // value for all concurrent invocations of the function in the execution of a 5642 // single SIMD loop. 5643 llvm::DenseMap<const Decl *, const Expr *> UniformedArgs; 5644 const Expr *UniformedLinearThis = nullptr; 5645 for (const Expr *E : Uniforms) { 5646 E = E->IgnoreParenImpCasts(); 5647 if (const auto *DRE = dyn_cast<DeclRefExpr>(E)) 5648 if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) 5649 if (FD->getNumParams() > PVD->getFunctionScopeIndex() && 5650 FD->getParamDecl(PVD->getFunctionScopeIndex()) 5651 ->getCanonicalDecl() == PVD->getCanonicalDecl()) { 5652 UniformedArgs.try_emplace(PVD->getCanonicalDecl(), E); 5653 continue; 5654 } 5655 if (isa<CXXThisExpr>(E)) { 5656 UniformedLinearThis = E; 5657 continue; 5658 } 5659 Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause) 5660 << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0); 5661 } 5662 // OpenMP [2.8.2, declare simd construct, Description] 5663 // The aligned clause declares that the object to which each list item points 5664 // is aligned to the number of bytes expressed in the optional parameter of 5665 // the aligned clause. 5666 // The special this pointer can be used as if was one of the arguments to the 5667 // function in any of the linear, aligned, or uniform clauses. 5668 // The type of list items appearing in the aligned clause must be array, 5669 // pointer, reference to array, or reference to pointer. 5670 llvm::DenseMap<const Decl *, const Expr *> AlignedArgs; 5671 const Expr *AlignedThis = nullptr; 5672 for (const Expr *E : Aligneds) { 5673 E = E->IgnoreParenImpCasts(); 5674 if (const auto *DRE = dyn_cast<DeclRefExpr>(E)) 5675 if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) { 5676 const VarDecl *CanonPVD = PVD->getCanonicalDecl(); 5677 if (FD->getNumParams() > PVD->getFunctionScopeIndex() && 5678 FD->getParamDecl(PVD->getFunctionScopeIndex()) 5679 ->getCanonicalDecl() == CanonPVD) { 5680 // OpenMP [2.8.1, simd construct, Restrictions] 5681 // A list-item cannot appear in more than one aligned clause. 5682 if (AlignedArgs.count(CanonPVD) > 0) { 5683 Diag(E->getExprLoc(), diag::err_omp_used_in_clause_twice) 5684 << 1 << getOpenMPClauseName(OMPC_aligned) 5685 << E->getSourceRange(); 5686 Diag(AlignedArgs[CanonPVD]->getExprLoc(), 5687 diag::note_omp_explicit_dsa) 5688 << getOpenMPClauseName(OMPC_aligned); 5689 continue; 5690 } 5691 AlignedArgs[CanonPVD] = E; 5692 QualType QTy = PVD->getType() 5693 .getNonReferenceType() 5694 .getUnqualifiedType() 5695 .getCanonicalType(); 5696 const Type *Ty = QTy.getTypePtrOrNull(); 5697 if (!Ty || (!Ty->isArrayType() && !Ty->isPointerType())) { 5698 Diag(E->getExprLoc(), diag::err_omp_aligned_expected_array_or_ptr) 5699 << QTy << getLangOpts().CPlusPlus << E->getSourceRange(); 5700 Diag(PVD->getLocation(), diag::note_previous_decl) << PVD; 5701 } 5702 continue; 5703 } 5704 } 5705 if (isa<CXXThisExpr>(E)) { 5706 if (AlignedThis) { 5707 Diag(E->getExprLoc(), diag::err_omp_used_in_clause_twice) 5708 << 2 << getOpenMPClauseName(OMPC_aligned) << E->getSourceRange(); 5709 Diag(AlignedThis->getExprLoc(), diag::note_omp_explicit_dsa) 5710 << getOpenMPClauseName(OMPC_aligned); 5711 } 5712 AlignedThis = E; 5713 continue; 5714 } 5715 Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause) 5716 << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0); 5717 } 5718 // The optional parameter of the aligned clause, alignment, must be a constant 5719 // positive integer expression. If no optional parameter is specified, 5720 // implementation-defined default alignments for SIMD instructions on the 5721 // target platforms are assumed. 5722 SmallVector<const Expr *, 4> NewAligns; 5723 for (Expr *E : Alignments) { 5724 ExprResult Align; 5725 if (E) 5726 Align = VerifyPositiveIntegerConstantInClause(E, OMPC_aligned); 5727 NewAligns.push_back(Align.get()); 5728 } 5729 // OpenMP [2.8.2, declare simd construct, Description] 5730 // The linear clause declares one or more list items to be private to a SIMD 5731 // lane and to have a linear relationship with respect to the iteration space 5732 // of a loop. 5733 // The special this pointer can be used as if was one of the arguments to the 5734 // function in any of the linear, aligned, or uniform clauses. 5735 // When a linear-step expression is specified in a linear clause it must be 5736 // either a constant integer expression or an integer-typed parameter that is 5737 // specified in a uniform clause on the directive. 5738 llvm::DenseMap<const Decl *, const Expr *> LinearArgs; 5739 const bool IsUniformedThis = UniformedLinearThis != nullptr; 5740 auto MI = LinModifiers.begin(); 5741 for (const Expr *E : Linears) { 5742 auto LinKind = static_cast<OpenMPLinearClauseKind>(*MI); 5743 ++MI; 5744 E = E->IgnoreParenImpCasts(); 5745 if (const auto *DRE = dyn_cast<DeclRefExpr>(E)) 5746 if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) { 5747 const VarDecl *CanonPVD = PVD->getCanonicalDecl(); 5748 if (FD->getNumParams() > PVD->getFunctionScopeIndex() && 5749 FD->getParamDecl(PVD->getFunctionScopeIndex()) 5750 ->getCanonicalDecl() == CanonPVD) { 5751 // OpenMP [2.15.3.7, linear Clause, Restrictions] 5752 // A list-item cannot appear in more than one linear clause. 5753 if (LinearArgs.count(CanonPVD) > 0) { 5754 Diag(E->getExprLoc(), diag::err_omp_wrong_dsa) 5755 << getOpenMPClauseName(OMPC_linear) 5756 << getOpenMPClauseName(OMPC_linear) << E->getSourceRange(); 5757 Diag(LinearArgs[CanonPVD]->getExprLoc(), 5758 diag::note_omp_explicit_dsa) 5759 << getOpenMPClauseName(OMPC_linear); 5760 continue; 5761 } 5762 // Each argument can appear in at most one uniform or linear clause. 5763 if (UniformedArgs.count(CanonPVD) > 0) { 5764 Diag(E->getExprLoc(), diag::err_omp_wrong_dsa) 5765 << getOpenMPClauseName(OMPC_linear) 5766 << getOpenMPClauseName(OMPC_uniform) << E->getSourceRange(); 5767 Diag(UniformedArgs[CanonPVD]->getExprLoc(), 5768 diag::note_omp_explicit_dsa) 5769 << getOpenMPClauseName(OMPC_uniform); 5770 continue; 5771 } 5772 LinearArgs[CanonPVD] = E; 5773 if (E->isValueDependent() || E->isTypeDependent() || 5774 E->isInstantiationDependent() || 5775 E->containsUnexpandedParameterPack()) 5776 continue; 5777 (void)CheckOpenMPLinearDecl(CanonPVD, E->getExprLoc(), LinKind, 5778 PVD->getOriginalType(), 5779 /*IsDeclareSimd=*/true); 5780 continue; 5781 } 5782 } 5783 if (isa<CXXThisExpr>(E)) { 5784 if (UniformedLinearThis) { 5785 Diag(E->getExprLoc(), diag::err_omp_wrong_dsa) 5786 << getOpenMPClauseName(OMPC_linear) 5787 << getOpenMPClauseName(IsUniformedThis ? OMPC_uniform : OMPC_linear) 5788 << E->getSourceRange(); 5789 Diag(UniformedLinearThis->getExprLoc(), diag::note_omp_explicit_dsa) 5790 << getOpenMPClauseName(IsUniformedThis ? OMPC_uniform 5791 : OMPC_linear); 5792 continue; 5793 } 5794 UniformedLinearThis = E; 5795 if (E->isValueDependent() || E->isTypeDependent() || 5796 E->isInstantiationDependent() || E->containsUnexpandedParameterPack()) 5797 continue; 5798 (void)CheckOpenMPLinearDecl(/*D=*/nullptr, E->getExprLoc(), LinKind, 5799 E->getType(), /*IsDeclareSimd=*/true); 5800 continue; 5801 } 5802 Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause) 5803 << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0); 5804 } 5805 Expr *Step = nullptr; 5806 Expr *NewStep = nullptr; 5807 SmallVector<Expr *, 4> NewSteps; 5808 for (Expr *E : Steps) { 5809 // Skip the same step expression, it was checked already. 5810 if (Step == E || !E) { 5811 NewSteps.push_back(E ? NewStep : nullptr); 5812 continue; 5813 } 5814 Step = E; 5815 if (const auto *DRE = dyn_cast<DeclRefExpr>(Step)) 5816 if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) { 5817 const VarDecl *CanonPVD = PVD->getCanonicalDecl(); 5818 if (UniformedArgs.count(CanonPVD) == 0) { 5819 Diag(Step->getExprLoc(), diag::err_omp_expected_uniform_param) 5820 << Step->getSourceRange(); 5821 } else if (E->isValueDependent() || E->isTypeDependent() || 5822 E->isInstantiationDependent() || 5823 E->containsUnexpandedParameterPack() || 5824 CanonPVD->getType()->hasIntegerRepresentation()) { 5825 NewSteps.push_back(Step); 5826 } else { 5827 Diag(Step->getExprLoc(), diag::err_omp_expected_int_param) 5828 << Step->getSourceRange(); 5829 } 5830 continue; 5831 } 5832 NewStep = Step; 5833 if (Step && !Step->isValueDependent() && !Step->isTypeDependent() && 5834 !Step->isInstantiationDependent() && 5835 !Step->containsUnexpandedParameterPack()) { 5836 NewStep = PerformOpenMPImplicitIntegerConversion(Step->getExprLoc(), Step) 5837 .get(); 5838 if (NewStep) 5839 NewStep = VerifyIntegerConstantExpression(NewStep).get(); 5840 } 5841 NewSteps.push_back(NewStep); 5842 } 5843 auto *NewAttr = OMPDeclareSimdDeclAttr::CreateImplicit( 5844 Context, BS, SL.get(), const_cast<Expr **>(Uniforms.data()), 5845 Uniforms.size(), const_cast<Expr **>(Aligneds.data()), Aligneds.size(), 5846 const_cast<Expr **>(NewAligns.data()), NewAligns.size(), 5847 const_cast<Expr **>(Linears.data()), Linears.size(), 5848 const_cast<unsigned *>(LinModifiers.data()), LinModifiers.size(), 5849 NewSteps.data(), NewSteps.size(), SR); 5850 ADecl->addAttr(NewAttr); 5851 return DG; 5852 } 5853 5854 static void setPrototype(Sema &S, FunctionDecl *FD, FunctionDecl *FDWithProto, 5855 QualType NewType) { 5856 assert(NewType->isFunctionProtoType() && 5857 "Expected function type with prototype."); 5858 assert(FD->getType()->isFunctionNoProtoType() && 5859 "Expected function with type with no prototype."); 5860 assert(FDWithProto->getType()->isFunctionProtoType() && 5861 "Expected function with prototype."); 5862 // Synthesize parameters with the same types. 5863 FD->setType(NewType); 5864 SmallVector<ParmVarDecl *, 16> Params; 5865 for (const ParmVarDecl *P : FDWithProto->parameters()) { 5866 auto *Param = ParmVarDecl::Create(S.getASTContext(), FD, SourceLocation(), 5867 SourceLocation(), nullptr, P->getType(), 5868 /*TInfo=*/nullptr, SC_None, nullptr); 5869 Param->setScopeInfo(0, Params.size()); 5870 Param->setImplicit(); 5871 Params.push_back(Param); 5872 } 5873 5874 FD->setParams(Params); 5875 } 5876 5877 Sema::OMPDeclareVariantScope::OMPDeclareVariantScope(OMPTraitInfo &TI) 5878 : TI(&TI), NameSuffix(TI.getMangledName()) {} 5879 5880 void Sema::ActOnStartOfFunctionDefinitionInOpenMPDeclareVariantScope( 5881 Scope *S, Declarator &D, MultiTemplateParamsArg TemplateParamLists, 5882 SmallVectorImpl<FunctionDecl *> &Bases) { 5883 if (!D.getIdentifier()) 5884 return; 5885 5886 OMPDeclareVariantScope &DVScope = OMPDeclareVariantScopes.back(); 5887 5888 // Template specialization is an extension, check if we do it. 5889 bool IsTemplated = !TemplateParamLists.empty(); 5890 if (IsTemplated & 5891 !DVScope.TI->isExtensionActive( 5892 llvm::omp::TraitProperty::implementation_extension_allow_templates)) 5893 return; 5894 5895 IdentifierInfo *BaseII = D.getIdentifier(); 5896 LookupResult Lookup(*this, DeclarationName(BaseII), D.getIdentifierLoc(), 5897 LookupOrdinaryName); 5898 LookupParsedName(Lookup, S, &D.getCXXScopeSpec()); 5899 5900 TypeSourceInfo *TInfo = GetTypeForDeclarator(D, S); 5901 QualType FType = TInfo->getType(); 5902 5903 bool IsConstexpr = D.getDeclSpec().getConstexprSpecifier() == CSK_constexpr; 5904 bool IsConsteval = D.getDeclSpec().getConstexprSpecifier() == CSK_consteval; 5905 5906 for (auto *Candidate : Lookup) { 5907 auto *CandidateDecl = Candidate->getUnderlyingDecl(); 5908 FunctionDecl *UDecl = nullptr; 5909 if (IsTemplated && isa<FunctionTemplateDecl>(CandidateDecl)) 5910 UDecl = cast<FunctionTemplateDecl>(CandidateDecl)->getTemplatedDecl(); 5911 else if (!IsTemplated) 5912 UDecl = dyn_cast<FunctionDecl>(CandidateDecl); 5913 if (!UDecl) 5914 continue; 5915 5916 // Don't specialize constexpr/consteval functions with 5917 // non-constexpr/consteval functions. 5918 if (UDecl->isConstexpr() && !IsConstexpr) 5919 continue; 5920 if (UDecl->isConsteval() && !IsConsteval) 5921 continue; 5922 5923 QualType UDeclTy = UDecl->getType(); 5924 // TODO: Verify types for templates eventually. 5925 if (!UDeclTy->isDependentType()) { 5926 QualType NewType = Context.mergeFunctionTypes( 5927 FType, UDeclTy, /* OfBlockPointer */ false, 5928 /* Unqualified */ false, /* AllowCXX */ true); 5929 if (NewType.isNull()) 5930 continue; 5931 } 5932 5933 // Found a base! 5934 Bases.push_back(UDecl); 5935 } 5936 5937 bool UseImplicitBase = !DVScope.TI->isExtensionActive( 5938 llvm::omp::TraitProperty::implementation_extension_disable_implicit_base); 5939 // If no base was found we create a declaration that we use as base. 5940 if (Bases.empty() && UseImplicitBase) { 5941 D.setFunctionDefinitionKind(FDK_Declaration); 5942 Decl *BaseD = HandleDeclarator(S, D, TemplateParamLists); 5943 BaseD->setImplicit(true); 5944 if (auto *BaseTemplD = dyn_cast<FunctionTemplateDecl>(BaseD)) 5945 Bases.push_back(BaseTemplD->getTemplatedDecl()); 5946 else 5947 Bases.push_back(cast<FunctionDecl>(BaseD)); 5948 } 5949 5950 std::string MangledName; 5951 MangledName += D.getIdentifier()->getName(); 5952 MangledName += getOpenMPVariantManglingSeparatorStr(); 5953 MangledName += DVScope.NameSuffix; 5954 IdentifierInfo &VariantII = Context.Idents.get(MangledName); 5955 5956 VariantII.setMangledOpenMPVariantName(true); 5957 D.SetIdentifier(&VariantII, D.getBeginLoc()); 5958 } 5959 5960 void Sema::ActOnFinishedFunctionDefinitionInOpenMPDeclareVariantScope( 5961 Decl *D, SmallVectorImpl<FunctionDecl *> &Bases) { 5962 // Do not mark function as is used to prevent its emission if this is the 5963 // only place where it is used. 5964 EnterExpressionEvaluationContext Unevaluated( 5965 *this, Sema::ExpressionEvaluationContext::Unevaluated); 5966 5967 FunctionDecl *FD = nullptr; 5968 if (auto *UTemplDecl = dyn_cast<FunctionTemplateDecl>(D)) 5969 FD = UTemplDecl->getTemplatedDecl(); 5970 else 5971 FD = cast<FunctionDecl>(D); 5972 auto *VariantFuncRef = DeclRefExpr::Create( 5973 Context, NestedNameSpecifierLoc(), SourceLocation(), FD, 5974 /* RefersToEnclosingVariableOrCapture */ false, 5975 /* NameLoc */ FD->getLocation(), FD->getType(), ExprValueKind::VK_RValue); 5976 5977 OMPDeclareVariantScope &DVScope = OMPDeclareVariantScopes.back(); 5978 auto *OMPDeclareVariantA = OMPDeclareVariantAttr::CreateImplicit( 5979 Context, VariantFuncRef, DVScope.TI); 5980 for (FunctionDecl *BaseFD : Bases) 5981 BaseFD->addAttr(OMPDeclareVariantA); 5982 } 5983 5984 ExprResult Sema::ActOnOpenMPCall(ExprResult Call, Scope *Scope, 5985 SourceLocation LParenLoc, 5986 MultiExprArg ArgExprs, 5987 SourceLocation RParenLoc, Expr *ExecConfig) { 5988 // The common case is a regular call we do not want to specialize at all. Try 5989 // to make that case fast by bailing early. 5990 CallExpr *CE = dyn_cast<CallExpr>(Call.get()); 5991 if (!CE) 5992 return Call; 5993 5994 FunctionDecl *CalleeFnDecl = CE->getDirectCallee(); 5995 if (!CalleeFnDecl) 5996 return Call; 5997 5998 if (!CalleeFnDecl->hasAttr<OMPDeclareVariantAttr>()) 5999 return Call; 6000 6001 ASTContext &Context = getASTContext(); 6002 std::function<void(StringRef)> DiagUnknownTrait = [this, 6003 CE](StringRef ISATrait) { 6004 // TODO Track the selector locations in a way that is accessible here to 6005 // improve the diagnostic location. 6006 Diag(CE->getBeginLoc(), diag::warn_unknown_declare_variant_isa_trait) 6007 << ISATrait; 6008 }; 6009 TargetOMPContext OMPCtx(Context, std::move(DiagUnknownTrait), 6010 getCurFunctionDecl()); 6011 6012 SmallVector<Expr *, 4> Exprs; 6013 SmallVector<VariantMatchInfo, 4> VMIs; 6014 while (CalleeFnDecl) { 6015 for (OMPDeclareVariantAttr *A : 6016 CalleeFnDecl->specific_attrs<OMPDeclareVariantAttr>()) { 6017 Expr *VariantRef = A->getVariantFuncRef(); 6018 6019 VariantMatchInfo VMI; 6020 OMPTraitInfo &TI = A->getTraitInfo(); 6021 TI.getAsVariantMatchInfo(Context, VMI); 6022 if (!isVariantApplicableInContext(VMI, OMPCtx, 6023 /* DeviceSetOnly */ false)) 6024 continue; 6025 6026 VMIs.push_back(VMI); 6027 Exprs.push_back(VariantRef); 6028 } 6029 6030 CalleeFnDecl = CalleeFnDecl->getPreviousDecl(); 6031 } 6032 6033 ExprResult NewCall; 6034 do { 6035 int BestIdx = getBestVariantMatchForContext(VMIs, OMPCtx); 6036 if (BestIdx < 0) 6037 return Call; 6038 Expr *BestExpr = cast<DeclRefExpr>(Exprs[BestIdx]); 6039 Decl *BestDecl = cast<DeclRefExpr>(BestExpr)->getDecl(); 6040 6041 { 6042 // Try to build a (member) call expression for the current best applicable 6043 // variant expression. We allow this to fail in which case we continue 6044 // with the next best variant expression. The fail case is part of the 6045 // implementation defined behavior in the OpenMP standard when it talks 6046 // about what differences in the function prototypes: "Any differences 6047 // that the specific OpenMP context requires in the prototype of the 6048 // variant from the base function prototype are implementation defined." 6049 // This wording is there to allow the specialized variant to have a 6050 // different type than the base function. This is intended and OK but if 6051 // we cannot create a call the difference is not in the "implementation 6052 // defined range" we allow. 6053 Sema::TentativeAnalysisScope Trap(*this); 6054 6055 if (auto *SpecializedMethod = dyn_cast<CXXMethodDecl>(BestDecl)) { 6056 auto *MemberCall = dyn_cast<CXXMemberCallExpr>(CE); 6057 BestExpr = MemberExpr::CreateImplicit( 6058 Context, MemberCall->getImplicitObjectArgument(), 6059 /* IsArrow */ false, SpecializedMethod, Context.BoundMemberTy, 6060 MemberCall->getValueKind(), MemberCall->getObjectKind()); 6061 } 6062 NewCall = BuildCallExpr(Scope, BestExpr, LParenLoc, ArgExprs, RParenLoc, 6063 ExecConfig); 6064 if (NewCall.isUsable()) 6065 break; 6066 } 6067 6068 VMIs.erase(VMIs.begin() + BestIdx); 6069 Exprs.erase(Exprs.begin() + BestIdx); 6070 } while (!VMIs.empty()); 6071 6072 if (!NewCall.isUsable()) 6073 return Call; 6074 return PseudoObjectExpr::Create(Context, CE, {NewCall.get()}, 0); 6075 } 6076 6077 Optional<std::pair<FunctionDecl *, Expr *>> 6078 Sema::checkOpenMPDeclareVariantFunction(Sema::DeclGroupPtrTy DG, 6079 Expr *VariantRef, OMPTraitInfo &TI, 6080 SourceRange SR) { 6081 if (!DG || DG.get().isNull()) 6082 return None; 6083 6084 const int VariantId = 1; 6085 // Must be applied only to single decl. 6086 if (!DG.get().isSingleDecl()) { 6087 Diag(SR.getBegin(), diag::err_omp_single_decl_in_declare_simd_variant) 6088 << VariantId << SR; 6089 return None; 6090 } 6091 Decl *ADecl = DG.get().getSingleDecl(); 6092 if (auto *FTD = dyn_cast<FunctionTemplateDecl>(ADecl)) 6093 ADecl = FTD->getTemplatedDecl(); 6094 6095 // Decl must be a function. 6096 auto *FD = dyn_cast<FunctionDecl>(ADecl); 6097 if (!FD) { 6098 Diag(ADecl->getLocation(), diag::err_omp_function_expected) 6099 << VariantId << SR; 6100 return None; 6101 } 6102 6103 auto &&HasMultiVersionAttributes = [](const FunctionDecl *FD) { 6104 return FD->hasAttrs() && 6105 (FD->hasAttr<CPUDispatchAttr>() || FD->hasAttr<CPUSpecificAttr>() || 6106 FD->hasAttr<TargetAttr>()); 6107 }; 6108 // OpenMP is not compatible with CPU-specific attributes. 6109 if (HasMultiVersionAttributes(FD)) { 6110 Diag(FD->getLocation(), diag::err_omp_declare_variant_incompat_attributes) 6111 << SR; 6112 return None; 6113 } 6114 6115 // Allow #pragma omp declare variant only if the function is not used. 6116 if (FD->isUsed(false)) 6117 Diag(SR.getBegin(), diag::warn_omp_declare_variant_after_used) 6118 << FD->getLocation(); 6119 6120 // Check if the function was emitted already. 6121 const FunctionDecl *Definition; 6122 if (!FD->isThisDeclarationADefinition() && FD->isDefined(Definition) && 6123 (LangOpts.EmitAllDecls || Context.DeclMustBeEmitted(Definition))) 6124 Diag(SR.getBegin(), diag::warn_omp_declare_variant_after_emitted) 6125 << FD->getLocation(); 6126 6127 // The VariantRef must point to function. 6128 if (!VariantRef) { 6129 Diag(SR.getBegin(), diag::err_omp_function_expected) << VariantId; 6130 return None; 6131 } 6132 6133 auto ShouldDelayChecks = [](Expr *&E, bool) { 6134 return E && (E->isTypeDependent() || E->isValueDependent() || 6135 E->containsUnexpandedParameterPack() || 6136 E->isInstantiationDependent()); 6137 }; 6138 // Do not check templates, wait until instantiation. 6139 if (FD->isDependentContext() || ShouldDelayChecks(VariantRef, false) || 6140 TI.anyScoreOrCondition(ShouldDelayChecks)) 6141 return std::make_pair(FD, VariantRef); 6142 6143 // Deal with non-constant score and user condition expressions. 6144 auto HandleNonConstantScoresAndConditions = [this](Expr *&E, 6145 bool IsScore) -> bool { 6146 if (!E || E->isIntegerConstantExpr(Context)) 6147 return false; 6148 6149 if (IsScore) { 6150 // We warn on non-constant scores and pretend they were not present. 6151 Diag(E->getExprLoc(), diag::warn_omp_declare_variant_score_not_constant) 6152 << E; 6153 E = nullptr; 6154 } else { 6155 // We could replace a non-constant user condition with "false" but we 6156 // will soon need to handle these anyway for the dynamic version of 6157 // OpenMP context selectors. 6158 Diag(E->getExprLoc(), 6159 diag::err_omp_declare_variant_user_condition_not_constant) 6160 << E; 6161 } 6162 return true; 6163 }; 6164 if (TI.anyScoreOrCondition(HandleNonConstantScoresAndConditions)) 6165 return None; 6166 6167 // Convert VariantRef expression to the type of the original function to 6168 // resolve possible conflicts. 6169 ExprResult VariantRefCast = VariantRef; 6170 if (LangOpts.CPlusPlus) { 6171 QualType FnPtrType; 6172 auto *Method = dyn_cast<CXXMethodDecl>(FD); 6173 if (Method && !Method->isStatic()) { 6174 const Type *ClassType = 6175 Context.getTypeDeclType(Method->getParent()).getTypePtr(); 6176 FnPtrType = Context.getMemberPointerType(FD->getType(), ClassType); 6177 ExprResult ER; 6178 { 6179 // Build adrr_of unary op to correctly handle type checks for member 6180 // functions. 6181 Sema::TentativeAnalysisScope Trap(*this); 6182 ER = CreateBuiltinUnaryOp(VariantRef->getBeginLoc(), UO_AddrOf, 6183 VariantRef); 6184 } 6185 if (!ER.isUsable()) { 6186 Diag(VariantRef->getExprLoc(), diag::err_omp_function_expected) 6187 << VariantId << VariantRef->getSourceRange(); 6188 return None; 6189 } 6190 VariantRef = ER.get(); 6191 } else { 6192 FnPtrType = Context.getPointerType(FD->getType()); 6193 } 6194 QualType VarianPtrType = Context.getPointerType(VariantRef->getType()); 6195 if (VarianPtrType.getUnqualifiedType() != FnPtrType.getUnqualifiedType()) { 6196 ImplicitConversionSequence ICS = TryImplicitConversion( 6197 VariantRef, FnPtrType.getUnqualifiedType(), 6198 /*SuppressUserConversions=*/false, AllowedExplicit::None, 6199 /*InOverloadResolution=*/false, 6200 /*CStyle=*/false, 6201 /*AllowObjCWritebackConversion=*/false); 6202 if (ICS.isFailure()) { 6203 Diag(VariantRef->getExprLoc(), 6204 diag::err_omp_declare_variant_incompat_types) 6205 << VariantRef->getType() 6206 << ((Method && !Method->isStatic()) ? FnPtrType : FD->getType()) 6207 << VariantRef->getSourceRange(); 6208 return None; 6209 } 6210 VariantRefCast = PerformImplicitConversion( 6211 VariantRef, FnPtrType.getUnqualifiedType(), AA_Converting); 6212 if (!VariantRefCast.isUsable()) 6213 return None; 6214 } 6215 // Drop previously built artificial addr_of unary op for member functions. 6216 if (Method && !Method->isStatic()) { 6217 Expr *PossibleAddrOfVariantRef = VariantRefCast.get(); 6218 if (auto *UO = dyn_cast<UnaryOperator>( 6219 PossibleAddrOfVariantRef->IgnoreImplicit())) 6220 VariantRefCast = UO->getSubExpr(); 6221 } 6222 } 6223 6224 ExprResult ER = CheckPlaceholderExpr(VariantRefCast.get()); 6225 if (!ER.isUsable() || 6226 !ER.get()->IgnoreParenImpCasts()->getType()->isFunctionType()) { 6227 Diag(VariantRef->getExprLoc(), diag::err_omp_function_expected) 6228 << VariantId << VariantRef->getSourceRange(); 6229 return None; 6230 } 6231 6232 // The VariantRef must point to function. 6233 auto *DRE = dyn_cast<DeclRefExpr>(ER.get()->IgnoreParenImpCasts()); 6234 if (!DRE) { 6235 Diag(VariantRef->getExprLoc(), diag::err_omp_function_expected) 6236 << VariantId << VariantRef->getSourceRange(); 6237 return None; 6238 } 6239 auto *NewFD = dyn_cast_or_null<FunctionDecl>(DRE->getDecl()); 6240 if (!NewFD) { 6241 Diag(VariantRef->getExprLoc(), diag::err_omp_function_expected) 6242 << VariantId << VariantRef->getSourceRange(); 6243 return None; 6244 } 6245 6246 // Check if function types are compatible in C. 6247 if (!LangOpts.CPlusPlus) { 6248 QualType NewType = 6249 Context.mergeFunctionTypes(FD->getType(), NewFD->getType()); 6250 if (NewType.isNull()) { 6251 Diag(VariantRef->getExprLoc(), 6252 diag::err_omp_declare_variant_incompat_types) 6253 << NewFD->getType() << FD->getType() << VariantRef->getSourceRange(); 6254 return None; 6255 } 6256 if (NewType->isFunctionProtoType()) { 6257 if (FD->getType()->isFunctionNoProtoType()) 6258 setPrototype(*this, FD, NewFD, NewType); 6259 else if (NewFD->getType()->isFunctionNoProtoType()) 6260 setPrototype(*this, NewFD, FD, NewType); 6261 } 6262 } 6263 6264 // Check if variant function is not marked with declare variant directive. 6265 if (NewFD->hasAttrs() && NewFD->hasAttr<OMPDeclareVariantAttr>()) { 6266 Diag(VariantRef->getExprLoc(), 6267 diag::warn_omp_declare_variant_marked_as_declare_variant) 6268 << VariantRef->getSourceRange(); 6269 SourceRange SR = 6270 NewFD->specific_attr_begin<OMPDeclareVariantAttr>()->getRange(); 6271 Diag(SR.getBegin(), diag::note_omp_marked_declare_variant_here) << SR; 6272 return None; 6273 } 6274 6275 enum DoesntSupport { 6276 VirtFuncs = 1, 6277 Constructors = 3, 6278 Destructors = 4, 6279 DeletedFuncs = 5, 6280 DefaultedFuncs = 6, 6281 ConstexprFuncs = 7, 6282 ConstevalFuncs = 8, 6283 }; 6284 if (const auto *CXXFD = dyn_cast<CXXMethodDecl>(FD)) { 6285 if (CXXFD->isVirtual()) { 6286 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support) 6287 << VirtFuncs; 6288 return None; 6289 } 6290 6291 if (isa<CXXConstructorDecl>(FD)) { 6292 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support) 6293 << Constructors; 6294 return None; 6295 } 6296 6297 if (isa<CXXDestructorDecl>(FD)) { 6298 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support) 6299 << Destructors; 6300 return None; 6301 } 6302 } 6303 6304 if (FD->isDeleted()) { 6305 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support) 6306 << DeletedFuncs; 6307 return None; 6308 } 6309 6310 if (FD->isDefaulted()) { 6311 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support) 6312 << DefaultedFuncs; 6313 return None; 6314 } 6315 6316 if (FD->isConstexpr()) { 6317 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support) 6318 << (NewFD->isConsteval() ? ConstevalFuncs : ConstexprFuncs); 6319 return None; 6320 } 6321 6322 // Check general compatibility. 6323 if (areMultiversionVariantFunctionsCompatible( 6324 FD, NewFD, PartialDiagnostic::NullDiagnostic(), 6325 PartialDiagnosticAt(SourceLocation(), 6326 PartialDiagnostic::NullDiagnostic()), 6327 PartialDiagnosticAt( 6328 VariantRef->getExprLoc(), 6329 PDiag(diag::err_omp_declare_variant_doesnt_support)), 6330 PartialDiagnosticAt(VariantRef->getExprLoc(), 6331 PDiag(diag::err_omp_declare_variant_diff) 6332 << FD->getLocation()), 6333 /*TemplatesSupported=*/true, /*ConstexprSupported=*/false, 6334 /*CLinkageMayDiffer=*/true)) 6335 return None; 6336 return std::make_pair(FD, cast<Expr>(DRE)); 6337 } 6338 6339 void Sema::ActOnOpenMPDeclareVariantDirective(FunctionDecl *FD, 6340 Expr *VariantRef, 6341 OMPTraitInfo &TI, 6342 SourceRange SR) { 6343 auto *NewAttr = 6344 OMPDeclareVariantAttr::CreateImplicit(Context, VariantRef, &TI, SR); 6345 FD->addAttr(NewAttr); 6346 } 6347 6348 StmtResult Sema::ActOnOpenMPParallelDirective(ArrayRef<OMPClause *> Clauses, 6349 Stmt *AStmt, 6350 SourceLocation StartLoc, 6351 SourceLocation EndLoc) { 6352 if (!AStmt) 6353 return StmtError(); 6354 6355 auto *CS = cast<CapturedStmt>(AStmt); 6356 // 1.2.2 OpenMP Language Terminology 6357 // Structured block - An executable statement with a single entry at the 6358 // top and a single exit at the bottom. 6359 // The point of exit cannot be a branch out of the structured block. 6360 // longjmp() and throw() must not violate the entry/exit criteria. 6361 CS->getCapturedDecl()->setNothrow(); 6362 6363 setFunctionHasBranchProtectedScope(); 6364 6365 return OMPParallelDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt, 6366 DSAStack->getTaskgroupReductionRef(), 6367 DSAStack->isCancelRegion()); 6368 } 6369 6370 namespace { 6371 /// Iteration space of a single for loop. 6372 struct LoopIterationSpace final { 6373 /// True if the condition operator is the strict compare operator (<, > or 6374 /// !=). 6375 bool IsStrictCompare = false; 6376 /// Condition of the loop. 6377 Expr *PreCond = nullptr; 6378 /// This expression calculates the number of iterations in the loop. 6379 /// It is always possible to calculate it before starting the loop. 6380 Expr *NumIterations = nullptr; 6381 /// The loop counter variable. 6382 Expr *CounterVar = nullptr; 6383 /// Private loop counter variable. 6384 Expr *PrivateCounterVar = nullptr; 6385 /// This is initializer for the initial value of #CounterVar. 6386 Expr *CounterInit = nullptr; 6387 /// This is step for the #CounterVar used to generate its update: 6388 /// #CounterVar = #CounterInit + #CounterStep * CurrentIteration. 6389 Expr *CounterStep = nullptr; 6390 /// Should step be subtracted? 6391 bool Subtract = false; 6392 /// Source range of the loop init. 6393 SourceRange InitSrcRange; 6394 /// Source range of the loop condition. 6395 SourceRange CondSrcRange; 6396 /// Source range of the loop increment. 6397 SourceRange IncSrcRange; 6398 /// Minimum value that can have the loop control variable. Used to support 6399 /// non-rectangular loops. Applied only for LCV with the non-iterator types, 6400 /// since only such variables can be used in non-loop invariant expressions. 6401 Expr *MinValue = nullptr; 6402 /// Maximum value that can have the loop control variable. Used to support 6403 /// non-rectangular loops. Applied only for LCV with the non-iterator type, 6404 /// since only such variables can be used in non-loop invariant expressions. 6405 Expr *MaxValue = nullptr; 6406 /// true, if the lower bound depends on the outer loop control var. 6407 bool IsNonRectangularLB = false; 6408 /// true, if the upper bound depends on the outer loop control var. 6409 bool IsNonRectangularUB = false; 6410 /// Index of the loop this loop depends on and forms non-rectangular loop 6411 /// nest. 6412 unsigned LoopDependentIdx = 0; 6413 /// Final condition for the non-rectangular loop nest support. It is used to 6414 /// check that the number of iterations for this particular counter must be 6415 /// finished. 6416 Expr *FinalCondition = nullptr; 6417 }; 6418 6419 /// Helper class for checking canonical form of the OpenMP loops and 6420 /// extracting iteration space of each loop in the loop nest, that will be used 6421 /// for IR generation. 6422 class OpenMPIterationSpaceChecker { 6423 /// Reference to Sema. 6424 Sema &SemaRef; 6425 /// Data-sharing stack. 6426 DSAStackTy &Stack; 6427 /// A location for diagnostics (when there is no some better location). 6428 SourceLocation DefaultLoc; 6429 /// A location for diagnostics (when increment is not compatible). 6430 SourceLocation ConditionLoc; 6431 /// A source location for referring to loop init later. 6432 SourceRange InitSrcRange; 6433 /// A source location for referring to condition later. 6434 SourceRange ConditionSrcRange; 6435 /// A source location for referring to increment later. 6436 SourceRange IncrementSrcRange; 6437 /// Loop variable. 6438 ValueDecl *LCDecl = nullptr; 6439 /// Reference to loop variable. 6440 Expr *LCRef = nullptr; 6441 /// Lower bound (initializer for the var). 6442 Expr *LB = nullptr; 6443 /// Upper bound. 6444 Expr *UB = nullptr; 6445 /// Loop step (increment). 6446 Expr *Step = nullptr; 6447 /// This flag is true when condition is one of: 6448 /// Var < UB 6449 /// Var <= UB 6450 /// UB > Var 6451 /// UB >= Var 6452 /// This will have no value when the condition is != 6453 llvm::Optional<bool> TestIsLessOp; 6454 /// This flag is true when condition is strict ( < or > ). 6455 bool TestIsStrictOp = false; 6456 /// This flag is true when step is subtracted on each iteration. 6457 bool SubtractStep = false; 6458 /// The outer loop counter this loop depends on (if any). 6459 const ValueDecl *DepDecl = nullptr; 6460 /// Contains number of loop (starts from 1) on which loop counter init 6461 /// expression of this loop depends on. 6462 Optional<unsigned> InitDependOnLC; 6463 /// Contains number of loop (starts from 1) on which loop counter condition 6464 /// expression of this loop depends on. 6465 Optional<unsigned> CondDependOnLC; 6466 /// Checks if the provide statement depends on the loop counter. 6467 Optional<unsigned> doesDependOnLoopCounter(const Stmt *S, bool IsInitializer); 6468 /// Original condition required for checking of the exit condition for 6469 /// non-rectangular loop. 6470 Expr *Condition = nullptr; 6471 6472 public: 6473 OpenMPIterationSpaceChecker(Sema &SemaRef, DSAStackTy &Stack, 6474 SourceLocation DefaultLoc) 6475 : SemaRef(SemaRef), Stack(Stack), DefaultLoc(DefaultLoc), 6476 ConditionLoc(DefaultLoc) {} 6477 /// Check init-expr for canonical loop form and save loop counter 6478 /// variable - #Var and its initialization value - #LB. 6479 bool checkAndSetInit(Stmt *S, bool EmitDiags = true); 6480 /// Check test-expr for canonical form, save upper-bound (#UB), flags 6481 /// for less/greater and for strict/non-strict comparison. 6482 bool checkAndSetCond(Expr *S); 6483 /// Check incr-expr for canonical loop form and return true if it 6484 /// does not conform, otherwise save loop step (#Step). 6485 bool checkAndSetInc(Expr *S); 6486 /// Return the loop counter variable. 6487 ValueDecl *getLoopDecl() const { return LCDecl; } 6488 /// Return the reference expression to loop counter variable. 6489 Expr *getLoopDeclRefExpr() const { return LCRef; } 6490 /// Source range of the loop init. 6491 SourceRange getInitSrcRange() const { return InitSrcRange; } 6492 /// Source range of the loop condition. 6493 SourceRange getConditionSrcRange() const { return ConditionSrcRange; } 6494 /// Source range of the loop increment. 6495 SourceRange getIncrementSrcRange() const { return IncrementSrcRange; } 6496 /// True if the step should be subtracted. 6497 bool shouldSubtractStep() const { return SubtractStep; } 6498 /// True, if the compare operator is strict (<, > or !=). 6499 bool isStrictTestOp() const { return TestIsStrictOp; } 6500 /// Build the expression to calculate the number of iterations. 6501 Expr *buildNumIterations( 6502 Scope *S, ArrayRef<LoopIterationSpace> ResultIterSpaces, bool LimitedType, 6503 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const; 6504 /// Build the precondition expression for the loops. 6505 Expr * 6506 buildPreCond(Scope *S, Expr *Cond, 6507 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const; 6508 /// Build reference expression to the counter be used for codegen. 6509 DeclRefExpr * 6510 buildCounterVar(llvm::MapVector<const Expr *, DeclRefExpr *> &Captures, 6511 DSAStackTy &DSA) const; 6512 /// Build reference expression to the private counter be used for 6513 /// codegen. 6514 Expr *buildPrivateCounterVar() const; 6515 /// Build initialization of the counter be used for codegen. 6516 Expr *buildCounterInit() const; 6517 /// Build step of the counter be used for codegen. 6518 Expr *buildCounterStep() const; 6519 /// Build loop data with counter value for depend clauses in ordered 6520 /// directives. 6521 Expr * 6522 buildOrderedLoopData(Scope *S, Expr *Counter, 6523 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures, 6524 SourceLocation Loc, Expr *Inc = nullptr, 6525 OverloadedOperatorKind OOK = OO_Amp); 6526 /// Builds the minimum value for the loop counter. 6527 std::pair<Expr *, Expr *> buildMinMaxValues( 6528 Scope *S, llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const; 6529 /// Builds final condition for the non-rectangular loops. 6530 Expr *buildFinalCondition(Scope *S) const; 6531 /// Return true if any expression is dependent. 6532 bool dependent() const; 6533 /// Returns true if the initializer forms non-rectangular loop. 6534 bool doesInitDependOnLC() const { return InitDependOnLC.hasValue(); } 6535 /// Returns true if the condition forms non-rectangular loop. 6536 bool doesCondDependOnLC() const { return CondDependOnLC.hasValue(); } 6537 /// Returns index of the loop we depend on (starting from 1), or 0 otherwise. 6538 unsigned getLoopDependentIdx() const { 6539 return InitDependOnLC.getValueOr(CondDependOnLC.getValueOr(0)); 6540 } 6541 6542 private: 6543 /// Check the right-hand side of an assignment in the increment 6544 /// expression. 6545 bool checkAndSetIncRHS(Expr *RHS); 6546 /// Helper to set loop counter variable and its initializer. 6547 bool setLCDeclAndLB(ValueDecl *NewLCDecl, Expr *NewDeclRefExpr, Expr *NewLB, 6548 bool EmitDiags); 6549 /// Helper to set upper bound. 6550 bool setUB(Expr *NewUB, llvm::Optional<bool> LessOp, bool StrictOp, 6551 SourceRange SR, SourceLocation SL); 6552 /// Helper to set loop increment. 6553 bool setStep(Expr *NewStep, bool Subtract); 6554 }; 6555 6556 bool OpenMPIterationSpaceChecker::dependent() const { 6557 if (!LCDecl) { 6558 assert(!LB && !UB && !Step); 6559 return false; 6560 } 6561 return LCDecl->getType()->isDependentType() || 6562 (LB && LB->isValueDependent()) || (UB && UB->isValueDependent()) || 6563 (Step && Step->isValueDependent()); 6564 } 6565 6566 bool OpenMPIterationSpaceChecker::setLCDeclAndLB(ValueDecl *NewLCDecl, 6567 Expr *NewLCRefExpr, 6568 Expr *NewLB, bool EmitDiags) { 6569 // State consistency checking to ensure correct usage. 6570 assert(LCDecl == nullptr && LB == nullptr && LCRef == nullptr && 6571 UB == nullptr && Step == nullptr && !TestIsLessOp && !TestIsStrictOp); 6572 if (!NewLCDecl || !NewLB) 6573 return true; 6574 LCDecl = getCanonicalDecl(NewLCDecl); 6575 LCRef = NewLCRefExpr; 6576 if (auto *CE = dyn_cast_or_null<CXXConstructExpr>(NewLB)) 6577 if (const CXXConstructorDecl *Ctor = CE->getConstructor()) 6578 if ((Ctor->isCopyOrMoveConstructor() || 6579 Ctor->isConvertingConstructor(/*AllowExplicit=*/false)) && 6580 CE->getNumArgs() > 0 && CE->getArg(0) != nullptr) 6581 NewLB = CE->getArg(0)->IgnoreParenImpCasts(); 6582 LB = NewLB; 6583 if (EmitDiags) 6584 InitDependOnLC = doesDependOnLoopCounter(LB, /*IsInitializer=*/true); 6585 return false; 6586 } 6587 6588 bool OpenMPIterationSpaceChecker::setUB(Expr *NewUB, 6589 llvm::Optional<bool> LessOp, 6590 bool StrictOp, SourceRange SR, 6591 SourceLocation SL) { 6592 // State consistency checking to ensure correct usage. 6593 assert(LCDecl != nullptr && LB != nullptr && UB == nullptr && 6594 Step == nullptr && !TestIsLessOp && !TestIsStrictOp); 6595 if (!NewUB) 6596 return true; 6597 UB = NewUB; 6598 if (LessOp) 6599 TestIsLessOp = LessOp; 6600 TestIsStrictOp = StrictOp; 6601 ConditionSrcRange = SR; 6602 ConditionLoc = SL; 6603 CondDependOnLC = doesDependOnLoopCounter(UB, /*IsInitializer=*/false); 6604 return false; 6605 } 6606 6607 bool OpenMPIterationSpaceChecker::setStep(Expr *NewStep, bool Subtract) { 6608 // State consistency checking to ensure correct usage. 6609 assert(LCDecl != nullptr && LB != nullptr && Step == nullptr); 6610 if (!NewStep) 6611 return true; 6612 if (!NewStep->isValueDependent()) { 6613 // Check that the step is integer expression. 6614 SourceLocation StepLoc = NewStep->getBeginLoc(); 6615 ExprResult Val = SemaRef.PerformOpenMPImplicitIntegerConversion( 6616 StepLoc, getExprAsWritten(NewStep)); 6617 if (Val.isInvalid()) 6618 return true; 6619 NewStep = Val.get(); 6620 6621 // OpenMP [2.6, Canonical Loop Form, Restrictions] 6622 // If test-expr is of form var relational-op b and relational-op is < or 6623 // <= then incr-expr must cause var to increase on each iteration of the 6624 // loop. If test-expr is of form var relational-op b and relational-op is 6625 // > or >= then incr-expr must cause var to decrease on each iteration of 6626 // the loop. 6627 // If test-expr is of form b relational-op var and relational-op is < or 6628 // <= then incr-expr must cause var to decrease on each iteration of the 6629 // loop. If test-expr is of form b relational-op var and relational-op is 6630 // > or >= then incr-expr must cause var to increase on each iteration of 6631 // the loop. 6632 Optional<llvm::APSInt> Result = 6633 NewStep->getIntegerConstantExpr(SemaRef.Context); 6634 bool IsUnsigned = !NewStep->getType()->hasSignedIntegerRepresentation(); 6635 bool IsConstNeg = 6636 Result && Result->isSigned() && (Subtract != Result->isNegative()); 6637 bool IsConstPos = 6638 Result && Result->isSigned() && (Subtract == Result->isNegative()); 6639 bool IsConstZero = Result && !Result->getBoolValue(); 6640 6641 // != with increment is treated as <; != with decrement is treated as > 6642 if (!TestIsLessOp.hasValue()) 6643 TestIsLessOp = IsConstPos || (IsUnsigned && !Subtract); 6644 if (UB && (IsConstZero || 6645 (TestIsLessOp.getValue() ? 6646 (IsConstNeg || (IsUnsigned && Subtract)) : 6647 (IsConstPos || (IsUnsigned && !Subtract))))) { 6648 SemaRef.Diag(NewStep->getExprLoc(), 6649 diag::err_omp_loop_incr_not_compatible) 6650 << LCDecl << TestIsLessOp.getValue() << NewStep->getSourceRange(); 6651 SemaRef.Diag(ConditionLoc, 6652 diag::note_omp_loop_cond_requres_compatible_incr) 6653 << TestIsLessOp.getValue() << ConditionSrcRange; 6654 return true; 6655 } 6656 if (TestIsLessOp.getValue() == Subtract) { 6657 NewStep = 6658 SemaRef.CreateBuiltinUnaryOp(NewStep->getExprLoc(), UO_Minus, NewStep) 6659 .get(); 6660 Subtract = !Subtract; 6661 } 6662 } 6663 6664 Step = NewStep; 6665 SubtractStep = Subtract; 6666 return false; 6667 } 6668 6669 namespace { 6670 /// Checker for the non-rectangular loops. Checks if the initializer or 6671 /// condition expression references loop counter variable. 6672 class LoopCounterRefChecker final 6673 : public ConstStmtVisitor<LoopCounterRefChecker, bool> { 6674 Sema &SemaRef; 6675 DSAStackTy &Stack; 6676 const ValueDecl *CurLCDecl = nullptr; 6677 const ValueDecl *DepDecl = nullptr; 6678 const ValueDecl *PrevDepDecl = nullptr; 6679 bool IsInitializer = true; 6680 unsigned BaseLoopId = 0; 6681 bool checkDecl(const Expr *E, const ValueDecl *VD) { 6682 if (getCanonicalDecl(VD) == getCanonicalDecl(CurLCDecl)) { 6683 SemaRef.Diag(E->getExprLoc(), diag::err_omp_stmt_depends_on_loop_counter) 6684 << (IsInitializer ? 0 : 1); 6685 return false; 6686 } 6687 const auto &&Data = Stack.isLoopControlVariable(VD); 6688 // OpenMP, 2.9.1 Canonical Loop Form, Restrictions. 6689 // The type of the loop iterator on which we depend may not have a random 6690 // access iterator type. 6691 if (Data.first && VD->getType()->isRecordType()) { 6692 SmallString<128> Name; 6693 llvm::raw_svector_ostream OS(Name); 6694 VD->getNameForDiagnostic(OS, SemaRef.getPrintingPolicy(), 6695 /*Qualified=*/true); 6696 SemaRef.Diag(E->getExprLoc(), 6697 diag::err_omp_wrong_dependency_iterator_type) 6698 << OS.str(); 6699 SemaRef.Diag(VD->getLocation(), diag::note_previous_decl) << VD; 6700 return false; 6701 } 6702 if (Data.first && 6703 (DepDecl || (PrevDepDecl && 6704 getCanonicalDecl(VD) != getCanonicalDecl(PrevDepDecl)))) { 6705 if (!DepDecl && PrevDepDecl) 6706 DepDecl = PrevDepDecl; 6707 SmallString<128> Name; 6708 llvm::raw_svector_ostream OS(Name); 6709 DepDecl->getNameForDiagnostic(OS, SemaRef.getPrintingPolicy(), 6710 /*Qualified=*/true); 6711 SemaRef.Diag(E->getExprLoc(), 6712 diag::err_omp_invariant_or_linear_dependency) 6713 << OS.str(); 6714 return false; 6715 } 6716 if (Data.first) { 6717 DepDecl = VD; 6718 BaseLoopId = Data.first; 6719 } 6720 return Data.first; 6721 } 6722 6723 public: 6724 bool VisitDeclRefExpr(const DeclRefExpr *E) { 6725 const ValueDecl *VD = E->getDecl(); 6726 if (isa<VarDecl>(VD)) 6727 return checkDecl(E, VD); 6728 return false; 6729 } 6730 bool VisitMemberExpr(const MemberExpr *E) { 6731 if (isa<CXXThisExpr>(E->getBase()->IgnoreParens())) { 6732 const ValueDecl *VD = E->getMemberDecl(); 6733 if (isa<VarDecl>(VD) || isa<FieldDecl>(VD)) 6734 return checkDecl(E, VD); 6735 } 6736 return false; 6737 } 6738 bool VisitStmt(const Stmt *S) { 6739 bool Res = false; 6740 for (const Stmt *Child : S->children()) 6741 Res = (Child && Visit(Child)) || Res; 6742 return Res; 6743 } 6744 explicit LoopCounterRefChecker(Sema &SemaRef, DSAStackTy &Stack, 6745 const ValueDecl *CurLCDecl, bool IsInitializer, 6746 const ValueDecl *PrevDepDecl = nullptr) 6747 : SemaRef(SemaRef), Stack(Stack), CurLCDecl(CurLCDecl), 6748 PrevDepDecl(PrevDepDecl), IsInitializer(IsInitializer) {} 6749 unsigned getBaseLoopId() const { 6750 assert(CurLCDecl && "Expected loop dependency."); 6751 return BaseLoopId; 6752 } 6753 const ValueDecl *getDepDecl() const { 6754 assert(CurLCDecl && "Expected loop dependency."); 6755 return DepDecl; 6756 } 6757 }; 6758 } // namespace 6759 6760 Optional<unsigned> 6761 OpenMPIterationSpaceChecker::doesDependOnLoopCounter(const Stmt *S, 6762 bool IsInitializer) { 6763 // Check for the non-rectangular loops. 6764 LoopCounterRefChecker LoopStmtChecker(SemaRef, Stack, LCDecl, IsInitializer, 6765 DepDecl); 6766 if (LoopStmtChecker.Visit(S)) { 6767 DepDecl = LoopStmtChecker.getDepDecl(); 6768 return LoopStmtChecker.getBaseLoopId(); 6769 } 6770 return llvm::None; 6771 } 6772 6773 bool OpenMPIterationSpaceChecker::checkAndSetInit(Stmt *S, bool EmitDiags) { 6774 // Check init-expr for canonical loop form and save loop counter 6775 // variable - #Var and its initialization value - #LB. 6776 // OpenMP [2.6] Canonical loop form. init-expr may be one of the following: 6777 // var = lb 6778 // integer-type var = lb 6779 // random-access-iterator-type var = lb 6780 // pointer-type var = lb 6781 // 6782 if (!S) { 6783 if (EmitDiags) { 6784 SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_init); 6785 } 6786 return true; 6787 } 6788 if (auto *ExprTemp = dyn_cast<ExprWithCleanups>(S)) 6789 if (!ExprTemp->cleanupsHaveSideEffects()) 6790 S = ExprTemp->getSubExpr(); 6791 6792 InitSrcRange = S->getSourceRange(); 6793 if (Expr *E = dyn_cast<Expr>(S)) 6794 S = E->IgnoreParens(); 6795 if (auto *BO = dyn_cast<BinaryOperator>(S)) { 6796 if (BO->getOpcode() == BO_Assign) { 6797 Expr *LHS = BO->getLHS()->IgnoreParens(); 6798 if (auto *DRE = dyn_cast<DeclRefExpr>(LHS)) { 6799 if (auto *CED = dyn_cast<OMPCapturedExprDecl>(DRE->getDecl())) 6800 if (auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit()))) 6801 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(), 6802 EmitDiags); 6803 return setLCDeclAndLB(DRE->getDecl(), DRE, BO->getRHS(), EmitDiags); 6804 } 6805 if (auto *ME = dyn_cast<MemberExpr>(LHS)) { 6806 if (ME->isArrow() && 6807 isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts())) 6808 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(), 6809 EmitDiags); 6810 } 6811 } 6812 } else if (auto *DS = dyn_cast<DeclStmt>(S)) { 6813 if (DS->isSingleDecl()) { 6814 if (auto *Var = dyn_cast_or_null<VarDecl>(DS->getSingleDecl())) { 6815 if (Var->hasInit() && !Var->getType()->isReferenceType()) { 6816 // Accept non-canonical init form here but emit ext. warning. 6817 if (Var->getInitStyle() != VarDecl::CInit && EmitDiags) 6818 SemaRef.Diag(S->getBeginLoc(), 6819 diag::ext_omp_loop_not_canonical_init) 6820 << S->getSourceRange(); 6821 return setLCDeclAndLB( 6822 Var, 6823 buildDeclRefExpr(SemaRef, Var, 6824 Var->getType().getNonReferenceType(), 6825 DS->getBeginLoc()), 6826 Var->getInit(), EmitDiags); 6827 } 6828 } 6829 } 6830 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) { 6831 if (CE->getOperator() == OO_Equal) { 6832 Expr *LHS = CE->getArg(0); 6833 if (auto *DRE = dyn_cast<DeclRefExpr>(LHS)) { 6834 if (auto *CED = dyn_cast<OMPCapturedExprDecl>(DRE->getDecl())) 6835 if (auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit()))) 6836 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(), 6837 EmitDiags); 6838 return setLCDeclAndLB(DRE->getDecl(), DRE, CE->getArg(1), EmitDiags); 6839 } 6840 if (auto *ME = dyn_cast<MemberExpr>(LHS)) { 6841 if (ME->isArrow() && 6842 isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts())) 6843 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(), 6844 EmitDiags); 6845 } 6846 } 6847 } 6848 6849 if (dependent() || SemaRef.CurContext->isDependentContext()) 6850 return false; 6851 if (EmitDiags) { 6852 SemaRef.Diag(S->getBeginLoc(), diag::err_omp_loop_not_canonical_init) 6853 << S->getSourceRange(); 6854 } 6855 return true; 6856 } 6857 6858 /// Ignore parenthesizes, implicit casts, copy constructor and return the 6859 /// variable (which may be the loop variable) if possible. 6860 static const ValueDecl *getInitLCDecl(const Expr *E) { 6861 if (!E) 6862 return nullptr; 6863 E = getExprAsWritten(E); 6864 if (const auto *CE = dyn_cast_or_null<CXXConstructExpr>(E)) 6865 if (const CXXConstructorDecl *Ctor = CE->getConstructor()) 6866 if ((Ctor->isCopyOrMoveConstructor() || 6867 Ctor->isConvertingConstructor(/*AllowExplicit=*/false)) && 6868 CE->getNumArgs() > 0 && CE->getArg(0) != nullptr) 6869 E = CE->getArg(0)->IgnoreParenImpCasts(); 6870 if (const auto *DRE = dyn_cast_or_null<DeclRefExpr>(E)) { 6871 if (const auto *VD = dyn_cast<VarDecl>(DRE->getDecl())) 6872 return getCanonicalDecl(VD); 6873 } 6874 if (const auto *ME = dyn_cast_or_null<MemberExpr>(E)) 6875 if (ME->isArrow() && isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts())) 6876 return getCanonicalDecl(ME->getMemberDecl()); 6877 return nullptr; 6878 } 6879 6880 bool OpenMPIterationSpaceChecker::checkAndSetCond(Expr *S) { 6881 // Check test-expr for canonical form, save upper-bound UB, flags for 6882 // less/greater and for strict/non-strict comparison. 6883 // OpenMP [2.9] Canonical loop form. Test-expr may be one of the following: 6884 // var relational-op b 6885 // b relational-op var 6886 // 6887 bool IneqCondIsCanonical = SemaRef.getLangOpts().OpenMP >= 50; 6888 if (!S) { 6889 SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_cond) 6890 << (IneqCondIsCanonical ? 1 : 0) << LCDecl; 6891 return true; 6892 } 6893 Condition = S; 6894 S = getExprAsWritten(S); 6895 SourceLocation CondLoc = S->getBeginLoc(); 6896 if (auto *BO = dyn_cast<BinaryOperator>(S)) { 6897 if (BO->isRelationalOp()) { 6898 if (getInitLCDecl(BO->getLHS()) == LCDecl) 6899 return setUB(BO->getRHS(), 6900 (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_LE), 6901 (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_GT), 6902 BO->getSourceRange(), BO->getOperatorLoc()); 6903 if (getInitLCDecl(BO->getRHS()) == LCDecl) 6904 return setUB(BO->getLHS(), 6905 (BO->getOpcode() == BO_GT || BO->getOpcode() == BO_GE), 6906 (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_GT), 6907 BO->getSourceRange(), BO->getOperatorLoc()); 6908 } else if (IneqCondIsCanonical && BO->getOpcode() == BO_NE) 6909 return setUB( 6910 getInitLCDecl(BO->getLHS()) == LCDecl ? BO->getRHS() : BO->getLHS(), 6911 /*LessOp=*/llvm::None, 6912 /*StrictOp=*/true, BO->getSourceRange(), BO->getOperatorLoc()); 6913 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) { 6914 if (CE->getNumArgs() == 2) { 6915 auto Op = CE->getOperator(); 6916 switch (Op) { 6917 case OO_Greater: 6918 case OO_GreaterEqual: 6919 case OO_Less: 6920 case OO_LessEqual: 6921 if (getInitLCDecl(CE->getArg(0)) == LCDecl) 6922 return setUB(CE->getArg(1), Op == OO_Less || Op == OO_LessEqual, 6923 Op == OO_Less || Op == OO_Greater, CE->getSourceRange(), 6924 CE->getOperatorLoc()); 6925 if (getInitLCDecl(CE->getArg(1)) == LCDecl) 6926 return setUB(CE->getArg(0), Op == OO_Greater || Op == OO_GreaterEqual, 6927 Op == OO_Less || Op == OO_Greater, CE->getSourceRange(), 6928 CE->getOperatorLoc()); 6929 break; 6930 case OO_ExclaimEqual: 6931 if (IneqCondIsCanonical) 6932 return setUB(getInitLCDecl(CE->getArg(0)) == LCDecl ? CE->getArg(1) 6933 : CE->getArg(0), 6934 /*LessOp=*/llvm::None, 6935 /*StrictOp=*/true, CE->getSourceRange(), 6936 CE->getOperatorLoc()); 6937 break; 6938 default: 6939 break; 6940 } 6941 } 6942 } 6943 if (dependent() || SemaRef.CurContext->isDependentContext()) 6944 return false; 6945 SemaRef.Diag(CondLoc, diag::err_omp_loop_not_canonical_cond) 6946 << (IneqCondIsCanonical ? 1 : 0) << S->getSourceRange() << LCDecl; 6947 return true; 6948 } 6949 6950 bool OpenMPIterationSpaceChecker::checkAndSetIncRHS(Expr *RHS) { 6951 // RHS of canonical loop form increment can be: 6952 // var + incr 6953 // incr + var 6954 // var - incr 6955 // 6956 RHS = RHS->IgnoreParenImpCasts(); 6957 if (auto *BO = dyn_cast<BinaryOperator>(RHS)) { 6958 if (BO->isAdditiveOp()) { 6959 bool IsAdd = BO->getOpcode() == BO_Add; 6960 if (getInitLCDecl(BO->getLHS()) == LCDecl) 6961 return setStep(BO->getRHS(), !IsAdd); 6962 if (IsAdd && getInitLCDecl(BO->getRHS()) == LCDecl) 6963 return setStep(BO->getLHS(), /*Subtract=*/false); 6964 } 6965 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(RHS)) { 6966 bool IsAdd = CE->getOperator() == OO_Plus; 6967 if ((IsAdd || CE->getOperator() == OO_Minus) && CE->getNumArgs() == 2) { 6968 if (getInitLCDecl(CE->getArg(0)) == LCDecl) 6969 return setStep(CE->getArg(1), !IsAdd); 6970 if (IsAdd && getInitLCDecl(CE->getArg(1)) == LCDecl) 6971 return setStep(CE->getArg(0), /*Subtract=*/false); 6972 } 6973 } 6974 if (dependent() || SemaRef.CurContext->isDependentContext()) 6975 return false; 6976 SemaRef.Diag(RHS->getBeginLoc(), diag::err_omp_loop_not_canonical_incr) 6977 << RHS->getSourceRange() << LCDecl; 6978 return true; 6979 } 6980 6981 bool OpenMPIterationSpaceChecker::checkAndSetInc(Expr *S) { 6982 // Check incr-expr for canonical loop form and return true if it 6983 // does not conform. 6984 // OpenMP [2.6] Canonical loop form. Test-expr may be one of the following: 6985 // ++var 6986 // var++ 6987 // --var 6988 // var-- 6989 // var += incr 6990 // var -= incr 6991 // var = var + incr 6992 // var = incr + var 6993 // var = var - incr 6994 // 6995 if (!S) { 6996 SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_incr) << LCDecl; 6997 return true; 6998 } 6999 if (auto *ExprTemp = dyn_cast<ExprWithCleanups>(S)) 7000 if (!ExprTemp->cleanupsHaveSideEffects()) 7001 S = ExprTemp->getSubExpr(); 7002 7003 IncrementSrcRange = S->getSourceRange(); 7004 S = S->IgnoreParens(); 7005 if (auto *UO = dyn_cast<UnaryOperator>(S)) { 7006 if (UO->isIncrementDecrementOp() && 7007 getInitLCDecl(UO->getSubExpr()) == LCDecl) 7008 return setStep(SemaRef 7009 .ActOnIntegerConstant(UO->getBeginLoc(), 7010 (UO->isDecrementOp() ? -1 : 1)) 7011 .get(), 7012 /*Subtract=*/false); 7013 } else if (auto *BO = dyn_cast<BinaryOperator>(S)) { 7014 switch (BO->getOpcode()) { 7015 case BO_AddAssign: 7016 case BO_SubAssign: 7017 if (getInitLCDecl(BO->getLHS()) == LCDecl) 7018 return setStep(BO->getRHS(), BO->getOpcode() == BO_SubAssign); 7019 break; 7020 case BO_Assign: 7021 if (getInitLCDecl(BO->getLHS()) == LCDecl) 7022 return checkAndSetIncRHS(BO->getRHS()); 7023 break; 7024 default: 7025 break; 7026 } 7027 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) { 7028 switch (CE->getOperator()) { 7029 case OO_PlusPlus: 7030 case OO_MinusMinus: 7031 if (getInitLCDecl(CE->getArg(0)) == LCDecl) 7032 return setStep(SemaRef 7033 .ActOnIntegerConstant( 7034 CE->getBeginLoc(), 7035 ((CE->getOperator() == OO_MinusMinus) ? -1 : 1)) 7036 .get(), 7037 /*Subtract=*/false); 7038 break; 7039 case OO_PlusEqual: 7040 case OO_MinusEqual: 7041 if (getInitLCDecl(CE->getArg(0)) == LCDecl) 7042 return setStep(CE->getArg(1), CE->getOperator() == OO_MinusEqual); 7043 break; 7044 case OO_Equal: 7045 if (getInitLCDecl(CE->getArg(0)) == LCDecl) 7046 return checkAndSetIncRHS(CE->getArg(1)); 7047 break; 7048 default: 7049 break; 7050 } 7051 } 7052 if (dependent() || SemaRef.CurContext->isDependentContext()) 7053 return false; 7054 SemaRef.Diag(S->getBeginLoc(), diag::err_omp_loop_not_canonical_incr) 7055 << S->getSourceRange() << LCDecl; 7056 return true; 7057 } 7058 7059 static ExprResult 7060 tryBuildCapture(Sema &SemaRef, Expr *Capture, 7061 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) { 7062 if (SemaRef.CurContext->isDependentContext() || Capture->containsErrors()) 7063 return Capture; 7064 if (Capture->isEvaluatable(SemaRef.Context, Expr::SE_AllowSideEffects)) 7065 return SemaRef.PerformImplicitConversion( 7066 Capture->IgnoreImpCasts(), Capture->getType(), Sema::AA_Converting, 7067 /*AllowExplicit=*/true); 7068 auto I = Captures.find(Capture); 7069 if (I != Captures.end()) 7070 return buildCapture(SemaRef, Capture, I->second); 7071 DeclRefExpr *Ref = nullptr; 7072 ExprResult Res = buildCapture(SemaRef, Capture, Ref); 7073 Captures[Capture] = Ref; 7074 return Res; 7075 } 7076 7077 /// Calculate number of iterations, transforming to unsigned, if number of 7078 /// iterations may be larger than the original type. 7079 static Expr * 7080 calculateNumIters(Sema &SemaRef, Scope *S, SourceLocation DefaultLoc, 7081 Expr *Lower, Expr *Upper, Expr *Step, QualType LCTy, 7082 bool TestIsStrictOp, bool RoundToStep, 7083 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) { 7084 ExprResult NewStep = tryBuildCapture(SemaRef, Step, Captures); 7085 if (!NewStep.isUsable()) 7086 return nullptr; 7087 llvm::APSInt LRes, SRes; 7088 bool IsLowerConst = false, IsStepConst = false; 7089 if (Optional<llvm::APSInt> Res = Lower->getIntegerConstantExpr(SemaRef.Context)) { 7090 LRes = *Res; 7091 IsLowerConst = true; 7092 } 7093 if (Optional<llvm::APSInt> Res = Step->getIntegerConstantExpr(SemaRef.Context)) { 7094 SRes = *Res; 7095 IsStepConst = true; 7096 } 7097 bool NoNeedToConvert = IsLowerConst && !RoundToStep && 7098 ((!TestIsStrictOp && LRes.isNonNegative()) || 7099 (TestIsStrictOp && LRes.isStrictlyPositive())); 7100 bool NeedToReorganize = false; 7101 // Check if any subexpressions in Lower -Step [+ 1] lead to overflow. 7102 if (!NoNeedToConvert && IsLowerConst && 7103 (TestIsStrictOp || (RoundToStep && IsStepConst))) { 7104 NoNeedToConvert = true; 7105 if (RoundToStep) { 7106 unsigned BW = LRes.getBitWidth() > SRes.getBitWidth() 7107 ? LRes.getBitWidth() 7108 : SRes.getBitWidth(); 7109 LRes = LRes.extend(BW + 1); 7110 LRes.setIsSigned(true); 7111 SRes = SRes.extend(BW + 1); 7112 SRes.setIsSigned(true); 7113 LRes -= SRes; 7114 NoNeedToConvert = LRes.trunc(BW).extend(BW + 1) == LRes; 7115 LRes = LRes.trunc(BW); 7116 } 7117 if (TestIsStrictOp) { 7118 unsigned BW = LRes.getBitWidth(); 7119 LRes = LRes.extend(BW + 1); 7120 LRes.setIsSigned(true); 7121 ++LRes; 7122 NoNeedToConvert = 7123 NoNeedToConvert && LRes.trunc(BW).extend(BW + 1) == LRes; 7124 // truncate to the original bitwidth. 7125 LRes = LRes.trunc(BW); 7126 } 7127 NeedToReorganize = NoNeedToConvert; 7128 } 7129 llvm::APSInt URes; 7130 bool IsUpperConst = false; 7131 if (Optional<llvm::APSInt> Res = Upper->getIntegerConstantExpr(SemaRef.Context)) { 7132 URes = *Res; 7133 IsUpperConst = true; 7134 } 7135 if (NoNeedToConvert && IsLowerConst && IsUpperConst && 7136 (!RoundToStep || IsStepConst)) { 7137 unsigned BW = LRes.getBitWidth() > URes.getBitWidth() ? LRes.getBitWidth() 7138 : URes.getBitWidth(); 7139 LRes = LRes.extend(BW + 1); 7140 LRes.setIsSigned(true); 7141 URes = URes.extend(BW + 1); 7142 URes.setIsSigned(true); 7143 URes -= LRes; 7144 NoNeedToConvert = URes.trunc(BW).extend(BW + 1) == URes; 7145 NeedToReorganize = NoNeedToConvert; 7146 } 7147 // If the boundaries are not constant or (Lower - Step [+ 1]) is not constant 7148 // or less than zero (Upper - (Lower - Step [+ 1]) may overflow) - promote to 7149 // unsigned. 7150 if ((!NoNeedToConvert || (LRes.isNegative() && !IsUpperConst)) && 7151 !LCTy->isDependentType() && LCTy->isIntegerType()) { 7152 QualType LowerTy = Lower->getType(); 7153 QualType UpperTy = Upper->getType(); 7154 uint64_t LowerSize = SemaRef.Context.getTypeSize(LowerTy); 7155 uint64_t UpperSize = SemaRef.Context.getTypeSize(UpperTy); 7156 if ((LowerSize <= UpperSize && UpperTy->hasSignedIntegerRepresentation()) || 7157 (LowerSize > UpperSize && LowerTy->hasSignedIntegerRepresentation())) { 7158 QualType CastType = SemaRef.Context.getIntTypeForBitwidth( 7159 LowerSize > UpperSize ? LowerSize : UpperSize, /*Signed=*/0); 7160 Upper = 7161 SemaRef 7162 .PerformImplicitConversion( 7163 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Upper).get(), 7164 CastType, Sema::AA_Converting) 7165 .get(); 7166 Lower = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Lower).get(); 7167 NewStep = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, NewStep.get()); 7168 } 7169 } 7170 if (!Lower || !Upper || NewStep.isInvalid()) 7171 return nullptr; 7172 7173 ExprResult Diff; 7174 // If need to reorganize, then calculate the form as Upper - (Lower - Step [+ 7175 // 1]). 7176 if (NeedToReorganize) { 7177 Diff = Lower; 7178 7179 if (RoundToStep) { 7180 // Lower - Step 7181 Diff = 7182 SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Diff.get(), NewStep.get()); 7183 if (!Diff.isUsable()) 7184 return nullptr; 7185 } 7186 7187 // Lower - Step [+ 1] 7188 if (TestIsStrictOp) 7189 Diff = SemaRef.BuildBinOp( 7190 S, DefaultLoc, BO_Add, Diff.get(), 7191 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()); 7192 if (!Diff.isUsable()) 7193 return nullptr; 7194 7195 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get()); 7196 if (!Diff.isUsable()) 7197 return nullptr; 7198 7199 // Upper - (Lower - Step [+ 1]). 7200 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Diff.get()); 7201 if (!Diff.isUsable()) 7202 return nullptr; 7203 } else { 7204 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Lower); 7205 7206 if (!Diff.isUsable() && LCTy->getAsCXXRecordDecl()) { 7207 // BuildBinOp already emitted error, this one is to point user to upper 7208 // and lower bound, and to tell what is passed to 'operator-'. 7209 SemaRef.Diag(Upper->getBeginLoc(), diag::err_omp_loop_diff_cxx) 7210 << Upper->getSourceRange() << Lower->getSourceRange(); 7211 return nullptr; 7212 } 7213 7214 if (!Diff.isUsable()) 7215 return nullptr; 7216 7217 // Upper - Lower [- 1] 7218 if (TestIsStrictOp) 7219 Diff = SemaRef.BuildBinOp( 7220 S, DefaultLoc, BO_Sub, Diff.get(), 7221 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()); 7222 if (!Diff.isUsable()) 7223 return nullptr; 7224 7225 if (RoundToStep) { 7226 // Upper - Lower [- 1] + Step 7227 Diff = 7228 SemaRef.BuildBinOp(S, DefaultLoc, BO_Add, Diff.get(), NewStep.get()); 7229 if (!Diff.isUsable()) 7230 return nullptr; 7231 } 7232 } 7233 7234 // Parentheses (for dumping/debugging purposes only). 7235 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get()); 7236 if (!Diff.isUsable()) 7237 return nullptr; 7238 7239 // (Upper - Lower [- 1] + Step) / Step or (Upper - Lower) / Step 7240 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Div, Diff.get(), NewStep.get()); 7241 if (!Diff.isUsable()) 7242 return nullptr; 7243 7244 return Diff.get(); 7245 } 7246 7247 /// Build the expression to calculate the number of iterations. 7248 Expr *OpenMPIterationSpaceChecker::buildNumIterations( 7249 Scope *S, ArrayRef<LoopIterationSpace> ResultIterSpaces, bool LimitedType, 7250 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const { 7251 QualType VarType = LCDecl->getType().getNonReferenceType(); 7252 if (!VarType->isIntegerType() && !VarType->isPointerType() && 7253 !SemaRef.getLangOpts().CPlusPlus) 7254 return nullptr; 7255 Expr *LBVal = LB; 7256 Expr *UBVal = UB; 7257 // LB = TestIsLessOp.getValue() ? min(LB(MinVal), LB(MaxVal)) : 7258 // max(LB(MinVal), LB(MaxVal)) 7259 if (InitDependOnLC) { 7260 const LoopIterationSpace &IS = 7261 ResultIterSpaces[ResultIterSpaces.size() - 1 - 7262 InitDependOnLC.getValueOr( 7263 CondDependOnLC.getValueOr(0))]; 7264 if (!IS.MinValue || !IS.MaxValue) 7265 return nullptr; 7266 // OuterVar = Min 7267 ExprResult MinValue = 7268 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MinValue); 7269 if (!MinValue.isUsable()) 7270 return nullptr; 7271 7272 ExprResult LBMinVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign, 7273 IS.CounterVar, MinValue.get()); 7274 if (!LBMinVal.isUsable()) 7275 return nullptr; 7276 // OuterVar = Min, LBVal 7277 LBMinVal = 7278 SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, LBMinVal.get(), LBVal); 7279 if (!LBMinVal.isUsable()) 7280 return nullptr; 7281 // (OuterVar = Min, LBVal) 7282 LBMinVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, LBMinVal.get()); 7283 if (!LBMinVal.isUsable()) 7284 return nullptr; 7285 7286 // OuterVar = Max 7287 ExprResult MaxValue = 7288 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MaxValue); 7289 if (!MaxValue.isUsable()) 7290 return nullptr; 7291 7292 ExprResult LBMaxVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign, 7293 IS.CounterVar, MaxValue.get()); 7294 if (!LBMaxVal.isUsable()) 7295 return nullptr; 7296 // OuterVar = Max, LBVal 7297 LBMaxVal = 7298 SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, LBMaxVal.get(), LBVal); 7299 if (!LBMaxVal.isUsable()) 7300 return nullptr; 7301 // (OuterVar = Max, LBVal) 7302 LBMaxVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, LBMaxVal.get()); 7303 if (!LBMaxVal.isUsable()) 7304 return nullptr; 7305 7306 Expr *LBMin = tryBuildCapture(SemaRef, LBMinVal.get(), Captures).get(); 7307 Expr *LBMax = tryBuildCapture(SemaRef, LBMaxVal.get(), Captures).get(); 7308 if (!LBMin || !LBMax) 7309 return nullptr; 7310 // LB(MinVal) < LB(MaxVal) 7311 ExprResult MinLessMaxRes = 7312 SemaRef.BuildBinOp(S, DefaultLoc, BO_LT, LBMin, LBMax); 7313 if (!MinLessMaxRes.isUsable()) 7314 return nullptr; 7315 Expr *MinLessMax = 7316 tryBuildCapture(SemaRef, MinLessMaxRes.get(), Captures).get(); 7317 if (!MinLessMax) 7318 return nullptr; 7319 if (TestIsLessOp.getValue()) { 7320 // LB(MinVal) < LB(MaxVal) ? LB(MinVal) : LB(MaxVal) - min(LB(MinVal), 7321 // LB(MaxVal)) 7322 ExprResult MinLB = SemaRef.ActOnConditionalOp(DefaultLoc, DefaultLoc, 7323 MinLessMax, LBMin, LBMax); 7324 if (!MinLB.isUsable()) 7325 return nullptr; 7326 LBVal = MinLB.get(); 7327 } else { 7328 // LB(MinVal) < LB(MaxVal) ? LB(MaxVal) : LB(MinVal) - max(LB(MinVal), 7329 // LB(MaxVal)) 7330 ExprResult MaxLB = SemaRef.ActOnConditionalOp(DefaultLoc, DefaultLoc, 7331 MinLessMax, LBMax, LBMin); 7332 if (!MaxLB.isUsable()) 7333 return nullptr; 7334 LBVal = MaxLB.get(); 7335 } 7336 } 7337 // UB = TestIsLessOp.getValue() ? max(UB(MinVal), UB(MaxVal)) : 7338 // min(UB(MinVal), UB(MaxVal)) 7339 if (CondDependOnLC) { 7340 const LoopIterationSpace &IS = 7341 ResultIterSpaces[ResultIterSpaces.size() - 1 - 7342 InitDependOnLC.getValueOr( 7343 CondDependOnLC.getValueOr(0))]; 7344 if (!IS.MinValue || !IS.MaxValue) 7345 return nullptr; 7346 // OuterVar = Min 7347 ExprResult MinValue = 7348 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MinValue); 7349 if (!MinValue.isUsable()) 7350 return nullptr; 7351 7352 ExprResult UBMinVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign, 7353 IS.CounterVar, MinValue.get()); 7354 if (!UBMinVal.isUsable()) 7355 return nullptr; 7356 // OuterVar = Min, UBVal 7357 UBMinVal = 7358 SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, UBMinVal.get(), UBVal); 7359 if (!UBMinVal.isUsable()) 7360 return nullptr; 7361 // (OuterVar = Min, UBVal) 7362 UBMinVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, UBMinVal.get()); 7363 if (!UBMinVal.isUsable()) 7364 return nullptr; 7365 7366 // OuterVar = Max 7367 ExprResult MaxValue = 7368 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MaxValue); 7369 if (!MaxValue.isUsable()) 7370 return nullptr; 7371 7372 ExprResult UBMaxVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign, 7373 IS.CounterVar, MaxValue.get()); 7374 if (!UBMaxVal.isUsable()) 7375 return nullptr; 7376 // OuterVar = Max, UBVal 7377 UBMaxVal = 7378 SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, UBMaxVal.get(), UBVal); 7379 if (!UBMaxVal.isUsable()) 7380 return nullptr; 7381 // (OuterVar = Max, UBVal) 7382 UBMaxVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, UBMaxVal.get()); 7383 if (!UBMaxVal.isUsable()) 7384 return nullptr; 7385 7386 Expr *UBMin = tryBuildCapture(SemaRef, UBMinVal.get(), Captures).get(); 7387 Expr *UBMax = tryBuildCapture(SemaRef, UBMaxVal.get(), Captures).get(); 7388 if (!UBMin || !UBMax) 7389 return nullptr; 7390 // UB(MinVal) > UB(MaxVal) 7391 ExprResult MinGreaterMaxRes = 7392 SemaRef.BuildBinOp(S, DefaultLoc, BO_GT, UBMin, UBMax); 7393 if (!MinGreaterMaxRes.isUsable()) 7394 return nullptr; 7395 Expr *MinGreaterMax = 7396 tryBuildCapture(SemaRef, MinGreaterMaxRes.get(), Captures).get(); 7397 if (!MinGreaterMax) 7398 return nullptr; 7399 if (TestIsLessOp.getValue()) { 7400 // UB(MinVal) > UB(MaxVal) ? UB(MinVal) : UB(MaxVal) - max(UB(MinVal), 7401 // UB(MaxVal)) 7402 ExprResult MaxUB = SemaRef.ActOnConditionalOp( 7403 DefaultLoc, DefaultLoc, MinGreaterMax, UBMin, UBMax); 7404 if (!MaxUB.isUsable()) 7405 return nullptr; 7406 UBVal = MaxUB.get(); 7407 } else { 7408 // UB(MinVal) > UB(MaxVal) ? UB(MaxVal) : UB(MinVal) - min(UB(MinVal), 7409 // UB(MaxVal)) 7410 ExprResult MinUB = SemaRef.ActOnConditionalOp( 7411 DefaultLoc, DefaultLoc, MinGreaterMax, UBMax, UBMin); 7412 if (!MinUB.isUsable()) 7413 return nullptr; 7414 UBVal = MinUB.get(); 7415 } 7416 } 7417 Expr *UBExpr = TestIsLessOp.getValue() ? UBVal : LBVal; 7418 Expr *LBExpr = TestIsLessOp.getValue() ? LBVal : UBVal; 7419 Expr *Upper = tryBuildCapture(SemaRef, UBExpr, Captures).get(); 7420 Expr *Lower = tryBuildCapture(SemaRef, LBExpr, Captures).get(); 7421 if (!Upper || !Lower) 7422 return nullptr; 7423 7424 ExprResult Diff = 7425 calculateNumIters(SemaRef, S, DefaultLoc, Lower, Upper, Step, VarType, 7426 TestIsStrictOp, /*RoundToStep=*/true, Captures); 7427 if (!Diff.isUsable()) 7428 return nullptr; 7429 7430 // OpenMP runtime requires 32-bit or 64-bit loop variables. 7431 QualType Type = Diff.get()->getType(); 7432 ASTContext &C = SemaRef.Context; 7433 bool UseVarType = VarType->hasIntegerRepresentation() && 7434 C.getTypeSize(Type) > C.getTypeSize(VarType); 7435 if (!Type->isIntegerType() || UseVarType) { 7436 unsigned NewSize = 7437 UseVarType ? C.getTypeSize(VarType) : C.getTypeSize(Type); 7438 bool IsSigned = UseVarType ? VarType->hasSignedIntegerRepresentation() 7439 : Type->hasSignedIntegerRepresentation(); 7440 Type = C.getIntTypeForBitwidth(NewSize, IsSigned); 7441 if (!SemaRef.Context.hasSameType(Diff.get()->getType(), Type)) { 7442 Diff = SemaRef.PerformImplicitConversion( 7443 Diff.get(), Type, Sema::AA_Converting, /*AllowExplicit=*/true); 7444 if (!Diff.isUsable()) 7445 return nullptr; 7446 } 7447 } 7448 if (LimitedType) { 7449 unsigned NewSize = (C.getTypeSize(Type) > 32) ? 64 : 32; 7450 if (NewSize != C.getTypeSize(Type)) { 7451 if (NewSize < C.getTypeSize(Type)) { 7452 assert(NewSize == 64 && "incorrect loop var size"); 7453 SemaRef.Diag(DefaultLoc, diag::warn_omp_loop_64_bit_var) 7454 << InitSrcRange << ConditionSrcRange; 7455 } 7456 QualType NewType = C.getIntTypeForBitwidth( 7457 NewSize, Type->hasSignedIntegerRepresentation() || 7458 C.getTypeSize(Type) < NewSize); 7459 if (!SemaRef.Context.hasSameType(Diff.get()->getType(), NewType)) { 7460 Diff = SemaRef.PerformImplicitConversion(Diff.get(), NewType, 7461 Sema::AA_Converting, true); 7462 if (!Diff.isUsable()) 7463 return nullptr; 7464 } 7465 } 7466 } 7467 7468 return Diff.get(); 7469 } 7470 7471 std::pair<Expr *, Expr *> OpenMPIterationSpaceChecker::buildMinMaxValues( 7472 Scope *S, llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const { 7473 // Do not build for iterators, they cannot be used in non-rectangular loop 7474 // nests. 7475 if (LCDecl->getType()->isRecordType()) 7476 return std::make_pair(nullptr, nullptr); 7477 // If we subtract, the min is in the condition, otherwise the min is in the 7478 // init value. 7479 Expr *MinExpr = nullptr; 7480 Expr *MaxExpr = nullptr; 7481 Expr *LBExpr = TestIsLessOp.getValue() ? LB : UB; 7482 Expr *UBExpr = TestIsLessOp.getValue() ? UB : LB; 7483 bool LBNonRect = TestIsLessOp.getValue() ? InitDependOnLC.hasValue() 7484 : CondDependOnLC.hasValue(); 7485 bool UBNonRect = TestIsLessOp.getValue() ? CondDependOnLC.hasValue() 7486 : InitDependOnLC.hasValue(); 7487 Expr *Lower = 7488 LBNonRect ? LBExpr : tryBuildCapture(SemaRef, LBExpr, Captures).get(); 7489 Expr *Upper = 7490 UBNonRect ? UBExpr : tryBuildCapture(SemaRef, UBExpr, Captures).get(); 7491 if (!Upper || !Lower) 7492 return std::make_pair(nullptr, nullptr); 7493 7494 if (TestIsLessOp.getValue()) 7495 MinExpr = Lower; 7496 else 7497 MaxExpr = Upper; 7498 7499 // Build minimum/maximum value based on number of iterations. 7500 QualType VarType = LCDecl->getType().getNonReferenceType(); 7501 7502 ExprResult Diff = 7503 calculateNumIters(SemaRef, S, DefaultLoc, Lower, Upper, Step, VarType, 7504 TestIsStrictOp, /*RoundToStep=*/false, Captures); 7505 if (!Diff.isUsable()) 7506 return std::make_pair(nullptr, nullptr); 7507 7508 // ((Upper - Lower [- 1]) / Step) * Step 7509 // Parentheses (for dumping/debugging purposes only). 7510 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get()); 7511 if (!Diff.isUsable()) 7512 return std::make_pair(nullptr, nullptr); 7513 7514 ExprResult NewStep = tryBuildCapture(SemaRef, Step, Captures); 7515 if (!NewStep.isUsable()) 7516 return std::make_pair(nullptr, nullptr); 7517 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Mul, Diff.get(), NewStep.get()); 7518 if (!Diff.isUsable()) 7519 return std::make_pair(nullptr, nullptr); 7520 7521 // Parentheses (for dumping/debugging purposes only). 7522 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get()); 7523 if (!Diff.isUsable()) 7524 return std::make_pair(nullptr, nullptr); 7525 7526 // Convert to the ptrdiff_t, if original type is pointer. 7527 if (VarType->isAnyPointerType() && 7528 !SemaRef.Context.hasSameType( 7529 Diff.get()->getType(), 7530 SemaRef.Context.getUnsignedPointerDiffType())) { 7531 Diff = SemaRef.PerformImplicitConversion( 7532 Diff.get(), SemaRef.Context.getUnsignedPointerDiffType(), 7533 Sema::AA_Converting, /*AllowExplicit=*/true); 7534 } 7535 if (!Diff.isUsable()) 7536 return std::make_pair(nullptr, nullptr); 7537 7538 if (TestIsLessOp.getValue()) { 7539 // MinExpr = Lower; 7540 // MaxExpr = Lower + (((Upper - Lower [- 1]) / Step) * Step) 7541 Diff = SemaRef.BuildBinOp( 7542 S, DefaultLoc, BO_Add, 7543 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Lower).get(), 7544 Diff.get()); 7545 if (!Diff.isUsable()) 7546 return std::make_pair(nullptr, nullptr); 7547 } else { 7548 // MaxExpr = Upper; 7549 // MinExpr = Upper - (((Upper - Lower [- 1]) / Step) * Step) 7550 Diff = SemaRef.BuildBinOp( 7551 S, DefaultLoc, BO_Sub, 7552 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Upper).get(), 7553 Diff.get()); 7554 if (!Diff.isUsable()) 7555 return std::make_pair(nullptr, nullptr); 7556 } 7557 7558 // Convert to the original type. 7559 if (SemaRef.Context.hasSameType(Diff.get()->getType(), VarType)) 7560 Diff = SemaRef.PerformImplicitConversion(Diff.get(), VarType, 7561 Sema::AA_Converting, 7562 /*AllowExplicit=*/true); 7563 if (!Diff.isUsable()) 7564 return std::make_pair(nullptr, nullptr); 7565 7566 Diff = SemaRef.ActOnFinishFullExpr(Diff.get(), /*DiscardedValue=*/false); 7567 if (!Diff.isUsable()) 7568 return std::make_pair(nullptr, nullptr); 7569 7570 if (TestIsLessOp.getValue()) 7571 MaxExpr = Diff.get(); 7572 else 7573 MinExpr = Diff.get(); 7574 7575 return std::make_pair(MinExpr, MaxExpr); 7576 } 7577 7578 Expr *OpenMPIterationSpaceChecker::buildFinalCondition(Scope *S) const { 7579 if (InitDependOnLC || CondDependOnLC) 7580 return Condition; 7581 return nullptr; 7582 } 7583 7584 Expr *OpenMPIterationSpaceChecker::buildPreCond( 7585 Scope *S, Expr *Cond, 7586 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const { 7587 // Do not build a precondition when the condition/initialization is dependent 7588 // to prevent pessimistic early loop exit. 7589 // TODO: this can be improved by calculating min/max values but not sure that 7590 // it will be very effective. 7591 if (CondDependOnLC || InitDependOnLC) 7592 return SemaRef.PerformImplicitConversion( 7593 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get(), 7594 SemaRef.Context.BoolTy, /*Action=*/Sema::AA_Casting, 7595 /*AllowExplicit=*/true).get(); 7596 7597 // Try to build LB <op> UB, where <op> is <, >, <=, or >=. 7598 Sema::TentativeAnalysisScope Trap(SemaRef); 7599 7600 ExprResult NewLB = tryBuildCapture(SemaRef, LB, Captures); 7601 ExprResult NewUB = tryBuildCapture(SemaRef, UB, Captures); 7602 if (!NewLB.isUsable() || !NewUB.isUsable()) 7603 return nullptr; 7604 7605 ExprResult CondExpr = 7606 SemaRef.BuildBinOp(S, DefaultLoc, 7607 TestIsLessOp.getValue() ? 7608 (TestIsStrictOp ? BO_LT : BO_LE) : 7609 (TestIsStrictOp ? BO_GT : BO_GE), 7610 NewLB.get(), NewUB.get()); 7611 if (CondExpr.isUsable()) { 7612 if (!SemaRef.Context.hasSameUnqualifiedType(CondExpr.get()->getType(), 7613 SemaRef.Context.BoolTy)) 7614 CondExpr = SemaRef.PerformImplicitConversion( 7615 CondExpr.get(), SemaRef.Context.BoolTy, /*Action=*/Sema::AA_Casting, 7616 /*AllowExplicit=*/true); 7617 } 7618 7619 // Otherwise use original loop condition and evaluate it in runtime. 7620 return CondExpr.isUsable() ? CondExpr.get() : Cond; 7621 } 7622 7623 /// Build reference expression to the counter be used for codegen. 7624 DeclRefExpr *OpenMPIterationSpaceChecker::buildCounterVar( 7625 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures, 7626 DSAStackTy &DSA) const { 7627 auto *VD = dyn_cast<VarDecl>(LCDecl); 7628 if (!VD) { 7629 VD = SemaRef.isOpenMPCapturedDecl(LCDecl); 7630 DeclRefExpr *Ref = buildDeclRefExpr( 7631 SemaRef, VD, VD->getType().getNonReferenceType(), DefaultLoc); 7632 const DSAStackTy::DSAVarData Data = 7633 DSA.getTopDSA(LCDecl, /*FromParent=*/false); 7634 // If the loop control decl is explicitly marked as private, do not mark it 7635 // as captured again. 7636 if (!isOpenMPPrivate(Data.CKind) || !Data.RefExpr) 7637 Captures.insert(std::make_pair(LCRef, Ref)); 7638 return Ref; 7639 } 7640 return cast<DeclRefExpr>(LCRef); 7641 } 7642 7643 Expr *OpenMPIterationSpaceChecker::buildPrivateCounterVar() const { 7644 if (LCDecl && !LCDecl->isInvalidDecl()) { 7645 QualType Type = LCDecl->getType().getNonReferenceType(); 7646 VarDecl *PrivateVar = buildVarDecl( 7647 SemaRef, DefaultLoc, Type, LCDecl->getName(), 7648 LCDecl->hasAttrs() ? &LCDecl->getAttrs() : nullptr, 7649 isa<VarDecl>(LCDecl) 7650 ? buildDeclRefExpr(SemaRef, cast<VarDecl>(LCDecl), Type, DefaultLoc) 7651 : nullptr); 7652 if (PrivateVar->isInvalidDecl()) 7653 return nullptr; 7654 return buildDeclRefExpr(SemaRef, PrivateVar, Type, DefaultLoc); 7655 } 7656 return nullptr; 7657 } 7658 7659 /// Build initialization of the counter to be used for codegen. 7660 Expr *OpenMPIterationSpaceChecker::buildCounterInit() const { return LB; } 7661 7662 /// Build step of the counter be used for codegen. 7663 Expr *OpenMPIterationSpaceChecker::buildCounterStep() const { return Step; } 7664 7665 Expr *OpenMPIterationSpaceChecker::buildOrderedLoopData( 7666 Scope *S, Expr *Counter, 7667 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures, SourceLocation Loc, 7668 Expr *Inc, OverloadedOperatorKind OOK) { 7669 Expr *Cnt = SemaRef.DefaultLvalueConversion(Counter).get(); 7670 if (!Cnt) 7671 return nullptr; 7672 if (Inc) { 7673 assert((OOK == OO_Plus || OOK == OO_Minus) && 7674 "Expected only + or - operations for depend clauses."); 7675 BinaryOperatorKind BOK = (OOK == OO_Plus) ? BO_Add : BO_Sub; 7676 Cnt = SemaRef.BuildBinOp(S, Loc, BOK, Cnt, Inc).get(); 7677 if (!Cnt) 7678 return nullptr; 7679 } 7680 QualType VarType = LCDecl->getType().getNonReferenceType(); 7681 if (!VarType->isIntegerType() && !VarType->isPointerType() && 7682 !SemaRef.getLangOpts().CPlusPlus) 7683 return nullptr; 7684 // Upper - Lower 7685 Expr *Upper = TestIsLessOp.getValue() 7686 ? Cnt 7687 : tryBuildCapture(SemaRef, LB, Captures).get(); 7688 Expr *Lower = TestIsLessOp.getValue() 7689 ? tryBuildCapture(SemaRef, LB, Captures).get() 7690 : Cnt; 7691 if (!Upper || !Lower) 7692 return nullptr; 7693 7694 ExprResult Diff = calculateNumIters(SemaRef, S, DefaultLoc, Lower, Upper, 7695 Step, VarType, /*TestIsStrictOp=*/false, 7696 /*RoundToStep=*/false, Captures); 7697 if (!Diff.isUsable()) 7698 return nullptr; 7699 7700 return Diff.get(); 7701 } 7702 } // namespace 7703 7704 void Sema::ActOnOpenMPLoopInitialization(SourceLocation ForLoc, Stmt *Init) { 7705 assert(getLangOpts().OpenMP && "OpenMP is not active."); 7706 assert(Init && "Expected loop in canonical form."); 7707 unsigned AssociatedLoops = DSAStack->getAssociatedLoops(); 7708 if (AssociatedLoops > 0 && 7709 isOpenMPLoopDirective(DSAStack->getCurrentDirective())) { 7710 DSAStack->loopStart(); 7711 OpenMPIterationSpaceChecker ISC(*this, *DSAStack, ForLoc); 7712 if (!ISC.checkAndSetInit(Init, /*EmitDiags=*/false)) { 7713 if (ValueDecl *D = ISC.getLoopDecl()) { 7714 auto *VD = dyn_cast<VarDecl>(D); 7715 DeclRefExpr *PrivateRef = nullptr; 7716 if (!VD) { 7717 if (VarDecl *Private = isOpenMPCapturedDecl(D)) { 7718 VD = Private; 7719 } else { 7720 PrivateRef = buildCapture(*this, D, ISC.getLoopDeclRefExpr(), 7721 /*WithInit=*/false); 7722 VD = cast<VarDecl>(PrivateRef->getDecl()); 7723 } 7724 } 7725 DSAStack->addLoopControlVariable(D, VD); 7726 const Decl *LD = DSAStack->getPossiblyLoopCunter(); 7727 if (LD != D->getCanonicalDecl()) { 7728 DSAStack->resetPossibleLoopCounter(); 7729 if (auto *Var = dyn_cast_or_null<VarDecl>(LD)) 7730 MarkDeclarationsReferencedInExpr( 7731 buildDeclRefExpr(*this, const_cast<VarDecl *>(Var), 7732 Var->getType().getNonLValueExprType(Context), 7733 ForLoc, /*RefersToCapture=*/true)); 7734 } 7735 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 7736 // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables 7737 // Referenced in a Construct, C/C++]. The loop iteration variable in the 7738 // associated for-loop of a simd construct with just one associated 7739 // for-loop may be listed in a linear clause with a constant-linear-step 7740 // that is the increment of the associated for-loop. The loop iteration 7741 // variable(s) in the associated for-loop(s) of a for or parallel for 7742 // construct may be listed in a private or lastprivate clause. 7743 DSAStackTy::DSAVarData DVar = 7744 DSAStack->getTopDSA(D, /*FromParent=*/false); 7745 // If LoopVarRefExpr is nullptr it means the corresponding loop variable 7746 // is declared in the loop and it is predetermined as a private. 7747 Expr *LoopDeclRefExpr = ISC.getLoopDeclRefExpr(); 7748 OpenMPClauseKind PredeterminedCKind = 7749 isOpenMPSimdDirective(DKind) 7750 ? (DSAStack->hasMutipleLoops() ? OMPC_lastprivate : OMPC_linear) 7751 : OMPC_private; 7752 if (((isOpenMPSimdDirective(DKind) && DVar.CKind != OMPC_unknown && 7753 DVar.CKind != PredeterminedCKind && DVar.RefExpr && 7754 (LangOpts.OpenMP <= 45 || (DVar.CKind != OMPC_lastprivate && 7755 DVar.CKind != OMPC_private))) || 7756 ((isOpenMPWorksharingDirective(DKind) || DKind == OMPD_taskloop || 7757 DKind == OMPD_master_taskloop || 7758 DKind == OMPD_parallel_master_taskloop || 7759 isOpenMPDistributeDirective(DKind)) && 7760 !isOpenMPSimdDirective(DKind) && DVar.CKind != OMPC_unknown && 7761 DVar.CKind != OMPC_private && DVar.CKind != OMPC_lastprivate)) && 7762 (DVar.CKind != OMPC_private || DVar.RefExpr)) { 7763 Diag(Init->getBeginLoc(), diag::err_omp_loop_var_dsa) 7764 << getOpenMPClauseName(DVar.CKind) 7765 << getOpenMPDirectiveName(DKind) 7766 << getOpenMPClauseName(PredeterminedCKind); 7767 if (DVar.RefExpr == nullptr) 7768 DVar.CKind = PredeterminedCKind; 7769 reportOriginalDsa(*this, DSAStack, D, DVar, 7770 /*IsLoopIterVar=*/true); 7771 } else if (LoopDeclRefExpr) { 7772 // Make the loop iteration variable private (for worksharing 7773 // constructs), linear (for simd directives with the only one 7774 // associated loop) or lastprivate (for simd directives with several 7775 // collapsed or ordered loops). 7776 if (DVar.CKind == OMPC_unknown) 7777 DSAStack->addDSA(D, LoopDeclRefExpr, PredeterminedCKind, 7778 PrivateRef); 7779 } 7780 } 7781 } 7782 DSAStack->setAssociatedLoops(AssociatedLoops - 1); 7783 } 7784 } 7785 7786 /// Called on a for stmt to check and extract its iteration space 7787 /// for further processing (such as collapsing). 7788 static bool checkOpenMPIterationSpace( 7789 OpenMPDirectiveKind DKind, Stmt *S, Sema &SemaRef, DSAStackTy &DSA, 7790 unsigned CurrentNestedLoopCount, unsigned NestedLoopCount, 7791 unsigned TotalNestedLoopCount, Expr *CollapseLoopCountExpr, 7792 Expr *OrderedLoopCountExpr, 7793 Sema::VarsWithInheritedDSAType &VarsWithImplicitDSA, 7794 llvm::MutableArrayRef<LoopIterationSpace> ResultIterSpaces, 7795 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) { 7796 // OpenMP [2.9.1, Canonical Loop Form] 7797 // for (init-expr; test-expr; incr-expr) structured-block 7798 // for (range-decl: range-expr) structured-block 7799 auto *For = dyn_cast_or_null<ForStmt>(S); 7800 auto *CXXFor = dyn_cast_or_null<CXXForRangeStmt>(S); 7801 // Ranged for is supported only in OpenMP 5.0. 7802 if (!For && (SemaRef.LangOpts.OpenMP <= 45 || !CXXFor)) { 7803 SemaRef.Diag(S->getBeginLoc(), diag::err_omp_not_for) 7804 << (CollapseLoopCountExpr != nullptr || OrderedLoopCountExpr != nullptr) 7805 << getOpenMPDirectiveName(DKind) << TotalNestedLoopCount 7806 << (CurrentNestedLoopCount > 0) << CurrentNestedLoopCount; 7807 if (TotalNestedLoopCount > 1) { 7808 if (CollapseLoopCountExpr && OrderedLoopCountExpr) 7809 SemaRef.Diag(DSA.getConstructLoc(), 7810 diag::note_omp_collapse_ordered_expr) 7811 << 2 << CollapseLoopCountExpr->getSourceRange() 7812 << OrderedLoopCountExpr->getSourceRange(); 7813 else if (CollapseLoopCountExpr) 7814 SemaRef.Diag(CollapseLoopCountExpr->getExprLoc(), 7815 diag::note_omp_collapse_ordered_expr) 7816 << 0 << CollapseLoopCountExpr->getSourceRange(); 7817 else 7818 SemaRef.Diag(OrderedLoopCountExpr->getExprLoc(), 7819 diag::note_omp_collapse_ordered_expr) 7820 << 1 << OrderedLoopCountExpr->getSourceRange(); 7821 } 7822 return true; 7823 } 7824 assert(((For && For->getBody()) || (CXXFor && CXXFor->getBody())) && 7825 "No loop body."); 7826 7827 OpenMPIterationSpaceChecker ISC(SemaRef, DSA, 7828 For ? For->getForLoc() : CXXFor->getForLoc()); 7829 7830 // Check init. 7831 Stmt *Init = For ? For->getInit() : CXXFor->getBeginStmt(); 7832 if (ISC.checkAndSetInit(Init)) 7833 return true; 7834 7835 bool HasErrors = false; 7836 7837 // Check loop variable's type. 7838 if (ValueDecl *LCDecl = ISC.getLoopDecl()) { 7839 // OpenMP [2.6, Canonical Loop Form] 7840 // Var is one of the following: 7841 // A variable of signed or unsigned integer type. 7842 // For C++, a variable of a random access iterator type. 7843 // For C, a variable of a pointer type. 7844 QualType VarType = LCDecl->getType().getNonReferenceType(); 7845 if (!VarType->isDependentType() && !VarType->isIntegerType() && 7846 !VarType->isPointerType() && 7847 !(SemaRef.getLangOpts().CPlusPlus && VarType->isOverloadableType())) { 7848 SemaRef.Diag(Init->getBeginLoc(), diag::err_omp_loop_variable_type) 7849 << SemaRef.getLangOpts().CPlusPlus; 7850 HasErrors = true; 7851 } 7852 7853 // OpenMP, 2.14.1.1 Data-sharing Attribute Rules for Variables Referenced in 7854 // a Construct 7855 // The loop iteration variable(s) in the associated for-loop(s) of a for or 7856 // parallel for construct is (are) private. 7857 // The loop iteration variable in the associated for-loop of a simd 7858 // construct with just one associated for-loop is linear with a 7859 // constant-linear-step that is the increment of the associated for-loop. 7860 // Exclude loop var from the list of variables with implicitly defined data 7861 // sharing attributes. 7862 VarsWithImplicitDSA.erase(LCDecl); 7863 7864 assert(isOpenMPLoopDirective(DKind) && "DSA for non-loop vars"); 7865 7866 // Check test-expr. 7867 HasErrors |= ISC.checkAndSetCond(For ? For->getCond() : CXXFor->getCond()); 7868 7869 // Check incr-expr. 7870 HasErrors |= ISC.checkAndSetInc(For ? For->getInc() : CXXFor->getInc()); 7871 } 7872 7873 if (ISC.dependent() || SemaRef.CurContext->isDependentContext() || HasErrors) 7874 return HasErrors; 7875 7876 // Build the loop's iteration space representation. 7877 ResultIterSpaces[CurrentNestedLoopCount].PreCond = ISC.buildPreCond( 7878 DSA.getCurScope(), For ? For->getCond() : CXXFor->getCond(), Captures); 7879 ResultIterSpaces[CurrentNestedLoopCount].NumIterations = 7880 ISC.buildNumIterations(DSA.getCurScope(), ResultIterSpaces, 7881 (isOpenMPWorksharingDirective(DKind) || 7882 isOpenMPTaskLoopDirective(DKind) || 7883 isOpenMPDistributeDirective(DKind)), 7884 Captures); 7885 ResultIterSpaces[CurrentNestedLoopCount].CounterVar = 7886 ISC.buildCounterVar(Captures, DSA); 7887 ResultIterSpaces[CurrentNestedLoopCount].PrivateCounterVar = 7888 ISC.buildPrivateCounterVar(); 7889 ResultIterSpaces[CurrentNestedLoopCount].CounterInit = ISC.buildCounterInit(); 7890 ResultIterSpaces[CurrentNestedLoopCount].CounterStep = ISC.buildCounterStep(); 7891 ResultIterSpaces[CurrentNestedLoopCount].InitSrcRange = ISC.getInitSrcRange(); 7892 ResultIterSpaces[CurrentNestedLoopCount].CondSrcRange = 7893 ISC.getConditionSrcRange(); 7894 ResultIterSpaces[CurrentNestedLoopCount].IncSrcRange = 7895 ISC.getIncrementSrcRange(); 7896 ResultIterSpaces[CurrentNestedLoopCount].Subtract = ISC.shouldSubtractStep(); 7897 ResultIterSpaces[CurrentNestedLoopCount].IsStrictCompare = 7898 ISC.isStrictTestOp(); 7899 std::tie(ResultIterSpaces[CurrentNestedLoopCount].MinValue, 7900 ResultIterSpaces[CurrentNestedLoopCount].MaxValue) = 7901 ISC.buildMinMaxValues(DSA.getCurScope(), Captures); 7902 ResultIterSpaces[CurrentNestedLoopCount].FinalCondition = 7903 ISC.buildFinalCondition(DSA.getCurScope()); 7904 ResultIterSpaces[CurrentNestedLoopCount].IsNonRectangularLB = 7905 ISC.doesInitDependOnLC(); 7906 ResultIterSpaces[CurrentNestedLoopCount].IsNonRectangularUB = 7907 ISC.doesCondDependOnLC(); 7908 ResultIterSpaces[CurrentNestedLoopCount].LoopDependentIdx = 7909 ISC.getLoopDependentIdx(); 7910 7911 HasErrors |= 7912 (ResultIterSpaces[CurrentNestedLoopCount].PreCond == nullptr || 7913 ResultIterSpaces[CurrentNestedLoopCount].NumIterations == nullptr || 7914 ResultIterSpaces[CurrentNestedLoopCount].CounterVar == nullptr || 7915 ResultIterSpaces[CurrentNestedLoopCount].PrivateCounterVar == nullptr || 7916 ResultIterSpaces[CurrentNestedLoopCount].CounterInit == nullptr || 7917 ResultIterSpaces[CurrentNestedLoopCount].CounterStep == nullptr); 7918 if (!HasErrors && DSA.isOrderedRegion()) { 7919 if (DSA.getOrderedRegionParam().second->getNumForLoops()) { 7920 if (CurrentNestedLoopCount < 7921 DSA.getOrderedRegionParam().second->getLoopNumIterations().size()) { 7922 DSA.getOrderedRegionParam().second->setLoopNumIterations( 7923 CurrentNestedLoopCount, 7924 ResultIterSpaces[CurrentNestedLoopCount].NumIterations); 7925 DSA.getOrderedRegionParam().second->setLoopCounter( 7926 CurrentNestedLoopCount, 7927 ResultIterSpaces[CurrentNestedLoopCount].CounterVar); 7928 } 7929 } 7930 for (auto &Pair : DSA.getDoacrossDependClauses()) { 7931 if (CurrentNestedLoopCount >= Pair.first->getNumLoops()) { 7932 // Erroneous case - clause has some problems. 7933 continue; 7934 } 7935 if (Pair.first->getDependencyKind() == OMPC_DEPEND_sink && 7936 Pair.second.size() <= CurrentNestedLoopCount) { 7937 // Erroneous case - clause has some problems. 7938 Pair.first->setLoopData(CurrentNestedLoopCount, nullptr); 7939 continue; 7940 } 7941 Expr *CntValue; 7942 if (Pair.first->getDependencyKind() == OMPC_DEPEND_source) 7943 CntValue = ISC.buildOrderedLoopData( 7944 DSA.getCurScope(), 7945 ResultIterSpaces[CurrentNestedLoopCount].CounterVar, Captures, 7946 Pair.first->getDependencyLoc()); 7947 else 7948 CntValue = ISC.buildOrderedLoopData( 7949 DSA.getCurScope(), 7950 ResultIterSpaces[CurrentNestedLoopCount].CounterVar, Captures, 7951 Pair.first->getDependencyLoc(), 7952 Pair.second[CurrentNestedLoopCount].first, 7953 Pair.second[CurrentNestedLoopCount].second); 7954 Pair.first->setLoopData(CurrentNestedLoopCount, CntValue); 7955 } 7956 } 7957 7958 return HasErrors; 7959 } 7960 7961 /// Build 'VarRef = Start. 7962 static ExprResult 7963 buildCounterInit(Sema &SemaRef, Scope *S, SourceLocation Loc, ExprResult VarRef, 7964 ExprResult Start, bool IsNonRectangularLB, 7965 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) { 7966 // Build 'VarRef = Start. 7967 ExprResult NewStart = IsNonRectangularLB 7968 ? Start.get() 7969 : tryBuildCapture(SemaRef, Start.get(), Captures); 7970 if (!NewStart.isUsable()) 7971 return ExprError(); 7972 if (!SemaRef.Context.hasSameType(NewStart.get()->getType(), 7973 VarRef.get()->getType())) { 7974 NewStart = SemaRef.PerformImplicitConversion( 7975 NewStart.get(), VarRef.get()->getType(), Sema::AA_Converting, 7976 /*AllowExplicit=*/true); 7977 if (!NewStart.isUsable()) 7978 return ExprError(); 7979 } 7980 7981 ExprResult Init = 7982 SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), NewStart.get()); 7983 return Init; 7984 } 7985 7986 /// Build 'VarRef = Start + Iter * Step'. 7987 static ExprResult buildCounterUpdate( 7988 Sema &SemaRef, Scope *S, SourceLocation Loc, ExprResult VarRef, 7989 ExprResult Start, ExprResult Iter, ExprResult Step, bool Subtract, 7990 bool IsNonRectangularLB, 7991 llvm::MapVector<const Expr *, DeclRefExpr *> *Captures = nullptr) { 7992 // Add parentheses (for debugging purposes only). 7993 Iter = SemaRef.ActOnParenExpr(Loc, Loc, Iter.get()); 7994 if (!VarRef.isUsable() || !Start.isUsable() || !Iter.isUsable() || 7995 !Step.isUsable()) 7996 return ExprError(); 7997 7998 ExprResult NewStep = Step; 7999 if (Captures) 8000 NewStep = tryBuildCapture(SemaRef, Step.get(), *Captures); 8001 if (NewStep.isInvalid()) 8002 return ExprError(); 8003 ExprResult Update = 8004 SemaRef.BuildBinOp(S, Loc, BO_Mul, Iter.get(), NewStep.get()); 8005 if (!Update.isUsable()) 8006 return ExprError(); 8007 8008 // Try to build 'VarRef = Start, VarRef (+|-)= Iter * Step' or 8009 // 'VarRef = Start (+|-) Iter * Step'. 8010 if (!Start.isUsable()) 8011 return ExprError(); 8012 ExprResult NewStart = SemaRef.ActOnParenExpr(Loc, Loc, Start.get()); 8013 if (!NewStart.isUsable()) 8014 return ExprError(); 8015 if (Captures && !IsNonRectangularLB) 8016 NewStart = tryBuildCapture(SemaRef, Start.get(), *Captures); 8017 if (NewStart.isInvalid()) 8018 return ExprError(); 8019 8020 // First attempt: try to build 'VarRef = Start, VarRef += Iter * Step'. 8021 ExprResult SavedUpdate = Update; 8022 ExprResult UpdateVal; 8023 if (VarRef.get()->getType()->isOverloadableType() || 8024 NewStart.get()->getType()->isOverloadableType() || 8025 Update.get()->getType()->isOverloadableType()) { 8026 Sema::TentativeAnalysisScope Trap(SemaRef); 8027 8028 Update = 8029 SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), NewStart.get()); 8030 if (Update.isUsable()) { 8031 UpdateVal = 8032 SemaRef.BuildBinOp(S, Loc, Subtract ? BO_SubAssign : BO_AddAssign, 8033 VarRef.get(), SavedUpdate.get()); 8034 if (UpdateVal.isUsable()) { 8035 Update = SemaRef.CreateBuiltinBinOp(Loc, BO_Comma, Update.get(), 8036 UpdateVal.get()); 8037 } 8038 } 8039 } 8040 8041 // Second attempt: try to build 'VarRef = Start (+|-) Iter * Step'. 8042 if (!Update.isUsable() || !UpdateVal.isUsable()) { 8043 Update = SemaRef.BuildBinOp(S, Loc, Subtract ? BO_Sub : BO_Add, 8044 NewStart.get(), SavedUpdate.get()); 8045 if (!Update.isUsable()) 8046 return ExprError(); 8047 8048 if (!SemaRef.Context.hasSameType(Update.get()->getType(), 8049 VarRef.get()->getType())) { 8050 Update = SemaRef.PerformImplicitConversion( 8051 Update.get(), VarRef.get()->getType(), Sema::AA_Converting, true); 8052 if (!Update.isUsable()) 8053 return ExprError(); 8054 } 8055 8056 Update = SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), Update.get()); 8057 } 8058 return Update; 8059 } 8060 8061 /// Convert integer expression \a E to make it have at least \a Bits 8062 /// bits. 8063 static ExprResult widenIterationCount(unsigned Bits, Expr *E, Sema &SemaRef) { 8064 if (E == nullptr) 8065 return ExprError(); 8066 ASTContext &C = SemaRef.Context; 8067 QualType OldType = E->getType(); 8068 unsigned HasBits = C.getTypeSize(OldType); 8069 if (HasBits >= Bits) 8070 return ExprResult(E); 8071 // OK to convert to signed, because new type has more bits than old. 8072 QualType NewType = C.getIntTypeForBitwidth(Bits, /* Signed */ true); 8073 return SemaRef.PerformImplicitConversion(E, NewType, Sema::AA_Converting, 8074 true); 8075 } 8076 8077 /// Check if the given expression \a E is a constant integer that fits 8078 /// into \a Bits bits. 8079 static bool fitsInto(unsigned Bits, bool Signed, const Expr *E, Sema &SemaRef) { 8080 if (E == nullptr) 8081 return false; 8082 if (Optional<llvm::APSInt> Result = 8083 E->getIntegerConstantExpr(SemaRef.Context)) 8084 return Signed ? Result->isSignedIntN(Bits) : Result->isIntN(Bits); 8085 return false; 8086 } 8087 8088 /// Build preinits statement for the given declarations. 8089 static Stmt *buildPreInits(ASTContext &Context, 8090 MutableArrayRef<Decl *> PreInits) { 8091 if (!PreInits.empty()) { 8092 return new (Context) DeclStmt( 8093 DeclGroupRef::Create(Context, PreInits.begin(), PreInits.size()), 8094 SourceLocation(), SourceLocation()); 8095 } 8096 return nullptr; 8097 } 8098 8099 /// Build preinits statement for the given declarations. 8100 static Stmt * 8101 buildPreInits(ASTContext &Context, 8102 const llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) { 8103 if (!Captures.empty()) { 8104 SmallVector<Decl *, 16> PreInits; 8105 for (const auto &Pair : Captures) 8106 PreInits.push_back(Pair.second->getDecl()); 8107 return buildPreInits(Context, PreInits); 8108 } 8109 return nullptr; 8110 } 8111 8112 /// Build postupdate expression for the given list of postupdates expressions. 8113 static Expr *buildPostUpdate(Sema &S, ArrayRef<Expr *> PostUpdates) { 8114 Expr *PostUpdate = nullptr; 8115 if (!PostUpdates.empty()) { 8116 for (Expr *E : PostUpdates) { 8117 Expr *ConvE = S.BuildCStyleCastExpr( 8118 E->getExprLoc(), 8119 S.Context.getTrivialTypeSourceInfo(S.Context.VoidTy), 8120 E->getExprLoc(), E) 8121 .get(); 8122 PostUpdate = PostUpdate 8123 ? S.CreateBuiltinBinOp(ConvE->getExprLoc(), BO_Comma, 8124 PostUpdate, ConvE) 8125 .get() 8126 : ConvE; 8127 } 8128 } 8129 return PostUpdate; 8130 } 8131 8132 /// Called on a for stmt to check itself and nested loops (if any). 8133 /// \return Returns 0 if one of the collapsed stmts is not canonical for loop, 8134 /// number of collapsed loops otherwise. 8135 static unsigned 8136 checkOpenMPLoop(OpenMPDirectiveKind DKind, Expr *CollapseLoopCountExpr, 8137 Expr *OrderedLoopCountExpr, Stmt *AStmt, Sema &SemaRef, 8138 DSAStackTy &DSA, 8139 Sema::VarsWithInheritedDSAType &VarsWithImplicitDSA, 8140 OMPLoopDirective::HelperExprs &Built) { 8141 unsigned NestedLoopCount = 1; 8142 if (CollapseLoopCountExpr) { 8143 // Found 'collapse' clause - calculate collapse number. 8144 Expr::EvalResult Result; 8145 if (!CollapseLoopCountExpr->isValueDependent() && 8146 CollapseLoopCountExpr->EvaluateAsInt(Result, SemaRef.getASTContext())) { 8147 NestedLoopCount = Result.Val.getInt().getLimitedValue(); 8148 } else { 8149 Built.clear(/*Size=*/1); 8150 return 1; 8151 } 8152 } 8153 unsigned OrderedLoopCount = 1; 8154 if (OrderedLoopCountExpr) { 8155 // Found 'ordered' clause - calculate collapse number. 8156 Expr::EvalResult EVResult; 8157 if (!OrderedLoopCountExpr->isValueDependent() && 8158 OrderedLoopCountExpr->EvaluateAsInt(EVResult, 8159 SemaRef.getASTContext())) { 8160 llvm::APSInt Result = EVResult.Val.getInt(); 8161 if (Result.getLimitedValue() < NestedLoopCount) { 8162 SemaRef.Diag(OrderedLoopCountExpr->getExprLoc(), 8163 diag::err_omp_wrong_ordered_loop_count) 8164 << OrderedLoopCountExpr->getSourceRange(); 8165 SemaRef.Diag(CollapseLoopCountExpr->getExprLoc(), 8166 diag::note_collapse_loop_count) 8167 << CollapseLoopCountExpr->getSourceRange(); 8168 } 8169 OrderedLoopCount = Result.getLimitedValue(); 8170 } else { 8171 Built.clear(/*Size=*/1); 8172 return 1; 8173 } 8174 } 8175 // This is helper routine for loop directives (e.g., 'for', 'simd', 8176 // 'for simd', etc.). 8177 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 8178 SmallVector<LoopIterationSpace, 4> IterSpaces( 8179 std::max(OrderedLoopCount, NestedLoopCount)); 8180 Stmt *CurStmt = AStmt->IgnoreContainers(/* IgnoreCaptured */ true); 8181 for (unsigned Cnt = 0; Cnt < NestedLoopCount; ++Cnt) { 8182 if (checkOpenMPIterationSpace( 8183 DKind, CurStmt, SemaRef, DSA, Cnt, NestedLoopCount, 8184 std::max(OrderedLoopCount, NestedLoopCount), CollapseLoopCountExpr, 8185 OrderedLoopCountExpr, VarsWithImplicitDSA, IterSpaces, Captures)) 8186 return 0; 8187 // Move on to the next nested for loop, or to the loop body. 8188 // OpenMP [2.8.1, simd construct, Restrictions] 8189 // All loops associated with the construct must be perfectly nested; that 8190 // is, there must be no intervening code nor any OpenMP directive between 8191 // any two loops. 8192 if (auto *For = dyn_cast<ForStmt>(CurStmt)) { 8193 CurStmt = For->getBody(); 8194 } else { 8195 assert(isa<CXXForRangeStmt>(CurStmt) && 8196 "Expected canonical for or range-based for loops."); 8197 CurStmt = cast<CXXForRangeStmt>(CurStmt)->getBody(); 8198 } 8199 CurStmt = OMPLoopDirective::tryToFindNextInnerLoop( 8200 CurStmt, SemaRef.LangOpts.OpenMP >= 50); 8201 } 8202 for (unsigned Cnt = NestedLoopCount; Cnt < OrderedLoopCount; ++Cnt) { 8203 if (checkOpenMPIterationSpace( 8204 DKind, CurStmt, SemaRef, DSA, Cnt, NestedLoopCount, 8205 std::max(OrderedLoopCount, NestedLoopCount), CollapseLoopCountExpr, 8206 OrderedLoopCountExpr, VarsWithImplicitDSA, IterSpaces, Captures)) 8207 return 0; 8208 if (Cnt > 0 && IterSpaces[Cnt].CounterVar) { 8209 // Handle initialization of captured loop iterator variables. 8210 auto *DRE = cast<DeclRefExpr>(IterSpaces[Cnt].CounterVar); 8211 if (isa<OMPCapturedExprDecl>(DRE->getDecl())) { 8212 Captures[DRE] = DRE; 8213 } 8214 } 8215 // Move on to the next nested for loop, or to the loop body. 8216 // OpenMP [2.8.1, simd construct, Restrictions] 8217 // All loops associated with the construct must be perfectly nested; that 8218 // is, there must be no intervening code nor any OpenMP directive between 8219 // any two loops. 8220 if (auto *For = dyn_cast<ForStmt>(CurStmt)) { 8221 CurStmt = For->getBody(); 8222 } else { 8223 assert(isa<CXXForRangeStmt>(CurStmt) && 8224 "Expected canonical for or range-based for loops."); 8225 CurStmt = cast<CXXForRangeStmt>(CurStmt)->getBody(); 8226 } 8227 CurStmt = OMPLoopDirective::tryToFindNextInnerLoop( 8228 CurStmt, SemaRef.LangOpts.OpenMP >= 50); 8229 } 8230 8231 Built.clear(/* size */ NestedLoopCount); 8232 8233 if (SemaRef.CurContext->isDependentContext()) 8234 return NestedLoopCount; 8235 8236 // An example of what is generated for the following code: 8237 // 8238 // #pragma omp simd collapse(2) ordered(2) 8239 // for (i = 0; i < NI; ++i) 8240 // for (k = 0; k < NK; ++k) 8241 // for (j = J0; j < NJ; j+=2) { 8242 // <loop body> 8243 // } 8244 // 8245 // We generate the code below. 8246 // Note: the loop body may be outlined in CodeGen. 8247 // Note: some counters may be C++ classes, operator- is used to find number of 8248 // iterations and operator+= to calculate counter value. 8249 // Note: decltype(NumIterations) must be integer type (in 'omp for', only i32 8250 // or i64 is currently supported). 8251 // 8252 // #define NumIterations (NI * ((NJ - J0 - 1 + 2) / 2)) 8253 // for (int[32|64]_t IV = 0; IV < NumIterations; ++IV ) { 8254 // .local.i = IV / ((NJ - J0 - 1 + 2) / 2); 8255 // .local.j = J0 + (IV % ((NJ - J0 - 1 + 2) / 2)) * 2; 8256 // // similar updates for vars in clauses (e.g. 'linear') 8257 // <loop body (using local i and j)> 8258 // } 8259 // i = NI; // assign final values of counters 8260 // j = NJ; 8261 // 8262 8263 // Last iteration number is (I1 * I2 * ... In) - 1, where I1, I2 ... In are 8264 // the iteration counts of the collapsed for loops. 8265 // Precondition tests if there is at least one iteration (all conditions are 8266 // true). 8267 auto PreCond = ExprResult(IterSpaces[0].PreCond); 8268 Expr *N0 = IterSpaces[0].NumIterations; 8269 ExprResult LastIteration32 = 8270 widenIterationCount(/*Bits=*/32, 8271 SemaRef 8272 .PerformImplicitConversion( 8273 N0->IgnoreImpCasts(), N0->getType(), 8274 Sema::AA_Converting, /*AllowExplicit=*/true) 8275 .get(), 8276 SemaRef); 8277 ExprResult LastIteration64 = widenIterationCount( 8278 /*Bits=*/64, 8279 SemaRef 8280 .PerformImplicitConversion(N0->IgnoreImpCasts(), N0->getType(), 8281 Sema::AA_Converting, 8282 /*AllowExplicit=*/true) 8283 .get(), 8284 SemaRef); 8285 8286 if (!LastIteration32.isUsable() || !LastIteration64.isUsable()) 8287 return NestedLoopCount; 8288 8289 ASTContext &C = SemaRef.Context; 8290 bool AllCountsNeedLessThan32Bits = C.getTypeSize(N0->getType()) < 32; 8291 8292 Scope *CurScope = DSA.getCurScope(); 8293 for (unsigned Cnt = 1; Cnt < NestedLoopCount; ++Cnt) { 8294 if (PreCond.isUsable()) { 8295 PreCond = 8296 SemaRef.BuildBinOp(CurScope, PreCond.get()->getExprLoc(), BO_LAnd, 8297 PreCond.get(), IterSpaces[Cnt].PreCond); 8298 } 8299 Expr *N = IterSpaces[Cnt].NumIterations; 8300 SourceLocation Loc = N->getExprLoc(); 8301 AllCountsNeedLessThan32Bits &= C.getTypeSize(N->getType()) < 32; 8302 if (LastIteration32.isUsable()) 8303 LastIteration32 = SemaRef.BuildBinOp( 8304 CurScope, Loc, BO_Mul, LastIteration32.get(), 8305 SemaRef 8306 .PerformImplicitConversion(N->IgnoreImpCasts(), N->getType(), 8307 Sema::AA_Converting, 8308 /*AllowExplicit=*/true) 8309 .get()); 8310 if (LastIteration64.isUsable()) 8311 LastIteration64 = SemaRef.BuildBinOp( 8312 CurScope, Loc, BO_Mul, LastIteration64.get(), 8313 SemaRef 8314 .PerformImplicitConversion(N->IgnoreImpCasts(), N->getType(), 8315 Sema::AA_Converting, 8316 /*AllowExplicit=*/true) 8317 .get()); 8318 } 8319 8320 // Choose either the 32-bit or 64-bit version. 8321 ExprResult LastIteration = LastIteration64; 8322 if (SemaRef.getLangOpts().OpenMPOptimisticCollapse || 8323 (LastIteration32.isUsable() && 8324 C.getTypeSize(LastIteration32.get()->getType()) == 32 && 8325 (AllCountsNeedLessThan32Bits || NestedLoopCount == 1 || 8326 fitsInto( 8327 /*Bits=*/32, 8328 LastIteration32.get()->getType()->hasSignedIntegerRepresentation(), 8329 LastIteration64.get(), SemaRef)))) 8330 LastIteration = LastIteration32; 8331 QualType VType = LastIteration.get()->getType(); 8332 QualType RealVType = VType; 8333 QualType StrideVType = VType; 8334 if (isOpenMPTaskLoopDirective(DKind)) { 8335 VType = 8336 SemaRef.Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/0); 8337 StrideVType = 8338 SemaRef.Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/1); 8339 } 8340 8341 if (!LastIteration.isUsable()) 8342 return 0; 8343 8344 // Save the number of iterations. 8345 ExprResult NumIterations = LastIteration; 8346 { 8347 LastIteration = SemaRef.BuildBinOp( 8348 CurScope, LastIteration.get()->getExprLoc(), BO_Sub, 8349 LastIteration.get(), 8350 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()); 8351 if (!LastIteration.isUsable()) 8352 return 0; 8353 } 8354 8355 // Calculate the last iteration number beforehand instead of doing this on 8356 // each iteration. Do not do this if the number of iterations may be kfold-ed. 8357 bool IsConstant = LastIteration.get()->isIntegerConstantExpr(SemaRef.Context); 8358 ExprResult CalcLastIteration; 8359 if (!IsConstant) { 8360 ExprResult SaveRef = 8361 tryBuildCapture(SemaRef, LastIteration.get(), Captures); 8362 LastIteration = SaveRef; 8363 8364 // Prepare SaveRef + 1. 8365 NumIterations = SemaRef.BuildBinOp( 8366 CurScope, SaveRef.get()->getExprLoc(), BO_Add, SaveRef.get(), 8367 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()); 8368 if (!NumIterations.isUsable()) 8369 return 0; 8370 } 8371 8372 SourceLocation InitLoc = IterSpaces[0].InitSrcRange.getBegin(); 8373 8374 // Build variables passed into runtime, necessary for worksharing directives. 8375 ExprResult LB, UB, IL, ST, EUB, CombLB, CombUB, PrevLB, PrevUB, CombEUB; 8376 if (isOpenMPWorksharingDirective(DKind) || isOpenMPTaskLoopDirective(DKind) || 8377 isOpenMPDistributeDirective(DKind)) { 8378 // Lower bound variable, initialized with zero. 8379 VarDecl *LBDecl = buildVarDecl(SemaRef, InitLoc, VType, ".omp.lb"); 8380 LB = buildDeclRefExpr(SemaRef, LBDecl, VType, InitLoc); 8381 SemaRef.AddInitializerToDecl(LBDecl, 8382 SemaRef.ActOnIntegerConstant(InitLoc, 0).get(), 8383 /*DirectInit*/ false); 8384 8385 // Upper bound variable, initialized with last iteration number. 8386 VarDecl *UBDecl = buildVarDecl(SemaRef, InitLoc, VType, ".omp.ub"); 8387 UB = buildDeclRefExpr(SemaRef, UBDecl, VType, InitLoc); 8388 SemaRef.AddInitializerToDecl(UBDecl, LastIteration.get(), 8389 /*DirectInit*/ false); 8390 8391 // A 32-bit variable-flag where runtime returns 1 for the last iteration. 8392 // This will be used to implement clause 'lastprivate'. 8393 QualType Int32Ty = SemaRef.Context.getIntTypeForBitwidth(32, true); 8394 VarDecl *ILDecl = buildVarDecl(SemaRef, InitLoc, Int32Ty, ".omp.is_last"); 8395 IL = buildDeclRefExpr(SemaRef, ILDecl, Int32Ty, InitLoc); 8396 SemaRef.AddInitializerToDecl(ILDecl, 8397 SemaRef.ActOnIntegerConstant(InitLoc, 0).get(), 8398 /*DirectInit*/ false); 8399 8400 // Stride variable returned by runtime (we initialize it to 1 by default). 8401 VarDecl *STDecl = 8402 buildVarDecl(SemaRef, InitLoc, StrideVType, ".omp.stride"); 8403 ST = buildDeclRefExpr(SemaRef, STDecl, StrideVType, InitLoc); 8404 SemaRef.AddInitializerToDecl(STDecl, 8405 SemaRef.ActOnIntegerConstant(InitLoc, 1).get(), 8406 /*DirectInit*/ false); 8407 8408 // Build expression: UB = min(UB, LastIteration) 8409 // It is necessary for CodeGen of directives with static scheduling. 8410 ExprResult IsUBGreater = SemaRef.BuildBinOp(CurScope, InitLoc, BO_GT, 8411 UB.get(), LastIteration.get()); 8412 ExprResult CondOp = SemaRef.ActOnConditionalOp( 8413 LastIteration.get()->getExprLoc(), InitLoc, IsUBGreater.get(), 8414 LastIteration.get(), UB.get()); 8415 EUB = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, UB.get(), 8416 CondOp.get()); 8417 EUB = SemaRef.ActOnFinishFullExpr(EUB.get(), /*DiscardedValue*/ false); 8418 8419 // If we have a combined directive that combines 'distribute', 'for' or 8420 // 'simd' we need to be able to access the bounds of the schedule of the 8421 // enclosing region. E.g. in 'distribute parallel for' the bounds obtained 8422 // by scheduling 'distribute' have to be passed to the schedule of 'for'. 8423 if (isOpenMPLoopBoundSharingDirective(DKind)) { 8424 // Lower bound variable, initialized with zero. 8425 VarDecl *CombLBDecl = 8426 buildVarDecl(SemaRef, InitLoc, VType, ".omp.comb.lb"); 8427 CombLB = buildDeclRefExpr(SemaRef, CombLBDecl, VType, InitLoc); 8428 SemaRef.AddInitializerToDecl( 8429 CombLBDecl, SemaRef.ActOnIntegerConstant(InitLoc, 0).get(), 8430 /*DirectInit*/ false); 8431 8432 // Upper bound variable, initialized with last iteration number. 8433 VarDecl *CombUBDecl = 8434 buildVarDecl(SemaRef, InitLoc, VType, ".omp.comb.ub"); 8435 CombUB = buildDeclRefExpr(SemaRef, CombUBDecl, VType, InitLoc); 8436 SemaRef.AddInitializerToDecl(CombUBDecl, LastIteration.get(), 8437 /*DirectInit*/ false); 8438 8439 ExprResult CombIsUBGreater = SemaRef.BuildBinOp( 8440 CurScope, InitLoc, BO_GT, CombUB.get(), LastIteration.get()); 8441 ExprResult CombCondOp = 8442 SemaRef.ActOnConditionalOp(InitLoc, InitLoc, CombIsUBGreater.get(), 8443 LastIteration.get(), CombUB.get()); 8444 CombEUB = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, CombUB.get(), 8445 CombCondOp.get()); 8446 CombEUB = 8447 SemaRef.ActOnFinishFullExpr(CombEUB.get(), /*DiscardedValue*/ false); 8448 8449 const CapturedDecl *CD = cast<CapturedStmt>(AStmt)->getCapturedDecl(); 8450 // We expect to have at least 2 more parameters than the 'parallel' 8451 // directive does - the lower and upper bounds of the previous schedule. 8452 assert(CD->getNumParams() >= 4 && 8453 "Unexpected number of parameters in loop combined directive"); 8454 8455 // Set the proper type for the bounds given what we learned from the 8456 // enclosed loops. 8457 ImplicitParamDecl *PrevLBDecl = CD->getParam(/*PrevLB=*/2); 8458 ImplicitParamDecl *PrevUBDecl = CD->getParam(/*PrevUB=*/3); 8459 8460 // Previous lower and upper bounds are obtained from the region 8461 // parameters. 8462 PrevLB = 8463 buildDeclRefExpr(SemaRef, PrevLBDecl, PrevLBDecl->getType(), InitLoc); 8464 PrevUB = 8465 buildDeclRefExpr(SemaRef, PrevUBDecl, PrevUBDecl->getType(), InitLoc); 8466 } 8467 } 8468 8469 // Build the iteration variable and its initialization before loop. 8470 ExprResult IV; 8471 ExprResult Init, CombInit; 8472 { 8473 VarDecl *IVDecl = buildVarDecl(SemaRef, InitLoc, RealVType, ".omp.iv"); 8474 IV = buildDeclRefExpr(SemaRef, IVDecl, RealVType, InitLoc); 8475 Expr *RHS = 8476 (isOpenMPWorksharingDirective(DKind) || 8477 isOpenMPTaskLoopDirective(DKind) || isOpenMPDistributeDirective(DKind)) 8478 ? LB.get() 8479 : SemaRef.ActOnIntegerConstant(SourceLocation(), 0).get(); 8480 Init = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, IV.get(), RHS); 8481 Init = SemaRef.ActOnFinishFullExpr(Init.get(), /*DiscardedValue*/ false); 8482 8483 if (isOpenMPLoopBoundSharingDirective(DKind)) { 8484 Expr *CombRHS = 8485 (isOpenMPWorksharingDirective(DKind) || 8486 isOpenMPTaskLoopDirective(DKind) || 8487 isOpenMPDistributeDirective(DKind)) 8488 ? CombLB.get() 8489 : SemaRef.ActOnIntegerConstant(SourceLocation(), 0).get(); 8490 CombInit = 8491 SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, IV.get(), CombRHS); 8492 CombInit = 8493 SemaRef.ActOnFinishFullExpr(CombInit.get(), /*DiscardedValue*/ false); 8494 } 8495 } 8496 8497 bool UseStrictCompare = 8498 RealVType->hasUnsignedIntegerRepresentation() && 8499 llvm::all_of(IterSpaces, [](const LoopIterationSpace &LIS) { 8500 return LIS.IsStrictCompare; 8501 }); 8502 // Loop condition (IV < NumIterations) or (IV <= UB or IV < UB + 1 (for 8503 // unsigned IV)) for worksharing loops. 8504 SourceLocation CondLoc = AStmt->getBeginLoc(); 8505 Expr *BoundUB = UB.get(); 8506 if (UseStrictCompare) { 8507 BoundUB = 8508 SemaRef 8509 .BuildBinOp(CurScope, CondLoc, BO_Add, BoundUB, 8510 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()) 8511 .get(); 8512 BoundUB = 8513 SemaRef.ActOnFinishFullExpr(BoundUB, /*DiscardedValue*/ false).get(); 8514 } 8515 ExprResult Cond = 8516 (isOpenMPWorksharingDirective(DKind) || 8517 isOpenMPTaskLoopDirective(DKind) || isOpenMPDistributeDirective(DKind)) 8518 ? SemaRef.BuildBinOp(CurScope, CondLoc, 8519 UseStrictCompare ? BO_LT : BO_LE, IV.get(), 8520 BoundUB) 8521 : SemaRef.BuildBinOp(CurScope, CondLoc, BO_LT, IV.get(), 8522 NumIterations.get()); 8523 ExprResult CombDistCond; 8524 if (isOpenMPLoopBoundSharingDirective(DKind)) { 8525 CombDistCond = SemaRef.BuildBinOp(CurScope, CondLoc, BO_LT, IV.get(), 8526 NumIterations.get()); 8527 } 8528 8529 ExprResult CombCond; 8530 if (isOpenMPLoopBoundSharingDirective(DKind)) { 8531 Expr *BoundCombUB = CombUB.get(); 8532 if (UseStrictCompare) { 8533 BoundCombUB = 8534 SemaRef 8535 .BuildBinOp( 8536 CurScope, CondLoc, BO_Add, BoundCombUB, 8537 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()) 8538 .get(); 8539 BoundCombUB = 8540 SemaRef.ActOnFinishFullExpr(BoundCombUB, /*DiscardedValue*/ false) 8541 .get(); 8542 } 8543 CombCond = 8544 SemaRef.BuildBinOp(CurScope, CondLoc, UseStrictCompare ? BO_LT : BO_LE, 8545 IV.get(), BoundCombUB); 8546 } 8547 // Loop increment (IV = IV + 1) 8548 SourceLocation IncLoc = AStmt->getBeginLoc(); 8549 ExprResult Inc = 8550 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, IV.get(), 8551 SemaRef.ActOnIntegerConstant(IncLoc, 1).get()); 8552 if (!Inc.isUsable()) 8553 return 0; 8554 Inc = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, IV.get(), Inc.get()); 8555 Inc = SemaRef.ActOnFinishFullExpr(Inc.get(), /*DiscardedValue*/ false); 8556 if (!Inc.isUsable()) 8557 return 0; 8558 8559 // Increments for worksharing loops (LB = LB + ST; UB = UB + ST). 8560 // Used for directives with static scheduling. 8561 // In combined construct, add combined version that use CombLB and CombUB 8562 // base variables for the update 8563 ExprResult NextLB, NextUB, CombNextLB, CombNextUB; 8564 if (isOpenMPWorksharingDirective(DKind) || isOpenMPTaskLoopDirective(DKind) || 8565 isOpenMPDistributeDirective(DKind)) { 8566 // LB + ST 8567 NextLB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, LB.get(), ST.get()); 8568 if (!NextLB.isUsable()) 8569 return 0; 8570 // LB = LB + ST 8571 NextLB = 8572 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, LB.get(), NextLB.get()); 8573 NextLB = 8574 SemaRef.ActOnFinishFullExpr(NextLB.get(), /*DiscardedValue*/ false); 8575 if (!NextLB.isUsable()) 8576 return 0; 8577 // UB + ST 8578 NextUB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, UB.get(), ST.get()); 8579 if (!NextUB.isUsable()) 8580 return 0; 8581 // UB = UB + ST 8582 NextUB = 8583 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, UB.get(), NextUB.get()); 8584 NextUB = 8585 SemaRef.ActOnFinishFullExpr(NextUB.get(), /*DiscardedValue*/ false); 8586 if (!NextUB.isUsable()) 8587 return 0; 8588 if (isOpenMPLoopBoundSharingDirective(DKind)) { 8589 CombNextLB = 8590 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, CombLB.get(), ST.get()); 8591 if (!NextLB.isUsable()) 8592 return 0; 8593 // LB = LB + ST 8594 CombNextLB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, CombLB.get(), 8595 CombNextLB.get()); 8596 CombNextLB = SemaRef.ActOnFinishFullExpr(CombNextLB.get(), 8597 /*DiscardedValue*/ false); 8598 if (!CombNextLB.isUsable()) 8599 return 0; 8600 // UB + ST 8601 CombNextUB = 8602 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, CombUB.get(), ST.get()); 8603 if (!CombNextUB.isUsable()) 8604 return 0; 8605 // UB = UB + ST 8606 CombNextUB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, CombUB.get(), 8607 CombNextUB.get()); 8608 CombNextUB = SemaRef.ActOnFinishFullExpr(CombNextUB.get(), 8609 /*DiscardedValue*/ false); 8610 if (!CombNextUB.isUsable()) 8611 return 0; 8612 } 8613 } 8614 8615 // Create increment expression for distribute loop when combined in a same 8616 // directive with for as IV = IV + ST; ensure upper bound expression based 8617 // on PrevUB instead of NumIterations - used to implement 'for' when found 8618 // in combination with 'distribute', like in 'distribute parallel for' 8619 SourceLocation DistIncLoc = AStmt->getBeginLoc(); 8620 ExprResult DistCond, DistInc, PrevEUB, ParForInDistCond; 8621 if (isOpenMPLoopBoundSharingDirective(DKind)) { 8622 DistCond = SemaRef.BuildBinOp( 8623 CurScope, CondLoc, UseStrictCompare ? BO_LT : BO_LE, IV.get(), BoundUB); 8624 assert(DistCond.isUsable() && "distribute cond expr was not built"); 8625 8626 DistInc = 8627 SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Add, IV.get(), ST.get()); 8628 assert(DistInc.isUsable() && "distribute inc expr was not built"); 8629 DistInc = SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Assign, IV.get(), 8630 DistInc.get()); 8631 DistInc = 8632 SemaRef.ActOnFinishFullExpr(DistInc.get(), /*DiscardedValue*/ false); 8633 assert(DistInc.isUsable() && "distribute inc expr was not built"); 8634 8635 // Build expression: UB = min(UB, prevUB) for #for in composite or combined 8636 // construct 8637 SourceLocation DistEUBLoc = AStmt->getBeginLoc(); 8638 ExprResult IsUBGreater = 8639 SemaRef.BuildBinOp(CurScope, DistEUBLoc, BO_GT, UB.get(), PrevUB.get()); 8640 ExprResult CondOp = SemaRef.ActOnConditionalOp( 8641 DistEUBLoc, DistEUBLoc, IsUBGreater.get(), PrevUB.get(), UB.get()); 8642 PrevEUB = SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Assign, UB.get(), 8643 CondOp.get()); 8644 PrevEUB = 8645 SemaRef.ActOnFinishFullExpr(PrevEUB.get(), /*DiscardedValue*/ false); 8646 8647 // Build IV <= PrevUB or IV < PrevUB + 1 for unsigned IV to be used in 8648 // parallel for is in combination with a distribute directive with 8649 // schedule(static, 1) 8650 Expr *BoundPrevUB = PrevUB.get(); 8651 if (UseStrictCompare) { 8652 BoundPrevUB = 8653 SemaRef 8654 .BuildBinOp( 8655 CurScope, CondLoc, BO_Add, BoundPrevUB, 8656 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()) 8657 .get(); 8658 BoundPrevUB = 8659 SemaRef.ActOnFinishFullExpr(BoundPrevUB, /*DiscardedValue*/ false) 8660 .get(); 8661 } 8662 ParForInDistCond = 8663 SemaRef.BuildBinOp(CurScope, CondLoc, UseStrictCompare ? BO_LT : BO_LE, 8664 IV.get(), BoundPrevUB); 8665 } 8666 8667 // Build updates and final values of the loop counters. 8668 bool HasErrors = false; 8669 Built.Counters.resize(NestedLoopCount); 8670 Built.Inits.resize(NestedLoopCount); 8671 Built.Updates.resize(NestedLoopCount); 8672 Built.Finals.resize(NestedLoopCount); 8673 Built.DependentCounters.resize(NestedLoopCount); 8674 Built.DependentInits.resize(NestedLoopCount); 8675 Built.FinalsConditions.resize(NestedLoopCount); 8676 { 8677 // We implement the following algorithm for obtaining the 8678 // original loop iteration variable values based on the 8679 // value of the collapsed loop iteration variable IV. 8680 // 8681 // Let n+1 be the number of collapsed loops in the nest. 8682 // Iteration variables (I0, I1, .... In) 8683 // Iteration counts (N0, N1, ... Nn) 8684 // 8685 // Acc = IV; 8686 // 8687 // To compute Ik for loop k, 0 <= k <= n, generate: 8688 // Prod = N(k+1) * N(k+2) * ... * Nn; 8689 // Ik = Acc / Prod; 8690 // Acc -= Ik * Prod; 8691 // 8692 ExprResult Acc = IV; 8693 for (unsigned int Cnt = 0; Cnt < NestedLoopCount; ++Cnt) { 8694 LoopIterationSpace &IS = IterSpaces[Cnt]; 8695 SourceLocation UpdLoc = IS.IncSrcRange.getBegin(); 8696 ExprResult Iter; 8697 8698 // Compute prod 8699 ExprResult Prod = 8700 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get(); 8701 for (unsigned int K = Cnt+1; K < NestedLoopCount; ++K) 8702 Prod = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Mul, Prod.get(), 8703 IterSpaces[K].NumIterations); 8704 8705 // Iter = Acc / Prod 8706 // If there is at least one more inner loop to avoid 8707 // multiplication by 1. 8708 if (Cnt + 1 < NestedLoopCount) 8709 Iter = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Div, 8710 Acc.get(), Prod.get()); 8711 else 8712 Iter = Acc; 8713 if (!Iter.isUsable()) { 8714 HasErrors = true; 8715 break; 8716 } 8717 8718 // Update Acc: 8719 // Acc -= Iter * Prod 8720 // Check if there is at least one more inner loop to avoid 8721 // multiplication by 1. 8722 if (Cnt + 1 < NestedLoopCount) 8723 Prod = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Mul, 8724 Iter.get(), Prod.get()); 8725 else 8726 Prod = Iter; 8727 Acc = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Sub, 8728 Acc.get(), Prod.get()); 8729 8730 // Build update: IS.CounterVar(Private) = IS.Start + Iter * IS.Step 8731 auto *VD = cast<VarDecl>(cast<DeclRefExpr>(IS.CounterVar)->getDecl()); 8732 DeclRefExpr *CounterVar = buildDeclRefExpr( 8733 SemaRef, VD, IS.CounterVar->getType(), IS.CounterVar->getExprLoc(), 8734 /*RefersToCapture=*/true); 8735 ExprResult Init = 8736 buildCounterInit(SemaRef, CurScope, UpdLoc, CounterVar, 8737 IS.CounterInit, IS.IsNonRectangularLB, Captures); 8738 if (!Init.isUsable()) { 8739 HasErrors = true; 8740 break; 8741 } 8742 ExprResult Update = buildCounterUpdate( 8743 SemaRef, CurScope, UpdLoc, CounterVar, IS.CounterInit, Iter, 8744 IS.CounterStep, IS.Subtract, IS.IsNonRectangularLB, &Captures); 8745 if (!Update.isUsable()) { 8746 HasErrors = true; 8747 break; 8748 } 8749 8750 // Build final: IS.CounterVar = IS.Start + IS.NumIters * IS.Step 8751 ExprResult Final = 8752 buildCounterUpdate(SemaRef, CurScope, UpdLoc, CounterVar, 8753 IS.CounterInit, IS.NumIterations, IS.CounterStep, 8754 IS.Subtract, IS.IsNonRectangularLB, &Captures); 8755 if (!Final.isUsable()) { 8756 HasErrors = true; 8757 break; 8758 } 8759 8760 if (!Update.isUsable() || !Final.isUsable()) { 8761 HasErrors = true; 8762 break; 8763 } 8764 // Save results 8765 Built.Counters[Cnt] = IS.CounterVar; 8766 Built.PrivateCounters[Cnt] = IS.PrivateCounterVar; 8767 Built.Inits[Cnt] = Init.get(); 8768 Built.Updates[Cnt] = Update.get(); 8769 Built.Finals[Cnt] = Final.get(); 8770 Built.DependentCounters[Cnt] = nullptr; 8771 Built.DependentInits[Cnt] = nullptr; 8772 Built.FinalsConditions[Cnt] = nullptr; 8773 if (IS.IsNonRectangularLB || IS.IsNonRectangularUB) { 8774 Built.DependentCounters[Cnt] = 8775 Built.Counters[NestedLoopCount - 1 - IS.LoopDependentIdx]; 8776 Built.DependentInits[Cnt] = 8777 Built.Inits[NestedLoopCount - 1 - IS.LoopDependentIdx]; 8778 Built.FinalsConditions[Cnt] = IS.FinalCondition; 8779 } 8780 } 8781 } 8782 8783 if (HasErrors) 8784 return 0; 8785 8786 // Save results 8787 Built.IterationVarRef = IV.get(); 8788 Built.LastIteration = LastIteration.get(); 8789 Built.NumIterations = NumIterations.get(); 8790 Built.CalcLastIteration = SemaRef 8791 .ActOnFinishFullExpr(CalcLastIteration.get(), 8792 /*DiscardedValue=*/false) 8793 .get(); 8794 Built.PreCond = PreCond.get(); 8795 Built.PreInits = buildPreInits(C, Captures); 8796 Built.Cond = Cond.get(); 8797 Built.Init = Init.get(); 8798 Built.Inc = Inc.get(); 8799 Built.LB = LB.get(); 8800 Built.UB = UB.get(); 8801 Built.IL = IL.get(); 8802 Built.ST = ST.get(); 8803 Built.EUB = EUB.get(); 8804 Built.NLB = NextLB.get(); 8805 Built.NUB = NextUB.get(); 8806 Built.PrevLB = PrevLB.get(); 8807 Built.PrevUB = PrevUB.get(); 8808 Built.DistInc = DistInc.get(); 8809 Built.PrevEUB = PrevEUB.get(); 8810 Built.DistCombinedFields.LB = CombLB.get(); 8811 Built.DistCombinedFields.UB = CombUB.get(); 8812 Built.DistCombinedFields.EUB = CombEUB.get(); 8813 Built.DistCombinedFields.Init = CombInit.get(); 8814 Built.DistCombinedFields.Cond = CombCond.get(); 8815 Built.DistCombinedFields.NLB = CombNextLB.get(); 8816 Built.DistCombinedFields.NUB = CombNextUB.get(); 8817 Built.DistCombinedFields.DistCond = CombDistCond.get(); 8818 Built.DistCombinedFields.ParForInDistCond = ParForInDistCond.get(); 8819 8820 return NestedLoopCount; 8821 } 8822 8823 static Expr *getCollapseNumberExpr(ArrayRef<OMPClause *> Clauses) { 8824 auto CollapseClauses = 8825 OMPExecutableDirective::getClausesOfKind<OMPCollapseClause>(Clauses); 8826 if (CollapseClauses.begin() != CollapseClauses.end()) 8827 return (*CollapseClauses.begin())->getNumForLoops(); 8828 return nullptr; 8829 } 8830 8831 static Expr *getOrderedNumberExpr(ArrayRef<OMPClause *> Clauses) { 8832 auto OrderedClauses = 8833 OMPExecutableDirective::getClausesOfKind<OMPOrderedClause>(Clauses); 8834 if (OrderedClauses.begin() != OrderedClauses.end()) 8835 return (*OrderedClauses.begin())->getNumForLoops(); 8836 return nullptr; 8837 } 8838 8839 static bool checkSimdlenSafelenSpecified(Sema &S, 8840 const ArrayRef<OMPClause *> Clauses) { 8841 const OMPSafelenClause *Safelen = nullptr; 8842 const OMPSimdlenClause *Simdlen = nullptr; 8843 8844 for (const OMPClause *Clause : Clauses) { 8845 if (Clause->getClauseKind() == OMPC_safelen) 8846 Safelen = cast<OMPSafelenClause>(Clause); 8847 else if (Clause->getClauseKind() == OMPC_simdlen) 8848 Simdlen = cast<OMPSimdlenClause>(Clause); 8849 if (Safelen && Simdlen) 8850 break; 8851 } 8852 8853 if (Simdlen && Safelen) { 8854 const Expr *SimdlenLength = Simdlen->getSimdlen(); 8855 const Expr *SafelenLength = Safelen->getSafelen(); 8856 if (SimdlenLength->isValueDependent() || SimdlenLength->isTypeDependent() || 8857 SimdlenLength->isInstantiationDependent() || 8858 SimdlenLength->containsUnexpandedParameterPack()) 8859 return false; 8860 if (SafelenLength->isValueDependent() || SafelenLength->isTypeDependent() || 8861 SafelenLength->isInstantiationDependent() || 8862 SafelenLength->containsUnexpandedParameterPack()) 8863 return false; 8864 Expr::EvalResult SimdlenResult, SafelenResult; 8865 SimdlenLength->EvaluateAsInt(SimdlenResult, S.Context); 8866 SafelenLength->EvaluateAsInt(SafelenResult, S.Context); 8867 llvm::APSInt SimdlenRes = SimdlenResult.Val.getInt(); 8868 llvm::APSInt SafelenRes = SafelenResult.Val.getInt(); 8869 // OpenMP 4.5 [2.8.1, simd Construct, Restrictions] 8870 // If both simdlen and safelen clauses are specified, the value of the 8871 // simdlen parameter must be less than or equal to the value of the safelen 8872 // parameter. 8873 if (SimdlenRes > SafelenRes) { 8874 S.Diag(SimdlenLength->getExprLoc(), 8875 diag::err_omp_wrong_simdlen_safelen_values) 8876 << SimdlenLength->getSourceRange() << SafelenLength->getSourceRange(); 8877 return true; 8878 } 8879 } 8880 return false; 8881 } 8882 8883 StmtResult 8884 Sema::ActOnOpenMPSimdDirective(ArrayRef<OMPClause *> Clauses, Stmt *AStmt, 8885 SourceLocation StartLoc, SourceLocation EndLoc, 8886 VarsWithInheritedDSAType &VarsWithImplicitDSA) { 8887 if (!AStmt) 8888 return StmtError(); 8889 8890 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 8891 OMPLoopDirective::HelperExprs B; 8892 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 8893 // define the nested loops number. 8894 unsigned NestedLoopCount = checkOpenMPLoop( 8895 OMPD_simd, getCollapseNumberExpr(Clauses), getOrderedNumberExpr(Clauses), 8896 AStmt, *this, *DSAStack, VarsWithImplicitDSA, B); 8897 if (NestedLoopCount == 0) 8898 return StmtError(); 8899 8900 assert((CurContext->isDependentContext() || B.builtAll()) && 8901 "omp simd loop exprs were not built"); 8902 8903 if (!CurContext->isDependentContext()) { 8904 // Finalize the clauses that need pre-built expressions for CodeGen. 8905 for (OMPClause *C : Clauses) { 8906 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 8907 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 8908 B.NumIterations, *this, CurScope, 8909 DSAStack)) 8910 return StmtError(); 8911 } 8912 } 8913 8914 if (checkSimdlenSafelenSpecified(*this, Clauses)) 8915 return StmtError(); 8916 8917 setFunctionHasBranchProtectedScope(); 8918 return OMPSimdDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount, 8919 Clauses, AStmt, B); 8920 } 8921 8922 StmtResult 8923 Sema::ActOnOpenMPForDirective(ArrayRef<OMPClause *> Clauses, Stmt *AStmt, 8924 SourceLocation StartLoc, SourceLocation EndLoc, 8925 VarsWithInheritedDSAType &VarsWithImplicitDSA) { 8926 if (!AStmt) 8927 return StmtError(); 8928 8929 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 8930 OMPLoopDirective::HelperExprs B; 8931 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 8932 // define the nested loops number. 8933 unsigned NestedLoopCount = checkOpenMPLoop( 8934 OMPD_for, getCollapseNumberExpr(Clauses), getOrderedNumberExpr(Clauses), 8935 AStmt, *this, *DSAStack, VarsWithImplicitDSA, B); 8936 if (NestedLoopCount == 0) 8937 return StmtError(); 8938 8939 assert((CurContext->isDependentContext() || B.builtAll()) && 8940 "omp for loop exprs were not built"); 8941 8942 if (!CurContext->isDependentContext()) { 8943 // Finalize the clauses that need pre-built expressions for CodeGen. 8944 for (OMPClause *C : Clauses) { 8945 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 8946 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 8947 B.NumIterations, *this, CurScope, 8948 DSAStack)) 8949 return StmtError(); 8950 } 8951 } 8952 8953 setFunctionHasBranchProtectedScope(); 8954 return OMPForDirective::Create( 8955 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B, 8956 DSAStack->getTaskgroupReductionRef(), DSAStack->isCancelRegion()); 8957 } 8958 8959 StmtResult Sema::ActOnOpenMPForSimdDirective( 8960 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 8961 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 8962 if (!AStmt) 8963 return StmtError(); 8964 8965 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 8966 OMPLoopDirective::HelperExprs B; 8967 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 8968 // define the nested loops number. 8969 unsigned NestedLoopCount = 8970 checkOpenMPLoop(OMPD_for_simd, getCollapseNumberExpr(Clauses), 8971 getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack, 8972 VarsWithImplicitDSA, B); 8973 if (NestedLoopCount == 0) 8974 return StmtError(); 8975 8976 assert((CurContext->isDependentContext() || B.builtAll()) && 8977 "omp for simd loop exprs were not built"); 8978 8979 if (!CurContext->isDependentContext()) { 8980 // Finalize the clauses that need pre-built expressions for CodeGen. 8981 for (OMPClause *C : Clauses) { 8982 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 8983 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 8984 B.NumIterations, *this, CurScope, 8985 DSAStack)) 8986 return StmtError(); 8987 } 8988 } 8989 8990 if (checkSimdlenSafelenSpecified(*this, Clauses)) 8991 return StmtError(); 8992 8993 setFunctionHasBranchProtectedScope(); 8994 return OMPForSimdDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount, 8995 Clauses, AStmt, B); 8996 } 8997 8998 StmtResult Sema::ActOnOpenMPSectionsDirective(ArrayRef<OMPClause *> Clauses, 8999 Stmt *AStmt, 9000 SourceLocation StartLoc, 9001 SourceLocation EndLoc) { 9002 if (!AStmt) 9003 return StmtError(); 9004 9005 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 9006 auto BaseStmt = AStmt; 9007 while (auto *CS = dyn_cast_or_null<CapturedStmt>(BaseStmt)) 9008 BaseStmt = CS->getCapturedStmt(); 9009 if (auto *C = dyn_cast_or_null<CompoundStmt>(BaseStmt)) { 9010 auto S = C->children(); 9011 if (S.begin() == S.end()) 9012 return StmtError(); 9013 // All associated statements must be '#pragma omp section' except for 9014 // the first one. 9015 for (Stmt *SectionStmt : llvm::make_range(std::next(S.begin()), S.end())) { 9016 if (!SectionStmt || !isa<OMPSectionDirective>(SectionStmt)) { 9017 if (SectionStmt) 9018 Diag(SectionStmt->getBeginLoc(), 9019 diag::err_omp_sections_substmt_not_section); 9020 return StmtError(); 9021 } 9022 cast<OMPSectionDirective>(SectionStmt) 9023 ->setHasCancel(DSAStack->isCancelRegion()); 9024 } 9025 } else { 9026 Diag(AStmt->getBeginLoc(), diag::err_omp_sections_not_compound_stmt); 9027 return StmtError(); 9028 } 9029 9030 setFunctionHasBranchProtectedScope(); 9031 9032 return OMPSectionsDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt, 9033 DSAStack->getTaskgroupReductionRef(), 9034 DSAStack->isCancelRegion()); 9035 } 9036 9037 StmtResult Sema::ActOnOpenMPSectionDirective(Stmt *AStmt, 9038 SourceLocation StartLoc, 9039 SourceLocation EndLoc) { 9040 if (!AStmt) 9041 return StmtError(); 9042 9043 setFunctionHasBranchProtectedScope(); 9044 DSAStack->setParentCancelRegion(DSAStack->isCancelRegion()); 9045 9046 return OMPSectionDirective::Create(Context, StartLoc, EndLoc, AStmt, 9047 DSAStack->isCancelRegion()); 9048 } 9049 9050 StmtResult Sema::ActOnOpenMPSingleDirective(ArrayRef<OMPClause *> Clauses, 9051 Stmt *AStmt, 9052 SourceLocation StartLoc, 9053 SourceLocation EndLoc) { 9054 if (!AStmt) 9055 return StmtError(); 9056 9057 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 9058 9059 setFunctionHasBranchProtectedScope(); 9060 9061 // OpenMP [2.7.3, single Construct, Restrictions] 9062 // The copyprivate clause must not be used with the nowait clause. 9063 const OMPClause *Nowait = nullptr; 9064 const OMPClause *Copyprivate = nullptr; 9065 for (const OMPClause *Clause : Clauses) { 9066 if (Clause->getClauseKind() == OMPC_nowait) 9067 Nowait = Clause; 9068 else if (Clause->getClauseKind() == OMPC_copyprivate) 9069 Copyprivate = Clause; 9070 if (Copyprivate && Nowait) { 9071 Diag(Copyprivate->getBeginLoc(), 9072 diag::err_omp_single_copyprivate_with_nowait); 9073 Diag(Nowait->getBeginLoc(), diag::note_omp_nowait_clause_here); 9074 return StmtError(); 9075 } 9076 } 9077 9078 return OMPSingleDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt); 9079 } 9080 9081 StmtResult Sema::ActOnOpenMPMasterDirective(Stmt *AStmt, 9082 SourceLocation StartLoc, 9083 SourceLocation EndLoc) { 9084 if (!AStmt) 9085 return StmtError(); 9086 9087 setFunctionHasBranchProtectedScope(); 9088 9089 return OMPMasterDirective::Create(Context, StartLoc, EndLoc, AStmt); 9090 } 9091 9092 StmtResult Sema::ActOnOpenMPCriticalDirective( 9093 const DeclarationNameInfo &DirName, ArrayRef<OMPClause *> Clauses, 9094 Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc) { 9095 if (!AStmt) 9096 return StmtError(); 9097 9098 bool ErrorFound = false; 9099 llvm::APSInt Hint; 9100 SourceLocation HintLoc; 9101 bool DependentHint = false; 9102 for (const OMPClause *C : Clauses) { 9103 if (C->getClauseKind() == OMPC_hint) { 9104 if (!DirName.getName()) { 9105 Diag(C->getBeginLoc(), diag::err_omp_hint_clause_no_name); 9106 ErrorFound = true; 9107 } 9108 Expr *E = cast<OMPHintClause>(C)->getHint(); 9109 if (E->isTypeDependent() || E->isValueDependent() || 9110 E->isInstantiationDependent()) { 9111 DependentHint = true; 9112 } else { 9113 Hint = E->EvaluateKnownConstInt(Context); 9114 HintLoc = C->getBeginLoc(); 9115 } 9116 } 9117 } 9118 if (ErrorFound) 9119 return StmtError(); 9120 const auto Pair = DSAStack->getCriticalWithHint(DirName); 9121 if (Pair.first && DirName.getName() && !DependentHint) { 9122 if (llvm::APSInt::compareValues(Hint, Pair.second) != 0) { 9123 Diag(StartLoc, diag::err_omp_critical_with_hint); 9124 if (HintLoc.isValid()) 9125 Diag(HintLoc, diag::note_omp_critical_hint_here) 9126 << 0 << Hint.toString(/*Radix=*/10, /*Signed=*/false); 9127 else 9128 Diag(StartLoc, diag::note_omp_critical_no_hint) << 0; 9129 if (const auto *C = Pair.first->getSingleClause<OMPHintClause>()) { 9130 Diag(C->getBeginLoc(), diag::note_omp_critical_hint_here) 9131 << 1 9132 << C->getHint()->EvaluateKnownConstInt(Context).toString( 9133 /*Radix=*/10, /*Signed=*/false); 9134 } else { 9135 Diag(Pair.first->getBeginLoc(), diag::note_omp_critical_no_hint) << 1; 9136 } 9137 } 9138 } 9139 9140 setFunctionHasBranchProtectedScope(); 9141 9142 auto *Dir = OMPCriticalDirective::Create(Context, DirName, StartLoc, EndLoc, 9143 Clauses, AStmt); 9144 if (!Pair.first && DirName.getName() && !DependentHint) 9145 DSAStack->addCriticalWithHint(Dir, Hint); 9146 return Dir; 9147 } 9148 9149 StmtResult Sema::ActOnOpenMPParallelForDirective( 9150 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 9151 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 9152 if (!AStmt) 9153 return StmtError(); 9154 9155 auto *CS = cast<CapturedStmt>(AStmt); 9156 // 1.2.2 OpenMP Language Terminology 9157 // Structured block - An executable statement with a single entry at the 9158 // top and a single exit at the bottom. 9159 // The point of exit cannot be a branch out of the structured block. 9160 // longjmp() and throw() must not violate the entry/exit criteria. 9161 CS->getCapturedDecl()->setNothrow(); 9162 9163 OMPLoopDirective::HelperExprs B; 9164 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 9165 // define the nested loops number. 9166 unsigned NestedLoopCount = 9167 checkOpenMPLoop(OMPD_parallel_for, getCollapseNumberExpr(Clauses), 9168 getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack, 9169 VarsWithImplicitDSA, B); 9170 if (NestedLoopCount == 0) 9171 return StmtError(); 9172 9173 assert((CurContext->isDependentContext() || B.builtAll()) && 9174 "omp parallel for loop exprs were not built"); 9175 9176 if (!CurContext->isDependentContext()) { 9177 // Finalize the clauses that need pre-built expressions for CodeGen. 9178 for (OMPClause *C : Clauses) { 9179 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 9180 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 9181 B.NumIterations, *this, CurScope, 9182 DSAStack)) 9183 return StmtError(); 9184 } 9185 } 9186 9187 setFunctionHasBranchProtectedScope(); 9188 return OMPParallelForDirective::Create( 9189 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B, 9190 DSAStack->getTaskgroupReductionRef(), DSAStack->isCancelRegion()); 9191 } 9192 9193 StmtResult Sema::ActOnOpenMPParallelForSimdDirective( 9194 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 9195 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 9196 if (!AStmt) 9197 return StmtError(); 9198 9199 auto *CS = cast<CapturedStmt>(AStmt); 9200 // 1.2.2 OpenMP Language Terminology 9201 // Structured block - An executable statement with a single entry at the 9202 // top and a single exit at the bottom. 9203 // The point of exit cannot be a branch out of the structured block. 9204 // longjmp() and throw() must not violate the entry/exit criteria. 9205 CS->getCapturedDecl()->setNothrow(); 9206 9207 OMPLoopDirective::HelperExprs B; 9208 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 9209 // define the nested loops number. 9210 unsigned NestedLoopCount = 9211 checkOpenMPLoop(OMPD_parallel_for_simd, getCollapseNumberExpr(Clauses), 9212 getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack, 9213 VarsWithImplicitDSA, B); 9214 if (NestedLoopCount == 0) 9215 return StmtError(); 9216 9217 if (!CurContext->isDependentContext()) { 9218 // Finalize the clauses that need pre-built expressions for CodeGen. 9219 for (OMPClause *C : Clauses) { 9220 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 9221 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 9222 B.NumIterations, *this, CurScope, 9223 DSAStack)) 9224 return StmtError(); 9225 } 9226 } 9227 9228 if (checkSimdlenSafelenSpecified(*this, Clauses)) 9229 return StmtError(); 9230 9231 setFunctionHasBranchProtectedScope(); 9232 return OMPParallelForSimdDirective::Create( 9233 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 9234 } 9235 9236 StmtResult 9237 Sema::ActOnOpenMPParallelMasterDirective(ArrayRef<OMPClause *> Clauses, 9238 Stmt *AStmt, SourceLocation StartLoc, 9239 SourceLocation EndLoc) { 9240 if (!AStmt) 9241 return StmtError(); 9242 9243 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 9244 auto *CS = cast<CapturedStmt>(AStmt); 9245 // 1.2.2 OpenMP Language Terminology 9246 // Structured block - An executable statement with a single entry at the 9247 // top and a single exit at the bottom. 9248 // The point of exit cannot be a branch out of the structured block. 9249 // longjmp() and throw() must not violate the entry/exit criteria. 9250 CS->getCapturedDecl()->setNothrow(); 9251 9252 setFunctionHasBranchProtectedScope(); 9253 9254 return OMPParallelMasterDirective::Create( 9255 Context, StartLoc, EndLoc, Clauses, AStmt, 9256 DSAStack->getTaskgroupReductionRef()); 9257 } 9258 9259 StmtResult 9260 Sema::ActOnOpenMPParallelSectionsDirective(ArrayRef<OMPClause *> Clauses, 9261 Stmt *AStmt, SourceLocation StartLoc, 9262 SourceLocation EndLoc) { 9263 if (!AStmt) 9264 return StmtError(); 9265 9266 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 9267 auto BaseStmt = AStmt; 9268 while (auto *CS = dyn_cast_or_null<CapturedStmt>(BaseStmt)) 9269 BaseStmt = CS->getCapturedStmt(); 9270 if (auto *C = dyn_cast_or_null<CompoundStmt>(BaseStmt)) { 9271 auto S = C->children(); 9272 if (S.begin() == S.end()) 9273 return StmtError(); 9274 // All associated statements must be '#pragma omp section' except for 9275 // the first one. 9276 for (Stmt *SectionStmt : llvm::make_range(std::next(S.begin()), S.end())) { 9277 if (!SectionStmt || !isa<OMPSectionDirective>(SectionStmt)) { 9278 if (SectionStmt) 9279 Diag(SectionStmt->getBeginLoc(), 9280 diag::err_omp_parallel_sections_substmt_not_section); 9281 return StmtError(); 9282 } 9283 cast<OMPSectionDirective>(SectionStmt) 9284 ->setHasCancel(DSAStack->isCancelRegion()); 9285 } 9286 } else { 9287 Diag(AStmt->getBeginLoc(), 9288 diag::err_omp_parallel_sections_not_compound_stmt); 9289 return StmtError(); 9290 } 9291 9292 setFunctionHasBranchProtectedScope(); 9293 9294 return OMPParallelSectionsDirective::Create( 9295 Context, StartLoc, EndLoc, Clauses, AStmt, 9296 DSAStack->getTaskgroupReductionRef(), DSAStack->isCancelRegion()); 9297 } 9298 9299 /// detach and mergeable clauses are mutially exclusive, check for it. 9300 static bool checkDetachMergeableClauses(Sema &S, 9301 ArrayRef<OMPClause *> Clauses) { 9302 const OMPClause *PrevClause = nullptr; 9303 bool ErrorFound = false; 9304 for (const OMPClause *C : Clauses) { 9305 if (C->getClauseKind() == OMPC_detach || 9306 C->getClauseKind() == OMPC_mergeable) { 9307 if (!PrevClause) { 9308 PrevClause = C; 9309 } else if (PrevClause->getClauseKind() != C->getClauseKind()) { 9310 S.Diag(C->getBeginLoc(), diag::err_omp_clauses_mutually_exclusive) 9311 << getOpenMPClauseName(C->getClauseKind()) 9312 << getOpenMPClauseName(PrevClause->getClauseKind()); 9313 S.Diag(PrevClause->getBeginLoc(), diag::note_omp_previous_clause) 9314 << getOpenMPClauseName(PrevClause->getClauseKind()); 9315 ErrorFound = true; 9316 } 9317 } 9318 } 9319 return ErrorFound; 9320 } 9321 9322 StmtResult Sema::ActOnOpenMPTaskDirective(ArrayRef<OMPClause *> Clauses, 9323 Stmt *AStmt, SourceLocation StartLoc, 9324 SourceLocation EndLoc) { 9325 if (!AStmt) 9326 return StmtError(); 9327 9328 // OpenMP 5.0, 2.10.1 task Construct 9329 // If a detach clause appears on the directive, then a mergeable clause cannot 9330 // appear on the same directive. 9331 if (checkDetachMergeableClauses(*this, Clauses)) 9332 return StmtError(); 9333 9334 auto *CS = cast<CapturedStmt>(AStmt); 9335 // 1.2.2 OpenMP Language Terminology 9336 // Structured block - An executable statement with a single entry at the 9337 // top and a single exit at the bottom. 9338 // The point of exit cannot be a branch out of the structured block. 9339 // longjmp() and throw() must not violate the entry/exit criteria. 9340 CS->getCapturedDecl()->setNothrow(); 9341 9342 setFunctionHasBranchProtectedScope(); 9343 9344 return OMPTaskDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt, 9345 DSAStack->isCancelRegion()); 9346 } 9347 9348 StmtResult Sema::ActOnOpenMPTaskyieldDirective(SourceLocation StartLoc, 9349 SourceLocation EndLoc) { 9350 return OMPTaskyieldDirective::Create(Context, StartLoc, EndLoc); 9351 } 9352 9353 StmtResult Sema::ActOnOpenMPBarrierDirective(SourceLocation StartLoc, 9354 SourceLocation EndLoc) { 9355 return OMPBarrierDirective::Create(Context, StartLoc, EndLoc); 9356 } 9357 9358 StmtResult Sema::ActOnOpenMPTaskwaitDirective(SourceLocation StartLoc, 9359 SourceLocation EndLoc) { 9360 return OMPTaskwaitDirective::Create(Context, StartLoc, EndLoc); 9361 } 9362 9363 StmtResult Sema::ActOnOpenMPTaskgroupDirective(ArrayRef<OMPClause *> Clauses, 9364 Stmt *AStmt, 9365 SourceLocation StartLoc, 9366 SourceLocation EndLoc) { 9367 if (!AStmt) 9368 return StmtError(); 9369 9370 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 9371 9372 setFunctionHasBranchProtectedScope(); 9373 9374 return OMPTaskgroupDirective::Create(Context, StartLoc, EndLoc, Clauses, 9375 AStmt, 9376 DSAStack->getTaskgroupReductionRef()); 9377 } 9378 9379 StmtResult Sema::ActOnOpenMPFlushDirective(ArrayRef<OMPClause *> Clauses, 9380 SourceLocation StartLoc, 9381 SourceLocation EndLoc) { 9382 OMPFlushClause *FC = nullptr; 9383 OMPClause *OrderClause = nullptr; 9384 for (OMPClause *C : Clauses) { 9385 if (C->getClauseKind() == OMPC_flush) 9386 FC = cast<OMPFlushClause>(C); 9387 else 9388 OrderClause = C; 9389 } 9390 OpenMPClauseKind MemOrderKind = OMPC_unknown; 9391 SourceLocation MemOrderLoc; 9392 for (const OMPClause *C : Clauses) { 9393 if (C->getClauseKind() == OMPC_acq_rel || 9394 C->getClauseKind() == OMPC_acquire || 9395 C->getClauseKind() == OMPC_release) { 9396 if (MemOrderKind != OMPC_unknown) { 9397 Diag(C->getBeginLoc(), diag::err_omp_several_mem_order_clauses) 9398 << getOpenMPDirectiveName(OMPD_flush) << 1 9399 << SourceRange(C->getBeginLoc(), C->getEndLoc()); 9400 Diag(MemOrderLoc, diag::note_omp_previous_mem_order_clause) 9401 << getOpenMPClauseName(MemOrderKind); 9402 } else { 9403 MemOrderKind = C->getClauseKind(); 9404 MemOrderLoc = C->getBeginLoc(); 9405 } 9406 } 9407 } 9408 if (FC && OrderClause) { 9409 Diag(FC->getLParenLoc(), diag::err_omp_flush_order_clause_and_list) 9410 << getOpenMPClauseName(OrderClause->getClauseKind()); 9411 Diag(OrderClause->getBeginLoc(), diag::note_omp_flush_order_clause_here) 9412 << getOpenMPClauseName(OrderClause->getClauseKind()); 9413 return StmtError(); 9414 } 9415 return OMPFlushDirective::Create(Context, StartLoc, EndLoc, Clauses); 9416 } 9417 9418 StmtResult Sema::ActOnOpenMPDepobjDirective(ArrayRef<OMPClause *> Clauses, 9419 SourceLocation StartLoc, 9420 SourceLocation EndLoc) { 9421 if (Clauses.empty()) { 9422 Diag(StartLoc, diag::err_omp_depobj_expected); 9423 return StmtError(); 9424 } else if (Clauses[0]->getClauseKind() != OMPC_depobj) { 9425 Diag(Clauses[0]->getBeginLoc(), diag::err_omp_depobj_expected); 9426 return StmtError(); 9427 } 9428 // Only depobj expression and another single clause is allowed. 9429 if (Clauses.size() > 2) { 9430 Diag(Clauses[2]->getBeginLoc(), 9431 diag::err_omp_depobj_single_clause_expected); 9432 return StmtError(); 9433 } else if (Clauses.size() < 1) { 9434 Diag(Clauses[0]->getEndLoc(), diag::err_omp_depobj_single_clause_expected); 9435 return StmtError(); 9436 } 9437 return OMPDepobjDirective::Create(Context, StartLoc, EndLoc, Clauses); 9438 } 9439 9440 StmtResult Sema::ActOnOpenMPScanDirective(ArrayRef<OMPClause *> Clauses, 9441 SourceLocation StartLoc, 9442 SourceLocation EndLoc) { 9443 // Check that exactly one clause is specified. 9444 if (Clauses.size() != 1) { 9445 Diag(Clauses.empty() ? EndLoc : Clauses[1]->getBeginLoc(), 9446 diag::err_omp_scan_single_clause_expected); 9447 return StmtError(); 9448 } 9449 // Check that scan directive is used in the scopeof the OpenMP loop body. 9450 if (Scope *S = DSAStack->getCurScope()) { 9451 Scope *ParentS = S->getParent(); 9452 if (!ParentS || ParentS->getParent() != ParentS->getBreakParent() || 9453 !ParentS->getBreakParent()->isOpenMPLoopScope()) 9454 return StmtError(Diag(StartLoc, diag::err_omp_orphaned_device_directive) 9455 << getOpenMPDirectiveName(OMPD_scan) << 5); 9456 } 9457 // Check that only one instance of scan directives is used in the same outer 9458 // region. 9459 if (DSAStack->doesParentHasScanDirective()) { 9460 Diag(StartLoc, diag::err_omp_several_directives_in_region) << "scan"; 9461 Diag(DSAStack->getParentScanDirectiveLoc(), 9462 diag::note_omp_previous_directive) 9463 << "scan"; 9464 return StmtError(); 9465 } 9466 DSAStack->setParentHasScanDirective(StartLoc); 9467 return OMPScanDirective::Create(Context, StartLoc, EndLoc, Clauses); 9468 } 9469 9470 StmtResult Sema::ActOnOpenMPOrderedDirective(ArrayRef<OMPClause *> Clauses, 9471 Stmt *AStmt, 9472 SourceLocation StartLoc, 9473 SourceLocation EndLoc) { 9474 const OMPClause *DependFound = nullptr; 9475 const OMPClause *DependSourceClause = nullptr; 9476 const OMPClause *DependSinkClause = nullptr; 9477 bool ErrorFound = false; 9478 const OMPThreadsClause *TC = nullptr; 9479 const OMPSIMDClause *SC = nullptr; 9480 for (const OMPClause *C : Clauses) { 9481 if (auto *DC = dyn_cast<OMPDependClause>(C)) { 9482 DependFound = C; 9483 if (DC->getDependencyKind() == OMPC_DEPEND_source) { 9484 if (DependSourceClause) { 9485 Diag(C->getBeginLoc(), diag::err_omp_more_one_clause) 9486 << getOpenMPDirectiveName(OMPD_ordered) 9487 << getOpenMPClauseName(OMPC_depend) << 2; 9488 ErrorFound = true; 9489 } else { 9490 DependSourceClause = C; 9491 } 9492 if (DependSinkClause) { 9493 Diag(C->getBeginLoc(), diag::err_omp_depend_sink_source_not_allowed) 9494 << 0; 9495 ErrorFound = true; 9496 } 9497 } else if (DC->getDependencyKind() == OMPC_DEPEND_sink) { 9498 if (DependSourceClause) { 9499 Diag(C->getBeginLoc(), diag::err_omp_depend_sink_source_not_allowed) 9500 << 1; 9501 ErrorFound = true; 9502 } 9503 DependSinkClause = C; 9504 } 9505 } else if (C->getClauseKind() == OMPC_threads) { 9506 TC = cast<OMPThreadsClause>(C); 9507 } else if (C->getClauseKind() == OMPC_simd) { 9508 SC = cast<OMPSIMDClause>(C); 9509 } 9510 } 9511 if (!ErrorFound && !SC && 9512 isOpenMPSimdDirective(DSAStack->getParentDirective())) { 9513 // OpenMP [2.8.1,simd Construct, Restrictions] 9514 // An ordered construct with the simd clause is the only OpenMP construct 9515 // that can appear in the simd region. 9516 Diag(StartLoc, diag::err_omp_prohibited_region_simd) 9517 << (LangOpts.OpenMP >= 50 ? 1 : 0); 9518 ErrorFound = true; 9519 } else if (DependFound && (TC || SC)) { 9520 Diag(DependFound->getBeginLoc(), diag::err_omp_depend_clause_thread_simd) 9521 << getOpenMPClauseName(TC ? TC->getClauseKind() : SC->getClauseKind()); 9522 ErrorFound = true; 9523 } else if (DependFound && !DSAStack->getParentOrderedRegionParam().first) { 9524 Diag(DependFound->getBeginLoc(), 9525 diag::err_omp_ordered_directive_without_param); 9526 ErrorFound = true; 9527 } else if (TC || Clauses.empty()) { 9528 if (const Expr *Param = DSAStack->getParentOrderedRegionParam().first) { 9529 SourceLocation ErrLoc = TC ? TC->getBeginLoc() : StartLoc; 9530 Diag(ErrLoc, diag::err_omp_ordered_directive_with_param) 9531 << (TC != nullptr); 9532 Diag(Param->getBeginLoc(), diag::note_omp_ordered_param) << 1; 9533 ErrorFound = true; 9534 } 9535 } 9536 if ((!AStmt && !DependFound) || ErrorFound) 9537 return StmtError(); 9538 9539 // OpenMP 5.0, 2.17.9, ordered Construct, Restrictions. 9540 // During execution of an iteration of a worksharing-loop or a loop nest 9541 // within a worksharing-loop, simd, or worksharing-loop SIMD region, a thread 9542 // must not execute more than one ordered region corresponding to an ordered 9543 // construct without a depend clause. 9544 if (!DependFound) { 9545 if (DSAStack->doesParentHasOrderedDirective()) { 9546 Diag(StartLoc, diag::err_omp_several_directives_in_region) << "ordered"; 9547 Diag(DSAStack->getParentOrderedDirectiveLoc(), 9548 diag::note_omp_previous_directive) 9549 << "ordered"; 9550 return StmtError(); 9551 } 9552 DSAStack->setParentHasOrderedDirective(StartLoc); 9553 } 9554 9555 if (AStmt) { 9556 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 9557 9558 setFunctionHasBranchProtectedScope(); 9559 } 9560 9561 return OMPOrderedDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt); 9562 } 9563 9564 namespace { 9565 /// Helper class for checking expression in 'omp atomic [update]' 9566 /// construct. 9567 class OpenMPAtomicUpdateChecker { 9568 /// Error results for atomic update expressions. 9569 enum ExprAnalysisErrorCode { 9570 /// A statement is not an expression statement. 9571 NotAnExpression, 9572 /// Expression is not builtin binary or unary operation. 9573 NotABinaryOrUnaryExpression, 9574 /// Unary operation is not post-/pre- increment/decrement operation. 9575 NotAnUnaryIncDecExpression, 9576 /// An expression is not of scalar type. 9577 NotAScalarType, 9578 /// A binary operation is not an assignment operation. 9579 NotAnAssignmentOp, 9580 /// RHS part of the binary operation is not a binary expression. 9581 NotABinaryExpression, 9582 /// RHS part is not additive/multiplicative/shift/biwise binary 9583 /// expression. 9584 NotABinaryOperator, 9585 /// RHS binary operation does not have reference to the updated LHS 9586 /// part. 9587 NotAnUpdateExpression, 9588 /// No errors is found. 9589 NoError 9590 }; 9591 /// Reference to Sema. 9592 Sema &SemaRef; 9593 /// A location for note diagnostics (when error is found). 9594 SourceLocation NoteLoc; 9595 /// 'x' lvalue part of the source atomic expression. 9596 Expr *X; 9597 /// 'expr' rvalue part of the source atomic expression. 9598 Expr *E; 9599 /// Helper expression of the form 9600 /// 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or 9601 /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'. 9602 Expr *UpdateExpr; 9603 /// Is 'x' a LHS in a RHS part of full update expression. It is 9604 /// important for non-associative operations. 9605 bool IsXLHSInRHSPart; 9606 BinaryOperatorKind Op; 9607 SourceLocation OpLoc; 9608 /// true if the source expression is a postfix unary operation, false 9609 /// if it is a prefix unary operation. 9610 bool IsPostfixUpdate; 9611 9612 public: 9613 OpenMPAtomicUpdateChecker(Sema &SemaRef) 9614 : SemaRef(SemaRef), X(nullptr), E(nullptr), UpdateExpr(nullptr), 9615 IsXLHSInRHSPart(false), Op(BO_PtrMemD), IsPostfixUpdate(false) {} 9616 /// Check specified statement that it is suitable for 'atomic update' 9617 /// constructs and extract 'x', 'expr' and Operation from the original 9618 /// expression. If DiagId and NoteId == 0, then only check is performed 9619 /// without error notification. 9620 /// \param DiagId Diagnostic which should be emitted if error is found. 9621 /// \param NoteId Diagnostic note for the main error message. 9622 /// \return true if statement is not an update expression, false otherwise. 9623 bool checkStatement(Stmt *S, unsigned DiagId = 0, unsigned NoteId = 0); 9624 /// Return the 'x' lvalue part of the source atomic expression. 9625 Expr *getX() const { return X; } 9626 /// Return the 'expr' rvalue part of the source atomic expression. 9627 Expr *getExpr() const { return E; } 9628 /// Return the update expression used in calculation of the updated 9629 /// value. Always has form 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or 9630 /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'. 9631 Expr *getUpdateExpr() const { return UpdateExpr; } 9632 /// Return true if 'x' is LHS in RHS part of full update expression, 9633 /// false otherwise. 9634 bool isXLHSInRHSPart() const { return IsXLHSInRHSPart; } 9635 9636 /// true if the source expression is a postfix unary operation, false 9637 /// if it is a prefix unary operation. 9638 bool isPostfixUpdate() const { return IsPostfixUpdate; } 9639 9640 private: 9641 bool checkBinaryOperation(BinaryOperator *AtomicBinOp, unsigned DiagId = 0, 9642 unsigned NoteId = 0); 9643 }; 9644 } // namespace 9645 9646 bool OpenMPAtomicUpdateChecker::checkBinaryOperation( 9647 BinaryOperator *AtomicBinOp, unsigned DiagId, unsigned NoteId) { 9648 ExprAnalysisErrorCode ErrorFound = NoError; 9649 SourceLocation ErrorLoc, NoteLoc; 9650 SourceRange ErrorRange, NoteRange; 9651 // Allowed constructs are: 9652 // x = x binop expr; 9653 // x = expr binop x; 9654 if (AtomicBinOp->getOpcode() == BO_Assign) { 9655 X = AtomicBinOp->getLHS(); 9656 if (const auto *AtomicInnerBinOp = dyn_cast<BinaryOperator>( 9657 AtomicBinOp->getRHS()->IgnoreParenImpCasts())) { 9658 if (AtomicInnerBinOp->isMultiplicativeOp() || 9659 AtomicInnerBinOp->isAdditiveOp() || AtomicInnerBinOp->isShiftOp() || 9660 AtomicInnerBinOp->isBitwiseOp()) { 9661 Op = AtomicInnerBinOp->getOpcode(); 9662 OpLoc = AtomicInnerBinOp->getOperatorLoc(); 9663 Expr *LHS = AtomicInnerBinOp->getLHS(); 9664 Expr *RHS = AtomicInnerBinOp->getRHS(); 9665 llvm::FoldingSetNodeID XId, LHSId, RHSId; 9666 X->IgnoreParenImpCasts()->Profile(XId, SemaRef.getASTContext(), 9667 /*Canonical=*/true); 9668 LHS->IgnoreParenImpCasts()->Profile(LHSId, SemaRef.getASTContext(), 9669 /*Canonical=*/true); 9670 RHS->IgnoreParenImpCasts()->Profile(RHSId, SemaRef.getASTContext(), 9671 /*Canonical=*/true); 9672 if (XId == LHSId) { 9673 E = RHS; 9674 IsXLHSInRHSPart = true; 9675 } else if (XId == RHSId) { 9676 E = LHS; 9677 IsXLHSInRHSPart = false; 9678 } else { 9679 ErrorLoc = AtomicInnerBinOp->getExprLoc(); 9680 ErrorRange = AtomicInnerBinOp->getSourceRange(); 9681 NoteLoc = X->getExprLoc(); 9682 NoteRange = X->getSourceRange(); 9683 ErrorFound = NotAnUpdateExpression; 9684 } 9685 } else { 9686 ErrorLoc = AtomicInnerBinOp->getExprLoc(); 9687 ErrorRange = AtomicInnerBinOp->getSourceRange(); 9688 NoteLoc = AtomicInnerBinOp->getOperatorLoc(); 9689 NoteRange = SourceRange(NoteLoc, NoteLoc); 9690 ErrorFound = NotABinaryOperator; 9691 } 9692 } else { 9693 NoteLoc = ErrorLoc = AtomicBinOp->getRHS()->getExprLoc(); 9694 NoteRange = ErrorRange = AtomicBinOp->getRHS()->getSourceRange(); 9695 ErrorFound = NotABinaryExpression; 9696 } 9697 } else { 9698 ErrorLoc = AtomicBinOp->getExprLoc(); 9699 ErrorRange = AtomicBinOp->getSourceRange(); 9700 NoteLoc = AtomicBinOp->getOperatorLoc(); 9701 NoteRange = SourceRange(NoteLoc, NoteLoc); 9702 ErrorFound = NotAnAssignmentOp; 9703 } 9704 if (ErrorFound != NoError && DiagId != 0 && NoteId != 0) { 9705 SemaRef.Diag(ErrorLoc, DiagId) << ErrorRange; 9706 SemaRef.Diag(NoteLoc, NoteId) << ErrorFound << NoteRange; 9707 return true; 9708 } 9709 if (SemaRef.CurContext->isDependentContext()) 9710 E = X = UpdateExpr = nullptr; 9711 return ErrorFound != NoError; 9712 } 9713 9714 bool OpenMPAtomicUpdateChecker::checkStatement(Stmt *S, unsigned DiagId, 9715 unsigned NoteId) { 9716 ExprAnalysisErrorCode ErrorFound = NoError; 9717 SourceLocation ErrorLoc, NoteLoc; 9718 SourceRange ErrorRange, NoteRange; 9719 // Allowed constructs are: 9720 // x++; 9721 // x--; 9722 // ++x; 9723 // --x; 9724 // x binop= expr; 9725 // x = x binop expr; 9726 // x = expr binop x; 9727 if (auto *AtomicBody = dyn_cast<Expr>(S)) { 9728 AtomicBody = AtomicBody->IgnoreParenImpCasts(); 9729 if (AtomicBody->getType()->isScalarType() || 9730 AtomicBody->isInstantiationDependent()) { 9731 if (const auto *AtomicCompAssignOp = dyn_cast<CompoundAssignOperator>( 9732 AtomicBody->IgnoreParenImpCasts())) { 9733 // Check for Compound Assignment Operation 9734 Op = BinaryOperator::getOpForCompoundAssignment( 9735 AtomicCompAssignOp->getOpcode()); 9736 OpLoc = AtomicCompAssignOp->getOperatorLoc(); 9737 E = AtomicCompAssignOp->getRHS(); 9738 X = AtomicCompAssignOp->getLHS()->IgnoreParens(); 9739 IsXLHSInRHSPart = true; 9740 } else if (auto *AtomicBinOp = dyn_cast<BinaryOperator>( 9741 AtomicBody->IgnoreParenImpCasts())) { 9742 // Check for Binary Operation 9743 if (checkBinaryOperation(AtomicBinOp, DiagId, NoteId)) 9744 return true; 9745 } else if (const auto *AtomicUnaryOp = dyn_cast<UnaryOperator>( 9746 AtomicBody->IgnoreParenImpCasts())) { 9747 // Check for Unary Operation 9748 if (AtomicUnaryOp->isIncrementDecrementOp()) { 9749 IsPostfixUpdate = AtomicUnaryOp->isPostfix(); 9750 Op = AtomicUnaryOp->isIncrementOp() ? BO_Add : BO_Sub; 9751 OpLoc = AtomicUnaryOp->getOperatorLoc(); 9752 X = AtomicUnaryOp->getSubExpr()->IgnoreParens(); 9753 E = SemaRef.ActOnIntegerConstant(OpLoc, /*uint64_t Val=*/1).get(); 9754 IsXLHSInRHSPart = true; 9755 } else { 9756 ErrorFound = NotAnUnaryIncDecExpression; 9757 ErrorLoc = AtomicUnaryOp->getExprLoc(); 9758 ErrorRange = AtomicUnaryOp->getSourceRange(); 9759 NoteLoc = AtomicUnaryOp->getOperatorLoc(); 9760 NoteRange = SourceRange(NoteLoc, NoteLoc); 9761 } 9762 } else if (!AtomicBody->isInstantiationDependent()) { 9763 ErrorFound = NotABinaryOrUnaryExpression; 9764 NoteLoc = ErrorLoc = AtomicBody->getExprLoc(); 9765 NoteRange = ErrorRange = AtomicBody->getSourceRange(); 9766 } 9767 } else { 9768 ErrorFound = NotAScalarType; 9769 NoteLoc = ErrorLoc = AtomicBody->getBeginLoc(); 9770 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc); 9771 } 9772 } else { 9773 ErrorFound = NotAnExpression; 9774 NoteLoc = ErrorLoc = S->getBeginLoc(); 9775 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc); 9776 } 9777 if (ErrorFound != NoError && DiagId != 0 && NoteId != 0) { 9778 SemaRef.Diag(ErrorLoc, DiagId) << ErrorRange; 9779 SemaRef.Diag(NoteLoc, NoteId) << ErrorFound << NoteRange; 9780 return true; 9781 } 9782 if (SemaRef.CurContext->isDependentContext()) 9783 E = X = UpdateExpr = nullptr; 9784 if (ErrorFound == NoError && E && X) { 9785 // Build an update expression of form 'OpaqueValueExpr(x) binop 9786 // OpaqueValueExpr(expr)' or 'OpaqueValueExpr(expr) binop 9787 // OpaqueValueExpr(x)' and then cast it to the type of the 'x' expression. 9788 auto *OVEX = new (SemaRef.getASTContext()) 9789 OpaqueValueExpr(X->getExprLoc(), X->getType(), VK_RValue); 9790 auto *OVEExpr = new (SemaRef.getASTContext()) 9791 OpaqueValueExpr(E->getExprLoc(), E->getType(), VK_RValue); 9792 ExprResult Update = 9793 SemaRef.CreateBuiltinBinOp(OpLoc, Op, IsXLHSInRHSPart ? OVEX : OVEExpr, 9794 IsXLHSInRHSPart ? OVEExpr : OVEX); 9795 if (Update.isInvalid()) 9796 return true; 9797 Update = SemaRef.PerformImplicitConversion(Update.get(), X->getType(), 9798 Sema::AA_Casting); 9799 if (Update.isInvalid()) 9800 return true; 9801 UpdateExpr = Update.get(); 9802 } 9803 return ErrorFound != NoError; 9804 } 9805 9806 StmtResult Sema::ActOnOpenMPAtomicDirective(ArrayRef<OMPClause *> Clauses, 9807 Stmt *AStmt, 9808 SourceLocation StartLoc, 9809 SourceLocation EndLoc) { 9810 // Register location of the first atomic directive. 9811 DSAStack->addAtomicDirectiveLoc(StartLoc); 9812 if (!AStmt) 9813 return StmtError(); 9814 9815 // 1.2.2 OpenMP Language Terminology 9816 // Structured block - An executable statement with a single entry at the 9817 // top and a single exit at the bottom. 9818 // The point of exit cannot be a branch out of the structured block. 9819 // longjmp() and throw() must not violate the entry/exit criteria. 9820 OpenMPClauseKind AtomicKind = OMPC_unknown; 9821 SourceLocation AtomicKindLoc; 9822 OpenMPClauseKind MemOrderKind = OMPC_unknown; 9823 SourceLocation MemOrderLoc; 9824 for (const OMPClause *C : Clauses) { 9825 if (C->getClauseKind() == OMPC_read || C->getClauseKind() == OMPC_write || 9826 C->getClauseKind() == OMPC_update || 9827 C->getClauseKind() == OMPC_capture) { 9828 if (AtomicKind != OMPC_unknown) { 9829 Diag(C->getBeginLoc(), diag::err_omp_atomic_several_clauses) 9830 << SourceRange(C->getBeginLoc(), C->getEndLoc()); 9831 Diag(AtomicKindLoc, diag::note_omp_previous_mem_order_clause) 9832 << getOpenMPClauseName(AtomicKind); 9833 } else { 9834 AtomicKind = C->getClauseKind(); 9835 AtomicKindLoc = C->getBeginLoc(); 9836 } 9837 } 9838 if (C->getClauseKind() == OMPC_seq_cst || 9839 C->getClauseKind() == OMPC_acq_rel || 9840 C->getClauseKind() == OMPC_acquire || 9841 C->getClauseKind() == OMPC_release || 9842 C->getClauseKind() == OMPC_relaxed) { 9843 if (MemOrderKind != OMPC_unknown) { 9844 Diag(C->getBeginLoc(), diag::err_omp_several_mem_order_clauses) 9845 << getOpenMPDirectiveName(OMPD_atomic) << 0 9846 << SourceRange(C->getBeginLoc(), C->getEndLoc()); 9847 Diag(MemOrderLoc, diag::note_omp_previous_mem_order_clause) 9848 << getOpenMPClauseName(MemOrderKind); 9849 } else { 9850 MemOrderKind = C->getClauseKind(); 9851 MemOrderLoc = C->getBeginLoc(); 9852 } 9853 } 9854 } 9855 // OpenMP 5.0, 2.17.7 atomic Construct, Restrictions 9856 // If atomic-clause is read then memory-order-clause must not be acq_rel or 9857 // release. 9858 // If atomic-clause is write then memory-order-clause must not be acq_rel or 9859 // acquire. 9860 // If atomic-clause is update or not present then memory-order-clause must not 9861 // be acq_rel or acquire. 9862 if ((AtomicKind == OMPC_read && 9863 (MemOrderKind == OMPC_acq_rel || MemOrderKind == OMPC_release)) || 9864 ((AtomicKind == OMPC_write || AtomicKind == OMPC_update || 9865 AtomicKind == OMPC_unknown) && 9866 (MemOrderKind == OMPC_acq_rel || MemOrderKind == OMPC_acquire))) { 9867 SourceLocation Loc = AtomicKindLoc; 9868 if (AtomicKind == OMPC_unknown) 9869 Loc = StartLoc; 9870 Diag(Loc, diag::err_omp_atomic_incompatible_mem_order_clause) 9871 << getOpenMPClauseName(AtomicKind) 9872 << (AtomicKind == OMPC_unknown ? 1 : 0) 9873 << getOpenMPClauseName(MemOrderKind); 9874 Diag(MemOrderLoc, diag::note_omp_previous_mem_order_clause) 9875 << getOpenMPClauseName(MemOrderKind); 9876 } 9877 9878 Stmt *Body = AStmt; 9879 if (auto *EWC = dyn_cast<ExprWithCleanups>(Body)) 9880 Body = EWC->getSubExpr(); 9881 9882 Expr *X = nullptr; 9883 Expr *V = nullptr; 9884 Expr *E = nullptr; 9885 Expr *UE = nullptr; 9886 bool IsXLHSInRHSPart = false; 9887 bool IsPostfixUpdate = false; 9888 // OpenMP [2.12.6, atomic Construct] 9889 // In the next expressions: 9890 // * x and v (as applicable) are both l-value expressions with scalar type. 9891 // * During the execution of an atomic region, multiple syntactic 9892 // occurrences of x must designate the same storage location. 9893 // * Neither of v and expr (as applicable) may access the storage location 9894 // designated by x. 9895 // * Neither of x and expr (as applicable) may access the storage location 9896 // designated by v. 9897 // * expr is an expression with scalar type. 9898 // * binop is one of +, *, -, /, &, ^, |, <<, or >>. 9899 // * binop, binop=, ++, and -- are not overloaded operators. 9900 // * The expression x binop expr must be numerically equivalent to x binop 9901 // (expr). This requirement is satisfied if the operators in expr have 9902 // precedence greater than binop, or by using parentheses around expr or 9903 // subexpressions of expr. 9904 // * The expression expr binop x must be numerically equivalent to (expr) 9905 // binop x. This requirement is satisfied if the operators in expr have 9906 // precedence equal to or greater than binop, or by using parentheses around 9907 // expr or subexpressions of expr. 9908 // * For forms that allow multiple occurrences of x, the number of times 9909 // that x is evaluated is unspecified. 9910 if (AtomicKind == OMPC_read) { 9911 enum { 9912 NotAnExpression, 9913 NotAnAssignmentOp, 9914 NotAScalarType, 9915 NotAnLValue, 9916 NoError 9917 } ErrorFound = NoError; 9918 SourceLocation ErrorLoc, NoteLoc; 9919 SourceRange ErrorRange, NoteRange; 9920 // If clause is read: 9921 // v = x; 9922 if (const auto *AtomicBody = dyn_cast<Expr>(Body)) { 9923 const auto *AtomicBinOp = 9924 dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts()); 9925 if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) { 9926 X = AtomicBinOp->getRHS()->IgnoreParenImpCasts(); 9927 V = AtomicBinOp->getLHS()->IgnoreParenImpCasts(); 9928 if ((X->isInstantiationDependent() || X->getType()->isScalarType()) && 9929 (V->isInstantiationDependent() || V->getType()->isScalarType())) { 9930 if (!X->isLValue() || !V->isLValue()) { 9931 const Expr *NotLValueExpr = X->isLValue() ? V : X; 9932 ErrorFound = NotAnLValue; 9933 ErrorLoc = AtomicBinOp->getExprLoc(); 9934 ErrorRange = AtomicBinOp->getSourceRange(); 9935 NoteLoc = NotLValueExpr->getExprLoc(); 9936 NoteRange = NotLValueExpr->getSourceRange(); 9937 } 9938 } else if (!X->isInstantiationDependent() || 9939 !V->isInstantiationDependent()) { 9940 const Expr *NotScalarExpr = 9941 (X->isInstantiationDependent() || X->getType()->isScalarType()) 9942 ? V 9943 : X; 9944 ErrorFound = NotAScalarType; 9945 ErrorLoc = AtomicBinOp->getExprLoc(); 9946 ErrorRange = AtomicBinOp->getSourceRange(); 9947 NoteLoc = NotScalarExpr->getExprLoc(); 9948 NoteRange = NotScalarExpr->getSourceRange(); 9949 } 9950 } else if (!AtomicBody->isInstantiationDependent()) { 9951 ErrorFound = NotAnAssignmentOp; 9952 ErrorLoc = AtomicBody->getExprLoc(); 9953 ErrorRange = AtomicBody->getSourceRange(); 9954 NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc() 9955 : AtomicBody->getExprLoc(); 9956 NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange() 9957 : AtomicBody->getSourceRange(); 9958 } 9959 } else { 9960 ErrorFound = NotAnExpression; 9961 NoteLoc = ErrorLoc = Body->getBeginLoc(); 9962 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc); 9963 } 9964 if (ErrorFound != NoError) { 9965 Diag(ErrorLoc, diag::err_omp_atomic_read_not_expression_statement) 9966 << ErrorRange; 9967 Diag(NoteLoc, diag::note_omp_atomic_read_write) << ErrorFound 9968 << NoteRange; 9969 return StmtError(); 9970 } 9971 if (CurContext->isDependentContext()) 9972 V = X = nullptr; 9973 } else if (AtomicKind == OMPC_write) { 9974 enum { 9975 NotAnExpression, 9976 NotAnAssignmentOp, 9977 NotAScalarType, 9978 NotAnLValue, 9979 NoError 9980 } ErrorFound = NoError; 9981 SourceLocation ErrorLoc, NoteLoc; 9982 SourceRange ErrorRange, NoteRange; 9983 // If clause is write: 9984 // x = expr; 9985 if (const auto *AtomicBody = dyn_cast<Expr>(Body)) { 9986 const auto *AtomicBinOp = 9987 dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts()); 9988 if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) { 9989 X = AtomicBinOp->getLHS(); 9990 E = AtomicBinOp->getRHS(); 9991 if ((X->isInstantiationDependent() || X->getType()->isScalarType()) && 9992 (E->isInstantiationDependent() || E->getType()->isScalarType())) { 9993 if (!X->isLValue()) { 9994 ErrorFound = NotAnLValue; 9995 ErrorLoc = AtomicBinOp->getExprLoc(); 9996 ErrorRange = AtomicBinOp->getSourceRange(); 9997 NoteLoc = X->getExprLoc(); 9998 NoteRange = X->getSourceRange(); 9999 } 10000 } else if (!X->isInstantiationDependent() || 10001 !E->isInstantiationDependent()) { 10002 const Expr *NotScalarExpr = 10003 (X->isInstantiationDependent() || X->getType()->isScalarType()) 10004 ? E 10005 : X; 10006 ErrorFound = NotAScalarType; 10007 ErrorLoc = AtomicBinOp->getExprLoc(); 10008 ErrorRange = AtomicBinOp->getSourceRange(); 10009 NoteLoc = NotScalarExpr->getExprLoc(); 10010 NoteRange = NotScalarExpr->getSourceRange(); 10011 } 10012 } else if (!AtomicBody->isInstantiationDependent()) { 10013 ErrorFound = NotAnAssignmentOp; 10014 ErrorLoc = AtomicBody->getExprLoc(); 10015 ErrorRange = AtomicBody->getSourceRange(); 10016 NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc() 10017 : AtomicBody->getExprLoc(); 10018 NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange() 10019 : AtomicBody->getSourceRange(); 10020 } 10021 } else { 10022 ErrorFound = NotAnExpression; 10023 NoteLoc = ErrorLoc = Body->getBeginLoc(); 10024 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc); 10025 } 10026 if (ErrorFound != NoError) { 10027 Diag(ErrorLoc, diag::err_omp_atomic_write_not_expression_statement) 10028 << ErrorRange; 10029 Diag(NoteLoc, diag::note_omp_atomic_read_write) << ErrorFound 10030 << NoteRange; 10031 return StmtError(); 10032 } 10033 if (CurContext->isDependentContext()) 10034 E = X = nullptr; 10035 } else if (AtomicKind == OMPC_update || AtomicKind == OMPC_unknown) { 10036 // If clause is update: 10037 // x++; 10038 // x--; 10039 // ++x; 10040 // --x; 10041 // x binop= expr; 10042 // x = x binop expr; 10043 // x = expr binop x; 10044 OpenMPAtomicUpdateChecker Checker(*this); 10045 if (Checker.checkStatement( 10046 Body, (AtomicKind == OMPC_update) 10047 ? diag::err_omp_atomic_update_not_expression_statement 10048 : diag::err_omp_atomic_not_expression_statement, 10049 diag::note_omp_atomic_update)) 10050 return StmtError(); 10051 if (!CurContext->isDependentContext()) { 10052 E = Checker.getExpr(); 10053 X = Checker.getX(); 10054 UE = Checker.getUpdateExpr(); 10055 IsXLHSInRHSPart = Checker.isXLHSInRHSPart(); 10056 } 10057 } else if (AtomicKind == OMPC_capture) { 10058 enum { 10059 NotAnAssignmentOp, 10060 NotACompoundStatement, 10061 NotTwoSubstatements, 10062 NotASpecificExpression, 10063 NoError 10064 } ErrorFound = NoError; 10065 SourceLocation ErrorLoc, NoteLoc; 10066 SourceRange ErrorRange, NoteRange; 10067 if (const auto *AtomicBody = dyn_cast<Expr>(Body)) { 10068 // If clause is a capture: 10069 // v = x++; 10070 // v = x--; 10071 // v = ++x; 10072 // v = --x; 10073 // v = x binop= expr; 10074 // v = x = x binop expr; 10075 // v = x = expr binop x; 10076 const auto *AtomicBinOp = 10077 dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts()); 10078 if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) { 10079 V = AtomicBinOp->getLHS(); 10080 Body = AtomicBinOp->getRHS()->IgnoreParenImpCasts(); 10081 OpenMPAtomicUpdateChecker Checker(*this); 10082 if (Checker.checkStatement( 10083 Body, diag::err_omp_atomic_capture_not_expression_statement, 10084 diag::note_omp_atomic_update)) 10085 return StmtError(); 10086 E = Checker.getExpr(); 10087 X = Checker.getX(); 10088 UE = Checker.getUpdateExpr(); 10089 IsXLHSInRHSPart = Checker.isXLHSInRHSPart(); 10090 IsPostfixUpdate = Checker.isPostfixUpdate(); 10091 } else if (!AtomicBody->isInstantiationDependent()) { 10092 ErrorLoc = AtomicBody->getExprLoc(); 10093 ErrorRange = AtomicBody->getSourceRange(); 10094 NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc() 10095 : AtomicBody->getExprLoc(); 10096 NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange() 10097 : AtomicBody->getSourceRange(); 10098 ErrorFound = NotAnAssignmentOp; 10099 } 10100 if (ErrorFound != NoError) { 10101 Diag(ErrorLoc, diag::err_omp_atomic_capture_not_expression_statement) 10102 << ErrorRange; 10103 Diag(NoteLoc, diag::note_omp_atomic_capture) << ErrorFound << NoteRange; 10104 return StmtError(); 10105 } 10106 if (CurContext->isDependentContext()) 10107 UE = V = E = X = nullptr; 10108 } else { 10109 // If clause is a capture: 10110 // { v = x; x = expr; } 10111 // { v = x; x++; } 10112 // { v = x; x--; } 10113 // { v = x; ++x; } 10114 // { v = x; --x; } 10115 // { v = x; x binop= expr; } 10116 // { v = x; x = x binop expr; } 10117 // { v = x; x = expr binop x; } 10118 // { x++; v = x; } 10119 // { x--; v = x; } 10120 // { ++x; v = x; } 10121 // { --x; v = x; } 10122 // { x binop= expr; v = x; } 10123 // { x = x binop expr; v = x; } 10124 // { x = expr binop x; v = x; } 10125 if (auto *CS = dyn_cast<CompoundStmt>(Body)) { 10126 // Check that this is { expr1; expr2; } 10127 if (CS->size() == 2) { 10128 Stmt *First = CS->body_front(); 10129 Stmt *Second = CS->body_back(); 10130 if (auto *EWC = dyn_cast<ExprWithCleanups>(First)) 10131 First = EWC->getSubExpr()->IgnoreParenImpCasts(); 10132 if (auto *EWC = dyn_cast<ExprWithCleanups>(Second)) 10133 Second = EWC->getSubExpr()->IgnoreParenImpCasts(); 10134 // Need to find what subexpression is 'v' and what is 'x'. 10135 OpenMPAtomicUpdateChecker Checker(*this); 10136 bool IsUpdateExprFound = !Checker.checkStatement(Second); 10137 BinaryOperator *BinOp = nullptr; 10138 if (IsUpdateExprFound) { 10139 BinOp = dyn_cast<BinaryOperator>(First); 10140 IsUpdateExprFound = BinOp && BinOp->getOpcode() == BO_Assign; 10141 } 10142 if (IsUpdateExprFound && !CurContext->isDependentContext()) { 10143 // { v = x; x++; } 10144 // { v = x; x--; } 10145 // { v = x; ++x; } 10146 // { v = x; --x; } 10147 // { v = x; x binop= expr; } 10148 // { v = x; x = x binop expr; } 10149 // { v = x; x = expr binop x; } 10150 // Check that the first expression has form v = x. 10151 Expr *PossibleX = BinOp->getRHS()->IgnoreParenImpCasts(); 10152 llvm::FoldingSetNodeID XId, PossibleXId; 10153 Checker.getX()->Profile(XId, Context, /*Canonical=*/true); 10154 PossibleX->Profile(PossibleXId, Context, /*Canonical=*/true); 10155 IsUpdateExprFound = XId == PossibleXId; 10156 if (IsUpdateExprFound) { 10157 V = BinOp->getLHS(); 10158 X = Checker.getX(); 10159 E = Checker.getExpr(); 10160 UE = Checker.getUpdateExpr(); 10161 IsXLHSInRHSPart = Checker.isXLHSInRHSPart(); 10162 IsPostfixUpdate = true; 10163 } 10164 } 10165 if (!IsUpdateExprFound) { 10166 IsUpdateExprFound = !Checker.checkStatement(First); 10167 BinOp = nullptr; 10168 if (IsUpdateExprFound) { 10169 BinOp = dyn_cast<BinaryOperator>(Second); 10170 IsUpdateExprFound = BinOp && BinOp->getOpcode() == BO_Assign; 10171 } 10172 if (IsUpdateExprFound && !CurContext->isDependentContext()) { 10173 // { x++; v = x; } 10174 // { x--; v = x; } 10175 // { ++x; v = x; } 10176 // { --x; v = x; } 10177 // { x binop= expr; v = x; } 10178 // { x = x binop expr; v = x; } 10179 // { x = expr binop x; v = x; } 10180 // Check that the second expression has form v = x. 10181 Expr *PossibleX = BinOp->getRHS()->IgnoreParenImpCasts(); 10182 llvm::FoldingSetNodeID XId, PossibleXId; 10183 Checker.getX()->Profile(XId, Context, /*Canonical=*/true); 10184 PossibleX->Profile(PossibleXId, Context, /*Canonical=*/true); 10185 IsUpdateExprFound = XId == PossibleXId; 10186 if (IsUpdateExprFound) { 10187 V = BinOp->getLHS(); 10188 X = Checker.getX(); 10189 E = Checker.getExpr(); 10190 UE = Checker.getUpdateExpr(); 10191 IsXLHSInRHSPart = Checker.isXLHSInRHSPart(); 10192 IsPostfixUpdate = false; 10193 } 10194 } 10195 } 10196 if (!IsUpdateExprFound) { 10197 // { v = x; x = expr; } 10198 auto *FirstExpr = dyn_cast<Expr>(First); 10199 auto *SecondExpr = dyn_cast<Expr>(Second); 10200 if (!FirstExpr || !SecondExpr || 10201 !(FirstExpr->isInstantiationDependent() || 10202 SecondExpr->isInstantiationDependent())) { 10203 auto *FirstBinOp = dyn_cast<BinaryOperator>(First); 10204 if (!FirstBinOp || FirstBinOp->getOpcode() != BO_Assign) { 10205 ErrorFound = NotAnAssignmentOp; 10206 NoteLoc = ErrorLoc = FirstBinOp ? FirstBinOp->getOperatorLoc() 10207 : First->getBeginLoc(); 10208 NoteRange = ErrorRange = FirstBinOp 10209 ? FirstBinOp->getSourceRange() 10210 : SourceRange(ErrorLoc, ErrorLoc); 10211 } else { 10212 auto *SecondBinOp = dyn_cast<BinaryOperator>(Second); 10213 if (!SecondBinOp || SecondBinOp->getOpcode() != BO_Assign) { 10214 ErrorFound = NotAnAssignmentOp; 10215 NoteLoc = ErrorLoc = SecondBinOp 10216 ? SecondBinOp->getOperatorLoc() 10217 : Second->getBeginLoc(); 10218 NoteRange = ErrorRange = 10219 SecondBinOp ? SecondBinOp->getSourceRange() 10220 : SourceRange(ErrorLoc, ErrorLoc); 10221 } else { 10222 Expr *PossibleXRHSInFirst = 10223 FirstBinOp->getRHS()->IgnoreParenImpCasts(); 10224 Expr *PossibleXLHSInSecond = 10225 SecondBinOp->getLHS()->IgnoreParenImpCasts(); 10226 llvm::FoldingSetNodeID X1Id, X2Id; 10227 PossibleXRHSInFirst->Profile(X1Id, Context, 10228 /*Canonical=*/true); 10229 PossibleXLHSInSecond->Profile(X2Id, Context, 10230 /*Canonical=*/true); 10231 IsUpdateExprFound = X1Id == X2Id; 10232 if (IsUpdateExprFound) { 10233 V = FirstBinOp->getLHS(); 10234 X = SecondBinOp->getLHS(); 10235 E = SecondBinOp->getRHS(); 10236 UE = nullptr; 10237 IsXLHSInRHSPart = false; 10238 IsPostfixUpdate = true; 10239 } else { 10240 ErrorFound = NotASpecificExpression; 10241 ErrorLoc = FirstBinOp->getExprLoc(); 10242 ErrorRange = FirstBinOp->getSourceRange(); 10243 NoteLoc = SecondBinOp->getLHS()->getExprLoc(); 10244 NoteRange = SecondBinOp->getRHS()->getSourceRange(); 10245 } 10246 } 10247 } 10248 } 10249 } 10250 } else { 10251 NoteLoc = ErrorLoc = Body->getBeginLoc(); 10252 NoteRange = ErrorRange = 10253 SourceRange(Body->getBeginLoc(), Body->getBeginLoc()); 10254 ErrorFound = NotTwoSubstatements; 10255 } 10256 } else { 10257 NoteLoc = ErrorLoc = Body->getBeginLoc(); 10258 NoteRange = ErrorRange = 10259 SourceRange(Body->getBeginLoc(), Body->getBeginLoc()); 10260 ErrorFound = NotACompoundStatement; 10261 } 10262 if (ErrorFound != NoError) { 10263 Diag(ErrorLoc, diag::err_omp_atomic_capture_not_compound_statement) 10264 << ErrorRange; 10265 Diag(NoteLoc, diag::note_omp_atomic_capture) << ErrorFound << NoteRange; 10266 return StmtError(); 10267 } 10268 if (CurContext->isDependentContext()) 10269 UE = V = E = X = nullptr; 10270 } 10271 } 10272 10273 setFunctionHasBranchProtectedScope(); 10274 10275 return OMPAtomicDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt, 10276 X, V, E, UE, IsXLHSInRHSPart, 10277 IsPostfixUpdate); 10278 } 10279 10280 StmtResult Sema::ActOnOpenMPTargetDirective(ArrayRef<OMPClause *> Clauses, 10281 Stmt *AStmt, 10282 SourceLocation StartLoc, 10283 SourceLocation EndLoc) { 10284 if (!AStmt) 10285 return StmtError(); 10286 10287 auto *CS = cast<CapturedStmt>(AStmt); 10288 // 1.2.2 OpenMP Language Terminology 10289 // Structured block - An executable statement with a single entry at the 10290 // top and a single exit at the bottom. 10291 // The point of exit cannot be a branch out of the structured block. 10292 // longjmp() and throw() must not violate the entry/exit criteria. 10293 CS->getCapturedDecl()->setNothrow(); 10294 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target); 10295 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10296 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10297 // 1.2.2 OpenMP Language Terminology 10298 // Structured block - An executable statement with a single entry at the 10299 // top and a single exit at the bottom. 10300 // The point of exit cannot be a branch out of the structured block. 10301 // longjmp() and throw() must not violate the entry/exit criteria. 10302 CS->getCapturedDecl()->setNothrow(); 10303 } 10304 10305 // OpenMP [2.16, Nesting of Regions] 10306 // If specified, a teams construct must be contained within a target 10307 // construct. That target construct must contain no statements or directives 10308 // outside of the teams construct. 10309 if (DSAStack->hasInnerTeamsRegion()) { 10310 const Stmt *S = CS->IgnoreContainers(/*IgnoreCaptured=*/true); 10311 bool OMPTeamsFound = true; 10312 if (const auto *CS = dyn_cast<CompoundStmt>(S)) { 10313 auto I = CS->body_begin(); 10314 while (I != CS->body_end()) { 10315 const auto *OED = dyn_cast<OMPExecutableDirective>(*I); 10316 if (!OED || !isOpenMPTeamsDirective(OED->getDirectiveKind()) || 10317 OMPTeamsFound) { 10318 10319 OMPTeamsFound = false; 10320 break; 10321 } 10322 ++I; 10323 } 10324 assert(I != CS->body_end() && "Not found statement"); 10325 S = *I; 10326 } else { 10327 const auto *OED = dyn_cast<OMPExecutableDirective>(S); 10328 OMPTeamsFound = OED && isOpenMPTeamsDirective(OED->getDirectiveKind()); 10329 } 10330 if (!OMPTeamsFound) { 10331 Diag(StartLoc, diag::err_omp_target_contains_not_only_teams); 10332 Diag(DSAStack->getInnerTeamsRegionLoc(), 10333 diag::note_omp_nested_teams_construct_here); 10334 Diag(S->getBeginLoc(), diag::note_omp_nested_statement_here) 10335 << isa<OMPExecutableDirective>(S); 10336 return StmtError(); 10337 } 10338 } 10339 10340 setFunctionHasBranchProtectedScope(); 10341 10342 return OMPTargetDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt); 10343 } 10344 10345 StmtResult 10346 Sema::ActOnOpenMPTargetParallelDirective(ArrayRef<OMPClause *> Clauses, 10347 Stmt *AStmt, SourceLocation StartLoc, 10348 SourceLocation EndLoc) { 10349 if (!AStmt) 10350 return StmtError(); 10351 10352 auto *CS = cast<CapturedStmt>(AStmt); 10353 // 1.2.2 OpenMP Language Terminology 10354 // Structured block - An executable statement with a single entry at the 10355 // top and a single exit at the bottom. 10356 // The point of exit cannot be a branch out of the structured block. 10357 // longjmp() and throw() must not violate the entry/exit criteria. 10358 CS->getCapturedDecl()->setNothrow(); 10359 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel); 10360 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10361 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10362 // 1.2.2 OpenMP Language Terminology 10363 // Structured block - An executable statement with a single entry at the 10364 // top and a single exit at the bottom. 10365 // The point of exit cannot be a branch out of the structured block. 10366 // longjmp() and throw() must not violate the entry/exit criteria. 10367 CS->getCapturedDecl()->setNothrow(); 10368 } 10369 10370 setFunctionHasBranchProtectedScope(); 10371 10372 return OMPTargetParallelDirective::Create( 10373 Context, StartLoc, EndLoc, Clauses, AStmt, 10374 DSAStack->getTaskgroupReductionRef(), DSAStack->isCancelRegion()); 10375 } 10376 10377 StmtResult Sema::ActOnOpenMPTargetParallelForDirective( 10378 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10379 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10380 if (!AStmt) 10381 return StmtError(); 10382 10383 auto *CS = cast<CapturedStmt>(AStmt); 10384 // 1.2.2 OpenMP Language Terminology 10385 // Structured block - An executable statement with a single entry at the 10386 // top and a single exit at the bottom. 10387 // The point of exit cannot be a branch out of the structured block. 10388 // longjmp() and throw() must not violate the entry/exit criteria. 10389 CS->getCapturedDecl()->setNothrow(); 10390 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel_for); 10391 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10392 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10393 // 1.2.2 OpenMP Language Terminology 10394 // Structured block - An executable statement with a single entry at the 10395 // top and a single exit at the bottom. 10396 // The point of exit cannot be a branch out of the structured block. 10397 // longjmp() and throw() must not violate the entry/exit criteria. 10398 CS->getCapturedDecl()->setNothrow(); 10399 } 10400 10401 OMPLoopDirective::HelperExprs B; 10402 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 10403 // define the nested loops number. 10404 unsigned NestedLoopCount = 10405 checkOpenMPLoop(OMPD_target_parallel_for, getCollapseNumberExpr(Clauses), 10406 getOrderedNumberExpr(Clauses), CS, *this, *DSAStack, 10407 VarsWithImplicitDSA, B); 10408 if (NestedLoopCount == 0) 10409 return StmtError(); 10410 10411 assert((CurContext->isDependentContext() || B.builtAll()) && 10412 "omp target parallel for loop exprs were not built"); 10413 10414 if (!CurContext->isDependentContext()) { 10415 // Finalize the clauses that need pre-built expressions for CodeGen. 10416 for (OMPClause *C : Clauses) { 10417 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 10418 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 10419 B.NumIterations, *this, CurScope, 10420 DSAStack)) 10421 return StmtError(); 10422 } 10423 } 10424 10425 setFunctionHasBranchProtectedScope(); 10426 return OMPTargetParallelForDirective::Create( 10427 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B, 10428 DSAStack->getTaskgroupReductionRef(), DSAStack->isCancelRegion()); 10429 } 10430 10431 /// Check for existence of a map clause in the list of clauses. 10432 static bool hasClauses(ArrayRef<OMPClause *> Clauses, 10433 const OpenMPClauseKind K) { 10434 return llvm::any_of( 10435 Clauses, [K](const OMPClause *C) { return C->getClauseKind() == K; }); 10436 } 10437 10438 template <typename... Params> 10439 static bool hasClauses(ArrayRef<OMPClause *> Clauses, const OpenMPClauseKind K, 10440 const Params... ClauseTypes) { 10441 return hasClauses(Clauses, K) || hasClauses(Clauses, ClauseTypes...); 10442 } 10443 10444 StmtResult Sema::ActOnOpenMPTargetDataDirective(ArrayRef<OMPClause *> Clauses, 10445 Stmt *AStmt, 10446 SourceLocation StartLoc, 10447 SourceLocation EndLoc) { 10448 if (!AStmt) 10449 return StmtError(); 10450 10451 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 10452 10453 // OpenMP [2.12.2, target data Construct, Restrictions] 10454 // At least one map, use_device_addr or use_device_ptr clause must appear on 10455 // the directive. 10456 if (!hasClauses(Clauses, OMPC_map, OMPC_use_device_ptr) && 10457 (LangOpts.OpenMP < 50 || !hasClauses(Clauses, OMPC_use_device_addr))) { 10458 StringRef Expected; 10459 if (LangOpts.OpenMP < 50) 10460 Expected = "'map' or 'use_device_ptr'"; 10461 else 10462 Expected = "'map', 'use_device_ptr', or 'use_device_addr'"; 10463 Diag(StartLoc, diag::err_omp_no_clause_for_directive) 10464 << Expected << getOpenMPDirectiveName(OMPD_target_data); 10465 return StmtError(); 10466 } 10467 10468 setFunctionHasBranchProtectedScope(); 10469 10470 return OMPTargetDataDirective::Create(Context, StartLoc, EndLoc, Clauses, 10471 AStmt); 10472 } 10473 10474 StmtResult 10475 Sema::ActOnOpenMPTargetEnterDataDirective(ArrayRef<OMPClause *> Clauses, 10476 SourceLocation StartLoc, 10477 SourceLocation EndLoc, Stmt *AStmt) { 10478 if (!AStmt) 10479 return StmtError(); 10480 10481 auto *CS = cast<CapturedStmt>(AStmt); 10482 // 1.2.2 OpenMP Language Terminology 10483 // Structured block - An executable statement with a single entry at the 10484 // top and a single exit at the bottom. 10485 // The point of exit cannot be a branch out of the structured block. 10486 // longjmp() and throw() must not violate the entry/exit criteria. 10487 CS->getCapturedDecl()->setNothrow(); 10488 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_enter_data); 10489 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10490 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10491 // 1.2.2 OpenMP Language Terminology 10492 // Structured block - An executable statement with a single entry at the 10493 // top and a single exit at the bottom. 10494 // The point of exit cannot be a branch out of the structured block. 10495 // longjmp() and throw() must not violate the entry/exit criteria. 10496 CS->getCapturedDecl()->setNothrow(); 10497 } 10498 10499 // OpenMP [2.10.2, Restrictions, p. 99] 10500 // At least one map clause must appear on the directive. 10501 if (!hasClauses(Clauses, OMPC_map)) { 10502 Diag(StartLoc, diag::err_omp_no_clause_for_directive) 10503 << "'map'" << getOpenMPDirectiveName(OMPD_target_enter_data); 10504 return StmtError(); 10505 } 10506 10507 return OMPTargetEnterDataDirective::Create(Context, StartLoc, EndLoc, Clauses, 10508 AStmt); 10509 } 10510 10511 StmtResult 10512 Sema::ActOnOpenMPTargetExitDataDirective(ArrayRef<OMPClause *> Clauses, 10513 SourceLocation StartLoc, 10514 SourceLocation EndLoc, Stmt *AStmt) { 10515 if (!AStmt) 10516 return StmtError(); 10517 10518 auto *CS = cast<CapturedStmt>(AStmt); 10519 // 1.2.2 OpenMP Language Terminology 10520 // Structured block - An executable statement with a single entry at the 10521 // top and a single exit at the bottom. 10522 // The point of exit cannot be a branch out of the structured block. 10523 // longjmp() and throw() must not violate the entry/exit criteria. 10524 CS->getCapturedDecl()->setNothrow(); 10525 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_exit_data); 10526 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10527 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10528 // 1.2.2 OpenMP Language Terminology 10529 // Structured block - An executable statement with a single entry at the 10530 // top and a single exit at the bottom. 10531 // The point of exit cannot be a branch out of the structured block. 10532 // longjmp() and throw() must not violate the entry/exit criteria. 10533 CS->getCapturedDecl()->setNothrow(); 10534 } 10535 10536 // OpenMP [2.10.3, Restrictions, p. 102] 10537 // At least one map clause must appear on the directive. 10538 if (!hasClauses(Clauses, OMPC_map)) { 10539 Diag(StartLoc, diag::err_omp_no_clause_for_directive) 10540 << "'map'" << getOpenMPDirectiveName(OMPD_target_exit_data); 10541 return StmtError(); 10542 } 10543 10544 return OMPTargetExitDataDirective::Create(Context, StartLoc, EndLoc, Clauses, 10545 AStmt); 10546 } 10547 10548 StmtResult Sema::ActOnOpenMPTargetUpdateDirective(ArrayRef<OMPClause *> Clauses, 10549 SourceLocation StartLoc, 10550 SourceLocation EndLoc, 10551 Stmt *AStmt) { 10552 if (!AStmt) 10553 return StmtError(); 10554 10555 auto *CS = cast<CapturedStmt>(AStmt); 10556 // 1.2.2 OpenMP Language Terminology 10557 // Structured block - An executable statement with a single entry at the 10558 // top and a single exit at the bottom. 10559 // The point of exit cannot be a branch out of the structured block. 10560 // longjmp() and throw() must not violate the entry/exit criteria. 10561 CS->getCapturedDecl()->setNothrow(); 10562 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_update); 10563 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10564 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10565 // 1.2.2 OpenMP Language Terminology 10566 // Structured block - An executable statement with a single entry at the 10567 // top and a single exit at the bottom. 10568 // The point of exit cannot be a branch out of the structured block. 10569 // longjmp() and throw() must not violate the entry/exit criteria. 10570 CS->getCapturedDecl()->setNothrow(); 10571 } 10572 10573 if (!hasClauses(Clauses, OMPC_to, OMPC_from)) { 10574 Diag(StartLoc, diag::err_omp_at_least_one_motion_clause_required); 10575 return StmtError(); 10576 } 10577 return OMPTargetUpdateDirective::Create(Context, StartLoc, EndLoc, Clauses, 10578 AStmt); 10579 } 10580 10581 StmtResult Sema::ActOnOpenMPTeamsDirective(ArrayRef<OMPClause *> Clauses, 10582 Stmt *AStmt, SourceLocation StartLoc, 10583 SourceLocation EndLoc) { 10584 if (!AStmt) 10585 return StmtError(); 10586 10587 auto *CS = cast<CapturedStmt>(AStmt); 10588 // 1.2.2 OpenMP Language Terminology 10589 // Structured block - An executable statement with a single entry at the 10590 // top and a single exit at the bottom. 10591 // The point of exit cannot be a branch out of the structured block. 10592 // longjmp() and throw() must not violate the entry/exit criteria. 10593 CS->getCapturedDecl()->setNothrow(); 10594 10595 setFunctionHasBranchProtectedScope(); 10596 10597 DSAStack->setParentTeamsRegionLoc(StartLoc); 10598 10599 return OMPTeamsDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt); 10600 } 10601 10602 StmtResult 10603 Sema::ActOnOpenMPCancellationPointDirective(SourceLocation StartLoc, 10604 SourceLocation EndLoc, 10605 OpenMPDirectiveKind CancelRegion) { 10606 if (DSAStack->isParentNowaitRegion()) { 10607 Diag(StartLoc, diag::err_omp_parent_cancel_region_nowait) << 0; 10608 return StmtError(); 10609 } 10610 if (DSAStack->isParentOrderedRegion()) { 10611 Diag(StartLoc, diag::err_omp_parent_cancel_region_ordered) << 0; 10612 return StmtError(); 10613 } 10614 return OMPCancellationPointDirective::Create(Context, StartLoc, EndLoc, 10615 CancelRegion); 10616 } 10617 10618 StmtResult Sema::ActOnOpenMPCancelDirective(ArrayRef<OMPClause *> Clauses, 10619 SourceLocation StartLoc, 10620 SourceLocation EndLoc, 10621 OpenMPDirectiveKind CancelRegion) { 10622 if (DSAStack->isParentNowaitRegion()) { 10623 Diag(StartLoc, diag::err_omp_parent_cancel_region_nowait) << 1; 10624 return StmtError(); 10625 } 10626 if (DSAStack->isParentOrderedRegion()) { 10627 Diag(StartLoc, diag::err_omp_parent_cancel_region_ordered) << 1; 10628 return StmtError(); 10629 } 10630 DSAStack->setParentCancelRegion(/*Cancel=*/true); 10631 return OMPCancelDirective::Create(Context, StartLoc, EndLoc, Clauses, 10632 CancelRegion); 10633 } 10634 10635 static bool checkGrainsizeNumTasksClauses(Sema &S, 10636 ArrayRef<OMPClause *> Clauses) { 10637 const OMPClause *PrevClause = nullptr; 10638 bool ErrorFound = false; 10639 for (const OMPClause *C : Clauses) { 10640 if (C->getClauseKind() == OMPC_grainsize || 10641 C->getClauseKind() == OMPC_num_tasks) { 10642 if (!PrevClause) 10643 PrevClause = C; 10644 else if (PrevClause->getClauseKind() != C->getClauseKind()) { 10645 S.Diag(C->getBeginLoc(), diag::err_omp_clauses_mutually_exclusive) 10646 << getOpenMPClauseName(C->getClauseKind()) 10647 << getOpenMPClauseName(PrevClause->getClauseKind()); 10648 S.Diag(PrevClause->getBeginLoc(), diag::note_omp_previous_clause) 10649 << getOpenMPClauseName(PrevClause->getClauseKind()); 10650 ErrorFound = true; 10651 } 10652 } 10653 } 10654 return ErrorFound; 10655 } 10656 10657 static bool checkReductionClauseWithNogroup(Sema &S, 10658 ArrayRef<OMPClause *> Clauses) { 10659 const OMPClause *ReductionClause = nullptr; 10660 const OMPClause *NogroupClause = nullptr; 10661 for (const OMPClause *C : Clauses) { 10662 if (C->getClauseKind() == OMPC_reduction) { 10663 ReductionClause = C; 10664 if (NogroupClause) 10665 break; 10666 continue; 10667 } 10668 if (C->getClauseKind() == OMPC_nogroup) { 10669 NogroupClause = C; 10670 if (ReductionClause) 10671 break; 10672 continue; 10673 } 10674 } 10675 if (ReductionClause && NogroupClause) { 10676 S.Diag(ReductionClause->getBeginLoc(), diag::err_omp_reduction_with_nogroup) 10677 << SourceRange(NogroupClause->getBeginLoc(), 10678 NogroupClause->getEndLoc()); 10679 return true; 10680 } 10681 return false; 10682 } 10683 10684 StmtResult Sema::ActOnOpenMPTaskLoopDirective( 10685 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10686 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10687 if (!AStmt) 10688 return StmtError(); 10689 10690 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 10691 OMPLoopDirective::HelperExprs B; 10692 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 10693 // define the nested loops number. 10694 unsigned NestedLoopCount = 10695 checkOpenMPLoop(OMPD_taskloop, getCollapseNumberExpr(Clauses), 10696 /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack, 10697 VarsWithImplicitDSA, B); 10698 if (NestedLoopCount == 0) 10699 return StmtError(); 10700 10701 assert((CurContext->isDependentContext() || B.builtAll()) && 10702 "omp for loop exprs were not built"); 10703 10704 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 10705 // The grainsize clause and num_tasks clause are mutually exclusive and may 10706 // not appear on the same taskloop directive. 10707 if (checkGrainsizeNumTasksClauses(*this, Clauses)) 10708 return StmtError(); 10709 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 10710 // If a reduction clause is present on the taskloop directive, the nogroup 10711 // clause must not be specified. 10712 if (checkReductionClauseWithNogroup(*this, Clauses)) 10713 return StmtError(); 10714 10715 setFunctionHasBranchProtectedScope(); 10716 return OMPTaskLoopDirective::Create(Context, StartLoc, EndLoc, 10717 NestedLoopCount, Clauses, AStmt, B, 10718 DSAStack->isCancelRegion()); 10719 } 10720 10721 StmtResult Sema::ActOnOpenMPTaskLoopSimdDirective( 10722 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10723 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10724 if (!AStmt) 10725 return StmtError(); 10726 10727 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 10728 OMPLoopDirective::HelperExprs B; 10729 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 10730 // define the nested loops number. 10731 unsigned NestedLoopCount = 10732 checkOpenMPLoop(OMPD_taskloop_simd, getCollapseNumberExpr(Clauses), 10733 /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack, 10734 VarsWithImplicitDSA, B); 10735 if (NestedLoopCount == 0) 10736 return StmtError(); 10737 10738 assert((CurContext->isDependentContext() || B.builtAll()) && 10739 "omp for loop exprs were not built"); 10740 10741 if (!CurContext->isDependentContext()) { 10742 // Finalize the clauses that need pre-built expressions for CodeGen. 10743 for (OMPClause *C : Clauses) { 10744 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 10745 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 10746 B.NumIterations, *this, CurScope, 10747 DSAStack)) 10748 return StmtError(); 10749 } 10750 } 10751 10752 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 10753 // The grainsize clause and num_tasks clause are mutually exclusive and may 10754 // not appear on the same taskloop directive. 10755 if (checkGrainsizeNumTasksClauses(*this, Clauses)) 10756 return StmtError(); 10757 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 10758 // If a reduction clause is present on the taskloop directive, the nogroup 10759 // clause must not be specified. 10760 if (checkReductionClauseWithNogroup(*this, Clauses)) 10761 return StmtError(); 10762 if (checkSimdlenSafelenSpecified(*this, Clauses)) 10763 return StmtError(); 10764 10765 setFunctionHasBranchProtectedScope(); 10766 return OMPTaskLoopSimdDirective::Create(Context, StartLoc, EndLoc, 10767 NestedLoopCount, Clauses, AStmt, B); 10768 } 10769 10770 StmtResult Sema::ActOnOpenMPMasterTaskLoopDirective( 10771 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10772 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10773 if (!AStmt) 10774 return StmtError(); 10775 10776 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 10777 OMPLoopDirective::HelperExprs B; 10778 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 10779 // define the nested loops number. 10780 unsigned NestedLoopCount = 10781 checkOpenMPLoop(OMPD_master_taskloop, getCollapseNumberExpr(Clauses), 10782 /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack, 10783 VarsWithImplicitDSA, B); 10784 if (NestedLoopCount == 0) 10785 return StmtError(); 10786 10787 assert((CurContext->isDependentContext() || B.builtAll()) && 10788 "omp for loop exprs were not built"); 10789 10790 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 10791 // The grainsize clause and num_tasks clause are mutually exclusive and may 10792 // not appear on the same taskloop directive. 10793 if (checkGrainsizeNumTasksClauses(*this, Clauses)) 10794 return StmtError(); 10795 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 10796 // If a reduction clause is present on the taskloop directive, the nogroup 10797 // clause must not be specified. 10798 if (checkReductionClauseWithNogroup(*this, Clauses)) 10799 return StmtError(); 10800 10801 setFunctionHasBranchProtectedScope(); 10802 return OMPMasterTaskLoopDirective::Create(Context, StartLoc, EndLoc, 10803 NestedLoopCount, Clauses, AStmt, B, 10804 DSAStack->isCancelRegion()); 10805 } 10806 10807 StmtResult Sema::ActOnOpenMPMasterTaskLoopSimdDirective( 10808 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10809 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10810 if (!AStmt) 10811 return StmtError(); 10812 10813 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 10814 OMPLoopDirective::HelperExprs B; 10815 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 10816 // define the nested loops number. 10817 unsigned NestedLoopCount = 10818 checkOpenMPLoop(OMPD_master_taskloop_simd, getCollapseNumberExpr(Clauses), 10819 /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack, 10820 VarsWithImplicitDSA, B); 10821 if (NestedLoopCount == 0) 10822 return StmtError(); 10823 10824 assert((CurContext->isDependentContext() || B.builtAll()) && 10825 "omp for loop exprs were not built"); 10826 10827 if (!CurContext->isDependentContext()) { 10828 // Finalize the clauses that need pre-built expressions for CodeGen. 10829 for (OMPClause *C : Clauses) { 10830 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 10831 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 10832 B.NumIterations, *this, CurScope, 10833 DSAStack)) 10834 return StmtError(); 10835 } 10836 } 10837 10838 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 10839 // The grainsize clause and num_tasks clause are mutually exclusive and may 10840 // not appear on the same taskloop directive. 10841 if (checkGrainsizeNumTasksClauses(*this, Clauses)) 10842 return StmtError(); 10843 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 10844 // If a reduction clause is present on the taskloop directive, the nogroup 10845 // clause must not be specified. 10846 if (checkReductionClauseWithNogroup(*this, Clauses)) 10847 return StmtError(); 10848 if (checkSimdlenSafelenSpecified(*this, Clauses)) 10849 return StmtError(); 10850 10851 setFunctionHasBranchProtectedScope(); 10852 return OMPMasterTaskLoopSimdDirective::Create( 10853 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 10854 } 10855 10856 StmtResult Sema::ActOnOpenMPParallelMasterTaskLoopDirective( 10857 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10858 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10859 if (!AStmt) 10860 return StmtError(); 10861 10862 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 10863 auto *CS = cast<CapturedStmt>(AStmt); 10864 // 1.2.2 OpenMP Language Terminology 10865 // Structured block - An executable statement with a single entry at the 10866 // top and a single exit at the bottom. 10867 // The point of exit cannot be a branch out of the structured block. 10868 // longjmp() and throw() must not violate the entry/exit criteria. 10869 CS->getCapturedDecl()->setNothrow(); 10870 for (int ThisCaptureLevel = 10871 getOpenMPCaptureLevels(OMPD_parallel_master_taskloop); 10872 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10873 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10874 // 1.2.2 OpenMP Language Terminology 10875 // Structured block - An executable statement with a single entry at the 10876 // top and a single exit at the bottom. 10877 // The point of exit cannot be a branch out of the structured block. 10878 // longjmp() and throw() must not violate the entry/exit criteria. 10879 CS->getCapturedDecl()->setNothrow(); 10880 } 10881 10882 OMPLoopDirective::HelperExprs B; 10883 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 10884 // define the nested loops number. 10885 unsigned NestedLoopCount = checkOpenMPLoop( 10886 OMPD_parallel_master_taskloop, getCollapseNumberExpr(Clauses), 10887 /*OrderedLoopCountExpr=*/nullptr, CS, *this, *DSAStack, 10888 VarsWithImplicitDSA, B); 10889 if (NestedLoopCount == 0) 10890 return StmtError(); 10891 10892 assert((CurContext->isDependentContext() || B.builtAll()) && 10893 "omp for loop exprs were not built"); 10894 10895 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 10896 // The grainsize clause and num_tasks clause are mutually exclusive and may 10897 // not appear on the same taskloop directive. 10898 if (checkGrainsizeNumTasksClauses(*this, Clauses)) 10899 return StmtError(); 10900 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 10901 // If a reduction clause is present on the taskloop directive, the nogroup 10902 // clause must not be specified. 10903 if (checkReductionClauseWithNogroup(*this, Clauses)) 10904 return StmtError(); 10905 10906 setFunctionHasBranchProtectedScope(); 10907 return OMPParallelMasterTaskLoopDirective::Create( 10908 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B, 10909 DSAStack->isCancelRegion()); 10910 } 10911 10912 StmtResult Sema::ActOnOpenMPParallelMasterTaskLoopSimdDirective( 10913 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10914 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10915 if (!AStmt) 10916 return StmtError(); 10917 10918 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 10919 auto *CS = cast<CapturedStmt>(AStmt); 10920 // 1.2.2 OpenMP Language Terminology 10921 // Structured block - An executable statement with a single entry at the 10922 // top and a single exit at the bottom. 10923 // The point of exit cannot be a branch out of the structured block. 10924 // longjmp() and throw() must not violate the entry/exit criteria. 10925 CS->getCapturedDecl()->setNothrow(); 10926 for (int ThisCaptureLevel = 10927 getOpenMPCaptureLevels(OMPD_parallel_master_taskloop_simd); 10928 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10929 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10930 // 1.2.2 OpenMP Language Terminology 10931 // Structured block - An executable statement with a single entry at the 10932 // top and a single exit at the bottom. 10933 // The point of exit cannot be a branch out of the structured block. 10934 // longjmp() and throw() must not violate the entry/exit criteria. 10935 CS->getCapturedDecl()->setNothrow(); 10936 } 10937 10938 OMPLoopDirective::HelperExprs B; 10939 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 10940 // define the nested loops number. 10941 unsigned NestedLoopCount = checkOpenMPLoop( 10942 OMPD_parallel_master_taskloop_simd, getCollapseNumberExpr(Clauses), 10943 /*OrderedLoopCountExpr=*/nullptr, CS, *this, *DSAStack, 10944 VarsWithImplicitDSA, B); 10945 if (NestedLoopCount == 0) 10946 return StmtError(); 10947 10948 assert((CurContext->isDependentContext() || B.builtAll()) && 10949 "omp for loop exprs were not built"); 10950 10951 if (!CurContext->isDependentContext()) { 10952 // Finalize the clauses that need pre-built expressions for CodeGen. 10953 for (OMPClause *C : Clauses) { 10954 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 10955 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 10956 B.NumIterations, *this, CurScope, 10957 DSAStack)) 10958 return StmtError(); 10959 } 10960 } 10961 10962 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 10963 // The grainsize clause and num_tasks clause are mutually exclusive and may 10964 // not appear on the same taskloop directive. 10965 if (checkGrainsizeNumTasksClauses(*this, Clauses)) 10966 return StmtError(); 10967 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 10968 // If a reduction clause is present on the taskloop directive, the nogroup 10969 // clause must not be specified. 10970 if (checkReductionClauseWithNogroup(*this, Clauses)) 10971 return StmtError(); 10972 if (checkSimdlenSafelenSpecified(*this, Clauses)) 10973 return StmtError(); 10974 10975 setFunctionHasBranchProtectedScope(); 10976 return OMPParallelMasterTaskLoopSimdDirective::Create( 10977 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 10978 } 10979 10980 StmtResult Sema::ActOnOpenMPDistributeDirective( 10981 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10982 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10983 if (!AStmt) 10984 return StmtError(); 10985 10986 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 10987 OMPLoopDirective::HelperExprs B; 10988 // In presence of clause 'collapse' with number of loops, it will 10989 // define the nested loops number. 10990 unsigned NestedLoopCount = 10991 checkOpenMPLoop(OMPD_distribute, getCollapseNumberExpr(Clauses), 10992 nullptr /*ordered not a clause on distribute*/, AStmt, 10993 *this, *DSAStack, VarsWithImplicitDSA, B); 10994 if (NestedLoopCount == 0) 10995 return StmtError(); 10996 10997 assert((CurContext->isDependentContext() || B.builtAll()) && 10998 "omp for loop exprs were not built"); 10999 11000 setFunctionHasBranchProtectedScope(); 11001 return OMPDistributeDirective::Create(Context, StartLoc, EndLoc, 11002 NestedLoopCount, Clauses, AStmt, B); 11003 } 11004 11005 StmtResult Sema::ActOnOpenMPDistributeParallelForDirective( 11006 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 11007 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 11008 if (!AStmt) 11009 return StmtError(); 11010 11011 auto *CS = cast<CapturedStmt>(AStmt); 11012 // 1.2.2 OpenMP Language Terminology 11013 // Structured block - An executable statement with a single entry at the 11014 // top and a single exit at the bottom. 11015 // The point of exit cannot be a branch out of the structured block. 11016 // longjmp() and throw() must not violate the entry/exit criteria. 11017 CS->getCapturedDecl()->setNothrow(); 11018 for (int ThisCaptureLevel = 11019 getOpenMPCaptureLevels(OMPD_distribute_parallel_for); 11020 ThisCaptureLevel > 1; --ThisCaptureLevel) { 11021 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 11022 // 1.2.2 OpenMP Language Terminology 11023 // Structured block - An executable statement with a single entry at the 11024 // top and a single exit at the bottom. 11025 // The point of exit cannot be a branch out of the structured block. 11026 // longjmp() and throw() must not violate the entry/exit criteria. 11027 CS->getCapturedDecl()->setNothrow(); 11028 } 11029 11030 OMPLoopDirective::HelperExprs B; 11031 // In presence of clause 'collapse' with number of loops, it will 11032 // define the nested loops number. 11033 unsigned NestedLoopCount = checkOpenMPLoop( 11034 OMPD_distribute_parallel_for, getCollapseNumberExpr(Clauses), 11035 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 11036 VarsWithImplicitDSA, B); 11037 if (NestedLoopCount == 0) 11038 return StmtError(); 11039 11040 assert((CurContext->isDependentContext() || B.builtAll()) && 11041 "omp for loop exprs were not built"); 11042 11043 setFunctionHasBranchProtectedScope(); 11044 return OMPDistributeParallelForDirective::Create( 11045 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B, 11046 DSAStack->getTaskgroupReductionRef(), DSAStack->isCancelRegion()); 11047 } 11048 11049 StmtResult Sema::ActOnOpenMPDistributeParallelForSimdDirective( 11050 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 11051 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 11052 if (!AStmt) 11053 return StmtError(); 11054 11055 auto *CS = cast<CapturedStmt>(AStmt); 11056 // 1.2.2 OpenMP Language Terminology 11057 // Structured block - An executable statement with a single entry at the 11058 // top and a single exit at the bottom. 11059 // The point of exit cannot be a branch out of the structured block. 11060 // longjmp() and throw() must not violate the entry/exit criteria. 11061 CS->getCapturedDecl()->setNothrow(); 11062 for (int ThisCaptureLevel = 11063 getOpenMPCaptureLevels(OMPD_distribute_parallel_for_simd); 11064 ThisCaptureLevel > 1; --ThisCaptureLevel) { 11065 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 11066 // 1.2.2 OpenMP Language Terminology 11067 // Structured block - An executable statement with a single entry at the 11068 // top and a single exit at the bottom. 11069 // The point of exit cannot be a branch out of the structured block. 11070 // longjmp() and throw() must not violate the entry/exit criteria. 11071 CS->getCapturedDecl()->setNothrow(); 11072 } 11073 11074 OMPLoopDirective::HelperExprs B; 11075 // In presence of clause 'collapse' with number of loops, it will 11076 // define the nested loops number. 11077 unsigned NestedLoopCount = checkOpenMPLoop( 11078 OMPD_distribute_parallel_for_simd, getCollapseNumberExpr(Clauses), 11079 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 11080 VarsWithImplicitDSA, B); 11081 if (NestedLoopCount == 0) 11082 return StmtError(); 11083 11084 assert((CurContext->isDependentContext() || B.builtAll()) && 11085 "omp for loop exprs were not built"); 11086 11087 if (!CurContext->isDependentContext()) { 11088 // Finalize the clauses that need pre-built expressions for CodeGen. 11089 for (OMPClause *C : Clauses) { 11090 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 11091 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 11092 B.NumIterations, *this, CurScope, 11093 DSAStack)) 11094 return StmtError(); 11095 } 11096 } 11097 11098 if (checkSimdlenSafelenSpecified(*this, Clauses)) 11099 return StmtError(); 11100 11101 setFunctionHasBranchProtectedScope(); 11102 return OMPDistributeParallelForSimdDirective::Create( 11103 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 11104 } 11105 11106 StmtResult Sema::ActOnOpenMPDistributeSimdDirective( 11107 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 11108 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 11109 if (!AStmt) 11110 return StmtError(); 11111 11112 auto *CS = cast<CapturedStmt>(AStmt); 11113 // 1.2.2 OpenMP Language Terminology 11114 // Structured block - An executable statement with a single entry at the 11115 // top and a single exit at the bottom. 11116 // The point of exit cannot be a branch out of the structured block. 11117 // longjmp() and throw() must not violate the entry/exit criteria. 11118 CS->getCapturedDecl()->setNothrow(); 11119 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_distribute_simd); 11120 ThisCaptureLevel > 1; --ThisCaptureLevel) { 11121 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 11122 // 1.2.2 OpenMP Language Terminology 11123 // Structured block - An executable statement with a single entry at the 11124 // top and a single exit at the bottom. 11125 // The point of exit cannot be a branch out of the structured block. 11126 // longjmp() and throw() must not violate the entry/exit criteria. 11127 CS->getCapturedDecl()->setNothrow(); 11128 } 11129 11130 OMPLoopDirective::HelperExprs B; 11131 // In presence of clause 'collapse' with number of loops, it will 11132 // define the nested loops number. 11133 unsigned NestedLoopCount = 11134 checkOpenMPLoop(OMPD_distribute_simd, getCollapseNumberExpr(Clauses), 11135 nullptr /*ordered not a clause on distribute*/, CS, *this, 11136 *DSAStack, VarsWithImplicitDSA, B); 11137 if (NestedLoopCount == 0) 11138 return StmtError(); 11139 11140 assert((CurContext->isDependentContext() || B.builtAll()) && 11141 "omp for loop exprs were not built"); 11142 11143 if (!CurContext->isDependentContext()) { 11144 // Finalize the clauses that need pre-built expressions for CodeGen. 11145 for (OMPClause *C : Clauses) { 11146 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 11147 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 11148 B.NumIterations, *this, CurScope, 11149 DSAStack)) 11150 return StmtError(); 11151 } 11152 } 11153 11154 if (checkSimdlenSafelenSpecified(*this, Clauses)) 11155 return StmtError(); 11156 11157 setFunctionHasBranchProtectedScope(); 11158 return OMPDistributeSimdDirective::Create(Context, StartLoc, EndLoc, 11159 NestedLoopCount, Clauses, AStmt, B); 11160 } 11161 11162 StmtResult Sema::ActOnOpenMPTargetParallelForSimdDirective( 11163 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 11164 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 11165 if (!AStmt) 11166 return StmtError(); 11167 11168 auto *CS = cast<CapturedStmt>(AStmt); 11169 // 1.2.2 OpenMP Language Terminology 11170 // Structured block - An executable statement with a single entry at the 11171 // top and a single exit at the bottom. 11172 // The point of exit cannot be a branch out of the structured block. 11173 // longjmp() and throw() must not violate the entry/exit criteria. 11174 CS->getCapturedDecl()->setNothrow(); 11175 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel_for); 11176 ThisCaptureLevel > 1; --ThisCaptureLevel) { 11177 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 11178 // 1.2.2 OpenMP Language Terminology 11179 // Structured block - An executable statement with a single entry at the 11180 // top and a single exit at the bottom. 11181 // The point of exit cannot be a branch out of the structured block. 11182 // longjmp() and throw() must not violate the entry/exit criteria. 11183 CS->getCapturedDecl()->setNothrow(); 11184 } 11185 11186 OMPLoopDirective::HelperExprs B; 11187 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 11188 // define the nested loops number. 11189 unsigned NestedLoopCount = checkOpenMPLoop( 11190 OMPD_target_parallel_for_simd, getCollapseNumberExpr(Clauses), 11191 getOrderedNumberExpr(Clauses), CS, *this, *DSAStack, 11192 VarsWithImplicitDSA, B); 11193 if (NestedLoopCount == 0) 11194 return StmtError(); 11195 11196 assert((CurContext->isDependentContext() || B.builtAll()) && 11197 "omp target parallel for simd loop exprs were not built"); 11198 11199 if (!CurContext->isDependentContext()) { 11200 // Finalize the clauses that need pre-built expressions for CodeGen. 11201 for (OMPClause *C : Clauses) { 11202 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 11203 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 11204 B.NumIterations, *this, CurScope, 11205 DSAStack)) 11206 return StmtError(); 11207 } 11208 } 11209 if (checkSimdlenSafelenSpecified(*this, Clauses)) 11210 return StmtError(); 11211 11212 setFunctionHasBranchProtectedScope(); 11213 return OMPTargetParallelForSimdDirective::Create( 11214 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 11215 } 11216 11217 StmtResult Sema::ActOnOpenMPTargetSimdDirective( 11218 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 11219 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 11220 if (!AStmt) 11221 return StmtError(); 11222 11223 auto *CS = cast<CapturedStmt>(AStmt); 11224 // 1.2.2 OpenMP Language Terminology 11225 // Structured block - An executable statement with a single entry at the 11226 // top and a single exit at the bottom. 11227 // The point of exit cannot be a branch out of the structured block. 11228 // longjmp() and throw() must not violate the entry/exit criteria. 11229 CS->getCapturedDecl()->setNothrow(); 11230 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_simd); 11231 ThisCaptureLevel > 1; --ThisCaptureLevel) { 11232 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 11233 // 1.2.2 OpenMP Language Terminology 11234 // Structured block - An executable statement with a single entry at the 11235 // top and a single exit at the bottom. 11236 // The point of exit cannot be a branch out of the structured block. 11237 // longjmp() and throw() must not violate the entry/exit criteria. 11238 CS->getCapturedDecl()->setNothrow(); 11239 } 11240 11241 OMPLoopDirective::HelperExprs B; 11242 // In presence of clause 'collapse' with number of loops, it will define the 11243 // nested loops number. 11244 unsigned NestedLoopCount = 11245 checkOpenMPLoop(OMPD_target_simd, getCollapseNumberExpr(Clauses), 11246 getOrderedNumberExpr(Clauses), CS, *this, *DSAStack, 11247 VarsWithImplicitDSA, B); 11248 if (NestedLoopCount == 0) 11249 return StmtError(); 11250 11251 assert((CurContext->isDependentContext() || B.builtAll()) && 11252 "omp target simd loop exprs were not built"); 11253 11254 if (!CurContext->isDependentContext()) { 11255 // Finalize the clauses that need pre-built expressions for CodeGen. 11256 for (OMPClause *C : Clauses) { 11257 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 11258 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 11259 B.NumIterations, *this, CurScope, 11260 DSAStack)) 11261 return StmtError(); 11262 } 11263 } 11264 11265 if (checkSimdlenSafelenSpecified(*this, Clauses)) 11266 return StmtError(); 11267 11268 setFunctionHasBranchProtectedScope(); 11269 return OMPTargetSimdDirective::Create(Context, StartLoc, EndLoc, 11270 NestedLoopCount, Clauses, AStmt, B); 11271 } 11272 11273 StmtResult Sema::ActOnOpenMPTeamsDistributeDirective( 11274 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 11275 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 11276 if (!AStmt) 11277 return StmtError(); 11278 11279 auto *CS = cast<CapturedStmt>(AStmt); 11280 // 1.2.2 OpenMP Language Terminology 11281 // Structured block - An executable statement with a single entry at the 11282 // top and a single exit at the bottom. 11283 // The point of exit cannot be a branch out of the structured block. 11284 // longjmp() and throw() must not violate the entry/exit criteria. 11285 CS->getCapturedDecl()->setNothrow(); 11286 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_teams_distribute); 11287 ThisCaptureLevel > 1; --ThisCaptureLevel) { 11288 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 11289 // 1.2.2 OpenMP Language Terminology 11290 // Structured block - An executable statement with a single entry at the 11291 // top and a single exit at the bottom. 11292 // The point of exit cannot be a branch out of the structured block. 11293 // longjmp() and throw() must not violate the entry/exit criteria. 11294 CS->getCapturedDecl()->setNothrow(); 11295 } 11296 11297 OMPLoopDirective::HelperExprs B; 11298 // In presence of clause 'collapse' with number of loops, it will 11299 // define the nested loops number. 11300 unsigned NestedLoopCount = 11301 checkOpenMPLoop(OMPD_teams_distribute, getCollapseNumberExpr(Clauses), 11302 nullptr /*ordered not a clause on distribute*/, CS, *this, 11303 *DSAStack, VarsWithImplicitDSA, B); 11304 if (NestedLoopCount == 0) 11305 return StmtError(); 11306 11307 assert((CurContext->isDependentContext() || B.builtAll()) && 11308 "omp teams distribute loop exprs were not built"); 11309 11310 setFunctionHasBranchProtectedScope(); 11311 11312 DSAStack->setParentTeamsRegionLoc(StartLoc); 11313 11314 return OMPTeamsDistributeDirective::Create( 11315 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 11316 } 11317 11318 StmtResult Sema::ActOnOpenMPTeamsDistributeSimdDirective( 11319 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 11320 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 11321 if (!AStmt) 11322 return StmtError(); 11323 11324 auto *CS = cast<CapturedStmt>(AStmt); 11325 // 1.2.2 OpenMP Language Terminology 11326 // Structured block - An executable statement with a single entry at the 11327 // top and a single exit at the bottom. 11328 // The point of exit cannot be a branch out of the structured block. 11329 // longjmp() and throw() must not violate the entry/exit criteria. 11330 CS->getCapturedDecl()->setNothrow(); 11331 for (int ThisCaptureLevel = 11332 getOpenMPCaptureLevels(OMPD_teams_distribute_simd); 11333 ThisCaptureLevel > 1; --ThisCaptureLevel) { 11334 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 11335 // 1.2.2 OpenMP Language Terminology 11336 // Structured block - An executable statement with a single entry at the 11337 // top and a single exit at the bottom. 11338 // The point of exit cannot be a branch out of the structured block. 11339 // longjmp() and throw() must not violate the entry/exit criteria. 11340 CS->getCapturedDecl()->setNothrow(); 11341 } 11342 11343 OMPLoopDirective::HelperExprs B; 11344 // In presence of clause 'collapse' with number of loops, it will 11345 // define the nested loops number. 11346 unsigned NestedLoopCount = checkOpenMPLoop( 11347 OMPD_teams_distribute_simd, getCollapseNumberExpr(Clauses), 11348 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 11349 VarsWithImplicitDSA, B); 11350 11351 if (NestedLoopCount == 0) 11352 return StmtError(); 11353 11354 assert((CurContext->isDependentContext() || B.builtAll()) && 11355 "omp teams distribute simd loop exprs were not built"); 11356 11357 if (!CurContext->isDependentContext()) { 11358 // Finalize the clauses that need pre-built expressions for CodeGen. 11359 for (OMPClause *C : Clauses) { 11360 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 11361 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 11362 B.NumIterations, *this, CurScope, 11363 DSAStack)) 11364 return StmtError(); 11365 } 11366 } 11367 11368 if (checkSimdlenSafelenSpecified(*this, Clauses)) 11369 return StmtError(); 11370 11371 setFunctionHasBranchProtectedScope(); 11372 11373 DSAStack->setParentTeamsRegionLoc(StartLoc); 11374 11375 return OMPTeamsDistributeSimdDirective::Create( 11376 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 11377 } 11378 11379 StmtResult Sema::ActOnOpenMPTeamsDistributeParallelForSimdDirective( 11380 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 11381 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 11382 if (!AStmt) 11383 return StmtError(); 11384 11385 auto *CS = cast<CapturedStmt>(AStmt); 11386 // 1.2.2 OpenMP Language Terminology 11387 // Structured block - An executable statement with a single entry at the 11388 // top and a single exit at the bottom. 11389 // The point of exit cannot be a branch out of the structured block. 11390 // longjmp() and throw() must not violate the entry/exit criteria. 11391 CS->getCapturedDecl()->setNothrow(); 11392 11393 for (int ThisCaptureLevel = 11394 getOpenMPCaptureLevels(OMPD_teams_distribute_parallel_for_simd); 11395 ThisCaptureLevel > 1; --ThisCaptureLevel) { 11396 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 11397 // 1.2.2 OpenMP Language Terminology 11398 // Structured block - An executable statement with a single entry at the 11399 // top and a single exit at the bottom. 11400 // The point of exit cannot be a branch out of the structured block. 11401 // longjmp() and throw() must not violate the entry/exit criteria. 11402 CS->getCapturedDecl()->setNothrow(); 11403 } 11404 11405 OMPLoopDirective::HelperExprs B; 11406 // In presence of clause 'collapse' with number of loops, it will 11407 // define the nested loops number. 11408 unsigned NestedLoopCount = checkOpenMPLoop( 11409 OMPD_teams_distribute_parallel_for_simd, getCollapseNumberExpr(Clauses), 11410 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 11411 VarsWithImplicitDSA, B); 11412 11413 if (NestedLoopCount == 0) 11414 return StmtError(); 11415 11416 assert((CurContext->isDependentContext() || B.builtAll()) && 11417 "omp for loop exprs were not built"); 11418 11419 if (!CurContext->isDependentContext()) { 11420 // Finalize the clauses that need pre-built expressions for CodeGen. 11421 for (OMPClause *C : Clauses) { 11422 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 11423 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 11424 B.NumIterations, *this, CurScope, 11425 DSAStack)) 11426 return StmtError(); 11427 } 11428 } 11429 11430 if (checkSimdlenSafelenSpecified(*this, Clauses)) 11431 return StmtError(); 11432 11433 setFunctionHasBranchProtectedScope(); 11434 11435 DSAStack->setParentTeamsRegionLoc(StartLoc); 11436 11437 return OMPTeamsDistributeParallelForSimdDirective::Create( 11438 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 11439 } 11440 11441 StmtResult Sema::ActOnOpenMPTeamsDistributeParallelForDirective( 11442 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 11443 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 11444 if (!AStmt) 11445 return StmtError(); 11446 11447 auto *CS = cast<CapturedStmt>(AStmt); 11448 // 1.2.2 OpenMP Language Terminology 11449 // Structured block - An executable statement with a single entry at the 11450 // top and a single exit at the bottom. 11451 // The point of exit cannot be a branch out of the structured block. 11452 // longjmp() and throw() must not violate the entry/exit criteria. 11453 CS->getCapturedDecl()->setNothrow(); 11454 11455 for (int ThisCaptureLevel = 11456 getOpenMPCaptureLevels(OMPD_teams_distribute_parallel_for); 11457 ThisCaptureLevel > 1; --ThisCaptureLevel) { 11458 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 11459 // 1.2.2 OpenMP Language Terminology 11460 // Structured block - An executable statement with a single entry at the 11461 // top and a single exit at the bottom. 11462 // The point of exit cannot be a branch out of the structured block. 11463 // longjmp() and throw() must not violate the entry/exit criteria. 11464 CS->getCapturedDecl()->setNothrow(); 11465 } 11466 11467 OMPLoopDirective::HelperExprs B; 11468 // In presence of clause 'collapse' with number of loops, it will 11469 // define the nested loops number. 11470 unsigned NestedLoopCount = checkOpenMPLoop( 11471 OMPD_teams_distribute_parallel_for, getCollapseNumberExpr(Clauses), 11472 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 11473 VarsWithImplicitDSA, B); 11474 11475 if (NestedLoopCount == 0) 11476 return StmtError(); 11477 11478 assert((CurContext->isDependentContext() || B.builtAll()) && 11479 "omp for loop exprs were not built"); 11480 11481 setFunctionHasBranchProtectedScope(); 11482 11483 DSAStack->setParentTeamsRegionLoc(StartLoc); 11484 11485 return OMPTeamsDistributeParallelForDirective::Create( 11486 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B, 11487 DSAStack->getTaskgroupReductionRef(), DSAStack->isCancelRegion()); 11488 } 11489 11490 StmtResult Sema::ActOnOpenMPTargetTeamsDirective(ArrayRef<OMPClause *> Clauses, 11491 Stmt *AStmt, 11492 SourceLocation StartLoc, 11493 SourceLocation EndLoc) { 11494 if (!AStmt) 11495 return StmtError(); 11496 11497 auto *CS = cast<CapturedStmt>(AStmt); 11498 // 1.2.2 OpenMP Language Terminology 11499 // Structured block - An executable statement with a single entry at the 11500 // top and a single exit at the bottom. 11501 // The point of exit cannot be a branch out of the structured block. 11502 // longjmp() and throw() must not violate the entry/exit criteria. 11503 CS->getCapturedDecl()->setNothrow(); 11504 11505 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_teams); 11506 ThisCaptureLevel > 1; --ThisCaptureLevel) { 11507 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 11508 // 1.2.2 OpenMP Language Terminology 11509 // Structured block - An executable statement with a single entry at the 11510 // top and a single exit at the bottom. 11511 // The point of exit cannot be a branch out of the structured block. 11512 // longjmp() and throw() must not violate the entry/exit criteria. 11513 CS->getCapturedDecl()->setNothrow(); 11514 } 11515 setFunctionHasBranchProtectedScope(); 11516 11517 return OMPTargetTeamsDirective::Create(Context, StartLoc, EndLoc, Clauses, 11518 AStmt); 11519 } 11520 11521 StmtResult Sema::ActOnOpenMPTargetTeamsDistributeDirective( 11522 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 11523 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 11524 if (!AStmt) 11525 return StmtError(); 11526 11527 auto *CS = cast<CapturedStmt>(AStmt); 11528 // 1.2.2 OpenMP Language Terminology 11529 // Structured block - An executable statement with a single entry at the 11530 // top and a single exit at the bottom. 11531 // The point of exit cannot be a branch out of the structured block. 11532 // longjmp() and throw() must not violate the entry/exit criteria. 11533 CS->getCapturedDecl()->setNothrow(); 11534 for (int ThisCaptureLevel = 11535 getOpenMPCaptureLevels(OMPD_target_teams_distribute); 11536 ThisCaptureLevel > 1; --ThisCaptureLevel) { 11537 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 11538 // 1.2.2 OpenMP Language Terminology 11539 // Structured block - An executable statement with a single entry at the 11540 // top and a single exit at the bottom. 11541 // The point of exit cannot be a branch out of the structured block. 11542 // longjmp() and throw() must not violate the entry/exit criteria. 11543 CS->getCapturedDecl()->setNothrow(); 11544 } 11545 11546 OMPLoopDirective::HelperExprs B; 11547 // In presence of clause 'collapse' with number of loops, it will 11548 // define the nested loops number. 11549 unsigned NestedLoopCount = checkOpenMPLoop( 11550 OMPD_target_teams_distribute, getCollapseNumberExpr(Clauses), 11551 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 11552 VarsWithImplicitDSA, B); 11553 if (NestedLoopCount == 0) 11554 return StmtError(); 11555 11556 assert((CurContext->isDependentContext() || B.builtAll()) && 11557 "omp target teams distribute loop exprs were not built"); 11558 11559 setFunctionHasBranchProtectedScope(); 11560 return OMPTargetTeamsDistributeDirective::Create( 11561 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 11562 } 11563 11564 StmtResult Sema::ActOnOpenMPTargetTeamsDistributeParallelForDirective( 11565 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 11566 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 11567 if (!AStmt) 11568 return StmtError(); 11569 11570 auto *CS = cast<CapturedStmt>(AStmt); 11571 // 1.2.2 OpenMP Language Terminology 11572 // Structured block - An executable statement with a single entry at the 11573 // top and a single exit at the bottom. 11574 // The point of exit cannot be a branch out of the structured block. 11575 // longjmp() and throw() must not violate the entry/exit criteria. 11576 CS->getCapturedDecl()->setNothrow(); 11577 for (int ThisCaptureLevel = 11578 getOpenMPCaptureLevels(OMPD_target_teams_distribute_parallel_for); 11579 ThisCaptureLevel > 1; --ThisCaptureLevel) { 11580 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 11581 // 1.2.2 OpenMP Language Terminology 11582 // Structured block - An executable statement with a single entry at the 11583 // top and a single exit at the bottom. 11584 // The point of exit cannot be a branch out of the structured block. 11585 // longjmp() and throw() must not violate the entry/exit criteria. 11586 CS->getCapturedDecl()->setNothrow(); 11587 } 11588 11589 OMPLoopDirective::HelperExprs B; 11590 // In presence of clause 'collapse' with number of loops, it will 11591 // define the nested loops number. 11592 unsigned NestedLoopCount = checkOpenMPLoop( 11593 OMPD_target_teams_distribute_parallel_for, getCollapseNumberExpr(Clauses), 11594 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 11595 VarsWithImplicitDSA, B); 11596 if (NestedLoopCount == 0) 11597 return StmtError(); 11598 11599 assert((CurContext->isDependentContext() || B.builtAll()) && 11600 "omp target teams distribute parallel for loop exprs were not built"); 11601 11602 if (!CurContext->isDependentContext()) { 11603 // Finalize the clauses that need pre-built expressions for CodeGen. 11604 for (OMPClause *C : Clauses) { 11605 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 11606 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 11607 B.NumIterations, *this, CurScope, 11608 DSAStack)) 11609 return StmtError(); 11610 } 11611 } 11612 11613 setFunctionHasBranchProtectedScope(); 11614 return OMPTargetTeamsDistributeParallelForDirective::Create( 11615 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B, 11616 DSAStack->getTaskgroupReductionRef(), DSAStack->isCancelRegion()); 11617 } 11618 11619 StmtResult Sema::ActOnOpenMPTargetTeamsDistributeParallelForSimdDirective( 11620 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 11621 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 11622 if (!AStmt) 11623 return StmtError(); 11624 11625 auto *CS = cast<CapturedStmt>(AStmt); 11626 // 1.2.2 OpenMP Language Terminology 11627 // Structured block - An executable statement with a single entry at the 11628 // top and a single exit at the bottom. 11629 // The point of exit cannot be a branch out of the structured block. 11630 // longjmp() and throw() must not violate the entry/exit criteria. 11631 CS->getCapturedDecl()->setNothrow(); 11632 for (int ThisCaptureLevel = getOpenMPCaptureLevels( 11633 OMPD_target_teams_distribute_parallel_for_simd); 11634 ThisCaptureLevel > 1; --ThisCaptureLevel) { 11635 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 11636 // 1.2.2 OpenMP Language Terminology 11637 // Structured block - An executable statement with a single entry at the 11638 // top and a single exit at the bottom. 11639 // The point of exit cannot be a branch out of the structured block. 11640 // longjmp() and throw() must not violate the entry/exit criteria. 11641 CS->getCapturedDecl()->setNothrow(); 11642 } 11643 11644 OMPLoopDirective::HelperExprs B; 11645 // In presence of clause 'collapse' with number of loops, it will 11646 // define the nested loops number. 11647 unsigned NestedLoopCount = 11648 checkOpenMPLoop(OMPD_target_teams_distribute_parallel_for_simd, 11649 getCollapseNumberExpr(Clauses), 11650 nullptr /*ordered not a clause on distribute*/, CS, *this, 11651 *DSAStack, VarsWithImplicitDSA, B); 11652 if (NestedLoopCount == 0) 11653 return StmtError(); 11654 11655 assert((CurContext->isDependentContext() || B.builtAll()) && 11656 "omp target teams distribute parallel for simd loop exprs were not " 11657 "built"); 11658 11659 if (!CurContext->isDependentContext()) { 11660 // Finalize the clauses that need pre-built expressions for CodeGen. 11661 for (OMPClause *C : Clauses) { 11662 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 11663 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 11664 B.NumIterations, *this, CurScope, 11665 DSAStack)) 11666 return StmtError(); 11667 } 11668 } 11669 11670 if (checkSimdlenSafelenSpecified(*this, Clauses)) 11671 return StmtError(); 11672 11673 setFunctionHasBranchProtectedScope(); 11674 return OMPTargetTeamsDistributeParallelForSimdDirective::Create( 11675 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 11676 } 11677 11678 StmtResult Sema::ActOnOpenMPTargetTeamsDistributeSimdDirective( 11679 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 11680 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 11681 if (!AStmt) 11682 return StmtError(); 11683 11684 auto *CS = cast<CapturedStmt>(AStmt); 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 for (int ThisCaptureLevel = 11692 getOpenMPCaptureLevels(OMPD_target_teams_distribute_simd); 11693 ThisCaptureLevel > 1; --ThisCaptureLevel) { 11694 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 11695 // 1.2.2 OpenMP Language Terminology 11696 // Structured block - An executable statement with a single entry at the 11697 // top and a single exit at the bottom. 11698 // The point of exit cannot be a branch out of the structured block. 11699 // longjmp() and throw() must not violate the entry/exit criteria. 11700 CS->getCapturedDecl()->setNothrow(); 11701 } 11702 11703 OMPLoopDirective::HelperExprs B; 11704 // In presence of clause 'collapse' with number of loops, it will 11705 // define the nested loops number. 11706 unsigned NestedLoopCount = checkOpenMPLoop( 11707 OMPD_target_teams_distribute_simd, getCollapseNumberExpr(Clauses), 11708 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 11709 VarsWithImplicitDSA, B); 11710 if (NestedLoopCount == 0) 11711 return StmtError(); 11712 11713 assert((CurContext->isDependentContext() || B.builtAll()) && 11714 "omp target teams distribute simd loop exprs were not built"); 11715 11716 if (!CurContext->isDependentContext()) { 11717 // Finalize the clauses that need pre-built expressions for CodeGen. 11718 for (OMPClause *C : Clauses) { 11719 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 11720 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 11721 B.NumIterations, *this, CurScope, 11722 DSAStack)) 11723 return StmtError(); 11724 } 11725 } 11726 11727 if (checkSimdlenSafelenSpecified(*this, Clauses)) 11728 return StmtError(); 11729 11730 setFunctionHasBranchProtectedScope(); 11731 return OMPTargetTeamsDistributeSimdDirective::Create( 11732 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 11733 } 11734 11735 OMPClause *Sema::ActOnOpenMPSingleExprClause(OpenMPClauseKind Kind, Expr *Expr, 11736 SourceLocation StartLoc, 11737 SourceLocation LParenLoc, 11738 SourceLocation EndLoc) { 11739 OMPClause *Res = nullptr; 11740 switch (Kind) { 11741 case OMPC_final: 11742 Res = ActOnOpenMPFinalClause(Expr, StartLoc, LParenLoc, EndLoc); 11743 break; 11744 case OMPC_num_threads: 11745 Res = ActOnOpenMPNumThreadsClause(Expr, StartLoc, LParenLoc, EndLoc); 11746 break; 11747 case OMPC_safelen: 11748 Res = ActOnOpenMPSafelenClause(Expr, StartLoc, LParenLoc, EndLoc); 11749 break; 11750 case OMPC_simdlen: 11751 Res = ActOnOpenMPSimdlenClause(Expr, StartLoc, LParenLoc, EndLoc); 11752 break; 11753 case OMPC_allocator: 11754 Res = ActOnOpenMPAllocatorClause(Expr, StartLoc, LParenLoc, EndLoc); 11755 break; 11756 case OMPC_collapse: 11757 Res = ActOnOpenMPCollapseClause(Expr, StartLoc, LParenLoc, EndLoc); 11758 break; 11759 case OMPC_ordered: 11760 Res = ActOnOpenMPOrderedClause(StartLoc, EndLoc, LParenLoc, Expr); 11761 break; 11762 case OMPC_num_teams: 11763 Res = ActOnOpenMPNumTeamsClause(Expr, StartLoc, LParenLoc, EndLoc); 11764 break; 11765 case OMPC_thread_limit: 11766 Res = ActOnOpenMPThreadLimitClause(Expr, StartLoc, LParenLoc, EndLoc); 11767 break; 11768 case OMPC_priority: 11769 Res = ActOnOpenMPPriorityClause(Expr, StartLoc, LParenLoc, EndLoc); 11770 break; 11771 case OMPC_grainsize: 11772 Res = ActOnOpenMPGrainsizeClause(Expr, StartLoc, LParenLoc, EndLoc); 11773 break; 11774 case OMPC_num_tasks: 11775 Res = ActOnOpenMPNumTasksClause(Expr, StartLoc, LParenLoc, EndLoc); 11776 break; 11777 case OMPC_hint: 11778 Res = ActOnOpenMPHintClause(Expr, StartLoc, LParenLoc, EndLoc); 11779 break; 11780 case OMPC_depobj: 11781 Res = ActOnOpenMPDepobjClause(Expr, StartLoc, LParenLoc, EndLoc); 11782 break; 11783 case OMPC_detach: 11784 Res = ActOnOpenMPDetachClause(Expr, StartLoc, LParenLoc, EndLoc); 11785 break; 11786 case OMPC_device: 11787 case OMPC_if: 11788 case OMPC_default: 11789 case OMPC_proc_bind: 11790 case OMPC_schedule: 11791 case OMPC_private: 11792 case OMPC_firstprivate: 11793 case OMPC_lastprivate: 11794 case OMPC_shared: 11795 case OMPC_reduction: 11796 case OMPC_task_reduction: 11797 case OMPC_in_reduction: 11798 case OMPC_linear: 11799 case OMPC_aligned: 11800 case OMPC_copyin: 11801 case OMPC_copyprivate: 11802 case OMPC_nowait: 11803 case OMPC_untied: 11804 case OMPC_mergeable: 11805 case OMPC_threadprivate: 11806 case OMPC_allocate: 11807 case OMPC_flush: 11808 case OMPC_read: 11809 case OMPC_write: 11810 case OMPC_update: 11811 case OMPC_capture: 11812 case OMPC_seq_cst: 11813 case OMPC_acq_rel: 11814 case OMPC_acquire: 11815 case OMPC_release: 11816 case OMPC_relaxed: 11817 case OMPC_depend: 11818 case OMPC_threads: 11819 case OMPC_simd: 11820 case OMPC_map: 11821 case OMPC_nogroup: 11822 case OMPC_dist_schedule: 11823 case OMPC_defaultmap: 11824 case OMPC_unknown: 11825 case OMPC_uniform: 11826 case OMPC_to: 11827 case OMPC_from: 11828 case OMPC_use_device_ptr: 11829 case OMPC_use_device_addr: 11830 case OMPC_is_device_ptr: 11831 case OMPC_unified_address: 11832 case OMPC_unified_shared_memory: 11833 case OMPC_reverse_offload: 11834 case OMPC_dynamic_allocators: 11835 case OMPC_atomic_default_mem_order: 11836 case OMPC_device_type: 11837 case OMPC_match: 11838 case OMPC_nontemporal: 11839 case OMPC_order: 11840 case OMPC_destroy: 11841 case OMPC_inclusive: 11842 case OMPC_exclusive: 11843 case OMPC_uses_allocators: 11844 case OMPC_affinity: 11845 default: 11846 llvm_unreachable("Clause is not allowed."); 11847 } 11848 return Res; 11849 } 11850 11851 // An OpenMP directive such as 'target parallel' has two captured regions: 11852 // for the 'target' and 'parallel' respectively. This function returns 11853 // the region in which to capture expressions associated with a clause. 11854 // A return value of OMPD_unknown signifies that the expression should not 11855 // be captured. 11856 static OpenMPDirectiveKind getOpenMPCaptureRegionForClause( 11857 OpenMPDirectiveKind DKind, OpenMPClauseKind CKind, unsigned OpenMPVersion, 11858 OpenMPDirectiveKind NameModifier = OMPD_unknown) { 11859 OpenMPDirectiveKind CaptureRegion = OMPD_unknown; 11860 switch (CKind) { 11861 case OMPC_if: 11862 switch (DKind) { 11863 case OMPD_target_parallel_for_simd: 11864 if (OpenMPVersion >= 50 && 11865 (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)) { 11866 CaptureRegion = OMPD_parallel; 11867 break; 11868 } 11869 LLVM_FALLTHROUGH; 11870 case OMPD_target_parallel: 11871 case OMPD_target_parallel_for: 11872 // If this clause applies to the nested 'parallel' region, capture within 11873 // the 'target' region, otherwise do not capture. 11874 if (NameModifier == OMPD_unknown || NameModifier == OMPD_parallel) 11875 CaptureRegion = OMPD_target; 11876 break; 11877 case OMPD_target_teams_distribute_parallel_for_simd: 11878 if (OpenMPVersion >= 50 && 11879 (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)) { 11880 CaptureRegion = OMPD_parallel; 11881 break; 11882 } 11883 LLVM_FALLTHROUGH; 11884 case OMPD_target_teams_distribute_parallel_for: 11885 // If this clause applies to the nested 'parallel' region, capture within 11886 // the 'teams' region, otherwise do not capture. 11887 if (NameModifier == OMPD_unknown || NameModifier == OMPD_parallel) 11888 CaptureRegion = OMPD_teams; 11889 break; 11890 case OMPD_teams_distribute_parallel_for_simd: 11891 if (OpenMPVersion >= 50 && 11892 (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)) { 11893 CaptureRegion = OMPD_parallel; 11894 break; 11895 } 11896 LLVM_FALLTHROUGH; 11897 case OMPD_teams_distribute_parallel_for: 11898 CaptureRegion = OMPD_teams; 11899 break; 11900 case OMPD_target_update: 11901 case OMPD_target_enter_data: 11902 case OMPD_target_exit_data: 11903 CaptureRegion = OMPD_task; 11904 break; 11905 case OMPD_parallel_master_taskloop: 11906 if (NameModifier == OMPD_unknown || NameModifier == OMPD_taskloop) 11907 CaptureRegion = OMPD_parallel; 11908 break; 11909 case OMPD_parallel_master_taskloop_simd: 11910 if ((OpenMPVersion <= 45 && NameModifier == OMPD_unknown) || 11911 NameModifier == OMPD_taskloop) { 11912 CaptureRegion = OMPD_parallel; 11913 break; 11914 } 11915 if (OpenMPVersion <= 45) 11916 break; 11917 if (NameModifier == OMPD_unknown || NameModifier == OMPD_simd) 11918 CaptureRegion = OMPD_taskloop; 11919 break; 11920 case OMPD_parallel_for_simd: 11921 if (OpenMPVersion <= 45) 11922 break; 11923 if (NameModifier == OMPD_unknown || NameModifier == OMPD_simd) 11924 CaptureRegion = OMPD_parallel; 11925 break; 11926 case OMPD_taskloop_simd: 11927 case OMPD_master_taskloop_simd: 11928 if (OpenMPVersion <= 45) 11929 break; 11930 if (NameModifier == OMPD_unknown || NameModifier == OMPD_simd) 11931 CaptureRegion = OMPD_taskloop; 11932 break; 11933 case OMPD_distribute_parallel_for_simd: 11934 if (OpenMPVersion <= 45) 11935 break; 11936 if (NameModifier == OMPD_unknown || NameModifier == OMPD_simd) 11937 CaptureRegion = OMPD_parallel; 11938 break; 11939 case OMPD_target_simd: 11940 if (OpenMPVersion >= 50 && 11941 (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)) 11942 CaptureRegion = OMPD_target; 11943 break; 11944 case OMPD_teams_distribute_simd: 11945 case OMPD_target_teams_distribute_simd: 11946 if (OpenMPVersion >= 50 && 11947 (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)) 11948 CaptureRegion = OMPD_teams; 11949 break; 11950 case OMPD_cancel: 11951 case OMPD_parallel: 11952 case OMPD_parallel_master: 11953 case OMPD_parallel_sections: 11954 case OMPD_parallel_for: 11955 case OMPD_target: 11956 case OMPD_target_teams: 11957 case OMPD_target_teams_distribute: 11958 case OMPD_distribute_parallel_for: 11959 case OMPD_task: 11960 case OMPD_taskloop: 11961 case OMPD_master_taskloop: 11962 case OMPD_target_data: 11963 case OMPD_simd: 11964 case OMPD_for_simd: 11965 case OMPD_distribute_simd: 11966 // Do not capture if-clause expressions. 11967 break; 11968 case OMPD_threadprivate: 11969 case OMPD_allocate: 11970 case OMPD_taskyield: 11971 case OMPD_barrier: 11972 case OMPD_taskwait: 11973 case OMPD_cancellation_point: 11974 case OMPD_flush: 11975 case OMPD_depobj: 11976 case OMPD_scan: 11977 case OMPD_declare_reduction: 11978 case OMPD_declare_mapper: 11979 case OMPD_declare_simd: 11980 case OMPD_declare_variant: 11981 case OMPD_begin_declare_variant: 11982 case OMPD_end_declare_variant: 11983 case OMPD_declare_target: 11984 case OMPD_end_declare_target: 11985 case OMPD_teams: 11986 case OMPD_for: 11987 case OMPD_sections: 11988 case OMPD_section: 11989 case OMPD_single: 11990 case OMPD_master: 11991 case OMPD_critical: 11992 case OMPD_taskgroup: 11993 case OMPD_distribute: 11994 case OMPD_ordered: 11995 case OMPD_atomic: 11996 case OMPD_teams_distribute: 11997 case OMPD_requires: 11998 llvm_unreachable("Unexpected OpenMP directive with if-clause"); 11999 case OMPD_unknown: 12000 default: 12001 llvm_unreachable("Unknown OpenMP directive"); 12002 } 12003 break; 12004 case OMPC_num_threads: 12005 switch (DKind) { 12006 case OMPD_target_parallel: 12007 case OMPD_target_parallel_for: 12008 case OMPD_target_parallel_for_simd: 12009 CaptureRegion = OMPD_target; 12010 break; 12011 case OMPD_teams_distribute_parallel_for: 12012 case OMPD_teams_distribute_parallel_for_simd: 12013 case OMPD_target_teams_distribute_parallel_for: 12014 case OMPD_target_teams_distribute_parallel_for_simd: 12015 CaptureRegion = OMPD_teams; 12016 break; 12017 case OMPD_parallel: 12018 case OMPD_parallel_master: 12019 case OMPD_parallel_sections: 12020 case OMPD_parallel_for: 12021 case OMPD_parallel_for_simd: 12022 case OMPD_distribute_parallel_for: 12023 case OMPD_distribute_parallel_for_simd: 12024 case OMPD_parallel_master_taskloop: 12025 case OMPD_parallel_master_taskloop_simd: 12026 // Do not capture num_threads-clause expressions. 12027 break; 12028 case OMPD_target_data: 12029 case OMPD_target_enter_data: 12030 case OMPD_target_exit_data: 12031 case OMPD_target_update: 12032 case OMPD_target: 12033 case OMPD_target_simd: 12034 case OMPD_target_teams: 12035 case OMPD_target_teams_distribute: 12036 case OMPD_target_teams_distribute_simd: 12037 case OMPD_cancel: 12038 case OMPD_task: 12039 case OMPD_taskloop: 12040 case OMPD_taskloop_simd: 12041 case OMPD_master_taskloop: 12042 case OMPD_master_taskloop_simd: 12043 case OMPD_threadprivate: 12044 case OMPD_allocate: 12045 case OMPD_taskyield: 12046 case OMPD_barrier: 12047 case OMPD_taskwait: 12048 case OMPD_cancellation_point: 12049 case OMPD_flush: 12050 case OMPD_depobj: 12051 case OMPD_scan: 12052 case OMPD_declare_reduction: 12053 case OMPD_declare_mapper: 12054 case OMPD_declare_simd: 12055 case OMPD_declare_variant: 12056 case OMPD_begin_declare_variant: 12057 case OMPD_end_declare_variant: 12058 case OMPD_declare_target: 12059 case OMPD_end_declare_target: 12060 case OMPD_teams: 12061 case OMPD_simd: 12062 case OMPD_for: 12063 case OMPD_for_simd: 12064 case OMPD_sections: 12065 case OMPD_section: 12066 case OMPD_single: 12067 case OMPD_master: 12068 case OMPD_critical: 12069 case OMPD_taskgroup: 12070 case OMPD_distribute: 12071 case OMPD_ordered: 12072 case OMPD_atomic: 12073 case OMPD_distribute_simd: 12074 case OMPD_teams_distribute: 12075 case OMPD_teams_distribute_simd: 12076 case OMPD_requires: 12077 llvm_unreachable("Unexpected OpenMP directive with num_threads-clause"); 12078 case OMPD_unknown: 12079 default: 12080 llvm_unreachable("Unknown OpenMP directive"); 12081 } 12082 break; 12083 case OMPC_num_teams: 12084 switch (DKind) { 12085 case OMPD_target_teams: 12086 case OMPD_target_teams_distribute: 12087 case OMPD_target_teams_distribute_simd: 12088 case OMPD_target_teams_distribute_parallel_for: 12089 case OMPD_target_teams_distribute_parallel_for_simd: 12090 CaptureRegion = OMPD_target; 12091 break; 12092 case OMPD_teams_distribute_parallel_for: 12093 case OMPD_teams_distribute_parallel_for_simd: 12094 case OMPD_teams: 12095 case OMPD_teams_distribute: 12096 case OMPD_teams_distribute_simd: 12097 // Do not capture num_teams-clause expressions. 12098 break; 12099 case OMPD_distribute_parallel_for: 12100 case OMPD_distribute_parallel_for_simd: 12101 case OMPD_task: 12102 case OMPD_taskloop: 12103 case OMPD_taskloop_simd: 12104 case OMPD_master_taskloop: 12105 case OMPD_master_taskloop_simd: 12106 case OMPD_parallel_master_taskloop: 12107 case OMPD_parallel_master_taskloop_simd: 12108 case OMPD_target_data: 12109 case OMPD_target_enter_data: 12110 case OMPD_target_exit_data: 12111 case OMPD_target_update: 12112 case OMPD_cancel: 12113 case OMPD_parallel: 12114 case OMPD_parallel_master: 12115 case OMPD_parallel_sections: 12116 case OMPD_parallel_for: 12117 case OMPD_parallel_for_simd: 12118 case OMPD_target: 12119 case OMPD_target_simd: 12120 case OMPD_target_parallel: 12121 case OMPD_target_parallel_for: 12122 case OMPD_target_parallel_for_simd: 12123 case OMPD_threadprivate: 12124 case OMPD_allocate: 12125 case OMPD_taskyield: 12126 case OMPD_barrier: 12127 case OMPD_taskwait: 12128 case OMPD_cancellation_point: 12129 case OMPD_flush: 12130 case OMPD_depobj: 12131 case OMPD_scan: 12132 case OMPD_declare_reduction: 12133 case OMPD_declare_mapper: 12134 case OMPD_declare_simd: 12135 case OMPD_declare_variant: 12136 case OMPD_begin_declare_variant: 12137 case OMPD_end_declare_variant: 12138 case OMPD_declare_target: 12139 case OMPD_end_declare_target: 12140 case OMPD_simd: 12141 case OMPD_for: 12142 case OMPD_for_simd: 12143 case OMPD_sections: 12144 case OMPD_section: 12145 case OMPD_single: 12146 case OMPD_master: 12147 case OMPD_critical: 12148 case OMPD_taskgroup: 12149 case OMPD_distribute: 12150 case OMPD_ordered: 12151 case OMPD_atomic: 12152 case OMPD_distribute_simd: 12153 case OMPD_requires: 12154 llvm_unreachable("Unexpected OpenMP directive with num_teams-clause"); 12155 case OMPD_unknown: 12156 default: 12157 llvm_unreachable("Unknown OpenMP directive"); 12158 } 12159 break; 12160 case OMPC_thread_limit: 12161 switch (DKind) { 12162 case OMPD_target_teams: 12163 case OMPD_target_teams_distribute: 12164 case OMPD_target_teams_distribute_simd: 12165 case OMPD_target_teams_distribute_parallel_for: 12166 case OMPD_target_teams_distribute_parallel_for_simd: 12167 CaptureRegion = OMPD_target; 12168 break; 12169 case OMPD_teams_distribute_parallel_for: 12170 case OMPD_teams_distribute_parallel_for_simd: 12171 case OMPD_teams: 12172 case OMPD_teams_distribute: 12173 case OMPD_teams_distribute_simd: 12174 // Do not capture thread_limit-clause expressions. 12175 break; 12176 case OMPD_distribute_parallel_for: 12177 case OMPD_distribute_parallel_for_simd: 12178 case OMPD_task: 12179 case OMPD_taskloop: 12180 case OMPD_taskloop_simd: 12181 case OMPD_master_taskloop: 12182 case OMPD_master_taskloop_simd: 12183 case OMPD_parallel_master_taskloop: 12184 case OMPD_parallel_master_taskloop_simd: 12185 case OMPD_target_data: 12186 case OMPD_target_enter_data: 12187 case OMPD_target_exit_data: 12188 case OMPD_target_update: 12189 case OMPD_cancel: 12190 case OMPD_parallel: 12191 case OMPD_parallel_master: 12192 case OMPD_parallel_sections: 12193 case OMPD_parallel_for: 12194 case OMPD_parallel_for_simd: 12195 case OMPD_target: 12196 case OMPD_target_simd: 12197 case OMPD_target_parallel: 12198 case OMPD_target_parallel_for: 12199 case OMPD_target_parallel_for_simd: 12200 case OMPD_threadprivate: 12201 case OMPD_allocate: 12202 case OMPD_taskyield: 12203 case OMPD_barrier: 12204 case OMPD_taskwait: 12205 case OMPD_cancellation_point: 12206 case OMPD_flush: 12207 case OMPD_depobj: 12208 case OMPD_scan: 12209 case OMPD_declare_reduction: 12210 case OMPD_declare_mapper: 12211 case OMPD_declare_simd: 12212 case OMPD_declare_variant: 12213 case OMPD_begin_declare_variant: 12214 case OMPD_end_declare_variant: 12215 case OMPD_declare_target: 12216 case OMPD_end_declare_target: 12217 case OMPD_simd: 12218 case OMPD_for: 12219 case OMPD_for_simd: 12220 case OMPD_sections: 12221 case OMPD_section: 12222 case OMPD_single: 12223 case OMPD_master: 12224 case OMPD_critical: 12225 case OMPD_taskgroup: 12226 case OMPD_distribute: 12227 case OMPD_ordered: 12228 case OMPD_atomic: 12229 case OMPD_distribute_simd: 12230 case OMPD_requires: 12231 llvm_unreachable("Unexpected OpenMP directive with thread_limit-clause"); 12232 case OMPD_unknown: 12233 default: 12234 llvm_unreachable("Unknown OpenMP directive"); 12235 } 12236 break; 12237 case OMPC_schedule: 12238 switch (DKind) { 12239 case OMPD_parallel_for: 12240 case OMPD_parallel_for_simd: 12241 case OMPD_distribute_parallel_for: 12242 case OMPD_distribute_parallel_for_simd: 12243 case OMPD_teams_distribute_parallel_for: 12244 case OMPD_teams_distribute_parallel_for_simd: 12245 case OMPD_target_parallel_for: 12246 case OMPD_target_parallel_for_simd: 12247 case OMPD_target_teams_distribute_parallel_for: 12248 case OMPD_target_teams_distribute_parallel_for_simd: 12249 CaptureRegion = OMPD_parallel; 12250 break; 12251 case OMPD_for: 12252 case OMPD_for_simd: 12253 // Do not capture schedule-clause expressions. 12254 break; 12255 case OMPD_task: 12256 case OMPD_taskloop: 12257 case OMPD_taskloop_simd: 12258 case OMPD_master_taskloop: 12259 case OMPD_master_taskloop_simd: 12260 case OMPD_parallel_master_taskloop: 12261 case OMPD_parallel_master_taskloop_simd: 12262 case OMPD_target_data: 12263 case OMPD_target_enter_data: 12264 case OMPD_target_exit_data: 12265 case OMPD_target_update: 12266 case OMPD_teams: 12267 case OMPD_teams_distribute: 12268 case OMPD_teams_distribute_simd: 12269 case OMPD_target_teams_distribute: 12270 case OMPD_target_teams_distribute_simd: 12271 case OMPD_target: 12272 case OMPD_target_simd: 12273 case OMPD_target_parallel: 12274 case OMPD_cancel: 12275 case OMPD_parallel: 12276 case OMPD_parallel_master: 12277 case OMPD_parallel_sections: 12278 case OMPD_threadprivate: 12279 case OMPD_allocate: 12280 case OMPD_taskyield: 12281 case OMPD_barrier: 12282 case OMPD_taskwait: 12283 case OMPD_cancellation_point: 12284 case OMPD_flush: 12285 case OMPD_depobj: 12286 case OMPD_scan: 12287 case OMPD_declare_reduction: 12288 case OMPD_declare_mapper: 12289 case OMPD_declare_simd: 12290 case OMPD_declare_variant: 12291 case OMPD_begin_declare_variant: 12292 case OMPD_end_declare_variant: 12293 case OMPD_declare_target: 12294 case OMPD_end_declare_target: 12295 case OMPD_simd: 12296 case OMPD_sections: 12297 case OMPD_section: 12298 case OMPD_single: 12299 case OMPD_master: 12300 case OMPD_critical: 12301 case OMPD_taskgroup: 12302 case OMPD_distribute: 12303 case OMPD_ordered: 12304 case OMPD_atomic: 12305 case OMPD_distribute_simd: 12306 case OMPD_target_teams: 12307 case OMPD_requires: 12308 llvm_unreachable("Unexpected OpenMP directive with schedule clause"); 12309 case OMPD_unknown: 12310 default: 12311 llvm_unreachable("Unknown OpenMP directive"); 12312 } 12313 break; 12314 case OMPC_dist_schedule: 12315 switch (DKind) { 12316 case OMPD_teams_distribute_parallel_for: 12317 case OMPD_teams_distribute_parallel_for_simd: 12318 case OMPD_teams_distribute: 12319 case OMPD_teams_distribute_simd: 12320 case OMPD_target_teams_distribute_parallel_for: 12321 case OMPD_target_teams_distribute_parallel_for_simd: 12322 case OMPD_target_teams_distribute: 12323 case OMPD_target_teams_distribute_simd: 12324 CaptureRegion = OMPD_teams; 12325 break; 12326 case OMPD_distribute_parallel_for: 12327 case OMPD_distribute_parallel_for_simd: 12328 case OMPD_distribute: 12329 case OMPD_distribute_simd: 12330 // Do not capture thread_limit-clause expressions. 12331 break; 12332 case OMPD_parallel_for: 12333 case OMPD_parallel_for_simd: 12334 case OMPD_target_parallel_for_simd: 12335 case OMPD_target_parallel_for: 12336 case OMPD_task: 12337 case OMPD_taskloop: 12338 case OMPD_taskloop_simd: 12339 case OMPD_master_taskloop: 12340 case OMPD_master_taskloop_simd: 12341 case OMPD_parallel_master_taskloop: 12342 case OMPD_parallel_master_taskloop_simd: 12343 case OMPD_target_data: 12344 case OMPD_target_enter_data: 12345 case OMPD_target_exit_data: 12346 case OMPD_target_update: 12347 case OMPD_teams: 12348 case OMPD_target: 12349 case OMPD_target_simd: 12350 case OMPD_target_parallel: 12351 case OMPD_cancel: 12352 case OMPD_parallel: 12353 case OMPD_parallel_master: 12354 case OMPD_parallel_sections: 12355 case OMPD_threadprivate: 12356 case OMPD_allocate: 12357 case OMPD_taskyield: 12358 case OMPD_barrier: 12359 case OMPD_taskwait: 12360 case OMPD_cancellation_point: 12361 case OMPD_flush: 12362 case OMPD_depobj: 12363 case OMPD_scan: 12364 case OMPD_declare_reduction: 12365 case OMPD_declare_mapper: 12366 case OMPD_declare_simd: 12367 case OMPD_declare_variant: 12368 case OMPD_begin_declare_variant: 12369 case OMPD_end_declare_variant: 12370 case OMPD_declare_target: 12371 case OMPD_end_declare_target: 12372 case OMPD_simd: 12373 case OMPD_for: 12374 case OMPD_for_simd: 12375 case OMPD_sections: 12376 case OMPD_section: 12377 case OMPD_single: 12378 case OMPD_master: 12379 case OMPD_critical: 12380 case OMPD_taskgroup: 12381 case OMPD_ordered: 12382 case OMPD_atomic: 12383 case OMPD_target_teams: 12384 case OMPD_requires: 12385 llvm_unreachable("Unexpected OpenMP directive with schedule clause"); 12386 case OMPD_unknown: 12387 default: 12388 llvm_unreachable("Unknown OpenMP directive"); 12389 } 12390 break; 12391 case OMPC_device: 12392 switch (DKind) { 12393 case OMPD_target_update: 12394 case OMPD_target_enter_data: 12395 case OMPD_target_exit_data: 12396 case OMPD_target: 12397 case OMPD_target_simd: 12398 case OMPD_target_teams: 12399 case OMPD_target_parallel: 12400 case OMPD_target_teams_distribute: 12401 case OMPD_target_teams_distribute_simd: 12402 case OMPD_target_parallel_for: 12403 case OMPD_target_parallel_for_simd: 12404 case OMPD_target_teams_distribute_parallel_for: 12405 case OMPD_target_teams_distribute_parallel_for_simd: 12406 CaptureRegion = OMPD_task; 12407 break; 12408 case OMPD_target_data: 12409 // Do not capture device-clause expressions. 12410 break; 12411 case OMPD_teams_distribute_parallel_for: 12412 case OMPD_teams_distribute_parallel_for_simd: 12413 case OMPD_teams: 12414 case OMPD_teams_distribute: 12415 case OMPD_teams_distribute_simd: 12416 case OMPD_distribute_parallel_for: 12417 case OMPD_distribute_parallel_for_simd: 12418 case OMPD_task: 12419 case OMPD_taskloop: 12420 case OMPD_taskloop_simd: 12421 case OMPD_master_taskloop: 12422 case OMPD_master_taskloop_simd: 12423 case OMPD_parallel_master_taskloop: 12424 case OMPD_parallel_master_taskloop_simd: 12425 case OMPD_cancel: 12426 case OMPD_parallel: 12427 case OMPD_parallel_master: 12428 case OMPD_parallel_sections: 12429 case OMPD_parallel_for: 12430 case OMPD_parallel_for_simd: 12431 case OMPD_threadprivate: 12432 case OMPD_allocate: 12433 case OMPD_taskyield: 12434 case OMPD_barrier: 12435 case OMPD_taskwait: 12436 case OMPD_cancellation_point: 12437 case OMPD_flush: 12438 case OMPD_depobj: 12439 case OMPD_scan: 12440 case OMPD_declare_reduction: 12441 case OMPD_declare_mapper: 12442 case OMPD_declare_simd: 12443 case OMPD_declare_variant: 12444 case OMPD_begin_declare_variant: 12445 case OMPD_end_declare_variant: 12446 case OMPD_declare_target: 12447 case OMPD_end_declare_target: 12448 case OMPD_simd: 12449 case OMPD_for: 12450 case OMPD_for_simd: 12451 case OMPD_sections: 12452 case OMPD_section: 12453 case OMPD_single: 12454 case OMPD_master: 12455 case OMPD_critical: 12456 case OMPD_taskgroup: 12457 case OMPD_distribute: 12458 case OMPD_ordered: 12459 case OMPD_atomic: 12460 case OMPD_distribute_simd: 12461 case OMPD_requires: 12462 llvm_unreachable("Unexpected OpenMP directive with num_teams-clause"); 12463 case OMPD_unknown: 12464 default: 12465 llvm_unreachable("Unknown OpenMP directive"); 12466 } 12467 break; 12468 case OMPC_grainsize: 12469 case OMPC_num_tasks: 12470 case OMPC_final: 12471 case OMPC_priority: 12472 switch (DKind) { 12473 case OMPD_task: 12474 case OMPD_taskloop: 12475 case OMPD_taskloop_simd: 12476 case OMPD_master_taskloop: 12477 case OMPD_master_taskloop_simd: 12478 break; 12479 case OMPD_parallel_master_taskloop: 12480 case OMPD_parallel_master_taskloop_simd: 12481 CaptureRegion = OMPD_parallel; 12482 break; 12483 case OMPD_target_update: 12484 case OMPD_target_enter_data: 12485 case OMPD_target_exit_data: 12486 case OMPD_target: 12487 case OMPD_target_simd: 12488 case OMPD_target_teams: 12489 case OMPD_target_parallel: 12490 case OMPD_target_teams_distribute: 12491 case OMPD_target_teams_distribute_simd: 12492 case OMPD_target_parallel_for: 12493 case OMPD_target_parallel_for_simd: 12494 case OMPD_target_teams_distribute_parallel_for: 12495 case OMPD_target_teams_distribute_parallel_for_simd: 12496 case OMPD_target_data: 12497 case OMPD_teams_distribute_parallel_for: 12498 case OMPD_teams_distribute_parallel_for_simd: 12499 case OMPD_teams: 12500 case OMPD_teams_distribute: 12501 case OMPD_teams_distribute_simd: 12502 case OMPD_distribute_parallel_for: 12503 case OMPD_distribute_parallel_for_simd: 12504 case OMPD_cancel: 12505 case OMPD_parallel: 12506 case OMPD_parallel_master: 12507 case OMPD_parallel_sections: 12508 case OMPD_parallel_for: 12509 case OMPD_parallel_for_simd: 12510 case OMPD_threadprivate: 12511 case OMPD_allocate: 12512 case OMPD_taskyield: 12513 case OMPD_barrier: 12514 case OMPD_taskwait: 12515 case OMPD_cancellation_point: 12516 case OMPD_flush: 12517 case OMPD_depobj: 12518 case OMPD_scan: 12519 case OMPD_declare_reduction: 12520 case OMPD_declare_mapper: 12521 case OMPD_declare_simd: 12522 case OMPD_declare_variant: 12523 case OMPD_begin_declare_variant: 12524 case OMPD_end_declare_variant: 12525 case OMPD_declare_target: 12526 case OMPD_end_declare_target: 12527 case OMPD_simd: 12528 case OMPD_for: 12529 case OMPD_for_simd: 12530 case OMPD_sections: 12531 case OMPD_section: 12532 case OMPD_single: 12533 case OMPD_master: 12534 case OMPD_critical: 12535 case OMPD_taskgroup: 12536 case OMPD_distribute: 12537 case OMPD_ordered: 12538 case OMPD_atomic: 12539 case OMPD_distribute_simd: 12540 case OMPD_requires: 12541 llvm_unreachable("Unexpected OpenMP directive with grainsize-clause"); 12542 case OMPD_unknown: 12543 default: 12544 llvm_unreachable("Unknown OpenMP directive"); 12545 } 12546 break; 12547 case OMPC_firstprivate: 12548 case OMPC_lastprivate: 12549 case OMPC_reduction: 12550 case OMPC_task_reduction: 12551 case OMPC_in_reduction: 12552 case OMPC_linear: 12553 case OMPC_default: 12554 case OMPC_proc_bind: 12555 case OMPC_safelen: 12556 case OMPC_simdlen: 12557 case OMPC_allocator: 12558 case OMPC_collapse: 12559 case OMPC_private: 12560 case OMPC_shared: 12561 case OMPC_aligned: 12562 case OMPC_copyin: 12563 case OMPC_copyprivate: 12564 case OMPC_ordered: 12565 case OMPC_nowait: 12566 case OMPC_untied: 12567 case OMPC_mergeable: 12568 case OMPC_threadprivate: 12569 case OMPC_allocate: 12570 case OMPC_flush: 12571 case OMPC_depobj: 12572 case OMPC_read: 12573 case OMPC_write: 12574 case OMPC_update: 12575 case OMPC_capture: 12576 case OMPC_seq_cst: 12577 case OMPC_acq_rel: 12578 case OMPC_acquire: 12579 case OMPC_release: 12580 case OMPC_relaxed: 12581 case OMPC_depend: 12582 case OMPC_threads: 12583 case OMPC_simd: 12584 case OMPC_map: 12585 case OMPC_nogroup: 12586 case OMPC_hint: 12587 case OMPC_defaultmap: 12588 case OMPC_unknown: 12589 case OMPC_uniform: 12590 case OMPC_to: 12591 case OMPC_from: 12592 case OMPC_use_device_ptr: 12593 case OMPC_use_device_addr: 12594 case OMPC_is_device_ptr: 12595 case OMPC_unified_address: 12596 case OMPC_unified_shared_memory: 12597 case OMPC_reverse_offload: 12598 case OMPC_dynamic_allocators: 12599 case OMPC_atomic_default_mem_order: 12600 case OMPC_device_type: 12601 case OMPC_match: 12602 case OMPC_nontemporal: 12603 case OMPC_order: 12604 case OMPC_destroy: 12605 case OMPC_detach: 12606 case OMPC_inclusive: 12607 case OMPC_exclusive: 12608 case OMPC_uses_allocators: 12609 case OMPC_affinity: 12610 default: 12611 llvm_unreachable("Unexpected OpenMP clause."); 12612 } 12613 return CaptureRegion; 12614 } 12615 12616 OMPClause *Sema::ActOnOpenMPIfClause(OpenMPDirectiveKind NameModifier, 12617 Expr *Condition, SourceLocation StartLoc, 12618 SourceLocation LParenLoc, 12619 SourceLocation NameModifierLoc, 12620 SourceLocation ColonLoc, 12621 SourceLocation EndLoc) { 12622 Expr *ValExpr = Condition; 12623 Stmt *HelperValStmt = nullptr; 12624 OpenMPDirectiveKind CaptureRegion = OMPD_unknown; 12625 if (!Condition->isValueDependent() && !Condition->isTypeDependent() && 12626 !Condition->isInstantiationDependent() && 12627 !Condition->containsUnexpandedParameterPack()) { 12628 ExprResult Val = CheckBooleanCondition(StartLoc, Condition); 12629 if (Val.isInvalid()) 12630 return nullptr; 12631 12632 ValExpr = Val.get(); 12633 12634 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 12635 CaptureRegion = getOpenMPCaptureRegionForClause( 12636 DKind, OMPC_if, LangOpts.OpenMP, NameModifier); 12637 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 12638 ValExpr = MakeFullExpr(ValExpr).get(); 12639 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 12640 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 12641 HelperValStmt = buildPreInits(Context, Captures); 12642 } 12643 } 12644 12645 return new (Context) 12646 OMPIfClause(NameModifier, ValExpr, HelperValStmt, CaptureRegion, StartLoc, 12647 LParenLoc, NameModifierLoc, ColonLoc, EndLoc); 12648 } 12649 12650 OMPClause *Sema::ActOnOpenMPFinalClause(Expr *Condition, 12651 SourceLocation StartLoc, 12652 SourceLocation LParenLoc, 12653 SourceLocation EndLoc) { 12654 Expr *ValExpr = Condition; 12655 Stmt *HelperValStmt = nullptr; 12656 OpenMPDirectiveKind CaptureRegion = OMPD_unknown; 12657 if (!Condition->isValueDependent() && !Condition->isTypeDependent() && 12658 !Condition->isInstantiationDependent() && 12659 !Condition->containsUnexpandedParameterPack()) { 12660 ExprResult Val = CheckBooleanCondition(StartLoc, Condition); 12661 if (Val.isInvalid()) 12662 return nullptr; 12663 12664 ValExpr = MakeFullExpr(Val.get()).get(); 12665 12666 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 12667 CaptureRegion = 12668 getOpenMPCaptureRegionForClause(DKind, OMPC_final, LangOpts.OpenMP); 12669 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 12670 ValExpr = MakeFullExpr(ValExpr).get(); 12671 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 12672 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 12673 HelperValStmt = buildPreInits(Context, Captures); 12674 } 12675 } 12676 12677 return new (Context) OMPFinalClause(ValExpr, HelperValStmt, CaptureRegion, 12678 StartLoc, LParenLoc, EndLoc); 12679 } 12680 12681 ExprResult Sema::PerformOpenMPImplicitIntegerConversion(SourceLocation Loc, 12682 Expr *Op) { 12683 if (!Op) 12684 return ExprError(); 12685 12686 class IntConvertDiagnoser : public ICEConvertDiagnoser { 12687 public: 12688 IntConvertDiagnoser() 12689 : ICEConvertDiagnoser(/*AllowScopedEnumerations*/ false, false, true) {} 12690 SemaDiagnosticBuilder diagnoseNotInt(Sema &S, SourceLocation Loc, 12691 QualType T) override { 12692 return S.Diag(Loc, diag::err_omp_not_integral) << T; 12693 } 12694 SemaDiagnosticBuilder diagnoseIncomplete(Sema &S, SourceLocation Loc, 12695 QualType T) override { 12696 return S.Diag(Loc, diag::err_omp_incomplete_type) << T; 12697 } 12698 SemaDiagnosticBuilder diagnoseExplicitConv(Sema &S, SourceLocation Loc, 12699 QualType T, 12700 QualType ConvTy) override { 12701 return S.Diag(Loc, diag::err_omp_explicit_conversion) << T << ConvTy; 12702 } 12703 SemaDiagnosticBuilder noteExplicitConv(Sema &S, CXXConversionDecl *Conv, 12704 QualType ConvTy) override { 12705 return S.Diag(Conv->getLocation(), diag::note_omp_conversion_here) 12706 << ConvTy->isEnumeralType() << ConvTy; 12707 } 12708 SemaDiagnosticBuilder diagnoseAmbiguous(Sema &S, SourceLocation Loc, 12709 QualType T) override { 12710 return S.Diag(Loc, diag::err_omp_ambiguous_conversion) << T; 12711 } 12712 SemaDiagnosticBuilder noteAmbiguous(Sema &S, CXXConversionDecl *Conv, 12713 QualType ConvTy) override { 12714 return S.Diag(Conv->getLocation(), diag::note_omp_conversion_here) 12715 << ConvTy->isEnumeralType() << ConvTy; 12716 } 12717 SemaDiagnosticBuilder diagnoseConversion(Sema &, SourceLocation, QualType, 12718 QualType) override { 12719 llvm_unreachable("conversion functions are permitted"); 12720 } 12721 } ConvertDiagnoser; 12722 return PerformContextualImplicitConversion(Loc, Op, ConvertDiagnoser); 12723 } 12724 12725 static bool 12726 isNonNegativeIntegerValue(Expr *&ValExpr, Sema &SemaRef, OpenMPClauseKind CKind, 12727 bool StrictlyPositive, bool BuildCapture = false, 12728 OpenMPDirectiveKind DKind = OMPD_unknown, 12729 OpenMPDirectiveKind *CaptureRegion = nullptr, 12730 Stmt **HelperValStmt = nullptr) { 12731 if (!ValExpr->isTypeDependent() && !ValExpr->isValueDependent() && 12732 !ValExpr->isInstantiationDependent()) { 12733 SourceLocation Loc = ValExpr->getExprLoc(); 12734 ExprResult Value = 12735 SemaRef.PerformOpenMPImplicitIntegerConversion(Loc, ValExpr); 12736 if (Value.isInvalid()) 12737 return false; 12738 12739 ValExpr = Value.get(); 12740 // The expression must evaluate to a non-negative integer value. 12741 if (Optional<llvm::APSInt> Result = 12742 ValExpr->getIntegerConstantExpr(SemaRef.Context)) { 12743 if (Result->isSigned() && 12744 !((!StrictlyPositive && Result->isNonNegative()) || 12745 (StrictlyPositive && Result->isStrictlyPositive()))) { 12746 SemaRef.Diag(Loc, diag::err_omp_negative_expression_in_clause) 12747 << getOpenMPClauseName(CKind) << (StrictlyPositive ? 1 : 0) 12748 << ValExpr->getSourceRange(); 12749 return false; 12750 } 12751 } 12752 if (!BuildCapture) 12753 return true; 12754 *CaptureRegion = 12755 getOpenMPCaptureRegionForClause(DKind, CKind, SemaRef.LangOpts.OpenMP); 12756 if (*CaptureRegion != OMPD_unknown && 12757 !SemaRef.CurContext->isDependentContext()) { 12758 ValExpr = SemaRef.MakeFullExpr(ValExpr).get(); 12759 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 12760 ValExpr = tryBuildCapture(SemaRef, ValExpr, Captures).get(); 12761 *HelperValStmt = buildPreInits(SemaRef.Context, Captures); 12762 } 12763 } 12764 return true; 12765 } 12766 12767 OMPClause *Sema::ActOnOpenMPNumThreadsClause(Expr *NumThreads, 12768 SourceLocation StartLoc, 12769 SourceLocation LParenLoc, 12770 SourceLocation EndLoc) { 12771 Expr *ValExpr = NumThreads; 12772 Stmt *HelperValStmt = nullptr; 12773 12774 // OpenMP [2.5, Restrictions] 12775 // The num_threads expression must evaluate to a positive integer value. 12776 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_num_threads, 12777 /*StrictlyPositive=*/true)) 12778 return nullptr; 12779 12780 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 12781 OpenMPDirectiveKind CaptureRegion = 12782 getOpenMPCaptureRegionForClause(DKind, OMPC_num_threads, LangOpts.OpenMP); 12783 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 12784 ValExpr = MakeFullExpr(ValExpr).get(); 12785 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 12786 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 12787 HelperValStmt = buildPreInits(Context, Captures); 12788 } 12789 12790 return new (Context) OMPNumThreadsClause( 12791 ValExpr, HelperValStmt, CaptureRegion, StartLoc, LParenLoc, EndLoc); 12792 } 12793 12794 ExprResult Sema::VerifyPositiveIntegerConstantInClause(Expr *E, 12795 OpenMPClauseKind CKind, 12796 bool StrictlyPositive) { 12797 if (!E) 12798 return ExprError(); 12799 if (E->isValueDependent() || E->isTypeDependent() || 12800 E->isInstantiationDependent() || E->containsUnexpandedParameterPack()) 12801 return E; 12802 llvm::APSInt Result; 12803 ExprResult ICE = VerifyIntegerConstantExpression(E, &Result); 12804 if (ICE.isInvalid()) 12805 return ExprError(); 12806 if ((StrictlyPositive && !Result.isStrictlyPositive()) || 12807 (!StrictlyPositive && !Result.isNonNegative())) { 12808 Diag(E->getExprLoc(), diag::err_omp_negative_expression_in_clause) 12809 << getOpenMPClauseName(CKind) << (StrictlyPositive ? 1 : 0) 12810 << E->getSourceRange(); 12811 return ExprError(); 12812 } 12813 if (CKind == OMPC_aligned && !Result.isPowerOf2()) { 12814 Diag(E->getExprLoc(), diag::warn_omp_alignment_not_power_of_two) 12815 << E->getSourceRange(); 12816 return ExprError(); 12817 } 12818 if (CKind == OMPC_collapse && DSAStack->getAssociatedLoops() == 1) 12819 DSAStack->setAssociatedLoops(Result.getExtValue()); 12820 else if (CKind == OMPC_ordered) 12821 DSAStack->setAssociatedLoops(Result.getExtValue()); 12822 return ICE; 12823 } 12824 12825 OMPClause *Sema::ActOnOpenMPSafelenClause(Expr *Len, SourceLocation StartLoc, 12826 SourceLocation LParenLoc, 12827 SourceLocation EndLoc) { 12828 // OpenMP [2.8.1, simd construct, Description] 12829 // The parameter of the safelen clause must be a constant 12830 // positive integer expression. 12831 ExprResult Safelen = VerifyPositiveIntegerConstantInClause(Len, OMPC_safelen); 12832 if (Safelen.isInvalid()) 12833 return nullptr; 12834 return new (Context) 12835 OMPSafelenClause(Safelen.get(), StartLoc, LParenLoc, EndLoc); 12836 } 12837 12838 OMPClause *Sema::ActOnOpenMPSimdlenClause(Expr *Len, SourceLocation StartLoc, 12839 SourceLocation LParenLoc, 12840 SourceLocation EndLoc) { 12841 // OpenMP [2.8.1, simd construct, Description] 12842 // The parameter of the simdlen clause must be a constant 12843 // positive integer expression. 12844 ExprResult Simdlen = VerifyPositiveIntegerConstantInClause(Len, OMPC_simdlen); 12845 if (Simdlen.isInvalid()) 12846 return nullptr; 12847 return new (Context) 12848 OMPSimdlenClause(Simdlen.get(), StartLoc, LParenLoc, EndLoc); 12849 } 12850 12851 /// Tries to find omp_allocator_handle_t type. 12852 static bool findOMPAllocatorHandleT(Sema &S, SourceLocation Loc, 12853 DSAStackTy *Stack) { 12854 QualType OMPAllocatorHandleT = Stack->getOMPAllocatorHandleT(); 12855 if (!OMPAllocatorHandleT.isNull()) 12856 return true; 12857 // Build the predefined allocator expressions. 12858 bool ErrorFound = false; 12859 for (int I = 0; I < OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; ++I) { 12860 auto AllocatorKind = static_cast<OMPAllocateDeclAttr::AllocatorTypeTy>(I); 12861 StringRef Allocator = 12862 OMPAllocateDeclAttr::ConvertAllocatorTypeTyToStr(AllocatorKind); 12863 DeclarationName AllocatorName = &S.getASTContext().Idents.get(Allocator); 12864 auto *VD = dyn_cast_or_null<ValueDecl>( 12865 S.LookupSingleName(S.TUScope, AllocatorName, Loc, Sema::LookupAnyName)); 12866 if (!VD) { 12867 ErrorFound = true; 12868 break; 12869 } 12870 QualType AllocatorType = 12871 VD->getType().getNonLValueExprType(S.getASTContext()); 12872 ExprResult Res = S.BuildDeclRefExpr(VD, AllocatorType, VK_LValue, Loc); 12873 if (!Res.isUsable()) { 12874 ErrorFound = true; 12875 break; 12876 } 12877 if (OMPAllocatorHandleT.isNull()) 12878 OMPAllocatorHandleT = AllocatorType; 12879 if (!S.getASTContext().hasSameType(OMPAllocatorHandleT, AllocatorType)) { 12880 ErrorFound = true; 12881 break; 12882 } 12883 Stack->setAllocator(AllocatorKind, Res.get()); 12884 } 12885 if (ErrorFound) { 12886 S.Diag(Loc, diag::err_omp_implied_type_not_found) 12887 << "omp_allocator_handle_t"; 12888 return false; 12889 } 12890 OMPAllocatorHandleT.addConst(); 12891 Stack->setOMPAllocatorHandleT(OMPAllocatorHandleT); 12892 return true; 12893 } 12894 12895 OMPClause *Sema::ActOnOpenMPAllocatorClause(Expr *A, SourceLocation StartLoc, 12896 SourceLocation LParenLoc, 12897 SourceLocation EndLoc) { 12898 // OpenMP [2.11.3, allocate Directive, Description] 12899 // allocator is an expression of omp_allocator_handle_t type. 12900 if (!findOMPAllocatorHandleT(*this, A->getExprLoc(), DSAStack)) 12901 return nullptr; 12902 12903 ExprResult Allocator = DefaultLvalueConversion(A); 12904 if (Allocator.isInvalid()) 12905 return nullptr; 12906 Allocator = PerformImplicitConversion(Allocator.get(), 12907 DSAStack->getOMPAllocatorHandleT(), 12908 Sema::AA_Initializing, 12909 /*AllowExplicit=*/true); 12910 if (Allocator.isInvalid()) 12911 return nullptr; 12912 return new (Context) 12913 OMPAllocatorClause(Allocator.get(), StartLoc, LParenLoc, EndLoc); 12914 } 12915 12916 OMPClause *Sema::ActOnOpenMPCollapseClause(Expr *NumForLoops, 12917 SourceLocation StartLoc, 12918 SourceLocation LParenLoc, 12919 SourceLocation EndLoc) { 12920 // OpenMP [2.7.1, loop construct, Description] 12921 // OpenMP [2.8.1, simd construct, Description] 12922 // OpenMP [2.9.6, distribute construct, Description] 12923 // The parameter of the collapse clause must be a constant 12924 // positive integer expression. 12925 ExprResult NumForLoopsResult = 12926 VerifyPositiveIntegerConstantInClause(NumForLoops, OMPC_collapse); 12927 if (NumForLoopsResult.isInvalid()) 12928 return nullptr; 12929 return new (Context) 12930 OMPCollapseClause(NumForLoopsResult.get(), StartLoc, LParenLoc, EndLoc); 12931 } 12932 12933 OMPClause *Sema::ActOnOpenMPOrderedClause(SourceLocation StartLoc, 12934 SourceLocation EndLoc, 12935 SourceLocation LParenLoc, 12936 Expr *NumForLoops) { 12937 // OpenMP [2.7.1, loop construct, Description] 12938 // OpenMP [2.8.1, simd construct, Description] 12939 // OpenMP [2.9.6, distribute construct, Description] 12940 // The parameter of the ordered clause must be a constant 12941 // positive integer expression if any. 12942 if (NumForLoops && LParenLoc.isValid()) { 12943 ExprResult NumForLoopsResult = 12944 VerifyPositiveIntegerConstantInClause(NumForLoops, OMPC_ordered); 12945 if (NumForLoopsResult.isInvalid()) 12946 return nullptr; 12947 NumForLoops = NumForLoopsResult.get(); 12948 } else { 12949 NumForLoops = nullptr; 12950 } 12951 auto *Clause = OMPOrderedClause::Create( 12952 Context, NumForLoops, NumForLoops ? DSAStack->getAssociatedLoops() : 0, 12953 StartLoc, LParenLoc, EndLoc); 12954 DSAStack->setOrderedRegion(/*IsOrdered=*/true, NumForLoops, Clause); 12955 return Clause; 12956 } 12957 12958 OMPClause *Sema::ActOnOpenMPSimpleClause( 12959 OpenMPClauseKind Kind, unsigned Argument, SourceLocation ArgumentLoc, 12960 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) { 12961 OMPClause *Res = nullptr; 12962 switch (Kind) { 12963 case OMPC_default: 12964 Res = ActOnOpenMPDefaultClause(static_cast<DefaultKind>(Argument), 12965 ArgumentLoc, StartLoc, LParenLoc, EndLoc); 12966 break; 12967 case OMPC_proc_bind: 12968 Res = ActOnOpenMPProcBindClause(static_cast<ProcBindKind>(Argument), 12969 ArgumentLoc, StartLoc, LParenLoc, EndLoc); 12970 break; 12971 case OMPC_atomic_default_mem_order: 12972 Res = ActOnOpenMPAtomicDefaultMemOrderClause( 12973 static_cast<OpenMPAtomicDefaultMemOrderClauseKind>(Argument), 12974 ArgumentLoc, StartLoc, LParenLoc, EndLoc); 12975 break; 12976 case OMPC_order: 12977 Res = ActOnOpenMPOrderClause(static_cast<OpenMPOrderClauseKind>(Argument), 12978 ArgumentLoc, StartLoc, LParenLoc, EndLoc); 12979 break; 12980 case OMPC_update: 12981 Res = ActOnOpenMPUpdateClause(static_cast<OpenMPDependClauseKind>(Argument), 12982 ArgumentLoc, StartLoc, LParenLoc, EndLoc); 12983 break; 12984 case OMPC_if: 12985 case OMPC_final: 12986 case OMPC_num_threads: 12987 case OMPC_safelen: 12988 case OMPC_simdlen: 12989 case OMPC_allocator: 12990 case OMPC_collapse: 12991 case OMPC_schedule: 12992 case OMPC_private: 12993 case OMPC_firstprivate: 12994 case OMPC_lastprivate: 12995 case OMPC_shared: 12996 case OMPC_reduction: 12997 case OMPC_task_reduction: 12998 case OMPC_in_reduction: 12999 case OMPC_linear: 13000 case OMPC_aligned: 13001 case OMPC_copyin: 13002 case OMPC_copyprivate: 13003 case OMPC_ordered: 13004 case OMPC_nowait: 13005 case OMPC_untied: 13006 case OMPC_mergeable: 13007 case OMPC_threadprivate: 13008 case OMPC_allocate: 13009 case OMPC_flush: 13010 case OMPC_depobj: 13011 case OMPC_read: 13012 case OMPC_write: 13013 case OMPC_capture: 13014 case OMPC_seq_cst: 13015 case OMPC_acq_rel: 13016 case OMPC_acquire: 13017 case OMPC_release: 13018 case OMPC_relaxed: 13019 case OMPC_depend: 13020 case OMPC_device: 13021 case OMPC_threads: 13022 case OMPC_simd: 13023 case OMPC_map: 13024 case OMPC_num_teams: 13025 case OMPC_thread_limit: 13026 case OMPC_priority: 13027 case OMPC_grainsize: 13028 case OMPC_nogroup: 13029 case OMPC_num_tasks: 13030 case OMPC_hint: 13031 case OMPC_dist_schedule: 13032 case OMPC_defaultmap: 13033 case OMPC_unknown: 13034 case OMPC_uniform: 13035 case OMPC_to: 13036 case OMPC_from: 13037 case OMPC_use_device_ptr: 13038 case OMPC_use_device_addr: 13039 case OMPC_is_device_ptr: 13040 case OMPC_unified_address: 13041 case OMPC_unified_shared_memory: 13042 case OMPC_reverse_offload: 13043 case OMPC_dynamic_allocators: 13044 case OMPC_device_type: 13045 case OMPC_match: 13046 case OMPC_nontemporal: 13047 case OMPC_destroy: 13048 case OMPC_detach: 13049 case OMPC_inclusive: 13050 case OMPC_exclusive: 13051 case OMPC_uses_allocators: 13052 case OMPC_affinity: 13053 default: 13054 llvm_unreachable("Clause is not allowed."); 13055 } 13056 return Res; 13057 } 13058 13059 static std::string 13060 getListOfPossibleValues(OpenMPClauseKind K, unsigned First, unsigned Last, 13061 ArrayRef<unsigned> Exclude = llvm::None) { 13062 SmallString<256> Buffer; 13063 llvm::raw_svector_ostream Out(Buffer); 13064 unsigned Skipped = Exclude.size(); 13065 auto S = Exclude.begin(), E = Exclude.end(); 13066 for (unsigned I = First; I < Last; ++I) { 13067 if (std::find(S, E, I) != E) { 13068 --Skipped; 13069 continue; 13070 } 13071 Out << "'" << getOpenMPSimpleClauseTypeName(K, I) << "'"; 13072 if (I + Skipped + 2 == Last) 13073 Out << " or "; 13074 else if (I + Skipped + 1 != Last) 13075 Out << ", "; 13076 } 13077 return std::string(Out.str()); 13078 } 13079 13080 OMPClause *Sema::ActOnOpenMPDefaultClause(DefaultKind Kind, 13081 SourceLocation KindKwLoc, 13082 SourceLocation StartLoc, 13083 SourceLocation LParenLoc, 13084 SourceLocation EndLoc) { 13085 if (Kind == OMP_DEFAULT_unknown) { 13086 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value) 13087 << getListOfPossibleValues(OMPC_default, /*First=*/0, 13088 /*Last=*/unsigned(OMP_DEFAULT_unknown)) 13089 << getOpenMPClauseName(OMPC_default); 13090 return nullptr; 13091 } 13092 13093 switch (Kind) { 13094 case OMP_DEFAULT_none: 13095 DSAStack->setDefaultDSANone(KindKwLoc); 13096 break; 13097 case OMP_DEFAULT_shared: 13098 DSAStack->setDefaultDSAShared(KindKwLoc); 13099 break; 13100 case OMP_DEFAULT_firstprivate: 13101 DSAStack->setDefaultDSAFirstPrivate(KindKwLoc); 13102 break; 13103 default: 13104 llvm_unreachable("DSA unexpected in OpenMP default clause"); 13105 } 13106 13107 return new (Context) 13108 OMPDefaultClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc); 13109 } 13110 13111 OMPClause *Sema::ActOnOpenMPProcBindClause(ProcBindKind Kind, 13112 SourceLocation KindKwLoc, 13113 SourceLocation StartLoc, 13114 SourceLocation LParenLoc, 13115 SourceLocation EndLoc) { 13116 if (Kind == OMP_PROC_BIND_unknown) { 13117 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value) 13118 << getListOfPossibleValues(OMPC_proc_bind, 13119 /*First=*/unsigned(OMP_PROC_BIND_master), 13120 /*Last=*/5) 13121 << getOpenMPClauseName(OMPC_proc_bind); 13122 return nullptr; 13123 } 13124 return new (Context) 13125 OMPProcBindClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc); 13126 } 13127 13128 OMPClause *Sema::ActOnOpenMPAtomicDefaultMemOrderClause( 13129 OpenMPAtomicDefaultMemOrderClauseKind Kind, SourceLocation KindKwLoc, 13130 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) { 13131 if (Kind == OMPC_ATOMIC_DEFAULT_MEM_ORDER_unknown) { 13132 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value) 13133 << getListOfPossibleValues( 13134 OMPC_atomic_default_mem_order, /*First=*/0, 13135 /*Last=*/OMPC_ATOMIC_DEFAULT_MEM_ORDER_unknown) 13136 << getOpenMPClauseName(OMPC_atomic_default_mem_order); 13137 return nullptr; 13138 } 13139 return new (Context) OMPAtomicDefaultMemOrderClause(Kind, KindKwLoc, StartLoc, 13140 LParenLoc, EndLoc); 13141 } 13142 13143 OMPClause *Sema::ActOnOpenMPOrderClause(OpenMPOrderClauseKind Kind, 13144 SourceLocation KindKwLoc, 13145 SourceLocation StartLoc, 13146 SourceLocation LParenLoc, 13147 SourceLocation EndLoc) { 13148 if (Kind == OMPC_ORDER_unknown) { 13149 static_assert(OMPC_ORDER_unknown > 0, 13150 "OMPC_ORDER_unknown not greater than 0"); 13151 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value) 13152 << getListOfPossibleValues(OMPC_order, /*First=*/0, 13153 /*Last=*/OMPC_ORDER_unknown) 13154 << getOpenMPClauseName(OMPC_order); 13155 return nullptr; 13156 } 13157 return new (Context) 13158 OMPOrderClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc); 13159 } 13160 13161 OMPClause *Sema::ActOnOpenMPUpdateClause(OpenMPDependClauseKind Kind, 13162 SourceLocation KindKwLoc, 13163 SourceLocation StartLoc, 13164 SourceLocation LParenLoc, 13165 SourceLocation EndLoc) { 13166 if (Kind == OMPC_DEPEND_unknown || Kind == OMPC_DEPEND_source || 13167 Kind == OMPC_DEPEND_sink || Kind == OMPC_DEPEND_depobj) { 13168 unsigned Except[] = {OMPC_DEPEND_source, OMPC_DEPEND_sink, 13169 OMPC_DEPEND_depobj}; 13170 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value) 13171 << getListOfPossibleValues(OMPC_depend, /*First=*/0, 13172 /*Last=*/OMPC_DEPEND_unknown, Except) 13173 << getOpenMPClauseName(OMPC_update); 13174 return nullptr; 13175 } 13176 return OMPUpdateClause::Create(Context, StartLoc, LParenLoc, KindKwLoc, Kind, 13177 EndLoc); 13178 } 13179 13180 OMPClause *Sema::ActOnOpenMPSingleExprWithArgClause( 13181 OpenMPClauseKind Kind, ArrayRef<unsigned> Argument, Expr *Expr, 13182 SourceLocation StartLoc, SourceLocation LParenLoc, 13183 ArrayRef<SourceLocation> ArgumentLoc, SourceLocation DelimLoc, 13184 SourceLocation EndLoc) { 13185 OMPClause *Res = nullptr; 13186 switch (Kind) { 13187 case OMPC_schedule: 13188 enum { Modifier1, Modifier2, ScheduleKind, NumberOfElements }; 13189 assert(Argument.size() == NumberOfElements && 13190 ArgumentLoc.size() == NumberOfElements); 13191 Res = ActOnOpenMPScheduleClause( 13192 static_cast<OpenMPScheduleClauseModifier>(Argument[Modifier1]), 13193 static_cast<OpenMPScheduleClauseModifier>(Argument[Modifier2]), 13194 static_cast<OpenMPScheduleClauseKind>(Argument[ScheduleKind]), Expr, 13195 StartLoc, LParenLoc, ArgumentLoc[Modifier1], ArgumentLoc[Modifier2], 13196 ArgumentLoc[ScheduleKind], DelimLoc, EndLoc); 13197 break; 13198 case OMPC_if: 13199 assert(Argument.size() == 1 && ArgumentLoc.size() == 1); 13200 Res = ActOnOpenMPIfClause(static_cast<OpenMPDirectiveKind>(Argument.back()), 13201 Expr, StartLoc, LParenLoc, ArgumentLoc.back(), 13202 DelimLoc, EndLoc); 13203 break; 13204 case OMPC_dist_schedule: 13205 Res = ActOnOpenMPDistScheduleClause( 13206 static_cast<OpenMPDistScheduleClauseKind>(Argument.back()), Expr, 13207 StartLoc, LParenLoc, ArgumentLoc.back(), DelimLoc, EndLoc); 13208 break; 13209 case OMPC_defaultmap: 13210 enum { Modifier, DefaultmapKind }; 13211 Res = ActOnOpenMPDefaultmapClause( 13212 static_cast<OpenMPDefaultmapClauseModifier>(Argument[Modifier]), 13213 static_cast<OpenMPDefaultmapClauseKind>(Argument[DefaultmapKind]), 13214 StartLoc, LParenLoc, ArgumentLoc[Modifier], ArgumentLoc[DefaultmapKind], 13215 EndLoc); 13216 break; 13217 case OMPC_device: 13218 assert(Argument.size() == 1 && ArgumentLoc.size() == 1); 13219 Res = ActOnOpenMPDeviceClause( 13220 static_cast<OpenMPDeviceClauseModifier>(Argument.back()), Expr, 13221 StartLoc, LParenLoc, ArgumentLoc.back(), EndLoc); 13222 break; 13223 case OMPC_final: 13224 case OMPC_num_threads: 13225 case OMPC_safelen: 13226 case OMPC_simdlen: 13227 case OMPC_allocator: 13228 case OMPC_collapse: 13229 case OMPC_default: 13230 case OMPC_proc_bind: 13231 case OMPC_private: 13232 case OMPC_firstprivate: 13233 case OMPC_lastprivate: 13234 case OMPC_shared: 13235 case OMPC_reduction: 13236 case OMPC_task_reduction: 13237 case OMPC_in_reduction: 13238 case OMPC_linear: 13239 case OMPC_aligned: 13240 case OMPC_copyin: 13241 case OMPC_copyprivate: 13242 case OMPC_ordered: 13243 case OMPC_nowait: 13244 case OMPC_untied: 13245 case OMPC_mergeable: 13246 case OMPC_threadprivate: 13247 case OMPC_allocate: 13248 case OMPC_flush: 13249 case OMPC_depobj: 13250 case OMPC_read: 13251 case OMPC_write: 13252 case OMPC_update: 13253 case OMPC_capture: 13254 case OMPC_seq_cst: 13255 case OMPC_acq_rel: 13256 case OMPC_acquire: 13257 case OMPC_release: 13258 case OMPC_relaxed: 13259 case OMPC_depend: 13260 case OMPC_threads: 13261 case OMPC_simd: 13262 case OMPC_map: 13263 case OMPC_num_teams: 13264 case OMPC_thread_limit: 13265 case OMPC_priority: 13266 case OMPC_grainsize: 13267 case OMPC_nogroup: 13268 case OMPC_num_tasks: 13269 case OMPC_hint: 13270 case OMPC_unknown: 13271 case OMPC_uniform: 13272 case OMPC_to: 13273 case OMPC_from: 13274 case OMPC_use_device_ptr: 13275 case OMPC_use_device_addr: 13276 case OMPC_is_device_ptr: 13277 case OMPC_unified_address: 13278 case OMPC_unified_shared_memory: 13279 case OMPC_reverse_offload: 13280 case OMPC_dynamic_allocators: 13281 case OMPC_atomic_default_mem_order: 13282 case OMPC_device_type: 13283 case OMPC_match: 13284 case OMPC_nontemporal: 13285 case OMPC_order: 13286 case OMPC_destroy: 13287 case OMPC_detach: 13288 case OMPC_inclusive: 13289 case OMPC_exclusive: 13290 case OMPC_uses_allocators: 13291 case OMPC_affinity: 13292 default: 13293 llvm_unreachable("Clause is not allowed."); 13294 } 13295 return Res; 13296 } 13297 13298 static bool checkScheduleModifiers(Sema &S, OpenMPScheduleClauseModifier M1, 13299 OpenMPScheduleClauseModifier M2, 13300 SourceLocation M1Loc, SourceLocation M2Loc) { 13301 if (M1 == OMPC_SCHEDULE_MODIFIER_unknown && M1Loc.isValid()) { 13302 SmallVector<unsigned, 2> Excluded; 13303 if (M2 != OMPC_SCHEDULE_MODIFIER_unknown) 13304 Excluded.push_back(M2); 13305 if (M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) 13306 Excluded.push_back(OMPC_SCHEDULE_MODIFIER_monotonic); 13307 if (M2 == OMPC_SCHEDULE_MODIFIER_monotonic) 13308 Excluded.push_back(OMPC_SCHEDULE_MODIFIER_nonmonotonic); 13309 S.Diag(M1Loc, diag::err_omp_unexpected_clause_value) 13310 << getListOfPossibleValues(OMPC_schedule, 13311 /*First=*/OMPC_SCHEDULE_MODIFIER_unknown + 1, 13312 /*Last=*/OMPC_SCHEDULE_MODIFIER_last, 13313 Excluded) 13314 << getOpenMPClauseName(OMPC_schedule); 13315 return true; 13316 } 13317 return false; 13318 } 13319 13320 OMPClause *Sema::ActOnOpenMPScheduleClause( 13321 OpenMPScheduleClauseModifier M1, OpenMPScheduleClauseModifier M2, 13322 OpenMPScheduleClauseKind Kind, Expr *ChunkSize, SourceLocation StartLoc, 13323 SourceLocation LParenLoc, SourceLocation M1Loc, SourceLocation M2Loc, 13324 SourceLocation KindLoc, SourceLocation CommaLoc, SourceLocation EndLoc) { 13325 if (checkScheduleModifiers(*this, M1, M2, M1Loc, M2Loc) || 13326 checkScheduleModifiers(*this, M2, M1, M2Loc, M1Loc)) 13327 return nullptr; 13328 // OpenMP, 2.7.1, Loop Construct, Restrictions 13329 // Either the monotonic modifier or the nonmonotonic modifier can be specified 13330 // but not both. 13331 if ((M1 == M2 && M1 != OMPC_SCHEDULE_MODIFIER_unknown) || 13332 (M1 == OMPC_SCHEDULE_MODIFIER_monotonic && 13333 M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) || 13334 (M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic && 13335 M2 == OMPC_SCHEDULE_MODIFIER_monotonic)) { 13336 Diag(M2Loc, diag::err_omp_unexpected_schedule_modifier) 13337 << getOpenMPSimpleClauseTypeName(OMPC_schedule, M2) 13338 << getOpenMPSimpleClauseTypeName(OMPC_schedule, M1); 13339 return nullptr; 13340 } 13341 if (Kind == OMPC_SCHEDULE_unknown) { 13342 std::string Values; 13343 if (M1Loc.isInvalid() && M2Loc.isInvalid()) { 13344 unsigned Exclude[] = {OMPC_SCHEDULE_unknown}; 13345 Values = getListOfPossibleValues(OMPC_schedule, /*First=*/0, 13346 /*Last=*/OMPC_SCHEDULE_MODIFIER_last, 13347 Exclude); 13348 } else { 13349 Values = getListOfPossibleValues(OMPC_schedule, /*First=*/0, 13350 /*Last=*/OMPC_SCHEDULE_unknown); 13351 } 13352 Diag(KindLoc, diag::err_omp_unexpected_clause_value) 13353 << Values << getOpenMPClauseName(OMPC_schedule); 13354 return nullptr; 13355 } 13356 // OpenMP, 2.7.1, Loop Construct, Restrictions 13357 // The nonmonotonic modifier can only be specified with schedule(dynamic) or 13358 // schedule(guided). 13359 // OpenMP 5.0 does not have this restriction. 13360 if (LangOpts.OpenMP < 50 && 13361 (M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic || 13362 M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) && 13363 Kind != OMPC_SCHEDULE_dynamic && Kind != OMPC_SCHEDULE_guided) { 13364 Diag(M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic ? M1Loc : M2Loc, 13365 diag::err_omp_schedule_nonmonotonic_static); 13366 return nullptr; 13367 } 13368 Expr *ValExpr = ChunkSize; 13369 Stmt *HelperValStmt = nullptr; 13370 if (ChunkSize) { 13371 if (!ChunkSize->isValueDependent() && !ChunkSize->isTypeDependent() && 13372 !ChunkSize->isInstantiationDependent() && 13373 !ChunkSize->containsUnexpandedParameterPack()) { 13374 SourceLocation ChunkSizeLoc = ChunkSize->getBeginLoc(); 13375 ExprResult Val = 13376 PerformOpenMPImplicitIntegerConversion(ChunkSizeLoc, ChunkSize); 13377 if (Val.isInvalid()) 13378 return nullptr; 13379 13380 ValExpr = Val.get(); 13381 13382 // OpenMP [2.7.1, Restrictions] 13383 // chunk_size must be a loop invariant integer expression with a positive 13384 // value. 13385 if (Optional<llvm::APSInt> Result = 13386 ValExpr->getIntegerConstantExpr(Context)) { 13387 if (Result->isSigned() && !Result->isStrictlyPositive()) { 13388 Diag(ChunkSizeLoc, diag::err_omp_negative_expression_in_clause) 13389 << "schedule" << 1 << ChunkSize->getSourceRange(); 13390 return nullptr; 13391 } 13392 } else if (getOpenMPCaptureRegionForClause( 13393 DSAStack->getCurrentDirective(), OMPC_schedule, 13394 LangOpts.OpenMP) != OMPD_unknown && 13395 !CurContext->isDependentContext()) { 13396 ValExpr = MakeFullExpr(ValExpr).get(); 13397 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 13398 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 13399 HelperValStmt = buildPreInits(Context, Captures); 13400 } 13401 } 13402 } 13403 13404 return new (Context) 13405 OMPScheduleClause(StartLoc, LParenLoc, KindLoc, CommaLoc, EndLoc, Kind, 13406 ValExpr, HelperValStmt, M1, M1Loc, M2, M2Loc); 13407 } 13408 13409 OMPClause *Sema::ActOnOpenMPClause(OpenMPClauseKind Kind, 13410 SourceLocation StartLoc, 13411 SourceLocation EndLoc) { 13412 OMPClause *Res = nullptr; 13413 switch (Kind) { 13414 case OMPC_ordered: 13415 Res = ActOnOpenMPOrderedClause(StartLoc, EndLoc); 13416 break; 13417 case OMPC_nowait: 13418 Res = ActOnOpenMPNowaitClause(StartLoc, EndLoc); 13419 break; 13420 case OMPC_untied: 13421 Res = ActOnOpenMPUntiedClause(StartLoc, EndLoc); 13422 break; 13423 case OMPC_mergeable: 13424 Res = ActOnOpenMPMergeableClause(StartLoc, EndLoc); 13425 break; 13426 case OMPC_read: 13427 Res = ActOnOpenMPReadClause(StartLoc, EndLoc); 13428 break; 13429 case OMPC_write: 13430 Res = ActOnOpenMPWriteClause(StartLoc, EndLoc); 13431 break; 13432 case OMPC_update: 13433 Res = ActOnOpenMPUpdateClause(StartLoc, EndLoc); 13434 break; 13435 case OMPC_capture: 13436 Res = ActOnOpenMPCaptureClause(StartLoc, EndLoc); 13437 break; 13438 case OMPC_seq_cst: 13439 Res = ActOnOpenMPSeqCstClause(StartLoc, EndLoc); 13440 break; 13441 case OMPC_acq_rel: 13442 Res = ActOnOpenMPAcqRelClause(StartLoc, EndLoc); 13443 break; 13444 case OMPC_acquire: 13445 Res = ActOnOpenMPAcquireClause(StartLoc, EndLoc); 13446 break; 13447 case OMPC_release: 13448 Res = ActOnOpenMPReleaseClause(StartLoc, EndLoc); 13449 break; 13450 case OMPC_relaxed: 13451 Res = ActOnOpenMPRelaxedClause(StartLoc, EndLoc); 13452 break; 13453 case OMPC_threads: 13454 Res = ActOnOpenMPThreadsClause(StartLoc, EndLoc); 13455 break; 13456 case OMPC_simd: 13457 Res = ActOnOpenMPSIMDClause(StartLoc, EndLoc); 13458 break; 13459 case OMPC_nogroup: 13460 Res = ActOnOpenMPNogroupClause(StartLoc, EndLoc); 13461 break; 13462 case OMPC_unified_address: 13463 Res = ActOnOpenMPUnifiedAddressClause(StartLoc, EndLoc); 13464 break; 13465 case OMPC_unified_shared_memory: 13466 Res = ActOnOpenMPUnifiedSharedMemoryClause(StartLoc, EndLoc); 13467 break; 13468 case OMPC_reverse_offload: 13469 Res = ActOnOpenMPReverseOffloadClause(StartLoc, EndLoc); 13470 break; 13471 case OMPC_dynamic_allocators: 13472 Res = ActOnOpenMPDynamicAllocatorsClause(StartLoc, EndLoc); 13473 break; 13474 case OMPC_destroy: 13475 Res = ActOnOpenMPDestroyClause(StartLoc, EndLoc); 13476 break; 13477 case OMPC_if: 13478 case OMPC_final: 13479 case OMPC_num_threads: 13480 case OMPC_safelen: 13481 case OMPC_simdlen: 13482 case OMPC_allocator: 13483 case OMPC_collapse: 13484 case OMPC_schedule: 13485 case OMPC_private: 13486 case OMPC_firstprivate: 13487 case OMPC_lastprivate: 13488 case OMPC_shared: 13489 case OMPC_reduction: 13490 case OMPC_task_reduction: 13491 case OMPC_in_reduction: 13492 case OMPC_linear: 13493 case OMPC_aligned: 13494 case OMPC_copyin: 13495 case OMPC_copyprivate: 13496 case OMPC_default: 13497 case OMPC_proc_bind: 13498 case OMPC_threadprivate: 13499 case OMPC_allocate: 13500 case OMPC_flush: 13501 case OMPC_depobj: 13502 case OMPC_depend: 13503 case OMPC_device: 13504 case OMPC_map: 13505 case OMPC_num_teams: 13506 case OMPC_thread_limit: 13507 case OMPC_priority: 13508 case OMPC_grainsize: 13509 case OMPC_num_tasks: 13510 case OMPC_hint: 13511 case OMPC_dist_schedule: 13512 case OMPC_defaultmap: 13513 case OMPC_unknown: 13514 case OMPC_uniform: 13515 case OMPC_to: 13516 case OMPC_from: 13517 case OMPC_use_device_ptr: 13518 case OMPC_use_device_addr: 13519 case OMPC_is_device_ptr: 13520 case OMPC_atomic_default_mem_order: 13521 case OMPC_device_type: 13522 case OMPC_match: 13523 case OMPC_nontemporal: 13524 case OMPC_order: 13525 case OMPC_detach: 13526 case OMPC_inclusive: 13527 case OMPC_exclusive: 13528 case OMPC_uses_allocators: 13529 case OMPC_affinity: 13530 default: 13531 llvm_unreachable("Clause is not allowed."); 13532 } 13533 return Res; 13534 } 13535 13536 OMPClause *Sema::ActOnOpenMPNowaitClause(SourceLocation StartLoc, 13537 SourceLocation EndLoc) { 13538 DSAStack->setNowaitRegion(); 13539 return new (Context) OMPNowaitClause(StartLoc, EndLoc); 13540 } 13541 13542 OMPClause *Sema::ActOnOpenMPUntiedClause(SourceLocation StartLoc, 13543 SourceLocation EndLoc) { 13544 return new (Context) OMPUntiedClause(StartLoc, EndLoc); 13545 } 13546 13547 OMPClause *Sema::ActOnOpenMPMergeableClause(SourceLocation StartLoc, 13548 SourceLocation EndLoc) { 13549 return new (Context) OMPMergeableClause(StartLoc, EndLoc); 13550 } 13551 13552 OMPClause *Sema::ActOnOpenMPReadClause(SourceLocation StartLoc, 13553 SourceLocation EndLoc) { 13554 return new (Context) OMPReadClause(StartLoc, EndLoc); 13555 } 13556 13557 OMPClause *Sema::ActOnOpenMPWriteClause(SourceLocation StartLoc, 13558 SourceLocation EndLoc) { 13559 return new (Context) OMPWriteClause(StartLoc, EndLoc); 13560 } 13561 13562 OMPClause *Sema::ActOnOpenMPUpdateClause(SourceLocation StartLoc, 13563 SourceLocation EndLoc) { 13564 return OMPUpdateClause::Create(Context, StartLoc, EndLoc); 13565 } 13566 13567 OMPClause *Sema::ActOnOpenMPCaptureClause(SourceLocation StartLoc, 13568 SourceLocation EndLoc) { 13569 return new (Context) OMPCaptureClause(StartLoc, EndLoc); 13570 } 13571 13572 OMPClause *Sema::ActOnOpenMPSeqCstClause(SourceLocation StartLoc, 13573 SourceLocation EndLoc) { 13574 return new (Context) OMPSeqCstClause(StartLoc, EndLoc); 13575 } 13576 13577 OMPClause *Sema::ActOnOpenMPAcqRelClause(SourceLocation StartLoc, 13578 SourceLocation EndLoc) { 13579 return new (Context) OMPAcqRelClause(StartLoc, EndLoc); 13580 } 13581 13582 OMPClause *Sema::ActOnOpenMPAcquireClause(SourceLocation StartLoc, 13583 SourceLocation EndLoc) { 13584 return new (Context) OMPAcquireClause(StartLoc, EndLoc); 13585 } 13586 13587 OMPClause *Sema::ActOnOpenMPReleaseClause(SourceLocation StartLoc, 13588 SourceLocation EndLoc) { 13589 return new (Context) OMPReleaseClause(StartLoc, EndLoc); 13590 } 13591 13592 OMPClause *Sema::ActOnOpenMPRelaxedClause(SourceLocation StartLoc, 13593 SourceLocation EndLoc) { 13594 return new (Context) OMPRelaxedClause(StartLoc, EndLoc); 13595 } 13596 13597 OMPClause *Sema::ActOnOpenMPThreadsClause(SourceLocation StartLoc, 13598 SourceLocation EndLoc) { 13599 return new (Context) OMPThreadsClause(StartLoc, EndLoc); 13600 } 13601 13602 OMPClause *Sema::ActOnOpenMPSIMDClause(SourceLocation StartLoc, 13603 SourceLocation EndLoc) { 13604 return new (Context) OMPSIMDClause(StartLoc, EndLoc); 13605 } 13606 13607 OMPClause *Sema::ActOnOpenMPNogroupClause(SourceLocation StartLoc, 13608 SourceLocation EndLoc) { 13609 return new (Context) OMPNogroupClause(StartLoc, EndLoc); 13610 } 13611 13612 OMPClause *Sema::ActOnOpenMPUnifiedAddressClause(SourceLocation StartLoc, 13613 SourceLocation EndLoc) { 13614 return new (Context) OMPUnifiedAddressClause(StartLoc, EndLoc); 13615 } 13616 13617 OMPClause *Sema::ActOnOpenMPUnifiedSharedMemoryClause(SourceLocation StartLoc, 13618 SourceLocation EndLoc) { 13619 return new (Context) OMPUnifiedSharedMemoryClause(StartLoc, EndLoc); 13620 } 13621 13622 OMPClause *Sema::ActOnOpenMPReverseOffloadClause(SourceLocation StartLoc, 13623 SourceLocation EndLoc) { 13624 return new (Context) OMPReverseOffloadClause(StartLoc, EndLoc); 13625 } 13626 13627 OMPClause *Sema::ActOnOpenMPDynamicAllocatorsClause(SourceLocation StartLoc, 13628 SourceLocation EndLoc) { 13629 return new (Context) OMPDynamicAllocatorsClause(StartLoc, EndLoc); 13630 } 13631 13632 OMPClause *Sema::ActOnOpenMPDestroyClause(SourceLocation StartLoc, 13633 SourceLocation EndLoc) { 13634 return new (Context) OMPDestroyClause(StartLoc, EndLoc); 13635 } 13636 13637 OMPClause *Sema::ActOnOpenMPVarListClause( 13638 OpenMPClauseKind Kind, ArrayRef<Expr *> VarList, Expr *DepModOrTailExpr, 13639 const OMPVarListLocTy &Locs, SourceLocation ColonLoc, 13640 CXXScopeSpec &ReductionOrMapperIdScopeSpec, 13641 DeclarationNameInfo &ReductionOrMapperId, int ExtraModifier, 13642 ArrayRef<OpenMPMapModifierKind> MapTypeModifiers, 13643 ArrayRef<SourceLocation> MapTypeModifiersLoc, bool IsMapTypeImplicit, 13644 SourceLocation ExtraModifierLoc, 13645 ArrayRef<OpenMPMotionModifierKind> MotionModifiers, 13646 ArrayRef<SourceLocation> MotionModifiersLoc) { 13647 SourceLocation StartLoc = Locs.StartLoc; 13648 SourceLocation LParenLoc = Locs.LParenLoc; 13649 SourceLocation EndLoc = Locs.EndLoc; 13650 OMPClause *Res = nullptr; 13651 switch (Kind) { 13652 case OMPC_private: 13653 Res = ActOnOpenMPPrivateClause(VarList, StartLoc, LParenLoc, EndLoc); 13654 break; 13655 case OMPC_firstprivate: 13656 Res = ActOnOpenMPFirstprivateClause(VarList, StartLoc, LParenLoc, EndLoc); 13657 break; 13658 case OMPC_lastprivate: 13659 assert(0 <= ExtraModifier && ExtraModifier <= OMPC_LASTPRIVATE_unknown && 13660 "Unexpected lastprivate modifier."); 13661 Res = ActOnOpenMPLastprivateClause( 13662 VarList, static_cast<OpenMPLastprivateModifier>(ExtraModifier), 13663 ExtraModifierLoc, ColonLoc, StartLoc, LParenLoc, EndLoc); 13664 break; 13665 case OMPC_shared: 13666 Res = ActOnOpenMPSharedClause(VarList, StartLoc, LParenLoc, EndLoc); 13667 break; 13668 case OMPC_reduction: 13669 assert(0 <= ExtraModifier && ExtraModifier <= OMPC_REDUCTION_unknown && 13670 "Unexpected lastprivate modifier."); 13671 Res = ActOnOpenMPReductionClause( 13672 VarList, static_cast<OpenMPReductionClauseModifier>(ExtraModifier), 13673 StartLoc, LParenLoc, ExtraModifierLoc, ColonLoc, EndLoc, 13674 ReductionOrMapperIdScopeSpec, ReductionOrMapperId); 13675 break; 13676 case OMPC_task_reduction: 13677 Res = ActOnOpenMPTaskReductionClause(VarList, StartLoc, LParenLoc, ColonLoc, 13678 EndLoc, ReductionOrMapperIdScopeSpec, 13679 ReductionOrMapperId); 13680 break; 13681 case OMPC_in_reduction: 13682 Res = ActOnOpenMPInReductionClause(VarList, StartLoc, LParenLoc, ColonLoc, 13683 EndLoc, ReductionOrMapperIdScopeSpec, 13684 ReductionOrMapperId); 13685 break; 13686 case OMPC_linear: 13687 assert(0 <= ExtraModifier && ExtraModifier <= OMPC_LINEAR_unknown && 13688 "Unexpected linear modifier."); 13689 Res = ActOnOpenMPLinearClause( 13690 VarList, DepModOrTailExpr, StartLoc, LParenLoc, 13691 static_cast<OpenMPLinearClauseKind>(ExtraModifier), ExtraModifierLoc, 13692 ColonLoc, EndLoc); 13693 break; 13694 case OMPC_aligned: 13695 Res = ActOnOpenMPAlignedClause(VarList, DepModOrTailExpr, StartLoc, 13696 LParenLoc, ColonLoc, EndLoc); 13697 break; 13698 case OMPC_copyin: 13699 Res = ActOnOpenMPCopyinClause(VarList, StartLoc, LParenLoc, EndLoc); 13700 break; 13701 case OMPC_copyprivate: 13702 Res = ActOnOpenMPCopyprivateClause(VarList, StartLoc, LParenLoc, EndLoc); 13703 break; 13704 case OMPC_flush: 13705 Res = ActOnOpenMPFlushClause(VarList, StartLoc, LParenLoc, EndLoc); 13706 break; 13707 case OMPC_depend: 13708 assert(0 <= ExtraModifier && ExtraModifier <= OMPC_DEPEND_unknown && 13709 "Unexpected depend modifier."); 13710 Res = ActOnOpenMPDependClause( 13711 DepModOrTailExpr, static_cast<OpenMPDependClauseKind>(ExtraModifier), 13712 ExtraModifierLoc, ColonLoc, VarList, StartLoc, LParenLoc, EndLoc); 13713 break; 13714 case OMPC_map: 13715 assert(0 <= ExtraModifier && ExtraModifier <= OMPC_MAP_unknown && 13716 "Unexpected map modifier."); 13717 Res = ActOnOpenMPMapClause( 13718 MapTypeModifiers, MapTypeModifiersLoc, ReductionOrMapperIdScopeSpec, 13719 ReductionOrMapperId, static_cast<OpenMPMapClauseKind>(ExtraModifier), 13720 IsMapTypeImplicit, ExtraModifierLoc, ColonLoc, VarList, Locs); 13721 break; 13722 case OMPC_to: 13723 Res = ActOnOpenMPToClause(MotionModifiers, MotionModifiersLoc, 13724 ReductionOrMapperIdScopeSpec, ReductionOrMapperId, 13725 ColonLoc, VarList, Locs); 13726 break; 13727 case OMPC_from: 13728 Res = ActOnOpenMPFromClause(MotionModifiers, MotionModifiersLoc, 13729 ReductionOrMapperIdScopeSpec, 13730 ReductionOrMapperId, ColonLoc, VarList, Locs); 13731 break; 13732 case OMPC_use_device_ptr: 13733 Res = ActOnOpenMPUseDevicePtrClause(VarList, Locs); 13734 break; 13735 case OMPC_use_device_addr: 13736 Res = ActOnOpenMPUseDeviceAddrClause(VarList, Locs); 13737 break; 13738 case OMPC_is_device_ptr: 13739 Res = ActOnOpenMPIsDevicePtrClause(VarList, Locs); 13740 break; 13741 case OMPC_allocate: 13742 Res = ActOnOpenMPAllocateClause(DepModOrTailExpr, VarList, StartLoc, 13743 LParenLoc, ColonLoc, EndLoc); 13744 break; 13745 case OMPC_nontemporal: 13746 Res = ActOnOpenMPNontemporalClause(VarList, StartLoc, LParenLoc, EndLoc); 13747 break; 13748 case OMPC_inclusive: 13749 Res = ActOnOpenMPInclusiveClause(VarList, StartLoc, LParenLoc, EndLoc); 13750 break; 13751 case OMPC_exclusive: 13752 Res = ActOnOpenMPExclusiveClause(VarList, StartLoc, LParenLoc, EndLoc); 13753 break; 13754 case OMPC_affinity: 13755 Res = ActOnOpenMPAffinityClause(StartLoc, LParenLoc, ColonLoc, EndLoc, 13756 DepModOrTailExpr, VarList); 13757 break; 13758 case OMPC_if: 13759 case OMPC_depobj: 13760 case OMPC_final: 13761 case OMPC_num_threads: 13762 case OMPC_safelen: 13763 case OMPC_simdlen: 13764 case OMPC_allocator: 13765 case OMPC_collapse: 13766 case OMPC_default: 13767 case OMPC_proc_bind: 13768 case OMPC_schedule: 13769 case OMPC_ordered: 13770 case OMPC_nowait: 13771 case OMPC_untied: 13772 case OMPC_mergeable: 13773 case OMPC_threadprivate: 13774 case OMPC_read: 13775 case OMPC_write: 13776 case OMPC_update: 13777 case OMPC_capture: 13778 case OMPC_seq_cst: 13779 case OMPC_acq_rel: 13780 case OMPC_acquire: 13781 case OMPC_release: 13782 case OMPC_relaxed: 13783 case OMPC_device: 13784 case OMPC_threads: 13785 case OMPC_simd: 13786 case OMPC_num_teams: 13787 case OMPC_thread_limit: 13788 case OMPC_priority: 13789 case OMPC_grainsize: 13790 case OMPC_nogroup: 13791 case OMPC_num_tasks: 13792 case OMPC_hint: 13793 case OMPC_dist_schedule: 13794 case OMPC_defaultmap: 13795 case OMPC_unknown: 13796 case OMPC_uniform: 13797 case OMPC_unified_address: 13798 case OMPC_unified_shared_memory: 13799 case OMPC_reverse_offload: 13800 case OMPC_dynamic_allocators: 13801 case OMPC_atomic_default_mem_order: 13802 case OMPC_device_type: 13803 case OMPC_match: 13804 case OMPC_order: 13805 case OMPC_destroy: 13806 case OMPC_detach: 13807 case OMPC_uses_allocators: 13808 default: 13809 llvm_unreachable("Clause is not allowed."); 13810 } 13811 return Res; 13812 } 13813 13814 ExprResult Sema::getOpenMPCapturedExpr(VarDecl *Capture, ExprValueKind VK, 13815 ExprObjectKind OK, SourceLocation Loc) { 13816 ExprResult Res = BuildDeclRefExpr( 13817 Capture, Capture->getType().getNonReferenceType(), VK_LValue, Loc); 13818 if (!Res.isUsable()) 13819 return ExprError(); 13820 if (OK == OK_Ordinary && !getLangOpts().CPlusPlus) { 13821 Res = CreateBuiltinUnaryOp(Loc, UO_Deref, Res.get()); 13822 if (!Res.isUsable()) 13823 return ExprError(); 13824 } 13825 if (VK != VK_LValue && Res.get()->isGLValue()) { 13826 Res = DefaultLvalueConversion(Res.get()); 13827 if (!Res.isUsable()) 13828 return ExprError(); 13829 } 13830 return Res; 13831 } 13832 13833 OMPClause *Sema::ActOnOpenMPPrivateClause(ArrayRef<Expr *> VarList, 13834 SourceLocation StartLoc, 13835 SourceLocation LParenLoc, 13836 SourceLocation EndLoc) { 13837 SmallVector<Expr *, 8> Vars; 13838 SmallVector<Expr *, 8> PrivateCopies; 13839 for (Expr *RefExpr : VarList) { 13840 assert(RefExpr && "NULL expr in OpenMP private clause."); 13841 SourceLocation ELoc; 13842 SourceRange ERange; 13843 Expr *SimpleRefExpr = RefExpr; 13844 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 13845 if (Res.second) { 13846 // It will be analyzed later. 13847 Vars.push_back(RefExpr); 13848 PrivateCopies.push_back(nullptr); 13849 } 13850 ValueDecl *D = Res.first; 13851 if (!D) 13852 continue; 13853 13854 QualType Type = D->getType(); 13855 auto *VD = dyn_cast<VarDecl>(D); 13856 13857 // OpenMP [2.9.3.3, Restrictions, C/C++, p.3] 13858 // A variable that appears in a private clause must not have an incomplete 13859 // type or a reference type. 13860 if (RequireCompleteType(ELoc, Type, diag::err_omp_private_incomplete_type)) 13861 continue; 13862 Type = Type.getNonReferenceType(); 13863 13864 // OpenMP 5.0 [2.19.3, List Item Privatization, Restrictions] 13865 // A variable that is privatized must not have a const-qualified type 13866 // unless it is of class type with a mutable member. This restriction does 13867 // not apply to the firstprivate clause. 13868 // 13869 // OpenMP 3.1 [2.9.3.3, private clause, Restrictions] 13870 // A variable that appears in a private clause must not have a 13871 // const-qualified type unless it is of class type with a mutable member. 13872 if (rejectConstNotMutableType(*this, D, Type, OMPC_private, ELoc)) 13873 continue; 13874 13875 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 13876 // in a Construct] 13877 // Variables with the predetermined data-sharing attributes may not be 13878 // listed in data-sharing attributes clauses, except for the cases 13879 // listed below. For these exceptions only, listing a predetermined 13880 // variable in a data-sharing attribute clause is allowed and overrides 13881 // the variable's predetermined data-sharing attributes. 13882 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false); 13883 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_private) { 13884 Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind) 13885 << getOpenMPClauseName(OMPC_private); 13886 reportOriginalDsa(*this, DSAStack, D, DVar); 13887 continue; 13888 } 13889 13890 OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective(); 13891 // Variably modified types are not supported for tasks. 13892 if (!Type->isAnyPointerType() && Type->isVariablyModifiedType() && 13893 isOpenMPTaskingDirective(CurrDir)) { 13894 Diag(ELoc, diag::err_omp_variably_modified_type_not_supported) 13895 << getOpenMPClauseName(OMPC_private) << Type 13896 << getOpenMPDirectiveName(CurrDir); 13897 bool IsDecl = 13898 !VD || 13899 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 13900 Diag(D->getLocation(), 13901 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 13902 << D; 13903 continue; 13904 } 13905 13906 // OpenMP 4.5 [2.15.5.1, Restrictions, p.3] 13907 // A list item cannot appear in both a map clause and a data-sharing 13908 // attribute clause on the same construct 13909 // 13910 // OpenMP 5.0 [2.19.7.1, Restrictions, p.7] 13911 // A list item cannot appear in both a map clause and a data-sharing 13912 // attribute clause on the same construct unless the construct is a 13913 // combined construct. 13914 if ((LangOpts.OpenMP <= 45 && isOpenMPTargetExecutionDirective(CurrDir)) || 13915 CurrDir == OMPD_target) { 13916 OpenMPClauseKind ConflictKind; 13917 if (DSAStack->checkMappableExprComponentListsForDecl( 13918 VD, /*CurrentRegionOnly=*/true, 13919 [&](OMPClauseMappableExprCommon::MappableExprComponentListRef, 13920 OpenMPClauseKind WhereFoundClauseKind) -> bool { 13921 ConflictKind = WhereFoundClauseKind; 13922 return true; 13923 })) { 13924 Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa) 13925 << getOpenMPClauseName(OMPC_private) 13926 << getOpenMPClauseName(ConflictKind) 13927 << getOpenMPDirectiveName(CurrDir); 13928 reportOriginalDsa(*this, DSAStack, D, DVar); 13929 continue; 13930 } 13931 } 13932 13933 // OpenMP [2.9.3.3, Restrictions, C/C++, p.1] 13934 // A variable of class type (or array thereof) that appears in a private 13935 // clause requires an accessible, unambiguous default constructor for the 13936 // class type. 13937 // Generate helper private variable and initialize it with the default 13938 // value. The address of the original variable is replaced by the address of 13939 // the new private variable in CodeGen. This new variable is not added to 13940 // IdResolver, so the code in the OpenMP region uses original variable for 13941 // proper diagnostics. 13942 Type = Type.getUnqualifiedType(); 13943 VarDecl *VDPrivate = 13944 buildVarDecl(*this, ELoc, Type, D->getName(), 13945 D->hasAttrs() ? &D->getAttrs() : nullptr, 13946 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr); 13947 ActOnUninitializedDecl(VDPrivate); 13948 if (VDPrivate->isInvalidDecl()) 13949 continue; 13950 DeclRefExpr *VDPrivateRefExpr = buildDeclRefExpr( 13951 *this, VDPrivate, RefExpr->getType().getUnqualifiedType(), ELoc); 13952 13953 DeclRefExpr *Ref = nullptr; 13954 if (!VD && !CurContext->isDependentContext()) 13955 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false); 13956 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_private, Ref); 13957 Vars.push_back((VD || CurContext->isDependentContext()) 13958 ? RefExpr->IgnoreParens() 13959 : Ref); 13960 PrivateCopies.push_back(VDPrivateRefExpr); 13961 } 13962 13963 if (Vars.empty()) 13964 return nullptr; 13965 13966 return OMPPrivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars, 13967 PrivateCopies); 13968 } 13969 13970 namespace { 13971 class DiagsUninitializedSeveretyRAII { 13972 private: 13973 DiagnosticsEngine &Diags; 13974 SourceLocation SavedLoc; 13975 bool IsIgnored = false; 13976 13977 public: 13978 DiagsUninitializedSeveretyRAII(DiagnosticsEngine &Diags, SourceLocation Loc, 13979 bool IsIgnored) 13980 : Diags(Diags), SavedLoc(Loc), IsIgnored(IsIgnored) { 13981 if (!IsIgnored) { 13982 Diags.setSeverity(/*Diag*/ diag::warn_uninit_self_reference_in_init, 13983 /*Map*/ diag::Severity::Ignored, Loc); 13984 } 13985 } 13986 ~DiagsUninitializedSeveretyRAII() { 13987 if (!IsIgnored) 13988 Diags.popMappings(SavedLoc); 13989 } 13990 }; 13991 } 13992 13993 OMPClause *Sema::ActOnOpenMPFirstprivateClause(ArrayRef<Expr *> VarList, 13994 SourceLocation StartLoc, 13995 SourceLocation LParenLoc, 13996 SourceLocation EndLoc) { 13997 SmallVector<Expr *, 8> Vars; 13998 SmallVector<Expr *, 8> PrivateCopies; 13999 SmallVector<Expr *, 8> Inits; 14000 SmallVector<Decl *, 4> ExprCaptures; 14001 bool IsImplicitClause = 14002 StartLoc.isInvalid() && LParenLoc.isInvalid() && EndLoc.isInvalid(); 14003 SourceLocation ImplicitClauseLoc = DSAStack->getConstructLoc(); 14004 14005 for (Expr *RefExpr : VarList) { 14006 assert(RefExpr && "NULL expr in OpenMP firstprivate clause."); 14007 SourceLocation ELoc; 14008 SourceRange ERange; 14009 Expr *SimpleRefExpr = RefExpr; 14010 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 14011 if (Res.second) { 14012 // It will be analyzed later. 14013 Vars.push_back(RefExpr); 14014 PrivateCopies.push_back(nullptr); 14015 Inits.push_back(nullptr); 14016 } 14017 ValueDecl *D = Res.first; 14018 if (!D) 14019 continue; 14020 14021 ELoc = IsImplicitClause ? ImplicitClauseLoc : ELoc; 14022 QualType Type = D->getType(); 14023 auto *VD = dyn_cast<VarDecl>(D); 14024 14025 // OpenMP [2.9.3.3, Restrictions, C/C++, p.3] 14026 // A variable that appears in a private clause must not have an incomplete 14027 // type or a reference type. 14028 if (RequireCompleteType(ELoc, Type, 14029 diag::err_omp_firstprivate_incomplete_type)) 14030 continue; 14031 Type = Type.getNonReferenceType(); 14032 14033 // OpenMP [2.9.3.4, Restrictions, C/C++, p.1] 14034 // A variable of class type (or array thereof) that appears in a private 14035 // clause requires an accessible, unambiguous copy constructor for the 14036 // class type. 14037 QualType ElemType = Context.getBaseElementType(Type).getNonReferenceType(); 14038 14039 // If an implicit firstprivate variable found it was checked already. 14040 DSAStackTy::DSAVarData TopDVar; 14041 if (!IsImplicitClause) { 14042 DSAStackTy::DSAVarData DVar = 14043 DSAStack->getTopDSA(D, /*FromParent=*/false); 14044 TopDVar = DVar; 14045 OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective(); 14046 bool IsConstant = ElemType.isConstant(Context); 14047 // OpenMP [2.4.13, Data-sharing Attribute Clauses] 14048 // A list item that specifies a given variable may not appear in more 14049 // than one clause on the same directive, except that a variable may be 14050 // specified in both firstprivate and lastprivate clauses. 14051 // OpenMP 4.5 [2.10.8, Distribute Construct, p.3] 14052 // A list item may appear in a firstprivate or lastprivate clause but not 14053 // both. 14054 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_firstprivate && 14055 (isOpenMPDistributeDirective(CurrDir) || 14056 DVar.CKind != OMPC_lastprivate) && 14057 DVar.RefExpr) { 14058 Diag(ELoc, diag::err_omp_wrong_dsa) 14059 << getOpenMPClauseName(DVar.CKind) 14060 << getOpenMPClauseName(OMPC_firstprivate); 14061 reportOriginalDsa(*this, DSAStack, D, DVar); 14062 continue; 14063 } 14064 14065 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 14066 // in a Construct] 14067 // Variables with the predetermined data-sharing attributes may not be 14068 // listed in data-sharing attributes clauses, except for the cases 14069 // listed below. For these exceptions only, listing a predetermined 14070 // variable in a data-sharing attribute clause is allowed and overrides 14071 // the variable's predetermined data-sharing attributes. 14072 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 14073 // in a Construct, C/C++, p.2] 14074 // Variables with const-qualified type having no mutable member may be 14075 // listed in a firstprivate clause, even if they are static data members. 14076 if (!(IsConstant || (VD && VD->isStaticDataMember())) && !DVar.RefExpr && 14077 DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_shared) { 14078 Diag(ELoc, diag::err_omp_wrong_dsa) 14079 << getOpenMPClauseName(DVar.CKind) 14080 << getOpenMPClauseName(OMPC_firstprivate); 14081 reportOriginalDsa(*this, DSAStack, D, DVar); 14082 continue; 14083 } 14084 14085 // OpenMP [2.9.3.4, Restrictions, p.2] 14086 // A list item that is private within a parallel region must not appear 14087 // in a firstprivate clause on a worksharing construct if any of the 14088 // worksharing regions arising from the worksharing construct ever bind 14089 // to any of the parallel regions arising from the parallel construct. 14090 // OpenMP 4.5 [2.15.3.4, Restrictions, p.3] 14091 // A list item that is private within a teams region must not appear in a 14092 // firstprivate clause on a distribute construct if any of the distribute 14093 // regions arising from the distribute construct ever bind to any of the 14094 // teams regions arising from the teams construct. 14095 // OpenMP 4.5 [2.15.3.4, Restrictions, p.3] 14096 // A list item that appears in a reduction clause of a teams construct 14097 // must not appear in a firstprivate clause on a distribute construct if 14098 // any of the distribute regions arising from the distribute construct 14099 // ever bind to any of the teams regions arising from the teams construct. 14100 if ((isOpenMPWorksharingDirective(CurrDir) || 14101 isOpenMPDistributeDirective(CurrDir)) && 14102 !isOpenMPParallelDirective(CurrDir) && 14103 !isOpenMPTeamsDirective(CurrDir)) { 14104 DVar = DSAStack->getImplicitDSA(D, true); 14105 if (DVar.CKind != OMPC_shared && 14106 (isOpenMPParallelDirective(DVar.DKind) || 14107 isOpenMPTeamsDirective(DVar.DKind) || 14108 DVar.DKind == OMPD_unknown)) { 14109 Diag(ELoc, diag::err_omp_required_access) 14110 << getOpenMPClauseName(OMPC_firstprivate) 14111 << getOpenMPClauseName(OMPC_shared); 14112 reportOriginalDsa(*this, DSAStack, D, DVar); 14113 continue; 14114 } 14115 } 14116 // OpenMP [2.9.3.4, Restrictions, p.3] 14117 // A list item that appears in a reduction clause of a parallel construct 14118 // must not appear in a firstprivate clause on a worksharing or task 14119 // construct if any of the worksharing or task regions arising from the 14120 // worksharing or task construct ever bind to any of the parallel regions 14121 // arising from the parallel construct. 14122 // OpenMP [2.9.3.4, Restrictions, p.4] 14123 // A list item that appears in a reduction clause in worksharing 14124 // construct must not appear in a firstprivate clause in a task construct 14125 // encountered during execution of any of the worksharing regions arising 14126 // from the worksharing construct. 14127 if (isOpenMPTaskingDirective(CurrDir)) { 14128 DVar = DSAStack->hasInnermostDSA( 14129 D, 14130 [](OpenMPClauseKind C, bool AppliedToPointee) { 14131 return C == OMPC_reduction && !AppliedToPointee; 14132 }, 14133 [](OpenMPDirectiveKind K) { 14134 return isOpenMPParallelDirective(K) || 14135 isOpenMPWorksharingDirective(K) || 14136 isOpenMPTeamsDirective(K); 14137 }, 14138 /*FromParent=*/true); 14139 if (DVar.CKind == OMPC_reduction && 14140 (isOpenMPParallelDirective(DVar.DKind) || 14141 isOpenMPWorksharingDirective(DVar.DKind) || 14142 isOpenMPTeamsDirective(DVar.DKind))) { 14143 Diag(ELoc, diag::err_omp_parallel_reduction_in_task_firstprivate) 14144 << getOpenMPDirectiveName(DVar.DKind); 14145 reportOriginalDsa(*this, DSAStack, D, DVar); 14146 continue; 14147 } 14148 } 14149 14150 // OpenMP 4.5 [2.15.5.1, Restrictions, p.3] 14151 // A list item cannot appear in both a map clause and a data-sharing 14152 // attribute clause on the same construct 14153 // 14154 // OpenMP 5.0 [2.19.7.1, Restrictions, p.7] 14155 // A list item cannot appear in both a map clause and a data-sharing 14156 // attribute clause on the same construct unless the construct is a 14157 // combined construct. 14158 if ((LangOpts.OpenMP <= 45 && 14159 isOpenMPTargetExecutionDirective(CurrDir)) || 14160 CurrDir == OMPD_target) { 14161 OpenMPClauseKind ConflictKind; 14162 if (DSAStack->checkMappableExprComponentListsForDecl( 14163 VD, /*CurrentRegionOnly=*/true, 14164 [&ConflictKind]( 14165 OMPClauseMappableExprCommon::MappableExprComponentListRef, 14166 OpenMPClauseKind WhereFoundClauseKind) { 14167 ConflictKind = WhereFoundClauseKind; 14168 return true; 14169 })) { 14170 Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa) 14171 << getOpenMPClauseName(OMPC_firstprivate) 14172 << getOpenMPClauseName(ConflictKind) 14173 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 14174 reportOriginalDsa(*this, DSAStack, D, DVar); 14175 continue; 14176 } 14177 } 14178 } 14179 14180 // Variably modified types are not supported for tasks. 14181 if (!Type->isAnyPointerType() && Type->isVariablyModifiedType() && 14182 isOpenMPTaskingDirective(DSAStack->getCurrentDirective())) { 14183 Diag(ELoc, diag::err_omp_variably_modified_type_not_supported) 14184 << getOpenMPClauseName(OMPC_firstprivate) << Type 14185 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 14186 bool IsDecl = 14187 !VD || 14188 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 14189 Diag(D->getLocation(), 14190 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 14191 << D; 14192 continue; 14193 } 14194 14195 Type = Type.getUnqualifiedType(); 14196 VarDecl *VDPrivate = 14197 buildVarDecl(*this, ELoc, Type, D->getName(), 14198 D->hasAttrs() ? &D->getAttrs() : nullptr, 14199 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr); 14200 // Generate helper private variable and initialize it with the value of the 14201 // original variable. The address of the original variable is replaced by 14202 // the address of the new private variable in the CodeGen. This new variable 14203 // is not added to IdResolver, so the code in the OpenMP region uses 14204 // original variable for proper diagnostics and variable capturing. 14205 Expr *VDInitRefExpr = nullptr; 14206 // For arrays generate initializer for single element and replace it by the 14207 // original array element in CodeGen. 14208 if (Type->isArrayType()) { 14209 VarDecl *VDInit = 14210 buildVarDecl(*this, RefExpr->getExprLoc(), ElemType, D->getName()); 14211 VDInitRefExpr = buildDeclRefExpr(*this, VDInit, ElemType, ELoc); 14212 Expr *Init = DefaultLvalueConversion(VDInitRefExpr).get(); 14213 ElemType = ElemType.getUnqualifiedType(); 14214 VarDecl *VDInitTemp = buildVarDecl(*this, RefExpr->getExprLoc(), ElemType, 14215 ".firstprivate.temp"); 14216 InitializedEntity Entity = 14217 InitializedEntity::InitializeVariable(VDInitTemp); 14218 InitializationKind Kind = InitializationKind::CreateCopy(ELoc, ELoc); 14219 14220 InitializationSequence InitSeq(*this, Entity, Kind, Init); 14221 ExprResult Result = InitSeq.Perform(*this, Entity, Kind, Init); 14222 if (Result.isInvalid()) 14223 VDPrivate->setInvalidDecl(); 14224 else 14225 VDPrivate->setInit(Result.getAs<Expr>()); 14226 // Remove temp variable declaration. 14227 Context.Deallocate(VDInitTemp); 14228 } else { 14229 VarDecl *VDInit = buildVarDecl(*this, RefExpr->getExprLoc(), Type, 14230 ".firstprivate.temp"); 14231 VDInitRefExpr = buildDeclRefExpr(*this, VDInit, RefExpr->getType(), 14232 RefExpr->getExprLoc()); 14233 AddInitializerToDecl(VDPrivate, 14234 DefaultLvalueConversion(VDInitRefExpr).get(), 14235 /*DirectInit=*/false); 14236 } 14237 if (VDPrivate->isInvalidDecl()) { 14238 if (IsImplicitClause) { 14239 Diag(RefExpr->getExprLoc(), 14240 diag::note_omp_task_predetermined_firstprivate_here); 14241 } 14242 continue; 14243 } 14244 CurContext->addDecl(VDPrivate); 14245 DeclRefExpr *VDPrivateRefExpr = buildDeclRefExpr( 14246 *this, VDPrivate, RefExpr->getType().getUnqualifiedType(), 14247 RefExpr->getExprLoc()); 14248 DeclRefExpr *Ref = nullptr; 14249 if (!VD && !CurContext->isDependentContext()) { 14250 if (TopDVar.CKind == OMPC_lastprivate) { 14251 Ref = TopDVar.PrivateCopy; 14252 } else { 14253 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true); 14254 if (!isOpenMPCapturedDecl(D)) 14255 ExprCaptures.push_back(Ref->getDecl()); 14256 } 14257 } 14258 if (!IsImplicitClause) 14259 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_firstprivate, Ref); 14260 Vars.push_back((VD || CurContext->isDependentContext()) 14261 ? RefExpr->IgnoreParens() 14262 : Ref); 14263 PrivateCopies.push_back(VDPrivateRefExpr); 14264 Inits.push_back(VDInitRefExpr); 14265 } 14266 14267 if (Vars.empty()) 14268 return nullptr; 14269 14270 return OMPFirstprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, 14271 Vars, PrivateCopies, Inits, 14272 buildPreInits(Context, ExprCaptures)); 14273 } 14274 14275 OMPClause *Sema::ActOnOpenMPLastprivateClause( 14276 ArrayRef<Expr *> VarList, OpenMPLastprivateModifier LPKind, 14277 SourceLocation LPKindLoc, SourceLocation ColonLoc, SourceLocation StartLoc, 14278 SourceLocation LParenLoc, SourceLocation EndLoc) { 14279 if (LPKind == OMPC_LASTPRIVATE_unknown && LPKindLoc.isValid()) { 14280 assert(ColonLoc.isValid() && "Colon location must be valid."); 14281 Diag(LPKindLoc, diag::err_omp_unexpected_clause_value) 14282 << getListOfPossibleValues(OMPC_lastprivate, /*First=*/0, 14283 /*Last=*/OMPC_LASTPRIVATE_unknown) 14284 << getOpenMPClauseName(OMPC_lastprivate); 14285 return nullptr; 14286 } 14287 14288 SmallVector<Expr *, 8> Vars; 14289 SmallVector<Expr *, 8> SrcExprs; 14290 SmallVector<Expr *, 8> DstExprs; 14291 SmallVector<Expr *, 8> AssignmentOps; 14292 SmallVector<Decl *, 4> ExprCaptures; 14293 SmallVector<Expr *, 4> ExprPostUpdates; 14294 for (Expr *RefExpr : VarList) { 14295 assert(RefExpr && "NULL expr in OpenMP lastprivate clause."); 14296 SourceLocation ELoc; 14297 SourceRange ERange; 14298 Expr *SimpleRefExpr = RefExpr; 14299 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 14300 if (Res.second) { 14301 // It will be analyzed later. 14302 Vars.push_back(RefExpr); 14303 SrcExprs.push_back(nullptr); 14304 DstExprs.push_back(nullptr); 14305 AssignmentOps.push_back(nullptr); 14306 } 14307 ValueDecl *D = Res.first; 14308 if (!D) 14309 continue; 14310 14311 QualType Type = D->getType(); 14312 auto *VD = dyn_cast<VarDecl>(D); 14313 14314 // OpenMP [2.14.3.5, Restrictions, C/C++, p.2] 14315 // A variable that appears in a lastprivate clause must not have an 14316 // incomplete type or a reference type. 14317 if (RequireCompleteType(ELoc, Type, 14318 diag::err_omp_lastprivate_incomplete_type)) 14319 continue; 14320 Type = Type.getNonReferenceType(); 14321 14322 // OpenMP 5.0 [2.19.3, List Item Privatization, Restrictions] 14323 // A variable that is privatized must not have a const-qualified type 14324 // unless it is of class type with a mutable member. This restriction does 14325 // not apply to the firstprivate clause. 14326 // 14327 // OpenMP 3.1 [2.9.3.5, lastprivate clause, Restrictions] 14328 // A variable that appears in a lastprivate clause must not have a 14329 // const-qualified type unless it is of class type with a mutable member. 14330 if (rejectConstNotMutableType(*this, D, Type, OMPC_lastprivate, ELoc)) 14331 continue; 14332 14333 // OpenMP 5.0 [2.19.4.5 lastprivate Clause, Restrictions] 14334 // A list item that appears in a lastprivate clause with the conditional 14335 // modifier must be a scalar variable. 14336 if (LPKind == OMPC_LASTPRIVATE_conditional && !Type->isScalarType()) { 14337 Diag(ELoc, diag::err_omp_lastprivate_conditional_non_scalar); 14338 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) == 14339 VarDecl::DeclarationOnly; 14340 Diag(D->getLocation(), 14341 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 14342 << D; 14343 continue; 14344 } 14345 14346 OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective(); 14347 // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables Referenced 14348 // in a Construct] 14349 // Variables with the predetermined data-sharing attributes may not be 14350 // listed in data-sharing attributes clauses, except for the cases 14351 // listed below. 14352 // OpenMP 4.5 [2.10.8, Distribute Construct, p.3] 14353 // A list item may appear in a firstprivate or lastprivate clause but not 14354 // both. 14355 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false); 14356 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_lastprivate && 14357 (isOpenMPDistributeDirective(CurrDir) || 14358 DVar.CKind != OMPC_firstprivate) && 14359 (DVar.CKind != OMPC_private || DVar.RefExpr != nullptr)) { 14360 Diag(ELoc, diag::err_omp_wrong_dsa) 14361 << getOpenMPClauseName(DVar.CKind) 14362 << getOpenMPClauseName(OMPC_lastprivate); 14363 reportOriginalDsa(*this, DSAStack, D, DVar); 14364 continue; 14365 } 14366 14367 // OpenMP [2.14.3.5, Restrictions, p.2] 14368 // A list item that is private within a parallel region, or that appears in 14369 // the reduction clause of a parallel construct, must not appear in a 14370 // lastprivate clause on a worksharing construct if any of the corresponding 14371 // worksharing regions ever binds to any of the corresponding parallel 14372 // regions. 14373 DSAStackTy::DSAVarData TopDVar = DVar; 14374 if (isOpenMPWorksharingDirective(CurrDir) && 14375 !isOpenMPParallelDirective(CurrDir) && 14376 !isOpenMPTeamsDirective(CurrDir)) { 14377 DVar = DSAStack->getImplicitDSA(D, true); 14378 if (DVar.CKind != OMPC_shared) { 14379 Diag(ELoc, diag::err_omp_required_access) 14380 << getOpenMPClauseName(OMPC_lastprivate) 14381 << getOpenMPClauseName(OMPC_shared); 14382 reportOriginalDsa(*this, DSAStack, D, DVar); 14383 continue; 14384 } 14385 } 14386 14387 // OpenMP [2.14.3.5, Restrictions, C++, p.1,2] 14388 // A variable of class type (or array thereof) that appears in a 14389 // lastprivate clause requires an accessible, unambiguous default 14390 // constructor for the class type, unless the list item is also specified 14391 // in a firstprivate clause. 14392 // A variable of class type (or array thereof) that appears in a 14393 // lastprivate clause requires an accessible, unambiguous copy assignment 14394 // operator for the class type. 14395 Type = Context.getBaseElementType(Type).getNonReferenceType(); 14396 VarDecl *SrcVD = buildVarDecl(*this, ERange.getBegin(), 14397 Type.getUnqualifiedType(), ".lastprivate.src", 14398 D->hasAttrs() ? &D->getAttrs() : nullptr); 14399 DeclRefExpr *PseudoSrcExpr = 14400 buildDeclRefExpr(*this, SrcVD, Type.getUnqualifiedType(), ELoc); 14401 VarDecl *DstVD = 14402 buildVarDecl(*this, ERange.getBegin(), Type, ".lastprivate.dst", 14403 D->hasAttrs() ? &D->getAttrs() : nullptr); 14404 DeclRefExpr *PseudoDstExpr = buildDeclRefExpr(*this, DstVD, Type, ELoc); 14405 // For arrays generate assignment operation for single element and replace 14406 // it by the original array element in CodeGen. 14407 ExprResult AssignmentOp = BuildBinOp(/*S=*/nullptr, ELoc, BO_Assign, 14408 PseudoDstExpr, PseudoSrcExpr); 14409 if (AssignmentOp.isInvalid()) 14410 continue; 14411 AssignmentOp = 14412 ActOnFinishFullExpr(AssignmentOp.get(), ELoc, /*DiscardedValue*/ false); 14413 if (AssignmentOp.isInvalid()) 14414 continue; 14415 14416 DeclRefExpr *Ref = nullptr; 14417 if (!VD && !CurContext->isDependentContext()) { 14418 if (TopDVar.CKind == OMPC_firstprivate) { 14419 Ref = TopDVar.PrivateCopy; 14420 } else { 14421 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false); 14422 if (!isOpenMPCapturedDecl(D)) 14423 ExprCaptures.push_back(Ref->getDecl()); 14424 } 14425 if ((TopDVar.CKind == OMPC_firstprivate && !TopDVar.PrivateCopy) || 14426 (!isOpenMPCapturedDecl(D) && 14427 Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>())) { 14428 ExprResult RefRes = DefaultLvalueConversion(Ref); 14429 if (!RefRes.isUsable()) 14430 continue; 14431 ExprResult PostUpdateRes = 14432 BuildBinOp(DSAStack->getCurScope(), ELoc, BO_Assign, SimpleRefExpr, 14433 RefRes.get()); 14434 if (!PostUpdateRes.isUsable()) 14435 continue; 14436 ExprPostUpdates.push_back( 14437 IgnoredValueConversions(PostUpdateRes.get()).get()); 14438 } 14439 } 14440 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_lastprivate, Ref); 14441 Vars.push_back((VD || CurContext->isDependentContext()) 14442 ? RefExpr->IgnoreParens() 14443 : Ref); 14444 SrcExprs.push_back(PseudoSrcExpr); 14445 DstExprs.push_back(PseudoDstExpr); 14446 AssignmentOps.push_back(AssignmentOp.get()); 14447 } 14448 14449 if (Vars.empty()) 14450 return nullptr; 14451 14452 return OMPLastprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, 14453 Vars, SrcExprs, DstExprs, AssignmentOps, 14454 LPKind, LPKindLoc, ColonLoc, 14455 buildPreInits(Context, ExprCaptures), 14456 buildPostUpdate(*this, ExprPostUpdates)); 14457 } 14458 14459 OMPClause *Sema::ActOnOpenMPSharedClause(ArrayRef<Expr *> VarList, 14460 SourceLocation StartLoc, 14461 SourceLocation LParenLoc, 14462 SourceLocation EndLoc) { 14463 SmallVector<Expr *, 8> Vars; 14464 for (Expr *RefExpr : VarList) { 14465 assert(RefExpr && "NULL expr in OpenMP lastprivate clause."); 14466 SourceLocation ELoc; 14467 SourceRange ERange; 14468 Expr *SimpleRefExpr = RefExpr; 14469 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 14470 if (Res.second) { 14471 // It will be analyzed later. 14472 Vars.push_back(RefExpr); 14473 } 14474 ValueDecl *D = Res.first; 14475 if (!D) 14476 continue; 14477 14478 auto *VD = dyn_cast<VarDecl>(D); 14479 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 14480 // in a Construct] 14481 // Variables with the predetermined data-sharing attributes may not be 14482 // listed in data-sharing attributes clauses, except for the cases 14483 // listed below. For these exceptions only, listing a predetermined 14484 // variable in a data-sharing attribute clause is allowed and overrides 14485 // the variable's predetermined data-sharing attributes. 14486 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false); 14487 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_shared && 14488 DVar.RefExpr) { 14489 Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind) 14490 << getOpenMPClauseName(OMPC_shared); 14491 reportOriginalDsa(*this, DSAStack, D, DVar); 14492 continue; 14493 } 14494 14495 DeclRefExpr *Ref = nullptr; 14496 if (!VD && isOpenMPCapturedDecl(D) && !CurContext->isDependentContext()) 14497 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true); 14498 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_shared, Ref); 14499 Vars.push_back((VD || !Ref || CurContext->isDependentContext()) 14500 ? RefExpr->IgnoreParens() 14501 : Ref); 14502 } 14503 14504 if (Vars.empty()) 14505 return nullptr; 14506 14507 return OMPSharedClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars); 14508 } 14509 14510 namespace { 14511 class DSARefChecker : public StmtVisitor<DSARefChecker, bool> { 14512 DSAStackTy *Stack; 14513 14514 public: 14515 bool VisitDeclRefExpr(DeclRefExpr *E) { 14516 if (auto *VD = dyn_cast<VarDecl>(E->getDecl())) { 14517 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(VD, /*FromParent=*/false); 14518 if (DVar.CKind == OMPC_shared && !DVar.RefExpr) 14519 return false; 14520 if (DVar.CKind != OMPC_unknown) 14521 return true; 14522 DSAStackTy::DSAVarData DVarPrivate = Stack->hasDSA( 14523 VD, 14524 [](OpenMPClauseKind C, bool AppliedToPointee) { 14525 return isOpenMPPrivate(C) && !AppliedToPointee; 14526 }, 14527 [](OpenMPDirectiveKind) { return true; }, 14528 /*FromParent=*/true); 14529 return DVarPrivate.CKind != OMPC_unknown; 14530 } 14531 return false; 14532 } 14533 bool VisitStmt(Stmt *S) { 14534 for (Stmt *Child : S->children()) { 14535 if (Child && Visit(Child)) 14536 return true; 14537 } 14538 return false; 14539 } 14540 explicit DSARefChecker(DSAStackTy *S) : Stack(S) {} 14541 }; 14542 } // namespace 14543 14544 namespace { 14545 // Transform MemberExpression for specified FieldDecl of current class to 14546 // DeclRefExpr to specified OMPCapturedExprDecl. 14547 class TransformExprToCaptures : public TreeTransform<TransformExprToCaptures> { 14548 typedef TreeTransform<TransformExprToCaptures> BaseTransform; 14549 ValueDecl *Field = nullptr; 14550 DeclRefExpr *CapturedExpr = nullptr; 14551 14552 public: 14553 TransformExprToCaptures(Sema &SemaRef, ValueDecl *FieldDecl) 14554 : BaseTransform(SemaRef), Field(FieldDecl), CapturedExpr(nullptr) {} 14555 14556 ExprResult TransformMemberExpr(MemberExpr *E) { 14557 if (isa<CXXThisExpr>(E->getBase()->IgnoreParenImpCasts()) && 14558 E->getMemberDecl() == Field) { 14559 CapturedExpr = buildCapture(SemaRef, Field, E, /*WithInit=*/false); 14560 return CapturedExpr; 14561 } 14562 return BaseTransform::TransformMemberExpr(E); 14563 } 14564 DeclRefExpr *getCapturedExpr() { return CapturedExpr; } 14565 }; 14566 } // namespace 14567 14568 template <typename T, typename U> 14569 static T filterLookupForUDReductionAndMapper( 14570 SmallVectorImpl<U> &Lookups, const llvm::function_ref<T(ValueDecl *)> Gen) { 14571 for (U &Set : Lookups) { 14572 for (auto *D : Set) { 14573 if (T Res = Gen(cast<ValueDecl>(D))) 14574 return Res; 14575 } 14576 } 14577 return T(); 14578 } 14579 14580 static NamedDecl *findAcceptableDecl(Sema &SemaRef, NamedDecl *D) { 14581 assert(!LookupResult::isVisible(SemaRef, D) && "not in slow case"); 14582 14583 for (auto RD : D->redecls()) { 14584 // Don't bother with extra checks if we already know this one isn't visible. 14585 if (RD == D) 14586 continue; 14587 14588 auto ND = cast<NamedDecl>(RD); 14589 if (LookupResult::isVisible(SemaRef, ND)) 14590 return ND; 14591 } 14592 14593 return nullptr; 14594 } 14595 14596 static void 14597 argumentDependentLookup(Sema &SemaRef, const DeclarationNameInfo &Id, 14598 SourceLocation Loc, QualType Ty, 14599 SmallVectorImpl<UnresolvedSet<8>> &Lookups) { 14600 // Find all of the associated namespaces and classes based on the 14601 // arguments we have. 14602 Sema::AssociatedNamespaceSet AssociatedNamespaces; 14603 Sema::AssociatedClassSet AssociatedClasses; 14604 OpaqueValueExpr OVE(Loc, Ty, VK_LValue); 14605 SemaRef.FindAssociatedClassesAndNamespaces(Loc, &OVE, AssociatedNamespaces, 14606 AssociatedClasses); 14607 14608 // C++ [basic.lookup.argdep]p3: 14609 // Let X be the lookup set produced by unqualified lookup (3.4.1) 14610 // and let Y be the lookup set produced by argument dependent 14611 // lookup (defined as follows). If X contains [...] then Y is 14612 // empty. Otherwise Y is the set of declarations found in the 14613 // namespaces associated with the argument types as described 14614 // below. The set of declarations found by the lookup of the name 14615 // is the union of X and Y. 14616 // 14617 // Here, we compute Y and add its members to the overloaded 14618 // candidate set. 14619 for (auto *NS : AssociatedNamespaces) { 14620 // When considering an associated namespace, the lookup is the 14621 // same as the lookup performed when the associated namespace is 14622 // used as a qualifier (3.4.3.2) except that: 14623 // 14624 // -- Any using-directives in the associated namespace are 14625 // ignored. 14626 // 14627 // -- Any namespace-scope friend functions declared in 14628 // associated classes are visible within their respective 14629 // namespaces even if they are not visible during an ordinary 14630 // lookup (11.4). 14631 DeclContext::lookup_result R = NS->lookup(Id.getName()); 14632 for (auto *D : R) { 14633 auto *Underlying = D; 14634 if (auto *USD = dyn_cast<UsingShadowDecl>(D)) 14635 Underlying = USD->getTargetDecl(); 14636 14637 if (!isa<OMPDeclareReductionDecl>(Underlying) && 14638 !isa<OMPDeclareMapperDecl>(Underlying)) 14639 continue; 14640 14641 if (!SemaRef.isVisible(D)) { 14642 D = findAcceptableDecl(SemaRef, D); 14643 if (!D) 14644 continue; 14645 if (auto *USD = dyn_cast<UsingShadowDecl>(D)) 14646 Underlying = USD->getTargetDecl(); 14647 } 14648 Lookups.emplace_back(); 14649 Lookups.back().addDecl(Underlying); 14650 } 14651 } 14652 } 14653 14654 static ExprResult 14655 buildDeclareReductionRef(Sema &SemaRef, SourceLocation Loc, SourceRange Range, 14656 Scope *S, CXXScopeSpec &ReductionIdScopeSpec, 14657 const DeclarationNameInfo &ReductionId, QualType Ty, 14658 CXXCastPath &BasePath, Expr *UnresolvedReduction) { 14659 if (ReductionIdScopeSpec.isInvalid()) 14660 return ExprError(); 14661 SmallVector<UnresolvedSet<8>, 4> Lookups; 14662 if (S) { 14663 LookupResult Lookup(SemaRef, ReductionId, Sema::LookupOMPReductionName); 14664 Lookup.suppressDiagnostics(); 14665 while (S && SemaRef.LookupParsedName(Lookup, S, &ReductionIdScopeSpec)) { 14666 NamedDecl *D = Lookup.getRepresentativeDecl(); 14667 do { 14668 S = S->getParent(); 14669 } while (S && !S->isDeclScope(D)); 14670 if (S) 14671 S = S->getParent(); 14672 Lookups.emplace_back(); 14673 Lookups.back().append(Lookup.begin(), Lookup.end()); 14674 Lookup.clear(); 14675 } 14676 } else if (auto *ULE = 14677 cast_or_null<UnresolvedLookupExpr>(UnresolvedReduction)) { 14678 Lookups.push_back(UnresolvedSet<8>()); 14679 Decl *PrevD = nullptr; 14680 for (NamedDecl *D : ULE->decls()) { 14681 if (D == PrevD) 14682 Lookups.push_back(UnresolvedSet<8>()); 14683 else if (auto *DRD = dyn_cast<OMPDeclareReductionDecl>(D)) 14684 Lookups.back().addDecl(DRD); 14685 PrevD = D; 14686 } 14687 } 14688 if (SemaRef.CurContext->isDependentContext() || Ty->isDependentType() || 14689 Ty->isInstantiationDependentType() || 14690 Ty->containsUnexpandedParameterPack() || 14691 filterLookupForUDReductionAndMapper<bool>(Lookups, [](ValueDecl *D) { 14692 return !D->isInvalidDecl() && 14693 (D->getType()->isDependentType() || 14694 D->getType()->isInstantiationDependentType() || 14695 D->getType()->containsUnexpandedParameterPack()); 14696 })) { 14697 UnresolvedSet<8> ResSet; 14698 for (const UnresolvedSet<8> &Set : Lookups) { 14699 if (Set.empty()) 14700 continue; 14701 ResSet.append(Set.begin(), Set.end()); 14702 // The last item marks the end of all declarations at the specified scope. 14703 ResSet.addDecl(Set[Set.size() - 1]); 14704 } 14705 return UnresolvedLookupExpr::Create( 14706 SemaRef.Context, /*NamingClass=*/nullptr, 14707 ReductionIdScopeSpec.getWithLocInContext(SemaRef.Context), ReductionId, 14708 /*ADL=*/true, /*Overloaded=*/true, ResSet.begin(), ResSet.end()); 14709 } 14710 // Lookup inside the classes. 14711 // C++ [over.match.oper]p3: 14712 // For a unary operator @ with an operand of a type whose 14713 // cv-unqualified version is T1, and for a binary operator @ with 14714 // a left operand of a type whose cv-unqualified version is T1 and 14715 // a right operand of a type whose cv-unqualified version is T2, 14716 // three sets of candidate functions, designated member 14717 // candidates, non-member candidates and built-in candidates, are 14718 // constructed as follows: 14719 // -- If T1 is a complete class type or a class currently being 14720 // defined, the set of member candidates is the result of the 14721 // qualified lookup of T1::operator@ (13.3.1.1.1); otherwise, 14722 // the set of member candidates is empty. 14723 LookupResult Lookup(SemaRef, ReductionId, Sema::LookupOMPReductionName); 14724 Lookup.suppressDiagnostics(); 14725 if (const auto *TyRec = Ty->getAs<RecordType>()) { 14726 // Complete the type if it can be completed. 14727 // If the type is neither complete nor being defined, bail out now. 14728 if (SemaRef.isCompleteType(Loc, Ty) || TyRec->isBeingDefined() || 14729 TyRec->getDecl()->getDefinition()) { 14730 Lookup.clear(); 14731 SemaRef.LookupQualifiedName(Lookup, TyRec->getDecl()); 14732 if (Lookup.empty()) { 14733 Lookups.emplace_back(); 14734 Lookups.back().append(Lookup.begin(), Lookup.end()); 14735 } 14736 } 14737 } 14738 // Perform ADL. 14739 if (SemaRef.getLangOpts().CPlusPlus) 14740 argumentDependentLookup(SemaRef, ReductionId, Loc, Ty, Lookups); 14741 if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>( 14742 Lookups, [&SemaRef, Ty](ValueDecl *D) -> ValueDecl * { 14743 if (!D->isInvalidDecl() && 14744 SemaRef.Context.hasSameType(D->getType(), Ty)) 14745 return D; 14746 return nullptr; 14747 })) 14748 return SemaRef.BuildDeclRefExpr(VD, VD->getType().getNonReferenceType(), 14749 VK_LValue, Loc); 14750 if (SemaRef.getLangOpts().CPlusPlus) { 14751 if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>( 14752 Lookups, [&SemaRef, Ty, Loc](ValueDecl *D) -> ValueDecl * { 14753 if (!D->isInvalidDecl() && 14754 SemaRef.IsDerivedFrom(Loc, Ty, D->getType()) && 14755 !Ty.isMoreQualifiedThan(D->getType())) 14756 return D; 14757 return nullptr; 14758 })) { 14759 CXXBasePaths Paths(/*FindAmbiguities=*/true, /*RecordPaths=*/true, 14760 /*DetectVirtual=*/false); 14761 if (SemaRef.IsDerivedFrom(Loc, Ty, VD->getType(), Paths)) { 14762 if (!Paths.isAmbiguous(SemaRef.Context.getCanonicalType( 14763 VD->getType().getUnqualifiedType()))) { 14764 if (SemaRef.CheckBaseClassAccess( 14765 Loc, VD->getType(), Ty, Paths.front(), 14766 /*DiagID=*/0) != Sema::AR_inaccessible) { 14767 SemaRef.BuildBasePathArray(Paths, BasePath); 14768 return SemaRef.BuildDeclRefExpr( 14769 VD, VD->getType().getNonReferenceType(), VK_LValue, Loc); 14770 } 14771 } 14772 } 14773 } 14774 } 14775 if (ReductionIdScopeSpec.isSet()) { 14776 SemaRef.Diag(Loc, diag::err_omp_not_resolved_reduction_identifier) 14777 << Ty << Range; 14778 return ExprError(); 14779 } 14780 return ExprEmpty(); 14781 } 14782 14783 namespace { 14784 /// Data for the reduction-based clauses. 14785 struct ReductionData { 14786 /// List of original reduction items. 14787 SmallVector<Expr *, 8> Vars; 14788 /// List of private copies of the reduction items. 14789 SmallVector<Expr *, 8> Privates; 14790 /// LHS expressions for the reduction_op expressions. 14791 SmallVector<Expr *, 8> LHSs; 14792 /// RHS expressions for the reduction_op expressions. 14793 SmallVector<Expr *, 8> RHSs; 14794 /// Reduction operation expression. 14795 SmallVector<Expr *, 8> ReductionOps; 14796 /// inscan copy operation expressions. 14797 SmallVector<Expr *, 8> InscanCopyOps; 14798 /// inscan copy temp array expressions for prefix sums. 14799 SmallVector<Expr *, 8> InscanCopyArrayTemps; 14800 /// inscan copy temp array element expressions for prefix sums. 14801 SmallVector<Expr *, 8> InscanCopyArrayElems; 14802 /// Taskgroup descriptors for the corresponding reduction items in 14803 /// in_reduction clauses. 14804 SmallVector<Expr *, 8> TaskgroupDescriptors; 14805 /// List of captures for clause. 14806 SmallVector<Decl *, 4> ExprCaptures; 14807 /// List of postupdate expressions. 14808 SmallVector<Expr *, 4> ExprPostUpdates; 14809 /// Reduction modifier. 14810 unsigned RedModifier = 0; 14811 ReductionData() = delete; 14812 /// Reserves required memory for the reduction data. 14813 ReductionData(unsigned Size, unsigned Modifier = 0) : RedModifier(Modifier) { 14814 Vars.reserve(Size); 14815 Privates.reserve(Size); 14816 LHSs.reserve(Size); 14817 RHSs.reserve(Size); 14818 ReductionOps.reserve(Size); 14819 if (RedModifier == OMPC_REDUCTION_inscan) { 14820 InscanCopyOps.reserve(Size); 14821 InscanCopyArrayTemps.reserve(Size); 14822 InscanCopyArrayElems.reserve(Size); 14823 } 14824 TaskgroupDescriptors.reserve(Size); 14825 ExprCaptures.reserve(Size); 14826 ExprPostUpdates.reserve(Size); 14827 } 14828 /// Stores reduction item and reduction operation only (required for dependent 14829 /// reduction item). 14830 void push(Expr *Item, Expr *ReductionOp) { 14831 Vars.emplace_back(Item); 14832 Privates.emplace_back(nullptr); 14833 LHSs.emplace_back(nullptr); 14834 RHSs.emplace_back(nullptr); 14835 ReductionOps.emplace_back(ReductionOp); 14836 TaskgroupDescriptors.emplace_back(nullptr); 14837 if (RedModifier == OMPC_REDUCTION_inscan) { 14838 InscanCopyOps.push_back(nullptr); 14839 InscanCopyArrayTemps.push_back(nullptr); 14840 InscanCopyArrayElems.push_back(nullptr); 14841 } 14842 } 14843 /// Stores reduction data. 14844 void push(Expr *Item, Expr *Private, Expr *LHS, Expr *RHS, Expr *ReductionOp, 14845 Expr *TaskgroupDescriptor, Expr *CopyOp, Expr *CopyArrayTemp, 14846 Expr *CopyArrayElem) { 14847 Vars.emplace_back(Item); 14848 Privates.emplace_back(Private); 14849 LHSs.emplace_back(LHS); 14850 RHSs.emplace_back(RHS); 14851 ReductionOps.emplace_back(ReductionOp); 14852 TaskgroupDescriptors.emplace_back(TaskgroupDescriptor); 14853 if (RedModifier == OMPC_REDUCTION_inscan) { 14854 InscanCopyOps.push_back(CopyOp); 14855 InscanCopyArrayTemps.push_back(CopyArrayTemp); 14856 InscanCopyArrayElems.push_back(CopyArrayElem); 14857 } else { 14858 assert(CopyOp == nullptr && CopyArrayTemp == nullptr && 14859 CopyArrayElem == nullptr && 14860 "Copy operation must be used for inscan reductions only."); 14861 } 14862 } 14863 }; 14864 } // namespace 14865 14866 static bool checkOMPArraySectionConstantForReduction( 14867 ASTContext &Context, const OMPArraySectionExpr *OASE, bool &SingleElement, 14868 SmallVectorImpl<llvm::APSInt> &ArraySizes) { 14869 const Expr *Length = OASE->getLength(); 14870 if (Length == nullptr) { 14871 // For array sections of the form [1:] or [:], we would need to analyze 14872 // the lower bound... 14873 if (OASE->getColonLocFirst().isValid()) 14874 return false; 14875 14876 // This is an array subscript which has implicit length 1! 14877 SingleElement = true; 14878 ArraySizes.push_back(llvm::APSInt::get(1)); 14879 } else { 14880 Expr::EvalResult Result; 14881 if (!Length->EvaluateAsInt(Result, Context)) 14882 return false; 14883 14884 llvm::APSInt ConstantLengthValue = Result.Val.getInt(); 14885 SingleElement = (ConstantLengthValue.getSExtValue() == 1); 14886 ArraySizes.push_back(ConstantLengthValue); 14887 } 14888 14889 // Get the base of this array section and walk up from there. 14890 const Expr *Base = OASE->getBase()->IgnoreParenImpCasts(); 14891 14892 // We require length = 1 for all array sections except the right-most to 14893 // guarantee that the memory region is contiguous and has no holes in it. 14894 while (const auto *TempOASE = dyn_cast<OMPArraySectionExpr>(Base)) { 14895 Length = TempOASE->getLength(); 14896 if (Length == nullptr) { 14897 // For array sections of the form [1:] or [:], we would need to analyze 14898 // the lower bound... 14899 if (OASE->getColonLocFirst().isValid()) 14900 return false; 14901 14902 // This is an array subscript which has implicit length 1! 14903 ArraySizes.push_back(llvm::APSInt::get(1)); 14904 } else { 14905 Expr::EvalResult Result; 14906 if (!Length->EvaluateAsInt(Result, Context)) 14907 return false; 14908 14909 llvm::APSInt ConstantLengthValue = Result.Val.getInt(); 14910 if (ConstantLengthValue.getSExtValue() != 1) 14911 return false; 14912 14913 ArraySizes.push_back(ConstantLengthValue); 14914 } 14915 Base = TempOASE->getBase()->IgnoreParenImpCasts(); 14916 } 14917 14918 // If we have a single element, we don't need to add the implicit lengths. 14919 if (!SingleElement) { 14920 while (const auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base)) { 14921 // Has implicit length 1! 14922 ArraySizes.push_back(llvm::APSInt::get(1)); 14923 Base = TempASE->getBase()->IgnoreParenImpCasts(); 14924 } 14925 } 14926 14927 // This array section can be privatized as a single value or as a constant 14928 // sized array. 14929 return true; 14930 } 14931 14932 static bool actOnOMPReductionKindClause( 14933 Sema &S, DSAStackTy *Stack, OpenMPClauseKind ClauseKind, 14934 ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, 14935 SourceLocation ColonLoc, SourceLocation EndLoc, 14936 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, 14937 ArrayRef<Expr *> UnresolvedReductions, ReductionData &RD) { 14938 DeclarationName DN = ReductionId.getName(); 14939 OverloadedOperatorKind OOK = DN.getCXXOverloadedOperator(); 14940 BinaryOperatorKind BOK = BO_Comma; 14941 14942 ASTContext &Context = S.Context; 14943 // OpenMP [2.14.3.6, reduction clause] 14944 // C 14945 // reduction-identifier is either an identifier or one of the following 14946 // operators: +, -, *, &, |, ^, && and || 14947 // C++ 14948 // reduction-identifier is either an id-expression or one of the following 14949 // operators: +, -, *, &, |, ^, && and || 14950 switch (OOK) { 14951 case OO_Plus: 14952 case OO_Minus: 14953 BOK = BO_Add; 14954 break; 14955 case OO_Star: 14956 BOK = BO_Mul; 14957 break; 14958 case OO_Amp: 14959 BOK = BO_And; 14960 break; 14961 case OO_Pipe: 14962 BOK = BO_Or; 14963 break; 14964 case OO_Caret: 14965 BOK = BO_Xor; 14966 break; 14967 case OO_AmpAmp: 14968 BOK = BO_LAnd; 14969 break; 14970 case OO_PipePipe: 14971 BOK = BO_LOr; 14972 break; 14973 case OO_New: 14974 case OO_Delete: 14975 case OO_Array_New: 14976 case OO_Array_Delete: 14977 case OO_Slash: 14978 case OO_Percent: 14979 case OO_Tilde: 14980 case OO_Exclaim: 14981 case OO_Equal: 14982 case OO_Less: 14983 case OO_Greater: 14984 case OO_LessEqual: 14985 case OO_GreaterEqual: 14986 case OO_PlusEqual: 14987 case OO_MinusEqual: 14988 case OO_StarEqual: 14989 case OO_SlashEqual: 14990 case OO_PercentEqual: 14991 case OO_CaretEqual: 14992 case OO_AmpEqual: 14993 case OO_PipeEqual: 14994 case OO_LessLess: 14995 case OO_GreaterGreater: 14996 case OO_LessLessEqual: 14997 case OO_GreaterGreaterEqual: 14998 case OO_EqualEqual: 14999 case OO_ExclaimEqual: 15000 case OO_Spaceship: 15001 case OO_PlusPlus: 15002 case OO_MinusMinus: 15003 case OO_Comma: 15004 case OO_ArrowStar: 15005 case OO_Arrow: 15006 case OO_Call: 15007 case OO_Subscript: 15008 case OO_Conditional: 15009 case OO_Coawait: 15010 case NUM_OVERLOADED_OPERATORS: 15011 llvm_unreachable("Unexpected reduction identifier"); 15012 case OO_None: 15013 if (IdentifierInfo *II = DN.getAsIdentifierInfo()) { 15014 if (II->isStr("max")) 15015 BOK = BO_GT; 15016 else if (II->isStr("min")) 15017 BOK = BO_LT; 15018 } 15019 break; 15020 } 15021 SourceRange ReductionIdRange; 15022 if (ReductionIdScopeSpec.isValid()) 15023 ReductionIdRange.setBegin(ReductionIdScopeSpec.getBeginLoc()); 15024 else 15025 ReductionIdRange.setBegin(ReductionId.getBeginLoc()); 15026 ReductionIdRange.setEnd(ReductionId.getEndLoc()); 15027 15028 auto IR = UnresolvedReductions.begin(), ER = UnresolvedReductions.end(); 15029 bool FirstIter = true; 15030 for (Expr *RefExpr : VarList) { 15031 assert(RefExpr && "nullptr expr in OpenMP reduction clause."); 15032 // OpenMP [2.1, C/C++] 15033 // A list item is a variable or array section, subject to the restrictions 15034 // specified in Section 2.4 on page 42 and in each of the sections 15035 // describing clauses and directives for which a list appears. 15036 // OpenMP [2.14.3.3, Restrictions, p.1] 15037 // A variable that is part of another variable (as an array or 15038 // structure element) cannot appear in a private clause. 15039 if (!FirstIter && IR != ER) 15040 ++IR; 15041 FirstIter = false; 15042 SourceLocation ELoc; 15043 SourceRange ERange; 15044 Expr *SimpleRefExpr = RefExpr; 15045 auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange, 15046 /*AllowArraySection=*/true); 15047 if (Res.second) { 15048 // Try to find 'declare reduction' corresponding construct before using 15049 // builtin/overloaded operators. 15050 QualType Type = Context.DependentTy; 15051 CXXCastPath BasePath; 15052 ExprResult DeclareReductionRef = buildDeclareReductionRef( 15053 S, ELoc, ERange, Stack->getCurScope(), ReductionIdScopeSpec, 15054 ReductionId, Type, BasePath, IR == ER ? nullptr : *IR); 15055 Expr *ReductionOp = nullptr; 15056 if (S.CurContext->isDependentContext() && 15057 (DeclareReductionRef.isUnset() || 15058 isa<UnresolvedLookupExpr>(DeclareReductionRef.get()))) 15059 ReductionOp = DeclareReductionRef.get(); 15060 // It will be analyzed later. 15061 RD.push(RefExpr, ReductionOp); 15062 } 15063 ValueDecl *D = Res.first; 15064 if (!D) 15065 continue; 15066 15067 Expr *TaskgroupDescriptor = nullptr; 15068 QualType Type; 15069 auto *ASE = dyn_cast<ArraySubscriptExpr>(RefExpr->IgnoreParens()); 15070 auto *OASE = dyn_cast<OMPArraySectionExpr>(RefExpr->IgnoreParens()); 15071 if (ASE) { 15072 Type = ASE->getType().getNonReferenceType(); 15073 } else if (OASE) { 15074 QualType BaseType = 15075 OMPArraySectionExpr::getBaseOriginalType(OASE->getBase()); 15076 if (const auto *ATy = BaseType->getAsArrayTypeUnsafe()) 15077 Type = ATy->getElementType(); 15078 else 15079 Type = BaseType->getPointeeType(); 15080 Type = Type.getNonReferenceType(); 15081 } else { 15082 Type = Context.getBaseElementType(D->getType().getNonReferenceType()); 15083 } 15084 auto *VD = dyn_cast<VarDecl>(D); 15085 15086 // OpenMP [2.9.3.3, Restrictions, C/C++, p.3] 15087 // A variable that appears in a private clause must not have an incomplete 15088 // type or a reference type. 15089 if (S.RequireCompleteType(ELoc, D->getType(), 15090 diag::err_omp_reduction_incomplete_type)) 15091 continue; 15092 // OpenMP [2.14.3.6, reduction clause, Restrictions] 15093 // A list item that appears in a reduction clause must not be 15094 // const-qualified. 15095 if (rejectConstNotMutableType(S, D, Type, ClauseKind, ELoc, 15096 /*AcceptIfMutable*/ false, ASE || OASE)) 15097 continue; 15098 15099 OpenMPDirectiveKind CurrDir = Stack->getCurrentDirective(); 15100 // OpenMP [2.9.3.6, Restrictions, C/C++, p.4] 15101 // If a list-item is a reference type then it must bind to the same object 15102 // for all threads of the team. 15103 if (!ASE && !OASE) { 15104 if (VD) { 15105 VarDecl *VDDef = VD->getDefinition(); 15106 if (VD->getType()->isReferenceType() && VDDef && VDDef->hasInit()) { 15107 DSARefChecker Check(Stack); 15108 if (Check.Visit(VDDef->getInit())) { 15109 S.Diag(ELoc, diag::err_omp_reduction_ref_type_arg) 15110 << getOpenMPClauseName(ClauseKind) << ERange; 15111 S.Diag(VDDef->getLocation(), diag::note_defined_here) << VDDef; 15112 continue; 15113 } 15114 } 15115 } 15116 15117 // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables Referenced 15118 // in a Construct] 15119 // Variables with the predetermined data-sharing attributes may not be 15120 // listed in data-sharing attributes clauses, except for the cases 15121 // listed below. For these exceptions only, listing a predetermined 15122 // variable in a data-sharing attribute clause is allowed and overrides 15123 // the variable's predetermined data-sharing attributes. 15124 // OpenMP [2.14.3.6, Restrictions, p.3] 15125 // Any number of reduction clauses can be specified on the directive, 15126 // but a list item can appear only once in the reduction clauses for that 15127 // directive. 15128 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(D, /*FromParent=*/false); 15129 if (DVar.CKind == OMPC_reduction) { 15130 S.Diag(ELoc, diag::err_omp_once_referenced) 15131 << getOpenMPClauseName(ClauseKind); 15132 if (DVar.RefExpr) 15133 S.Diag(DVar.RefExpr->getExprLoc(), diag::note_omp_referenced); 15134 continue; 15135 } 15136 if (DVar.CKind != OMPC_unknown) { 15137 S.Diag(ELoc, diag::err_omp_wrong_dsa) 15138 << getOpenMPClauseName(DVar.CKind) 15139 << getOpenMPClauseName(OMPC_reduction); 15140 reportOriginalDsa(S, Stack, D, DVar); 15141 continue; 15142 } 15143 15144 // OpenMP [2.14.3.6, Restrictions, p.1] 15145 // A list item that appears in a reduction clause of a worksharing 15146 // construct must be shared in the parallel regions to which any of the 15147 // worksharing regions arising from the worksharing construct bind. 15148 if (isOpenMPWorksharingDirective(CurrDir) && 15149 !isOpenMPParallelDirective(CurrDir) && 15150 !isOpenMPTeamsDirective(CurrDir)) { 15151 DVar = Stack->getImplicitDSA(D, true); 15152 if (DVar.CKind != OMPC_shared) { 15153 S.Diag(ELoc, diag::err_omp_required_access) 15154 << getOpenMPClauseName(OMPC_reduction) 15155 << getOpenMPClauseName(OMPC_shared); 15156 reportOriginalDsa(S, Stack, D, DVar); 15157 continue; 15158 } 15159 } 15160 } else { 15161 // Threadprivates cannot be shared between threads, so dignose if the base 15162 // is a threadprivate variable. 15163 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(D, /*FromParent=*/false); 15164 if (DVar.CKind == OMPC_threadprivate) { 15165 S.Diag(ELoc, diag::err_omp_wrong_dsa) 15166 << getOpenMPClauseName(DVar.CKind) 15167 << getOpenMPClauseName(OMPC_reduction); 15168 reportOriginalDsa(S, Stack, D, DVar); 15169 continue; 15170 } 15171 } 15172 15173 // Try to find 'declare reduction' corresponding construct before using 15174 // builtin/overloaded operators. 15175 CXXCastPath BasePath; 15176 ExprResult DeclareReductionRef = buildDeclareReductionRef( 15177 S, ELoc, ERange, Stack->getCurScope(), ReductionIdScopeSpec, 15178 ReductionId, Type, BasePath, IR == ER ? nullptr : *IR); 15179 if (DeclareReductionRef.isInvalid()) 15180 continue; 15181 if (S.CurContext->isDependentContext() && 15182 (DeclareReductionRef.isUnset() || 15183 isa<UnresolvedLookupExpr>(DeclareReductionRef.get()))) { 15184 RD.push(RefExpr, DeclareReductionRef.get()); 15185 continue; 15186 } 15187 if (BOK == BO_Comma && DeclareReductionRef.isUnset()) { 15188 // Not allowed reduction identifier is found. 15189 S.Diag(ReductionId.getBeginLoc(), 15190 diag::err_omp_unknown_reduction_identifier) 15191 << Type << ReductionIdRange; 15192 continue; 15193 } 15194 15195 // OpenMP [2.14.3.6, reduction clause, Restrictions] 15196 // The type of a list item that appears in a reduction clause must be valid 15197 // for the reduction-identifier. For a max or min reduction in C, the type 15198 // of the list item must be an allowed arithmetic data type: char, int, 15199 // float, double, or _Bool, possibly modified with long, short, signed, or 15200 // unsigned. For a max or min reduction in C++, the type of the list item 15201 // must be an allowed arithmetic data type: char, wchar_t, int, float, 15202 // double, or bool, possibly modified with long, short, signed, or unsigned. 15203 if (DeclareReductionRef.isUnset()) { 15204 if ((BOK == BO_GT || BOK == BO_LT) && 15205 !(Type->isScalarType() || 15206 (S.getLangOpts().CPlusPlus && Type->isArithmeticType()))) { 15207 S.Diag(ELoc, diag::err_omp_clause_not_arithmetic_type_arg) 15208 << getOpenMPClauseName(ClauseKind) << S.getLangOpts().CPlusPlus; 15209 if (!ASE && !OASE) { 15210 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) == 15211 VarDecl::DeclarationOnly; 15212 S.Diag(D->getLocation(), 15213 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 15214 << D; 15215 } 15216 continue; 15217 } 15218 if ((BOK == BO_OrAssign || BOK == BO_AndAssign || BOK == BO_XorAssign) && 15219 !S.getLangOpts().CPlusPlus && Type->isFloatingType()) { 15220 S.Diag(ELoc, diag::err_omp_clause_floating_type_arg) 15221 << getOpenMPClauseName(ClauseKind); 15222 if (!ASE && !OASE) { 15223 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) == 15224 VarDecl::DeclarationOnly; 15225 S.Diag(D->getLocation(), 15226 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 15227 << D; 15228 } 15229 continue; 15230 } 15231 } 15232 15233 Type = Type.getNonLValueExprType(Context).getUnqualifiedType(); 15234 VarDecl *LHSVD = buildVarDecl(S, ELoc, Type, ".reduction.lhs", 15235 D->hasAttrs() ? &D->getAttrs() : nullptr); 15236 VarDecl *RHSVD = buildVarDecl(S, ELoc, Type, D->getName(), 15237 D->hasAttrs() ? &D->getAttrs() : nullptr); 15238 QualType PrivateTy = Type; 15239 15240 // Try if we can determine constant lengths for all array sections and avoid 15241 // the VLA. 15242 bool ConstantLengthOASE = false; 15243 if (OASE) { 15244 bool SingleElement; 15245 llvm::SmallVector<llvm::APSInt, 4> ArraySizes; 15246 ConstantLengthOASE = checkOMPArraySectionConstantForReduction( 15247 Context, OASE, SingleElement, ArraySizes); 15248 15249 // If we don't have a single element, we must emit a constant array type. 15250 if (ConstantLengthOASE && !SingleElement) { 15251 for (llvm::APSInt &Size : ArraySizes) 15252 PrivateTy = Context.getConstantArrayType(PrivateTy, Size, nullptr, 15253 ArrayType::Normal, 15254 /*IndexTypeQuals=*/0); 15255 } 15256 } 15257 15258 if ((OASE && !ConstantLengthOASE) || 15259 (!OASE && !ASE && 15260 D->getType().getNonReferenceType()->isVariablyModifiedType())) { 15261 if (!Context.getTargetInfo().isVLASupported()) { 15262 if (isOpenMPTargetExecutionDirective(Stack->getCurrentDirective())) { 15263 S.Diag(ELoc, diag::err_omp_reduction_vla_unsupported) << !!OASE; 15264 S.Diag(ELoc, diag::note_vla_unsupported); 15265 continue; 15266 } else { 15267 S.targetDiag(ELoc, diag::err_omp_reduction_vla_unsupported) << !!OASE; 15268 S.targetDiag(ELoc, diag::note_vla_unsupported); 15269 } 15270 } 15271 // For arrays/array sections only: 15272 // Create pseudo array type for private copy. The size for this array will 15273 // be generated during codegen. 15274 // For array subscripts or single variables Private Ty is the same as Type 15275 // (type of the variable or single array element). 15276 PrivateTy = Context.getVariableArrayType( 15277 Type, 15278 new (Context) OpaqueValueExpr(ELoc, Context.getSizeType(), VK_RValue), 15279 ArrayType::Normal, /*IndexTypeQuals=*/0, SourceRange()); 15280 } else if (!ASE && !OASE && 15281 Context.getAsArrayType(D->getType().getNonReferenceType())) { 15282 PrivateTy = D->getType().getNonReferenceType(); 15283 } 15284 // Private copy. 15285 VarDecl *PrivateVD = 15286 buildVarDecl(S, ELoc, PrivateTy, D->getName(), 15287 D->hasAttrs() ? &D->getAttrs() : nullptr, 15288 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr); 15289 // Add initializer for private variable. 15290 Expr *Init = nullptr; 15291 DeclRefExpr *LHSDRE = buildDeclRefExpr(S, LHSVD, Type, ELoc); 15292 DeclRefExpr *RHSDRE = buildDeclRefExpr(S, RHSVD, Type, ELoc); 15293 if (DeclareReductionRef.isUsable()) { 15294 auto *DRDRef = DeclareReductionRef.getAs<DeclRefExpr>(); 15295 auto *DRD = cast<OMPDeclareReductionDecl>(DRDRef->getDecl()); 15296 if (DRD->getInitializer()) { 15297 S.ActOnUninitializedDecl(PrivateVD); 15298 Init = DRDRef; 15299 RHSVD->setInit(DRDRef); 15300 RHSVD->setInitStyle(VarDecl::CallInit); 15301 } 15302 } else { 15303 switch (BOK) { 15304 case BO_Add: 15305 case BO_Xor: 15306 case BO_Or: 15307 case BO_LOr: 15308 // '+', '-', '^', '|', '||' reduction ops - initializer is '0'. 15309 if (Type->isScalarType() || Type->isAnyComplexType()) 15310 Init = S.ActOnIntegerConstant(ELoc, /*Val=*/0).get(); 15311 break; 15312 case BO_Mul: 15313 case BO_LAnd: 15314 if (Type->isScalarType() || Type->isAnyComplexType()) { 15315 // '*' and '&&' reduction ops - initializer is '1'. 15316 Init = S.ActOnIntegerConstant(ELoc, /*Val=*/1).get(); 15317 } 15318 break; 15319 case BO_And: { 15320 // '&' reduction op - initializer is '~0'. 15321 QualType OrigType = Type; 15322 if (auto *ComplexTy = OrigType->getAs<ComplexType>()) 15323 Type = ComplexTy->getElementType(); 15324 if (Type->isRealFloatingType()) { 15325 llvm::APFloat InitValue = llvm::APFloat::getAllOnesValue( 15326 Context.getFloatTypeSemantics(Type), 15327 Context.getTypeSize(Type)); 15328 Init = FloatingLiteral::Create(Context, InitValue, /*isexact=*/true, 15329 Type, ELoc); 15330 } else if (Type->isScalarType()) { 15331 uint64_t Size = Context.getTypeSize(Type); 15332 QualType IntTy = Context.getIntTypeForBitwidth(Size, /*Signed=*/0); 15333 llvm::APInt InitValue = llvm::APInt::getAllOnesValue(Size); 15334 Init = IntegerLiteral::Create(Context, InitValue, IntTy, ELoc); 15335 } 15336 if (Init && OrigType->isAnyComplexType()) { 15337 // Init = 0xFFFF + 0xFFFFi; 15338 auto *Im = new (Context) ImaginaryLiteral(Init, OrigType); 15339 Init = S.CreateBuiltinBinOp(ELoc, BO_Add, Init, Im).get(); 15340 } 15341 Type = OrigType; 15342 break; 15343 } 15344 case BO_LT: 15345 case BO_GT: { 15346 // 'min' reduction op - initializer is 'Largest representable number in 15347 // the reduction list item type'. 15348 // 'max' reduction op - initializer is 'Least representable number in 15349 // the reduction list item type'. 15350 if (Type->isIntegerType() || Type->isPointerType()) { 15351 bool IsSigned = Type->hasSignedIntegerRepresentation(); 15352 uint64_t Size = Context.getTypeSize(Type); 15353 QualType IntTy = 15354 Context.getIntTypeForBitwidth(Size, /*Signed=*/IsSigned); 15355 llvm::APInt InitValue = 15356 (BOK != BO_LT) ? IsSigned ? llvm::APInt::getSignedMinValue(Size) 15357 : llvm::APInt::getMinValue(Size) 15358 : IsSigned ? llvm::APInt::getSignedMaxValue(Size) 15359 : llvm::APInt::getMaxValue(Size); 15360 Init = IntegerLiteral::Create(Context, InitValue, IntTy, ELoc); 15361 if (Type->isPointerType()) { 15362 // Cast to pointer type. 15363 ExprResult CastExpr = S.BuildCStyleCastExpr( 15364 ELoc, Context.getTrivialTypeSourceInfo(Type, ELoc), ELoc, Init); 15365 if (CastExpr.isInvalid()) 15366 continue; 15367 Init = CastExpr.get(); 15368 } 15369 } else if (Type->isRealFloatingType()) { 15370 llvm::APFloat InitValue = llvm::APFloat::getLargest( 15371 Context.getFloatTypeSemantics(Type), BOK != BO_LT); 15372 Init = FloatingLiteral::Create(Context, InitValue, /*isexact=*/true, 15373 Type, ELoc); 15374 } 15375 break; 15376 } 15377 case BO_PtrMemD: 15378 case BO_PtrMemI: 15379 case BO_MulAssign: 15380 case BO_Div: 15381 case BO_Rem: 15382 case BO_Sub: 15383 case BO_Shl: 15384 case BO_Shr: 15385 case BO_LE: 15386 case BO_GE: 15387 case BO_EQ: 15388 case BO_NE: 15389 case BO_Cmp: 15390 case BO_AndAssign: 15391 case BO_XorAssign: 15392 case BO_OrAssign: 15393 case BO_Assign: 15394 case BO_AddAssign: 15395 case BO_SubAssign: 15396 case BO_DivAssign: 15397 case BO_RemAssign: 15398 case BO_ShlAssign: 15399 case BO_ShrAssign: 15400 case BO_Comma: 15401 llvm_unreachable("Unexpected reduction operation"); 15402 } 15403 } 15404 if (Init && DeclareReductionRef.isUnset()) { 15405 S.AddInitializerToDecl(RHSVD, Init, /*DirectInit=*/false); 15406 // Store initializer for single element in private copy. Will be used 15407 // during codegen. 15408 PrivateVD->setInit(RHSVD->getInit()); 15409 PrivateVD->setInitStyle(RHSVD->getInitStyle()); 15410 } else if (!Init) { 15411 S.ActOnUninitializedDecl(RHSVD); 15412 // Store initializer for single element in private copy. Will be used 15413 // during codegen. 15414 PrivateVD->setInit(RHSVD->getInit()); 15415 PrivateVD->setInitStyle(RHSVD->getInitStyle()); 15416 } 15417 if (RHSVD->isInvalidDecl()) 15418 continue; 15419 if (!RHSVD->hasInit() && 15420 (DeclareReductionRef.isUnset() || !S.LangOpts.CPlusPlus)) { 15421 S.Diag(ELoc, diag::err_omp_reduction_id_not_compatible) 15422 << Type << ReductionIdRange; 15423 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) == 15424 VarDecl::DeclarationOnly; 15425 S.Diag(D->getLocation(), 15426 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 15427 << D; 15428 continue; 15429 } 15430 DeclRefExpr *PrivateDRE = buildDeclRefExpr(S, PrivateVD, PrivateTy, ELoc); 15431 ExprResult ReductionOp; 15432 if (DeclareReductionRef.isUsable()) { 15433 QualType RedTy = DeclareReductionRef.get()->getType(); 15434 QualType PtrRedTy = Context.getPointerType(RedTy); 15435 ExprResult LHS = S.CreateBuiltinUnaryOp(ELoc, UO_AddrOf, LHSDRE); 15436 ExprResult RHS = S.CreateBuiltinUnaryOp(ELoc, UO_AddrOf, RHSDRE); 15437 if (!BasePath.empty()) { 15438 LHS = S.DefaultLvalueConversion(LHS.get()); 15439 RHS = S.DefaultLvalueConversion(RHS.get()); 15440 LHS = ImplicitCastExpr::Create( 15441 Context, PtrRedTy, CK_UncheckedDerivedToBase, LHS.get(), &BasePath, 15442 LHS.get()->getValueKind(), FPOptionsOverride()); 15443 RHS = ImplicitCastExpr::Create( 15444 Context, PtrRedTy, CK_UncheckedDerivedToBase, RHS.get(), &BasePath, 15445 RHS.get()->getValueKind(), FPOptionsOverride()); 15446 } 15447 FunctionProtoType::ExtProtoInfo EPI; 15448 QualType Params[] = {PtrRedTy, PtrRedTy}; 15449 QualType FnTy = Context.getFunctionType(Context.VoidTy, Params, EPI); 15450 auto *OVE = new (Context) OpaqueValueExpr( 15451 ELoc, Context.getPointerType(FnTy), VK_RValue, OK_Ordinary, 15452 S.DefaultLvalueConversion(DeclareReductionRef.get()).get()); 15453 Expr *Args[] = {LHS.get(), RHS.get()}; 15454 ReductionOp = 15455 CallExpr::Create(Context, OVE, Args, Context.VoidTy, VK_RValue, ELoc, 15456 S.CurFPFeatureOverrides()); 15457 } else { 15458 ReductionOp = S.BuildBinOp( 15459 Stack->getCurScope(), ReductionId.getBeginLoc(), BOK, LHSDRE, RHSDRE); 15460 if (ReductionOp.isUsable()) { 15461 if (BOK != BO_LT && BOK != BO_GT) { 15462 ReductionOp = 15463 S.BuildBinOp(Stack->getCurScope(), ReductionId.getBeginLoc(), 15464 BO_Assign, LHSDRE, ReductionOp.get()); 15465 } else { 15466 auto *ConditionalOp = new (Context) 15467 ConditionalOperator(ReductionOp.get(), ELoc, LHSDRE, ELoc, RHSDRE, 15468 Type, VK_LValue, OK_Ordinary); 15469 ReductionOp = 15470 S.BuildBinOp(Stack->getCurScope(), ReductionId.getBeginLoc(), 15471 BO_Assign, LHSDRE, ConditionalOp); 15472 } 15473 if (ReductionOp.isUsable()) 15474 ReductionOp = S.ActOnFinishFullExpr(ReductionOp.get(), 15475 /*DiscardedValue*/ false); 15476 } 15477 if (!ReductionOp.isUsable()) 15478 continue; 15479 } 15480 15481 // Add copy operations for inscan reductions. 15482 // LHS = RHS; 15483 ExprResult CopyOpRes, TempArrayRes, TempArrayElem; 15484 if (ClauseKind == OMPC_reduction && 15485 RD.RedModifier == OMPC_REDUCTION_inscan) { 15486 ExprResult RHS = S.DefaultLvalueConversion(RHSDRE); 15487 CopyOpRes = S.BuildBinOp(Stack->getCurScope(), ELoc, BO_Assign, LHSDRE, 15488 RHS.get()); 15489 if (!CopyOpRes.isUsable()) 15490 continue; 15491 CopyOpRes = 15492 S.ActOnFinishFullExpr(CopyOpRes.get(), /*DiscardedValue=*/true); 15493 if (!CopyOpRes.isUsable()) 15494 continue; 15495 // For simd directive and simd-based directives in simd mode no need to 15496 // construct temp array, need just a single temp element. 15497 if (Stack->getCurrentDirective() == OMPD_simd || 15498 (S.getLangOpts().OpenMPSimd && 15499 isOpenMPSimdDirective(Stack->getCurrentDirective()))) { 15500 VarDecl *TempArrayVD = 15501 buildVarDecl(S, ELoc, PrivateTy, D->getName(), 15502 D->hasAttrs() ? &D->getAttrs() : nullptr); 15503 // Add a constructor to the temp decl. 15504 S.ActOnUninitializedDecl(TempArrayVD); 15505 TempArrayRes = buildDeclRefExpr(S, TempArrayVD, PrivateTy, ELoc); 15506 } else { 15507 // Build temp array for prefix sum. 15508 auto *Dim = new (S.Context) 15509 OpaqueValueExpr(ELoc, S.Context.getSizeType(), VK_RValue); 15510 QualType ArrayTy = 15511 S.Context.getVariableArrayType(PrivateTy, Dim, ArrayType::Normal, 15512 /*IndexTypeQuals=*/0, {ELoc, ELoc}); 15513 VarDecl *TempArrayVD = 15514 buildVarDecl(S, ELoc, ArrayTy, D->getName(), 15515 D->hasAttrs() ? &D->getAttrs() : nullptr); 15516 // Add a constructor to the temp decl. 15517 S.ActOnUninitializedDecl(TempArrayVD); 15518 TempArrayRes = buildDeclRefExpr(S, TempArrayVD, ArrayTy, ELoc); 15519 TempArrayElem = 15520 S.DefaultFunctionArrayLvalueConversion(TempArrayRes.get()); 15521 auto *Idx = new (S.Context) 15522 OpaqueValueExpr(ELoc, S.Context.getSizeType(), VK_RValue); 15523 TempArrayElem = S.CreateBuiltinArraySubscriptExpr(TempArrayElem.get(), 15524 ELoc, Idx, ELoc); 15525 } 15526 } 15527 15528 // OpenMP [2.15.4.6, Restrictions, p.2] 15529 // A list item that appears in an in_reduction clause of a task construct 15530 // must appear in a task_reduction clause of a construct associated with a 15531 // taskgroup region that includes the participating task in its taskgroup 15532 // set. The construct associated with the innermost region that meets this 15533 // condition must specify the same reduction-identifier as the in_reduction 15534 // clause. 15535 if (ClauseKind == OMPC_in_reduction) { 15536 SourceRange ParentSR; 15537 BinaryOperatorKind ParentBOK; 15538 const Expr *ParentReductionOp = nullptr; 15539 Expr *ParentBOKTD = nullptr, *ParentReductionOpTD = nullptr; 15540 DSAStackTy::DSAVarData ParentBOKDSA = 15541 Stack->getTopMostTaskgroupReductionData(D, ParentSR, ParentBOK, 15542 ParentBOKTD); 15543 DSAStackTy::DSAVarData ParentReductionOpDSA = 15544 Stack->getTopMostTaskgroupReductionData( 15545 D, ParentSR, ParentReductionOp, ParentReductionOpTD); 15546 bool IsParentBOK = ParentBOKDSA.DKind != OMPD_unknown; 15547 bool IsParentReductionOp = ParentReductionOpDSA.DKind != OMPD_unknown; 15548 if ((DeclareReductionRef.isUnset() && IsParentReductionOp) || 15549 (DeclareReductionRef.isUsable() && IsParentBOK) || 15550 (IsParentBOK && BOK != ParentBOK) || IsParentReductionOp) { 15551 bool EmitError = true; 15552 if (IsParentReductionOp && DeclareReductionRef.isUsable()) { 15553 llvm::FoldingSetNodeID RedId, ParentRedId; 15554 ParentReductionOp->Profile(ParentRedId, Context, /*Canonical=*/true); 15555 DeclareReductionRef.get()->Profile(RedId, Context, 15556 /*Canonical=*/true); 15557 EmitError = RedId != ParentRedId; 15558 } 15559 if (EmitError) { 15560 S.Diag(ReductionId.getBeginLoc(), 15561 diag::err_omp_reduction_identifier_mismatch) 15562 << ReductionIdRange << RefExpr->getSourceRange(); 15563 S.Diag(ParentSR.getBegin(), 15564 diag::note_omp_previous_reduction_identifier) 15565 << ParentSR 15566 << (IsParentBOK ? ParentBOKDSA.RefExpr 15567 : ParentReductionOpDSA.RefExpr) 15568 ->getSourceRange(); 15569 continue; 15570 } 15571 } 15572 TaskgroupDescriptor = IsParentBOK ? ParentBOKTD : ParentReductionOpTD; 15573 } 15574 15575 DeclRefExpr *Ref = nullptr; 15576 Expr *VarsExpr = RefExpr->IgnoreParens(); 15577 if (!VD && !S.CurContext->isDependentContext()) { 15578 if (ASE || OASE) { 15579 TransformExprToCaptures RebuildToCapture(S, D); 15580 VarsExpr = 15581 RebuildToCapture.TransformExpr(RefExpr->IgnoreParens()).get(); 15582 Ref = RebuildToCapture.getCapturedExpr(); 15583 } else { 15584 VarsExpr = Ref = buildCapture(S, D, SimpleRefExpr, /*WithInit=*/false); 15585 } 15586 if (!S.isOpenMPCapturedDecl(D)) { 15587 RD.ExprCaptures.emplace_back(Ref->getDecl()); 15588 if (Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>()) { 15589 ExprResult RefRes = S.DefaultLvalueConversion(Ref); 15590 if (!RefRes.isUsable()) 15591 continue; 15592 ExprResult PostUpdateRes = 15593 S.BuildBinOp(Stack->getCurScope(), ELoc, BO_Assign, SimpleRefExpr, 15594 RefRes.get()); 15595 if (!PostUpdateRes.isUsable()) 15596 continue; 15597 if (isOpenMPTaskingDirective(Stack->getCurrentDirective()) || 15598 Stack->getCurrentDirective() == OMPD_taskgroup) { 15599 S.Diag(RefExpr->getExprLoc(), 15600 diag::err_omp_reduction_non_addressable_expression) 15601 << RefExpr->getSourceRange(); 15602 continue; 15603 } 15604 RD.ExprPostUpdates.emplace_back( 15605 S.IgnoredValueConversions(PostUpdateRes.get()).get()); 15606 } 15607 } 15608 } 15609 // All reduction items are still marked as reduction (to do not increase 15610 // code base size). 15611 unsigned Modifier = RD.RedModifier; 15612 // Consider task_reductions as reductions with task modifier. Required for 15613 // correct analysis of in_reduction clauses. 15614 if (CurrDir == OMPD_taskgroup && ClauseKind == OMPC_task_reduction) 15615 Modifier = OMPC_REDUCTION_task; 15616 Stack->addDSA(D, RefExpr->IgnoreParens(), OMPC_reduction, Ref, Modifier, 15617 ASE || OASE); 15618 if (Modifier == OMPC_REDUCTION_task && 15619 (CurrDir == OMPD_taskgroup || 15620 ((isOpenMPParallelDirective(CurrDir) || 15621 isOpenMPWorksharingDirective(CurrDir)) && 15622 !isOpenMPSimdDirective(CurrDir)))) { 15623 if (DeclareReductionRef.isUsable()) 15624 Stack->addTaskgroupReductionData(D, ReductionIdRange, 15625 DeclareReductionRef.get()); 15626 else 15627 Stack->addTaskgroupReductionData(D, ReductionIdRange, BOK); 15628 } 15629 RD.push(VarsExpr, PrivateDRE, LHSDRE, RHSDRE, ReductionOp.get(), 15630 TaskgroupDescriptor, CopyOpRes.get(), TempArrayRes.get(), 15631 TempArrayElem.get()); 15632 } 15633 return RD.Vars.empty(); 15634 } 15635 15636 OMPClause *Sema::ActOnOpenMPReductionClause( 15637 ArrayRef<Expr *> VarList, OpenMPReductionClauseModifier Modifier, 15638 SourceLocation StartLoc, SourceLocation LParenLoc, 15639 SourceLocation ModifierLoc, SourceLocation ColonLoc, SourceLocation EndLoc, 15640 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, 15641 ArrayRef<Expr *> UnresolvedReductions) { 15642 if (ModifierLoc.isValid() && Modifier == OMPC_REDUCTION_unknown) { 15643 Diag(LParenLoc, diag::err_omp_unexpected_clause_value) 15644 << getListOfPossibleValues(OMPC_reduction, /*First=*/0, 15645 /*Last=*/OMPC_REDUCTION_unknown) 15646 << getOpenMPClauseName(OMPC_reduction); 15647 return nullptr; 15648 } 15649 // OpenMP 5.0, 2.19.5.4 reduction Clause, Restrictions 15650 // A reduction clause with the inscan reduction-modifier may only appear on a 15651 // worksharing-loop construct, a worksharing-loop SIMD construct, a simd 15652 // construct, a parallel worksharing-loop construct or a parallel 15653 // worksharing-loop SIMD construct. 15654 if (Modifier == OMPC_REDUCTION_inscan && 15655 (DSAStack->getCurrentDirective() != OMPD_for && 15656 DSAStack->getCurrentDirective() != OMPD_for_simd && 15657 DSAStack->getCurrentDirective() != OMPD_simd && 15658 DSAStack->getCurrentDirective() != OMPD_parallel_for && 15659 DSAStack->getCurrentDirective() != OMPD_parallel_for_simd)) { 15660 Diag(ModifierLoc, diag::err_omp_wrong_inscan_reduction); 15661 return nullptr; 15662 } 15663 15664 ReductionData RD(VarList.size(), Modifier); 15665 if (actOnOMPReductionKindClause(*this, DSAStack, OMPC_reduction, VarList, 15666 StartLoc, LParenLoc, ColonLoc, EndLoc, 15667 ReductionIdScopeSpec, ReductionId, 15668 UnresolvedReductions, RD)) 15669 return nullptr; 15670 15671 return OMPReductionClause::Create( 15672 Context, StartLoc, LParenLoc, ModifierLoc, ColonLoc, EndLoc, Modifier, 15673 RD.Vars, ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId, 15674 RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps, RD.InscanCopyOps, 15675 RD.InscanCopyArrayTemps, RD.InscanCopyArrayElems, 15676 buildPreInits(Context, RD.ExprCaptures), 15677 buildPostUpdate(*this, RD.ExprPostUpdates)); 15678 } 15679 15680 OMPClause *Sema::ActOnOpenMPTaskReductionClause( 15681 ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, 15682 SourceLocation ColonLoc, SourceLocation EndLoc, 15683 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, 15684 ArrayRef<Expr *> UnresolvedReductions) { 15685 ReductionData RD(VarList.size()); 15686 if (actOnOMPReductionKindClause(*this, DSAStack, OMPC_task_reduction, VarList, 15687 StartLoc, LParenLoc, ColonLoc, EndLoc, 15688 ReductionIdScopeSpec, ReductionId, 15689 UnresolvedReductions, RD)) 15690 return nullptr; 15691 15692 return OMPTaskReductionClause::Create( 15693 Context, StartLoc, LParenLoc, ColonLoc, EndLoc, RD.Vars, 15694 ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId, 15695 RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps, 15696 buildPreInits(Context, RD.ExprCaptures), 15697 buildPostUpdate(*this, RD.ExprPostUpdates)); 15698 } 15699 15700 OMPClause *Sema::ActOnOpenMPInReductionClause( 15701 ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, 15702 SourceLocation ColonLoc, SourceLocation EndLoc, 15703 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, 15704 ArrayRef<Expr *> UnresolvedReductions) { 15705 ReductionData RD(VarList.size()); 15706 if (actOnOMPReductionKindClause(*this, DSAStack, OMPC_in_reduction, VarList, 15707 StartLoc, LParenLoc, ColonLoc, EndLoc, 15708 ReductionIdScopeSpec, ReductionId, 15709 UnresolvedReductions, RD)) 15710 return nullptr; 15711 15712 return OMPInReductionClause::Create( 15713 Context, StartLoc, LParenLoc, ColonLoc, EndLoc, RD.Vars, 15714 ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId, 15715 RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps, RD.TaskgroupDescriptors, 15716 buildPreInits(Context, RD.ExprCaptures), 15717 buildPostUpdate(*this, RD.ExprPostUpdates)); 15718 } 15719 15720 bool Sema::CheckOpenMPLinearModifier(OpenMPLinearClauseKind LinKind, 15721 SourceLocation LinLoc) { 15722 if ((!LangOpts.CPlusPlus && LinKind != OMPC_LINEAR_val) || 15723 LinKind == OMPC_LINEAR_unknown) { 15724 Diag(LinLoc, diag::err_omp_wrong_linear_modifier) << LangOpts.CPlusPlus; 15725 return true; 15726 } 15727 return false; 15728 } 15729 15730 bool Sema::CheckOpenMPLinearDecl(const ValueDecl *D, SourceLocation ELoc, 15731 OpenMPLinearClauseKind LinKind, QualType Type, 15732 bool IsDeclareSimd) { 15733 const auto *VD = dyn_cast_or_null<VarDecl>(D); 15734 // A variable must not have an incomplete type or a reference type. 15735 if (RequireCompleteType(ELoc, Type, diag::err_omp_linear_incomplete_type)) 15736 return true; 15737 if ((LinKind == OMPC_LINEAR_uval || LinKind == OMPC_LINEAR_ref) && 15738 !Type->isReferenceType()) { 15739 Diag(ELoc, diag::err_omp_wrong_linear_modifier_non_reference) 15740 << Type << getOpenMPSimpleClauseTypeName(OMPC_linear, LinKind); 15741 return true; 15742 } 15743 Type = Type.getNonReferenceType(); 15744 15745 // OpenMP 5.0 [2.19.3, List Item Privatization, Restrictions] 15746 // A variable that is privatized must not have a const-qualified type 15747 // unless it is of class type with a mutable member. This restriction does 15748 // not apply to the firstprivate clause, nor to the linear clause on 15749 // declarative directives (like declare simd). 15750 if (!IsDeclareSimd && 15751 rejectConstNotMutableType(*this, D, Type, OMPC_linear, ELoc)) 15752 return true; 15753 15754 // A list item must be of integral or pointer type. 15755 Type = Type.getUnqualifiedType().getCanonicalType(); 15756 const auto *Ty = Type.getTypePtrOrNull(); 15757 if (!Ty || (LinKind != OMPC_LINEAR_ref && !Ty->isDependentType() && 15758 !Ty->isIntegralType(Context) && !Ty->isPointerType())) { 15759 Diag(ELoc, diag::err_omp_linear_expected_int_or_ptr) << Type; 15760 if (D) { 15761 bool IsDecl = 15762 !VD || 15763 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 15764 Diag(D->getLocation(), 15765 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 15766 << D; 15767 } 15768 return true; 15769 } 15770 return false; 15771 } 15772 15773 OMPClause *Sema::ActOnOpenMPLinearClause( 15774 ArrayRef<Expr *> VarList, Expr *Step, SourceLocation StartLoc, 15775 SourceLocation LParenLoc, OpenMPLinearClauseKind LinKind, 15776 SourceLocation LinLoc, SourceLocation ColonLoc, SourceLocation EndLoc) { 15777 SmallVector<Expr *, 8> Vars; 15778 SmallVector<Expr *, 8> Privates; 15779 SmallVector<Expr *, 8> Inits; 15780 SmallVector<Decl *, 4> ExprCaptures; 15781 SmallVector<Expr *, 4> ExprPostUpdates; 15782 if (CheckOpenMPLinearModifier(LinKind, LinLoc)) 15783 LinKind = OMPC_LINEAR_val; 15784 for (Expr *RefExpr : VarList) { 15785 assert(RefExpr && "NULL expr in OpenMP linear clause."); 15786 SourceLocation ELoc; 15787 SourceRange ERange; 15788 Expr *SimpleRefExpr = RefExpr; 15789 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 15790 if (Res.second) { 15791 // It will be analyzed later. 15792 Vars.push_back(RefExpr); 15793 Privates.push_back(nullptr); 15794 Inits.push_back(nullptr); 15795 } 15796 ValueDecl *D = Res.first; 15797 if (!D) 15798 continue; 15799 15800 QualType Type = D->getType(); 15801 auto *VD = dyn_cast<VarDecl>(D); 15802 15803 // OpenMP [2.14.3.7, linear clause] 15804 // A list-item cannot appear in more than one linear clause. 15805 // A list-item that appears in a linear clause cannot appear in any 15806 // other data-sharing attribute clause. 15807 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false); 15808 if (DVar.RefExpr) { 15809 Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind) 15810 << getOpenMPClauseName(OMPC_linear); 15811 reportOriginalDsa(*this, DSAStack, D, DVar); 15812 continue; 15813 } 15814 15815 if (CheckOpenMPLinearDecl(D, ELoc, LinKind, Type)) 15816 continue; 15817 Type = Type.getNonReferenceType().getUnqualifiedType().getCanonicalType(); 15818 15819 // Build private copy of original var. 15820 VarDecl *Private = 15821 buildVarDecl(*this, ELoc, Type, D->getName(), 15822 D->hasAttrs() ? &D->getAttrs() : nullptr, 15823 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr); 15824 DeclRefExpr *PrivateRef = buildDeclRefExpr(*this, Private, Type, ELoc); 15825 // Build var to save initial value. 15826 VarDecl *Init = buildVarDecl(*this, ELoc, Type, ".linear.start"); 15827 Expr *InitExpr; 15828 DeclRefExpr *Ref = nullptr; 15829 if (!VD && !CurContext->isDependentContext()) { 15830 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false); 15831 if (!isOpenMPCapturedDecl(D)) { 15832 ExprCaptures.push_back(Ref->getDecl()); 15833 if (Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>()) { 15834 ExprResult RefRes = DefaultLvalueConversion(Ref); 15835 if (!RefRes.isUsable()) 15836 continue; 15837 ExprResult PostUpdateRes = 15838 BuildBinOp(DSAStack->getCurScope(), ELoc, BO_Assign, 15839 SimpleRefExpr, RefRes.get()); 15840 if (!PostUpdateRes.isUsable()) 15841 continue; 15842 ExprPostUpdates.push_back( 15843 IgnoredValueConversions(PostUpdateRes.get()).get()); 15844 } 15845 } 15846 } 15847 if (LinKind == OMPC_LINEAR_uval) 15848 InitExpr = VD ? VD->getInit() : SimpleRefExpr; 15849 else 15850 InitExpr = VD ? SimpleRefExpr : Ref; 15851 AddInitializerToDecl(Init, DefaultLvalueConversion(InitExpr).get(), 15852 /*DirectInit=*/false); 15853 DeclRefExpr *InitRef = buildDeclRefExpr(*this, Init, Type, ELoc); 15854 15855 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_linear, Ref); 15856 Vars.push_back((VD || CurContext->isDependentContext()) 15857 ? RefExpr->IgnoreParens() 15858 : Ref); 15859 Privates.push_back(PrivateRef); 15860 Inits.push_back(InitRef); 15861 } 15862 15863 if (Vars.empty()) 15864 return nullptr; 15865 15866 Expr *StepExpr = Step; 15867 Expr *CalcStepExpr = nullptr; 15868 if (Step && !Step->isValueDependent() && !Step->isTypeDependent() && 15869 !Step->isInstantiationDependent() && 15870 !Step->containsUnexpandedParameterPack()) { 15871 SourceLocation StepLoc = Step->getBeginLoc(); 15872 ExprResult Val = PerformOpenMPImplicitIntegerConversion(StepLoc, Step); 15873 if (Val.isInvalid()) 15874 return nullptr; 15875 StepExpr = Val.get(); 15876 15877 // Build var to save the step value. 15878 VarDecl *SaveVar = 15879 buildVarDecl(*this, StepLoc, StepExpr->getType(), ".linear.step"); 15880 ExprResult SaveRef = 15881 buildDeclRefExpr(*this, SaveVar, StepExpr->getType(), StepLoc); 15882 ExprResult CalcStep = 15883 BuildBinOp(CurScope, StepLoc, BO_Assign, SaveRef.get(), StepExpr); 15884 CalcStep = ActOnFinishFullExpr(CalcStep.get(), /*DiscardedValue*/ false); 15885 15886 // Warn about zero linear step (it would be probably better specified as 15887 // making corresponding variables 'const'). 15888 if (Optional<llvm::APSInt> Result = 15889 StepExpr->getIntegerConstantExpr(Context)) { 15890 if (!Result->isNegative() && !Result->isStrictlyPositive()) 15891 Diag(StepLoc, diag::warn_omp_linear_step_zero) 15892 << Vars[0] << (Vars.size() > 1); 15893 } else if (CalcStep.isUsable()) { 15894 // Calculate the step beforehand instead of doing this on each iteration. 15895 // (This is not used if the number of iterations may be kfold-ed). 15896 CalcStepExpr = CalcStep.get(); 15897 } 15898 } 15899 15900 return OMPLinearClause::Create(Context, StartLoc, LParenLoc, LinKind, LinLoc, 15901 ColonLoc, EndLoc, Vars, Privates, Inits, 15902 StepExpr, CalcStepExpr, 15903 buildPreInits(Context, ExprCaptures), 15904 buildPostUpdate(*this, ExprPostUpdates)); 15905 } 15906 15907 static bool FinishOpenMPLinearClause(OMPLinearClause &Clause, DeclRefExpr *IV, 15908 Expr *NumIterations, Sema &SemaRef, 15909 Scope *S, DSAStackTy *Stack) { 15910 // Walk the vars and build update/final expressions for the CodeGen. 15911 SmallVector<Expr *, 8> Updates; 15912 SmallVector<Expr *, 8> Finals; 15913 SmallVector<Expr *, 8> UsedExprs; 15914 Expr *Step = Clause.getStep(); 15915 Expr *CalcStep = Clause.getCalcStep(); 15916 // OpenMP [2.14.3.7, linear clause] 15917 // If linear-step is not specified it is assumed to be 1. 15918 if (!Step) 15919 Step = SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get(); 15920 else if (CalcStep) 15921 Step = cast<BinaryOperator>(CalcStep)->getLHS(); 15922 bool HasErrors = false; 15923 auto CurInit = Clause.inits().begin(); 15924 auto CurPrivate = Clause.privates().begin(); 15925 OpenMPLinearClauseKind LinKind = Clause.getModifier(); 15926 for (Expr *RefExpr : Clause.varlists()) { 15927 SourceLocation ELoc; 15928 SourceRange ERange; 15929 Expr *SimpleRefExpr = RefExpr; 15930 auto Res = getPrivateItem(SemaRef, SimpleRefExpr, ELoc, ERange); 15931 ValueDecl *D = Res.first; 15932 if (Res.second || !D) { 15933 Updates.push_back(nullptr); 15934 Finals.push_back(nullptr); 15935 HasErrors = true; 15936 continue; 15937 } 15938 auto &&Info = Stack->isLoopControlVariable(D); 15939 // OpenMP [2.15.11, distribute simd Construct] 15940 // A list item may not appear in a linear clause, unless it is the loop 15941 // iteration variable. 15942 if (isOpenMPDistributeDirective(Stack->getCurrentDirective()) && 15943 isOpenMPSimdDirective(Stack->getCurrentDirective()) && !Info.first) { 15944 SemaRef.Diag(ELoc, 15945 diag::err_omp_linear_distribute_var_non_loop_iteration); 15946 Updates.push_back(nullptr); 15947 Finals.push_back(nullptr); 15948 HasErrors = true; 15949 continue; 15950 } 15951 Expr *InitExpr = *CurInit; 15952 15953 // Build privatized reference to the current linear var. 15954 auto *DE = cast<DeclRefExpr>(SimpleRefExpr); 15955 Expr *CapturedRef; 15956 if (LinKind == OMPC_LINEAR_uval) 15957 CapturedRef = cast<VarDecl>(DE->getDecl())->getInit(); 15958 else 15959 CapturedRef = 15960 buildDeclRefExpr(SemaRef, cast<VarDecl>(DE->getDecl()), 15961 DE->getType().getUnqualifiedType(), DE->getExprLoc(), 15962 /*RefersToCapture=*/true); 15963 15964 // Build update: Var = InitExpr + IV * Step 15965 ExprResult Update; 15966 if (!Info.first) 15967 Update = buildCounterUpdate( 15968 SemaRef, S, RefExpr->getExprLoc(), *CurPrivate, InitExpr, IV, Step, 15969 /*Subtract=*/false, /*IsNonRectangularLB=*/false); 15970 else 15971 Update = *CurPrivate; 15972 Update = SemaRef.ActOnFinishFullExpr(Update.get(), DE->getBeginLoc(), 15973 /*DiscardedValue*/ false); 15974 15975 // Build final: Var = InitExpr + NumIterations * Step 15976 ExprResult Final; 15977 if (!Info.first) 15978 Final = 15979 buildCounterUpdate(SemaRef, S, RefExpr->getExprLoc(), CapturedRef, 15980 InitExpr, NumIterations, Step, /*Subtract=*/false, 15981 /*IsNonRectangularLB=*/false); 15982 else 15983 Final = *CurPrivate; 15984 Final = SemaRef.ActOnFinishFullExpr(Final.get(), DE->getBeginLoc(), 15985 /*DiscardedValue*/ false); 15986 15987 if (!Update.isUsable() || !Final.isUsable()) { 15988 Updates.push_back(nullptr); 15989 Finals.push_back(nullptr); 15990 UsedExprs.push_back(nullptr); 15991 HasErrors = true; 15992 } else { 15993 Updates.push_back(Update.get()); 15994 Finals.push_back(Final.get()); 15995 if (!Info.first) 15996 UsedExprs.push_back(SimpleRefExpr); 15997 } 15998 ++CurInit; 15999 ++CurPrivate; 16000 } 16001 if (Expr *S = Clause.getStep()) 16002 UsedExprs.push_back(S); 16003 // Fill the remaining part with the nullptr. 16004 UsedExprs.append(Clause.varlist_size() + 1 - UsedExprs.size(), nullptr); 16005 Clause.setUpdates(Updates); 16006 Clause.setFinals(Finals); 16007 Clause.setUsedExprs(UsedExprs); 16008 return HasErrors; 16009 } 16010 16011 OMPClause *Sema::ActOnOpenMPAlignedClause( 16012 ArrayRef<Expr *> VarList, Expr *Alignment, SourceLocation StartLoc, 16013 SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc) { 16014 SmallVector<Expr *, 8> Vars; 16015 for (Expr *RefExpr : VarList) { 16016 assert(RefExpr && "NULL expr in OpenMP linear clause."); 16017 SourceLocation ELoc; 16018 SourceRange ERange; 16019 Expr *SimpleRefExpr = RefExpr; 16020 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 16021 if (Res.second) { 16022 // It will be analyzed later. 16023 Vars.push_back(RefExpr); 16024 } 16025 ValueDecl *D = Res.first; 16026 if (!D) 16027 continue; 16028 16029 QualType QType = D->getType(); 16030 auto *VD = dyn_cast<VarDecl>(D); 16031 16032 // OpenMP [2.8.1, simd construct, Restrictions] 16033 // The type of list items appearing in the aligned clause must be 16034 // array, pointer, reference to array, or reference to pointer. 16035 QType = QType.getNonReferenceType().getUnqualifiedType().getCanonicalType(); 16036 const Type *Ty = QType.getTypePtrOrNull(); 16037 if (!Ty || (!Ty->isArrayType() && !Ty->isPointerType())) { 16038 Diag(ELoc, diag::err_omp_aligned_expected_array_or_ptr) 16039 << QType << getLangOpts().CPlusPlus << ERange; 16040 bool IsDecl = 16041 !VD || 16042 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 16043 Diag(D->getLocation(), 16044 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 16045 << D; 16046 continue; 16047 } 16048 16049 // OpenMP [2.8.1, simd construct, Restrictions] 16050 // A list-item cannot appear in more than one aligned clause. 16051 if (const Expr *PrevRef = DSAStack->addUniqueAligned(D, SimpleRefExpr)) { 16052 Diag(ELoc, diag::err_omp_used_in_clause_twice) 16053 << 0 << getOpenMPClauseName(OMPC_aligned) << ERange; 16054 Diag(PrevRef->getExprLoc(), diag::note_omp_explicit_dsa) 16055 << getOpenMPClauseName(OMPC_aligned); 16056 continue; 16057 } 16058 16059 DeclRefExpr *Ref = nullptr; 16060 if (!VD && isOpenMPCapturedDecl(D)) 16061 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true); 16062 Vars.push_back(DefaultFunctionArrayConversion( 16063 (VD || !Ref) ? RefExpr->IgnoreParens() : Ref) 16064 .get()); 16065 } 16066 16067 // OpenMP [2.8.1, simd construct, Description] 16068 // The parameter of the aligned clause, alignment, must be a constant 16069 // positive integer expression. 16070 // If no optional parameter is specified, implementation-defined default 16071 // alignments for SIMD instructions on the target platforms are assumed. 16072 if (Alignment != nullptr) { 16073 ExprResult AlignResult = 16074 VerifyPositiveIntegerConstantInClause(Alignment, OMPC_aligned); 16075 if (AlignResult.isInvalid()) 16076 return nullptr; 16077 Alignment = AlignResult.get(); 16078 } 16079 if (Vars.empty()) 16080 return nullptr; 16081 16082 return OMPAlignedClause::Create(Context, StartLoc, LParenLoc, ColonLoc, 16083 EndLoc, Vars, Alignment); 16084 } 16085 16086 OMPClause *Sema::ActOnOpenMPCopyinClause(ArrayRef<Expr *> VarList, 16087 SourceLocation StartLoc, 16088 SourceLocation LParenLoc, 16089 SourceLocation EndLoc) { 16090 SmallVector<Expr *, 8> Vars; 16091 SmallVector<Expr *, 8> SrcExprs; 16092 SmallVector<Expr *, 8> DstExprs; 16093 SmallVector<Expr *, 8> AssignmentOps; 16094 for (Expr *RefExpr : VarList) { 16095 assert(RefExpr && "NULL expr in OpenMP copyin clause."); 16096 if (isa<DependentScopeDeclRefExpr>(RefExpr)) { 16097 // It will be analyzed later. 16098 Vars.push_back(RefExpr); 16099 SrcExprs.push_back(nullptr); 16100 DstExprs.push_back(nullptr); 16101 AssignmentOps.push_back(nullptr); 16102 continue; 16103 } 16104 16105 SourceLocation ELoc = RefExpr->getExprLoc(); 16106 // OpenMP [2.1, C/C++] 16107 // A list item is a variable name. 16108 // OpenMP [2.14.4.1, Restrictions, p.1] 16109 // A list item that appears in a copyin clause must be threadprivate. 16110 auto *DE = dyn_cast<DeclRefExpr>(RefExpr); 16111 if (!DE || !isa<VarDecl>(DE->getDecl())) { 16112 Diag(ELoc, diag::err_omp_expected_var_name_member_expr) 16113 << 0 << RefExpr->getSourceRange(); 16114 continue; 16115 } 16116 16117 Decl *D = DE->getDecl(); 16118 auto *VD = cast<VarDecl>(D); 16119 16120 QualType Type = VD->getType(); 16121 if (Type->isDependentType() || Type->isInstantiationDependentType()) { 16122 // It will be analyzed later. 16123 Vars.push_back(DE); 16124 SrcExprs.push_back(nullptr); 16125 DstExprs.push_back(nullptr); 16126 AssignmentOps.push_back(nullptr); 16127 continue; 16128 } 16129 16130 // OpenMP [2.14.4.1, Restrictions, C/C++, p.1] 16131 // A list item that appears in a copyin clause must be threadprivate. 16132 if (!DSAStack->isThreadPrivate(VD)) { 16133 Diag(ELoc, diag::err_omp_required_access) 16134 << getOpenMPClauseName(OMPC_copyin) 16135 << getOpenMPDirectiveName(OMPD_threadprivate); 16136 continue; 16137 } 16138 16139 // OpenMP [2.14.4.1, Restrictions, C/C++, p.2] 16140 // A variable of class type (or array thereof) that appears in a 16141 // copyin clause requires an accessible, unambiguous copy assignment 16142 // operator for the class type. 16143 QualType ElemType = Context.getBaseElementType(Type).getNonReferenceType(); 16144 VarDecl *SrcVD = 16145 buildVarDecl(*this, DE->getBeginLoc(), ElemType.getUnqualifiedType(), 16146 ".copyin.src", VD->hasAttrs() ? &VD->getAttrs() : nullptr); 16147 DeclRefExpr *PseudoSrcExpr = buildDeclRefExpr( 16148 *this, SrcVD, ElemType.getUnqualifiedType(), DE->getExprLoc()); 16149 VarDecl *DstVD = 16150 buildVarDecl(*this, DE->getBeginLoc(), ElemType, ".copyin.dst", 16151 VD->hasAttrs() ? &VD->getAttrs() : nullptr); 16152 DeclRefExpr *PseudoDstExpr = 16153 buildDeclRefExpr(*this, DstVD, ElemType, DE->getExprLoc()); 16154 // For arrays generate assignment operation for single element and replace 16155 // it by the original array element in CodeGen. 16156 ExprResult AssignmentOp = 16157 BuildBinOp(/*S=*/nullptr, DE->getExprLoc(), BO_Assign, PseudoDstExpr, 16158 PseudoSrcExpr); 16159 if (AssignmentOp.isInvalid()) 16160 continue; 16161 AssignmentOp = ActOnFinishFullExpr(AssignmentOp.get(), DE->getExprLoc(), 16162 /*DiscardedValue*/ false); 16163 if (AssignmentOp.isInvalid()) 16164 continue; 16165 16166 DSAStack->addDSA(VD, DE, OMPC_copyin); 16167 Vars.push_back(DE); 16168 SrcExprs.push_back(PseudoSrcExpr); 16169 DstExprs.push_back(PseudoDstExpr); 16170 AssignmentOps.push_back(AssignmentOp.get()); 16171 } 16172 16173 if (Vars.empty()) 16174 return nullptr; 16175 16176 return OMPCopyinClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars, 16177 SrcExprs, DstExprs, AssignmentOps); 16178 } 16179 16180 OMPClause *Sema::ActOnOpenMPCopyprivateClause(ArrayRef<Expr *> VarList, 16181 SourceLocation StartLoc, 16182 SourceLocation LParenLoc, 16183 SourceLocation EndLoc) { 16184 SmallVector<Expr *, 8> Vars; 16185 SmallVector<Expr *, 8> SrcExprs; 16186 SmallVector<Expr *, 8> DstExprs; 16187 SmallVector<Expr *, 8> AssignmentOps; 16188 for (Expr *RefExpr : VarList) { 16189 assert(RefExpr && "NULL expr in OpenMP linear clause."); 16190 SourceLocation ELoc; 16191 SourceRange ERange; 16192 Expr *SimpleRefExpr = RefExpr; 16193 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 16194 if (Res.second) { 16195 // It will be analyzed later. 16196 Vars.push_back(RefExpr); 16197 SrcExprs.push_back(nullptr); 16198 DstExprs.push_back(nullptr); 16199 AssignmentOps.push_back(nullptr); 16200 } 16201 ValueDecl *D = Res.first; 16202 if (!D) 16203 continue; 16204 16205 QualType Type = D->getType(); 16206 auto *VD = dyn_cast<VarDecl>(D); 16207 16208 // OpenMP [2.14.4.2, Restrictions, p.2] 16209 // A list item that appears in a copyprivate clause may not appear in a 16210 // private or firstprivate clause on the single construct. 16211 if (!VD || !DSAStack->isThreadPrivate(VD)) { 16212 DSAStackTy::DSAVarData DVar = 16213 DSAStack->getTopDSA(D, /*FromParent=*/false); 16214 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_copyprivate && 16215 DVar.RefExpr) { 16216 Diag(ELoc, diag::err_omp_wrong_dsa) 16217 << getOpenMPClauseName(DVar.CKind) 16218 << getOpenMPClauseName(OMPC_copyprivate); 16219 reportOriginalDsa(*this, DSAStack, D, DVar); 16220 continue; 16221 } 16222 16223 // OpenMP [2.11.4.2, Restrictions, p.1] 16224 // All list items that appear in a copyprivate clause must be either 16225 // threadprivate or private in the enclosing context. 16226 if (DVar.CKind == OMPC_unknown) { 16227 DVar = DSAStack->getImplicitDSA(D, false); 16228 if (DVar.CKind == OMPC_shared) { 16229 Diag(ELoc, diag::err_omp_required_access) 16230 << getOpenMPClauseName(OMPC_copyprivate) 16231 << "threadprivate or private in the enclosing context"; 16232 reportOriginalDsa(*this, DSAStack, D, DVar); 16233 continue; 16234 } 16235 } 16236 } 16237 16238 // Variably modified types are not supported. 16239 if (!Type->isAnyPointerType() && Type->isVariablyModifiedType()) { 16240 Diag(ELoc, diag::err_omp_variably_modified_type_not_supported) 16241 << getOpenMPClauseName(OMPC_copyprivate) << Type 16242 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 16243 bool IsDecl = 16244 !VD || 16245 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 16246 Diag(D->getLocation(), 16247 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 16248 << D; 16249 continue; 16250 } 16251 16252 // OpenMP [2.14.4.1, Restrictions, C/C++, p.2] 16253 // A variable of class type (or array thereof) that appears in a 16254 // copyin clause requires an accessible, unambiguous copy assignment 16255 // operator for the class type. 16256 Type = Context.getBaseElementType(Type.getNonReferenceType()) 16257 .getUnqualifiedType(); 16258 VarDecl *SrcVD = 16259 buildVarDecl(*this, RefExpr->getBeginLoc(), Type, ".copyprivate.src", 16260 D->hasAttrs() ? &D->getAttrs() : nullptr); 16261 DeclRefExpr *PseudoSrcExpr = buildDeclRefExpr(*this, SrcVD, Type, ELoc); 16262 VarDecl *DstVD = 16263 buildVarDecl(*this, RefExpr->getBeginLoc(), Type, ".copyprivate.dst", 16264 D->hasAttrs() ? &D->getAttrs() : nullptr); 16265 DeclRefExpr *PseudoDstExpr = buildDeclRefExpr(*this, DstVD, Type, ELoc); 16266 ExprResult AssignmentOp = BuildBinOp( 16267 DSAStack->getCurScope(), ELoc, BO_Assign, PseudoDstExpr, PseudoSrcExpr); 16268 if (AssignmentOp.isInvalid()) 16269 continue; 16270 AssignmentOp = 16271 ActOnFinishFullExpr(AssignmentOp.get(), ELoc, /*DiscardedValue*/ false); 16272 if (AssignmentOp.isInvalid()) 16273 continue; 16274 16275 // No need to mark vars as copyprivate, they are already threadprivate or 16276 // implicitly private. 16277 assert(VD || isOpenMPCapturedDecl(D)); 16278 Vars.push_back( 16279 VD ? RefExpr->IgnoreParens() 16280 : buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false)); 16281 SrcExprs.push_back(PseudoSrcExpr); 16282 DstExprs.push_back(PseudoDstExpr); 16283 AssignmentOps.push_back(AssignmentOp.get()); 16284 } 16285 16286 if (Vars.empty()) 16287 return nullptr; 16288 16289 return OMPCopyprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, 16290 Vars, SrcExprs, DstExprs, AssignmentOps); 16291 } 16292 16293 OMPClause *Sema::ActOnOpenMPFlushClause(ArrayRef<Expr *> VarList, 16294 SourceLocation StartLoc, 16295 SourceLocation LParenLoc, 16296 SourceLocation EndLoc) { 16297 if (VarList.empty()) 16298 return nullptr; 16299 16300 return OMPFlushClause::Create(Context, StartLoc, LParenLoc, EndLoc, VarList); 16301 } 16302 16303 /// Tries to find omp_depend_t. type. 16304 static bool findOMPDependT(Sema &S, SourceLocation Loc, DSAStackTy *Stack, 16305 bool Diagnose = true) { 16306 QualType OMPDependT = Stack->getOMPDependT(); 16307 if (!OMPDependT.isNull()) 16308 return true; 16309 IdentifierInfo *II = &S.PP.getIdentifierTable().get("omp_depend_t"); 16310 ParsedType PT = S.getTypeName(*II, Loc, S.getCurScope()); 16311 if (!PT.getAsOpaquePtr() || PT.get().isNull()) { 16312 if (Diagnose) 16313 S.Diag(Loc, diag::err_omp_implied_type_not_found) << "omp_depend_t"; 16314 return false; 16315 } 16316 Stack->setOMPDependT(PT.get()); 16317 return true; 16318 } 16319 16320 OMPClause *Sema::ActOnOpenMPDepobjClause(Expr *Depobj, SourceLocation StartLoc, 16321 SourceLocation LParenLoc, 16322 SourceLocation EndLoc) { 16323 if (!Depobj) 16324 return nullptr; 16325 16326 bool OMPDependTFound = findOMPDependT(*this, StartLoc, DSAStack); 16327 16328 // OpenMP 5.0, 2.17.10.1 depobj Construct 16329 // depobj is an lvalue expression of type omp_depend_t. 16330 if (!Depobj->isTypeDependent() && !Depobj->isValueDependent() && 16331 !Depobj->isInstantiationDependent() && 16332 !Depobj->containsUnexpandedParameterPack() && 16333 (OMPDependTFound && 16334 !Context.typesAreCompatible(DSAStack->getOMPDependT(), Depobj->getType(), 16335 /*CompareUnqualified=*/true))) { 16336 Diag(Depobj->getExprLoc(), diag::err_omp_expected_omp_depend_t_lvalue) 16337 << 0 << Depobj->getType() << Depobj->getSourceRange(); 16338 } 16339 16340 if (!Depobj->isLValue()) { 16341 Diag(Depobj->getExprLoc(), diag::err_omp_expected_omp_depend_t_lvalue) 16342 << 1 << Depobj->getSourceRange(); 16343 } 16344 16345 return OMPDepobjClause::Create(Context, StartLoc, LParenLoc, EndLoc, Depobj); 16346 } 16347 16348 OMPClause * 16349 Sema::ActOnOpenMPDependClause(Expr *DepModifier, OpenMPDependClauseKind DepKind, 16350 SourceLocation DepLoc, SourceLocation ColonLoc, 16351 ArrayRef<Expr *> VarList, SourceLocation StartLoc, 16352 SourceLocation LParenLoc, SourceLocation EndLoc) { 16353 if (DSAStack->getCurrentDirective() == OMPD_ordered && 16354 DepKind != OMPC_DEPEND_source && DepKind != OMPC_DEPEND_sink) { 16355 Diag(DepLoc, diag::err_omp_unexpected_clause_value) 16356 << "'source' or 'sink'" << getOpenMPClauseName(OMPC_depend); 16357 return nullptr; 16358 } 16359 if ((DSAStack->getCurrentDirective() != OMPD_ordered || 16360 DSAStack->getCurrentDirective() == OMPD_depobj) && 16361 (DepKind == OMPC_DEPEND_unknown || DepKind == OMPC_DEPEND_source || 16362 DepKind == OMPC_DEPEND_sink || 16363 ((LangOpts.OpenMP < 50 || 16364 DSAStack->getCurrentDirective() == OMPD_depobj) && 16365 DepKind == OMPC_DEPEND_depobj))) { 16366 SmallVector<unsigned, 3> Except; 16367 Except.push_back(OMPC_DEPEND_source); 16368 Except.push_back(OMPC_DEPEND_sink); 16369 if (LangOpts.OpenMP < 50 || DSAStack->getCurrentDirective() == OMPD_depobj) 16370 Except.push_back(OMPC_DEPEND_depobj); 16371 std::string Expected = (LangOpts.OpenMP >= 50 && !DepModifier) 16372 ? "depend modifier(iterator) or " 16373 : ""; 16374 Diag(DepLoc, diag::err_omp_unexpected_clause_value) 16375 << Expected + getListOfPossibleValues(OMPC_depend, /*First=*/0, 16376 /*Last=*/OMPC_DEPEND_unknown, 16377 Except) 16378 << getOpenMPClauseName(OMPC_depend); 16379 return nullptr; 16380 } 16381 if (DepModifier && 16382 (DepKind == OMPC_DEPEND_source || DepKind == OMPC_DEPEND_sink)) { 16383 Diag(DepModifier->getExprLoc(), 16384 diag::err_omp_depend_sink_source_with_modifier); 16385 return nullptr; 16386 } 16387 if (DepModifier && 16388 !DepModifier->getType()->isSpecificBuiltinType(BuiltinType::OMPIterator)) 16389 Diag(DepModifier->getExprLoc(), diag::err_omp_depend_modifier_not_iterator); 16390 16391 SmallVector<Expr *, 8> Vars; 16392 DSAStackTy::OperatorOffsetTy OpsOffs; 16393 llvm::APSInt DepCounter(/*BitWidth=*/32); 16394 llvm::APSInt TotalDepCount(/*BitWidth=*/32); 16395 if (DepKind == OMPC_DEPEND_sink || DepKind == OMPC_DEPEND_source) { 16396 if (const Expr *OrderedCountExpr = 16397 DSAStack->getParentOrderedRegionParam().first) { 16398 TotalDepCount = OrderedCountExpr->EvaluateKnownConstInt(Context); 16399 TotalDepCount.setIsUnsigned(/*Val=*/true); 16400 } 16401 } 16402 for (Expr *RefExpr : VarList) { 16403 assert(RefExpr && "NULL expr in OpenMP shared clause."); 16404 if (isa<DependentScopeDeclRefExpr>(RefExpr)) { 16405 // It will be analyzed later. 16406 Vars.push_back(RefExpr); 16407 continue; 16408 } 16409 16410 SourceLocation ELoc = RefExpr->getExprLoc(); 16411 Expr *SimpleExpr = RefExpr->IgnoreParenCasts(); 16412 if (DepKind == OMPC_DEPEND_sink) { 16413 if (DSAStack->getParentOrderedRegionParam().first && 16414 DepCounter >= TotalDepCount) { 16415 Diag(ELoc, diag::err_omp_depend_sink_unexpected_expr); 16416 continue; 16417 } 16418 ++DepCounter; 16419 // OpenMP [2.13.9, Summary] 16420 // depend(dependence-type : vec), where dependence-type is: 16421 // 'sink' and where vec is the iteration vector, which has the form: 16422 // x1 [+- d1], x2 [+- d2 ], . . . , xn [+- dn] 16423 // where n is the value specified by the ordered clause in the loop 16424 // directive, xi denotes the loop iteration variable of the i-th nested 16425 // loop associated with the loop directive, and di is a constant 16426 // non-negative integer. 16427 if (CurContext->isDependentContext()) { 16428 // It will be analyzed later. 16429 Vars.push_back(RefExpr); 16430 continue; 16431 } 16432 SimpleExpr = SimpleExpr->IgnoreImplicit(); 16433 OverloadedOperatorKind OOK = OO_None; 16434 SourceLocation OOLoc; 16435 Expr *LHS = SimpleExpr; 16436 Expr *RHS = nullptr; 16437 if (auto *BO = dyn_cast<BinaryOperator>(SimpleExpr)) { 16438 OOK = BinaryOperator::getOverloadedOperator(BO->getOpcode()); 16439 OOLoc = BO->getOperatorLoc(); 16440 LHS = BO->getLHS()->IgnoreParenImpCasts(); 16441 RHS = BO->getRHS()->IgnoreParenImpCasts(); 16442 } else if (auto *OCE = dyn_cast<CXXOperatorCallExpr>(SimpleExpr)) { 16443 OOK = OCE->getOperator(); 16444 OOLoc = OCE->getOperatorLoc(); 16445 LHS = OCE->getArg(/*Arg=*/0)->IgnoreParenImpCasts(); 16446 RHS = OCE->getArg(/*Arg=*/1)->IgnoreParenImpCasts(); 16447 } else if (auto *MCE = dyn_cast<CXXMemberCallExpr>(SimpleExpr)) { 16448 OOK = MCE->getMethodDecl() 16449 ->getNameInfo() 16450 .getName() 16451 .getCXXOverloadedOperator(); 16452 OOLoc = MCE->getCallee()->getExprLoc(); 16453 LHS = MCE->getImplicitObjectArgument()->IgnoreParenImpCasts(); 16454 RHS = MCE->getArg(/*Arg=*/0)->IgnoreParenImpCasts(); 16455 } 16456 SourceLocation ELoc; 16457 SourceRange ERange; 16458 auto Res = getPrivateItem(*this, LHS, ELoc, ERange); 16459 if (Res.second) { 16460 // It will be analyzed later. 16461 Vars.push_back(RefExpr); 16462 } 16463 ValueDecl *D = Res.first; 16464 if (!D) 16465 continue; 16466 16467 if (OOK != OO_Plus && OOK != OO_Minus && (RHS || OOK != OO_None)) { 16468 Diag(OOLoc, diag::err_omp_depend_sink_expected_plus_minus); 16469 continue; 16470 } 16471 if (RHS) { 16472 ExprResult RHSRes = VerifyPositiveIntegerConstantInClause( 16473 RHS, OMPC_depend, /*StrictlyPositive=*/false); 16474 if (RHSRes.isInvalid()) 16475 continue; 16476 } 16477 if (!CurContext->isDependentContext() && 16478 DSAStack->getParentOrderedRegionParam().first && 16479 DepCounter != DSAStack->isParentLoopControlVariable(D).first) { 16480 const ValueDecl *VD = 16481 DSAStack->getParentLoopControlVariable(DepCounter.getZExtValue()); 16482 if (VD) 16483 Diag(ELoc, diag::err_omp_depend_sink_expected_loop_iteration) 16484 << 1 << VD; 16485 else 16486 Diag(ELoc, diag::err_omp_depend_sink_expected_loop_iteration) << 0; 16487 continue; 16488 } 16489 OpsOffs.emplace_back(RHS, OOK); 16490 } else { 16491 bool OMPDependTFound = LangOpts.OpenMP >= 50; 16492 if (OMPDependTFound) 16493 OMPDependTFound = findOMPDependT(*this, StartLoc, DSAStack, 16494 DepKind == OMPC_DEPEND_depobj); 16495 if (DepKind == OMPC_DEPEND_depobj) { 16496 // OpenMP 5.0, 2.17.11 depend Clause, Restrictions, C/C++ 16497 // List items used in depend clauses with the depobj dependence type 16498 // must be expressions of the omp_depend_t type. 16499 if (!RefExpr->isValueDependent() && !RefExpr->isTypeDependent() && 16500 !RefExpr->isInstantiationDependent() && 16501 !RefExpr->containsUnexpandedParameterPack() && 16502 (OMPDependTFound && 16503 !Context.hasSameUnqualifiedType(DSAStack->getOMPDependT(), 16504 RefExpr->getType()))) { 16505 Diag(ELoc, diag::err_omp_expected_omp_depend_t_lvalue) 16506 << 0 << RefExpr->getType() << RefExpr->getSourceRange(); 16507 continue; 16508 } 16509 if (!RefExpr->isLValue()) { 16510 Diag(ELoc, diag::err_omp_expected_omp_depend_t_lvalue) 16511 << 1 << RefExpr->getType() << RefExpr->getSourceRange(); 16512 continue; 16513 } 16514 } else { 16515 // OpenMP 5.0 [2.17.11, Restrictions] 16516 // List items used in depend clauses cannot be zero-length array 16517 // sections. 16518 QualType ExprTy = RefExpr->getType().getNonReferenceType(); 16519 const auto *OASE = dyn_cast<OMPArraySectionExpr>(SimpleExpr); 16520 if (OASE) { 16521 QualType BaseType = 16522 OMPArraySectionExpr::getBaseOriginalType(OASE->getBase()); 16523 if (const auto *ATy = BaseType->getAsArrayTypeUnsafe()) 16524 ExprTy = ATy->getElementType(); 16525 else 16526 ExprTy = BaseType->getPointeeType(); 16527 ExprTy = ExprTy.getNonReferenceType(); 16528 const Expr *Length = OASE->getLength(); 16529 Expr::EvalResult Result; 16530 if (Length && !Length->isValueDependent() && 16531 Length->EvaluateAsInt(Result, Context) && 16532 Result.Val.getInt().isNullValue()) { 16533 Diag(ELoc, 16534 diag::err_omp_depend_zero_length_array_section_not_allowed) 16535 << SimpleExpr->getSourceRange(); 16536 continue; 16537 } 16538 } 16539 16540 // OpenMP 5.0, 2.17.11 depend Clause, Restrictions, C/C++ 16541 // List items used in depend clauses with the in, out, inout or 16542 // mutexinoutset dependence types cannot be expressions of the 16543 // omp_depend_t type. 16544 if (!RefExpr->isValueDependent() && !RefExpr->isTypeDependent() && 16545 !RefExpr->isInstantiationDependent() && 16546 !RefExpr->containsUnexpandedParameterPack() && 16547 (OMPDependTFound && 16548 DSAStack->getOMPDependT().getTypePtr() == ExprTy.getTypePtr())) { 16549 Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item) 16550 << (LangOpts.OpenMP >= 50 ? 1 : 0) << 1 16551 << RefExpr->getSourceRange(); 16552 continue; 16553 } 16554 16555 auto *ASE = dyn_cast<ArraySubscriptExpr>(SimpleExpr); 16556 if (!RefExpr->IgnoreParenImpCasts()->isLValue() || 16557 (ASE && !ASE->getBase()->isTypeDependent() && 16558 !ASE->getBase() 16559 ->getType() 16560 .getNonReferenceType() 16561 ->isPointerType() && 16562 !ASE->getBase()->getType().getNonReferenceType()->isArrayType())) { 16563 Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item) 16564 << (LangOpts.OpenMP >= 50 ? 1 : 0) 16565 << (LangOpts.OpenMP >= 50 ? 1 : 0) << RefExpr->getSourceRange(); 16566 continue; 16567 } 16568 16569 ExprResult Res; 16570 { 16571 Sema::TentativeAnalysisScope Trap(*this); 16572 Res = CreateBuiltinUnaryOp(ELoc, UO_AddrOf, 16573 RefExpr->IgnoreParenImpCasts()); 16574 } 16575 if (!Res.isUsable() && !isa<OMPArraySectionExpr>(SimpleExpr) && 16576 !isa<OMPArrayShapingExpr>(SimpleExpr)) { 16577 Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item) 16578 << (LangOpts.OpenMP >= 50 ? 1 : 0) 16579 << (LangOpts.OpenMP >= 50 ? 1 : 0) << RefExpr->getSourceRange(); 16580 continue; 16581 } 16582 } 16583 } 16584 Vars.push_back(RefExpr->IgnoreParenImpCasts()); 16585 } 16586 16587 if (!CurContext->isDependentContext() && DepKind == OMPC_DEPEND_sink && 16588 TotalDepCount > VarList.size() && 16589 DSAStack->getParentOrderedRegionParam().first && 16590 DSAStack->getParentLoopControlVariable(VarList.size() + 1)) { 16591 Diag(EndLoc, diag::err_omp_depend_sink_expected_loop_iteration) 16592 << 1 << DSAStack->getParentLoopControlVariable(VarList.size() + 1); 16593 } 16594 if (DepKind != OMPC_DEPEND_source && DepKind != OMPC_DEPEND_sink && 16595 Vars.empty()) 16596 return nullptr; 16597 16598 auto *C = OMPDependClause::Create(Context, StartLoc, LParenLoc, EndLoc, 16599 DepModifier, DepKind, DepLoc, ColonLoc, 16600 Vars, TotalDepCount.getZExtValue()); 16601 if ((DepKind == OMPC_DEPEND_sink || DepKind == OMPC_DEPEND_source) && 16602 DSAStack->isParentOrderedRegion()) 16603 DSAStack->addDoacrossDependClause(C, OpsOffs); 16604 return C; 16605 } 16606 16607 OMPClause *Sema::ActOnOpenMPDeviceClause(OpenMPDeviceClauseModifier Modifier, 16608 Expr *Device, SourceLocation StartLoc, 16609 SourceLocation LParenLoc, 16610 SourceLocation ModifierLoc, 16611 SourceLocation EndLoc) { 16612 assert((ModifierLoc.isInvalid() || LangOpts.OpenMP >= 50) && 16613 "Unexpected device modifier in OpenMP < 50."); 16614 16615 bool ErrorFound = false; 16616 if (ModifierLoc.isValid() && Modifier == OMPC_DEVICE_unknown) { 16617 std::string Values = 16618 getListOfPossibleValues(OMPC_device, /*First=*/0, OMPC_DEVICE_unknown); 16619 Diag(ModifierLoc, diag::err_omp_unexpected_clause_value) 16620 << Values << getOpenMPClauseName(OMPC_device); 16621 ErrorFound = true; 16622 } 16623 16624 Expr *ValExpr = Device; 16625 Stmt *HelperValStmt = nullptr; 16626 16627 // OpenMP [2.9.1, Restrictions] 16628 // The device expression must evaluate to a non-negative integer value. 16629 ErrorFound = !isNonNegativeIntegerValue(ValExpr, *this, OMPC_device, 16630 /*StrictlyPositive=*/false) || 16631 ErrorFound; 16632 if (ErrorFound) 16633 return nullptr; 16634 16635 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 16636 OpenMPDirectiveKind CaptureRegion = 16637 getOpenMPCaptureRegionForClause(DKind, OMPC_device, LangOpts.OpenMP); 16638 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 16639 ValExpr = MakeFullExpr(ValExpr).get(); 16640 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 16641 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 16642 HelperValStmt = buildPreInits(Context, Captures); 16643 } 16644 16645 return new (Context) 16646 OMPDeviceClause(Modifier, ValExpr, HelperValStmt, CaptureRegion, StartLoc, 16647 LParenLoc, ModifierLoc, EndLoc); 16648 } 16649 16650 static bool checkTypeMappable(SourceLocation SL, SourceRange SR, Sema &SemaRef, 16651 DSAStackTy *Stack, QualType QTy, 16652 bool FullCheck = true) { 16653 NamedDecl *ND; 16654 if (QTy->isIncompleteType(&ND)) { 16655 SemaRef.Diag(SL, diag::err_incomplete_type) << QTy << SR; 16656 return false; 16657 } 16658 if (FullCheck && !SemaRef.CurContext->isDependentContext() && 16659 !QTy.isTriviallyCopyableType(SemaRef.Context)) 16660 SemaRef.Diag(SL, diag::warn_omp_non_trivial_type_mapped) << QTy << SR; 16661 return true; 16662 } 16663 16664 /// Return true if it can be proven that the provided array expression 16665 /// (array section or array subscript) does NOT specify the whole size of the 16666 /// array whose base type is \a BaseQTy. 16667 static bool checkArrayExpressionDoesNotReferToWholeSize(Sema &SemaRef, 16668 const Expr *E, 16669 QualType BaseQTy) { 16670 const auto *OASE = dyn_cast<OMPArraySectionExpr>(E); 16671 16672 // If this is an array subscript, it refers to the whole size if the size of 16673 // the dimension is constant and equals 1. Also, an array section assumes the 16674 // format of an array subscript if no colon is used. 16675 if (isa<ArraySubscriptExpr>(E) || 16676 (OASE && OASE->getColonLocFirst().isInvalid())) { 16677 if (const auto *ATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr())) 16678 return ATy->getSize().getSExtValue() != 1; 16679 // Size can't be evaluated statically. 16680 return false; 16681 } 16682 16683 assert(OASE && "Expecting array section if not an array subscript."); 16684 const Expr *LowerBound = OASE->getLowerBound(); 16685 const Expr *Length = OASE->getLength(); 16686 16687 // If there is a lower bound that does not evaluates to zero, we are not 16688 // covering the whole dimension. 16689 if (LowerBound) { 16690 Expr::EvalResult Result; 16691 if (!LowerBound->EvaluateAsInt(Result, SemaRef.getASTContext())) 16692 return false; // Can't get the integer value as a constant. 16693 16694 llvm::APSInt ConstLowerBound = Result.Val.getInt(); 16695 if (ConstLowerBound.getSExtValue()) 16696 return true; 16697 } 16698 16699 // If we don't have a length we covering the whole dimension. 16700 if (!Length) 16701 return false; 16702 16703 // If the base is a pointer, we don't have a way to get the size of the 16704 // pointee. 16705 if (BaseQTy->isPointerType()) 16706 return false; 16707 16708 // We can only check if the length is the same as the size of the dimension 16709 // if we have a constant array. 16710 const auto *CATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr()); 16711 if (!CATy) 16712 return false; 16713 16714 Expr::EvalResult Result; 16715 if (!Length->EvaluateAsInt(Result, SemaRef.getASTContext())) 16716 return false; // Can't get the integer value as a constant. 16717 16718 llvm::APSInt ConstLength = Result.Val.getInt(); 16719 return CATy->getSize().getSExtValue() != ConstLength.getSExtValue(); 16720 } 16721 16722 // Return true if it can be proven that the provided array expression (array 16723 // section or array subscript) does NOT specify a single element of the array 16724 // whose base type is \a BaseQTy. 16725 static bool checkArrayExpressionDoesNotReferToUnitySize(Sema &SemaRef, 16726 const Expr *E, 16727 QualType BaseQTy) { 16728 const auto *OASE = dyn_cast<OMPArraySectionExpr>(E); 16729 16730 // An array subscript always refer to a single element. Also, an array section 16731 // assumes the format of an array subscript if no colon is used. 16732 if (isa<ArraySubscriptExpr>(E) || 16733 (OASE && OASE->getColonLocFirst().isInvalid())) 16734 return false; 16735 16736 assert(OASE && "Expecting array section if not an array subscript."); 16737 const Expr *Length = OASE->getLength(); 16738 16739 // If we don't have a length we have to check if the array has unitary size 16740 // for this dimension. Also, we should always expect a length if the base type 16741 // is pointer. 16742 if (!Length) { 16743 if (const auto *ATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr())) 16744 return ATy->getSize().getSExtValue() != 1; 16745 // We cannot assume anything. 16746 return false; 16747 } 16748 16749 // Check if the length evaluates to 1. 16750 Expr::EvalResult Result; 16751 if (!Length->EvaluateAsInt(Result, SemaRef.getASTContext())) 16752 return false; // Can't get the integer value as a constant. 16753 16754 llvm::APSInt ConstLength = Result.Val.getInt(); 16755 return ConstLength.getSExtValue() != 1; 16756 } 16757 16758 // The base of elements of list in a map clause have to be either: 16759 // - a reference to variable or field. 16760 // - a member expression. 16761 // - an array expression. 16762 // 16763 // E.g. if we have the expression 'r.S.Arr[:12]', we want to retrieve the 16764 // reference to 'r'. 16765 // 16766 // If we have: 16767 // 16768 // struct SS { 16769 // Bla S; 16770 // foo() { 16771 // #pragma omp target map (S.Arr[:12]); 16772 // } 16773 // } 16774 // 16775 // We want to retrieve the member expression 'this->S'; 16776 16777 // OpenMP 5.0 [2.19.7.1, map Clause, Restrictions, p.2] 16778 // If a list item is an array section, it must specify contiguous storage. 16779 // 16780 // For this restriction it is sufficient that we make sure only references 16781 // to variables or fields and array expressions, and that no array sections 16782 // exist except in the rightmost expression (unless they cover the whole 16783 // dimension of the array). E.g. these would be invalid: 16784 // 16785 // r.ArrS[3:5].Arr[6:7] 16786 // 16787 // r.ArrS[3:5].x 16788 // 16789 // but these would be valid: 16790 // r.ArrS[3].Arr[6:7] 16791 // 16792 // r.ArrS[3].x 16793 namespace { 16794 class MapBaseChecker final : public StmtVisitor<MapBaseChecker, bool> { 16795 Sema &SemaRef; 16796 OpenMPClauseKind CKind = OMPC_unknown; 16797 OMPClauseMappableExprCommon::MappableExprComponentList &Components; 16798 bool NoDiagnose = false; 16799 const Expr *RelevantExpr = nullptr; 16800 bool AllowUnitySizeArraySection = true; 16801 bool AllowWholeSizeArraySection = true; 16802 SourceLocation ELoc; 16803 SourceRange ERange; 16804 16805 void emitErrorMsg() { 16806 // If nothing else worked, this is not a valid map clause expression. 16807 if (SemaRef.getLangOpts().OpenMP < 50) { 16808 SemaRef.Diag(ELoc, 16809 diag::err_omp_expected_named_var_member_or_array_expression) 16810 << ERange; 16811 } else { 16812 SemaRef.Diag(ELoc, diag::err_omp_non_lvalue_in_map_or_motion_clauses) 16813 << getOpenMPClauseName(CKind) << ERange; 16814 } 16815 } 16816 16817 public: 16818 bool VisitDeclRefExpr(DeclRefExpr *DRE) { 16819 if (!isa<VarDecl>(DRE->getDecl())) { 16820 emitErrorMsg(); 16821 return false; 16822 } 16823 assert(!RelevantExpr && "RelevantExpr is expected to be nullptr"); 16824 RelevantExpr = DRE; 16825 // Record the component. 16826 Components.emplace_back(DRE, DRE->getDecl()); 16827 return true; 16828 } 16829 16830 bool VisitMemberExpr(MemberExpr *ME) { 16831 Expr *E = ME; 16832 Expr *BaseE = ME->getBase()->IgnoreParenCasts(); 16833 16834 if (isa<CXXThisExpr>(BaseE)) { 16835 assert(!RelevantExpr && "RelevantExpr is expected to be nullptr"); 16836 // We found a base expression: this->Val. 16837 RelevantExpr = ME; 16838 } else { 16839 E = BaseE; 16840 } 16841 16842 if (!isa<FieldDecl>(ME->getMemberDecl())) { 16843 if (!NoDiagnose) { 16844 SemaRef.Diag(ELoc, diag::err_omp_expected_access_to_data_field) 16845 << ME->getSourceRange(); 16846 return false; 16847 } 16848 if (RelevantExpr) 16849 return false; 16850 return Visit(E); 16851 } 16852 16853 auto *FD = cast<FieldDecl>(ME->getMemberDecl()); 16854 16855 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.3] 16856 // A bit-field cannot appear in a map clause. 16857 // 16858 if (FD->isBitField()) { 16859 if (!NoDiagnose) { 16860 SemaRef.Diag(ELoc, diag::err_omp_bit_fields_forbidden_in_clause) 16861 << ME->getSourceRange() << getOpenMPClauseName(CKind); 16862 return false; 16863 } 16864 if (RelevantExpr) 16865 return false; 16866 return Visit(E); 16867 } 16868 16869 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1] 16870 // If the type of a list item is a reference to a type T then the type 16871 // will be considered to be T for all purposes of this clause. 16872 QualType CurType = BaseE->getType().getNonReferenceType(); 16873 16874 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.2] 16875 // A list item cannot be a variable that is a member of a structure with 16876 // a union type. 16877 // 16878 if (CurType->isUnionType()) { 16879 if (!NoDiagnose) { 16880 SemaRef.Diag(ELoc, diag::err_omp_union_type_not_allowed) 16881 << ME->getSourceRange(); 16882 return false; 16883 } 16884 return RelevantExpr || Visit(E); 16885 } 16886 16887 // If we got a member expression, we should not expect any array section 16888 // before that: 16889 // 16890 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.7] 16891 // If a list item is an element of a structure, only the rightmost symbol 16892 // of the variable reference can be an array section. 16893 // 16894 AllowUnitySizeArraySection = false; 16895 AllowWholeSizeArraySection = false; 16896 16897 // Record the component. 16898 Components.emplace_back(ME, FD); 16899 return RelevantExpr || Visit(E); 16900 } 16901 16902 bool VisitArraySubscriptExpr(ArraySubscriptExpr *AE) { 16903 Expr *E = AE->getBase()->IgnoreParenImpCasts(); 16904 16905 if (!E->getType()->isAnyPointerType() && !E->getType()->isArrayType()) { 16906 if (!NoDiagnose) { 16907 SemaRef.Diag(ELoc, diag::err_omp_expected_base_var_name) 16908 << 0 << AE->getSourceRange(); 16909 return false; 16910 } 16911 return RelevantExpr || Visit(E); 16912 } 16913 16914 // If we got an array subscript that express the whole dimension we 16915 // can have any array expressions before. If it only expressing part of 16916 // the dimension, we can only have unitary-size array expressions. 16917 if (checkArrayExpressionDoesNotReferToWholeSize(SemaRef, AE, 16918 E->getType())) 16919 AllowWholeSizeArraySection = false; 16920 16921 if (const auto *TE = dyn_cast<CXXThisExpr>(E->IgnoreParenCasts())) { 16922 Expr::EvalResult Result; 16923 if (!AE->getIdx()->isValueDependent() && 16924 AE->getIdx()->EvaluateAsInt(Result, SemaRef.getASTContext()) && 16925 !Result.Val.getInt().isNullValue()) { 16926 SemaRef.Diag(AE->getIdx()->getExprLoc(), 16927 diag::err_omp_invalid_map_this_expr); 16928 SemaRef.Diag(AE->getIdx()->getExprLoc(), 16929 diag::note_omp_invalid_subscript_on_this_ptr_map); 16930 } 16931 assert(!RelevantExpr && "RelevantExpr is expected to be nullptr"); 16932 RelevantExpr = TE; 16933 } 16934 16935 // Record the component - we don't have any declaration associated. 16936 Components.emplace_back(AE, nullptr); 16937 16938 return RelevantExpr || Visit(E); 16939 } 16940 16941 bool VisitOMPArraySectionExpr(OMPArraySectionExpr *OASE) { 16942 assert(!NoDiagnose && "Array sections cannot be implicitly mapped."); 16943 Expr *E = OASE->getBase()->IgnoreParenImpCasts(); 16944 QualType CurType = 16945 OMPArraySectionExpr::getBaseOriginalType(E).getCanonicalType(); 16946 16947 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1] 16948 // If the type of a list item is a reference to a type T then the type 16949 // will be considered to be T for all purposes of this clause. 16950 if (CurType->isReferenceType()) 16951 CurType = CurType->getPointeeType(); 16952 16953 bool IsPointer = CurType->isAnyPointerType(); 16954 16955 if (!IsPointer && !CurType->isArrayType()) { 16956 SemaRef.Diag(ELoc, diag::err_omp_expected_base_var_name) 16957 << 0 << OASE->getSourceRange(); 16958 return false; 16959 } 16960 16961 bool NotWhole = 16962 checkArrayExpressionDoesNotReferToWholeSize(SemaRef, OASE, CurType); 16963 bool NotUnity = 16964 checkArrayExpressionDoesNotReferToUnitySize(SemaRef, OASE, CurType); 16965 16966 if (AllowWholeSizeArraySection) { 16967 // Any array section is currently allowed. Allowing a whole size array 16968 // section implies allowing a unity array section as well. 16969 // 16970 // If this array section refers to the whole dimension we can still 16971 // accept other array sections before this one, except if the base is a 16972 // pointer. Otherwise, only unitary sections are accepted. 16973 if (NotWhole || IsPointer) 16974 AllowWholeSizeArraySection = false; 16975 } else if (AllowUnitySizeArraySection && NotUnity) { 16976 // A unity or whole array section is not allowed and that is not 16977 // compatible with the properties of the current array section. 16978 SemaRef.Diag( 16979 ELoc, diag::err_array_section_does_not_specify_contiguous_storage) 16980 << OASE->getSourceRange(); 16981 return false; 16982 } 16983 16984 if (const auto *TE = dyn_cast<CXXThisExpr>(E)) { 16985 Expr::EvalResult ResultR; 16986 Expr::EvalResult ResultL; 16987 if (!OASE->getLength()->isValueDependent() && 16988 OASE->getLength()->EvaluateAsInt(ResultR, SemaRef.getASTContext()) && 16989 !ResultR.Val.getInt().isOneValue()) { 16990 SemaRef.Diag(OASE->getLength()->getExprLoc(), 16991 diag::err_omp_invalid_map_this_expr); 16992 SemaRef.Diag(OASE->getLength()->getExprLoc(), 16993 diag::note_omp_invalid_length_on_this_ptr_mapping); 16994 } 16995 if (OASE->getLowerBound() && !OASE->getLowerBound()->isValueDependent() && 16996 OASE->getLowerBound()->EvaluateAsInt(ResultL, 16997 SemaRef.getASTContext()) && 16998 !ResultL.Val.getInt().isNullValue()) { 16999 SemaRef.Diag(OASE->getLowerBound()->getExprLoc(), 17000 diag::err_omp_invalid_map_this_expr); 17001 SemaRef.Diag(OASE->getLowerBound()->getExprLoc(), 17002 diag::note_omp_invalid_lower_bound_on_this_ptr_mapping); 17003 } 17004 assert(!RelevantExpr && "RelevantExpr is expected to be nullptr"); 17005 RelevantExpr = TE; 17006 } 17007 17008 // Record the component - we don't have any declaration associated. 17009 Components.emplace_back(OASE, nullptr); 17010 return RelevantExpr || Visit(E); 17011 } 17012 bool VisitOMPArrayShapingExpr(OMPArrayShapingExpr *E) { 17013 Expr *Base = E->getBase(); 17014 17015 // Record the component - we don't have any declaration associated. 17016 Components.emplace_back(E, nullptr); 17017 17018 return Visit(Base->IgnoreParenImpCasts()); 17019 } 17020 17021 bool VisitUnaryOperator(UnaryOperator *UO) { 17022 if (SemaRef.getLangOpts().OpenMP < 50 || !UO->isLValue() || 17023 UO->getOpcode() != UO_Deref) { 17024 emitErrorMsg(); 17025 return false; 17026 } 17027 if (!RelevantExpr) { 17028 // Record the component if haven't found base decl. 17029 Components.emplace_back(UO, nullptr); 17030 } 17031 return RelevantExpr || Visit(UO->getSubExpr()->IgnoreParenImpCasts()); 17032 } 17033 bool VisitBinaryOperator(BinaryOperator *BO) { 17034 if (SemaRef.getLangOpts().OpenMP < 50 || !BO->getType()->isPointerType()) { 17035 emitErrorMsg(); 17036 return false; 17037 } 17038 17039 // Pointer arithmetic is the only thing we expect to happen here so after we 17040 // make sure the binary operator is a pointer type, the we only thing need 17041 // to to is to visit the subtree that has the same type as root (so that we 17042 // know the other subtree is just an offset) 17043 Expr *LE = BO->getLHS()->IgnoreParenImpCasts(); 17044 Expr *RE = BO->getRHS()->IgnoreParenImpCasts(); 17045 Components.emplace_back(BO, nullptr); 17046 assert((LE->getType().getTypePtr() == BO->getType().getTypePtr() || 17047 RE->getType().getTypePtr() == BO->getType().getTypePtr()) && 17048 "Either LHS or RHS have base decl inside"); 17049 if (BO->getType().getTypePtr() == LE->getType().getTypePtr()) 17050 return RelevantExpr || Visit(LE); 17051 return RelevantExpr || Visit(RE); 17052 } 17053 bool VisitCXXThisExpr(CXXThisExpr *CTE) { 17054 assert(!RelevantExpr && "RelevantExpr is expected to be nullptr"); 17055 RelevantExpr = CTE; 17056 Components.emplace_back(CTE, nullptr); 17057 return true; 17058 } 17059 bool VisitCXXOperatorCallExpr(CXXOperatorCallExpr *COCE) { 17060 assert(!RelevantExpr && "RelevantExpr is expected to be nullptr"); 17061 Components.emplace_back(COCE, nullptr); 17062 return true; 17063 } 17064 bool VisitStmt(Stmt *) { 17065 emitErrorMsg(); 17066 return false; 17067 } 17068 const Expr *getFoundBase() const { 17069 return RelevantExpr; 17070 } 17071 explicit MapBaseChecker( 17072 Sema &SemaRef, OpenMPClauseKind CKind, 17073 OMPClauseMappableExprCommon::MappableExprComponentList &Components, 17074 bool NoDiagnose, SourceLocation &ELoc, SourceRange &ERange) 17075 : SemaRef(SemaRef), CKind(CKind), Components(Components), 17076 NoDiagnose(NoDiagnose), ELoc(ELoc), ERange(ERange) {} 17077 }; 17078 } // namespace 17079 17080 /// Return the expression of the base of the mappable expression or null if it 17081 /// cannot be determined and do all the necessary checks to see if the expression 17082 /// is valid as a standalone mappable expression. In the process, record all the 17083 /// components of the expression. 17084 static const Expr *checkMapClauseExpressionBase( 17085 Sema &SemaRef, Expr *E, 17086 OMPClauseMappableExprCommon::MappableExprComponentList &CurComponents, 17087 OpenMPClauseKind CKind, bool NoDiagnose) { 17088 SourceLocation ELoc = E->getExprLoc(); 17089 SourceRange ERange = E->getSourceRange(); 17090 MapBaseChecker Checker(SemaRef, CKind, CurComponents, NoDiagnose, ELoc, 17091 ERange); 17092 if (Checker.Visit(E->IgnoreParens())) 17093 return Checker.getFoundBase(); 17094 return nullptr; 17095 } 17096 17097 // Return true if expression E associated with value VD has conflicts with other 17098 // map information. 17099 static bool checkMapConflicts( 17100 Sema &SemaRef, DSAStackTy *DSAS, const ValueDecl *VD, const Expr *E, 17101 bool CurrentRegionOnly, 17102 OMPClauseMappableExprCommon::MappableExprComponentListRef CurComponents, 17103 OpenMPClauseKind CKind) { 17104 assert(VD && E); 17105 SourceLocation ELoc = E->getExprLoc(); 17106 SourceRange ERange = E->getSourceRange(); 17107 17108 // In order to easily check the conflicts we need to match each component of 17109 // the expression under test with the components of the expressions that are 17110 // already in the stack. 17111 17112 assert(!CurComponents.empty() && "Map clause expression with no components!"); 17113 assert(CurComponents.back().getAssociatedDeclaration() == VD && 17114 "Map clause expression with unexpected base!"); 17115 17116 // Variables to help detecting enclosing problems in data environment nests. 17117 bool IsEnclosedByDataEnvironmentExpr = false; 17118 const Expr *EnclosingExpr = nullptr; 17119 17120 bool FoundError = DSAS->checkMappableExprComponentListsForDecl( 17121 VD, CurrentRegionOnly, 17122 [&IsEnclosedByDataEnvironmentExpr, &SemaRef, VD, CurrentRegionOnly, ELoc, 17123 ERange, CKind, &EnclosingExpr, 17124 CurComponents](OMPClauseMappableExprCommon::MappableExprComponentListRef 17125 StackComponents, 17126 OpenMPClauseKind) { 17127 assert(!StackComponents.empty() && 17128 "Map clause expression with no components!"); 17129 assert(StackComponents.back().getAssociatedDeclaration() == VD && 17130 "Map clause expression with unexpected base!"); 17131 (void)VD; 17132 17133 // The whole expression in the stack. 17134 const Expr *RE = StackComponents.front().getAssociatedExpression(); 17135 17136 // Expressions must start from the same base. Here we detect at which 17137 // point both expressions diverge from each other and see if we can 17138 // detect if the memory referred to both expressions is contiguous and 17139 // do not overlap. 17140 auto CI = CurComponents.rbegin(); 17141 auto CE = CurComponents.rend(); 17142 auto SI = StackComponents.rbegin(); 17143 auto SE = StackComponents.rend(); 17144 for (; CI != CE && SI != SE; ++CI, ++SI) { 17145 17146 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.3] 17147 // At most one list item can be an array item derived from a given 17148 // variable in map clauses of the same construct. 17149 if (CurrentRegionOnly && 17150 (isa<ArraySubscriptExpr>(CI->getAssociatedExpression()) || 17151 isa<OMPArraySectionExpr>(CI->getAssociatedExpression()) || 17152 isa<OMPArrayShapingExpr>(CI->getAssociatedExpression())) && 17153 (isa<ArraySubscriptExpr>(SI->getAssociatedExpression()) || 17154 isa<OMPArraySectionExpr>(SI->getAssociatedExpression()) || 17155 isa<OMPArrayShapingExpr>(SI->getAssociatedExpression()))) { 17156 SemaRef.Diag(CI->getAssociatedExpression()->getExprLoc(), 17157 diag::err_omp_multiple_array_items_in_map_clause) 17158 << CI->getAssociatedExpression()->getSourceRange(); 17159 SemaRef.Diag(SI->getAssociatedExpression()->getExprLoc(), 17160 diag::note_used_here) 17161 << SI->getAssociatedExpression()->getSourceRange(); 17162 return true; 17163 } 17164 17165 // Do both expressions have the same kind? 17166 if (CI->getAssociatedExpression()->getStmtClass() != 17167 SI->getAssociatedExpression()->getStmtClass()) 17168 break; 17169 17170 // Are we dealing with different variables/fields? 17171 if (CI->getAssociatedDeclaration() != SI->getAssociatedDeclaration()) 17172 break; 17173 } 17174 // Check if the extra components of the expressions in the enclosing 17175 // data environment are redundant for the current base declaration. 17176 // If they are, the maps completely overlap, which is legal. 17177 for (; SI != SE; ++SI) { 17178 QualType Type; 17179 if (const auto *ASE = 17180 dyn_cast<ArraySubscriptExpr>(SI->getAssociatedExpression())) { 17181 Type = ASE->getBase()->IgnoreParenImpCasts()->getType(); 17182 } else if (const auto *OASE = dyn_cast<OMPArraySectionExpr>( 17183 SI->getAssociatedExpression())) { 17184 const Expr *E = OASE->getBase()->IgnoreParenImpCasts(); 17185 Type = 17186 OMPArraySectionExpr::getBaseOriginalType(E).getCanonicalType(); 17187 } else if (const auto *OASE = dyn_cast<OMPArrayShapingExpr>( 17188 SI->getAssociatedExpression())) { 17189 Type = OASE->getBase()->getType()->getPointeeType(); 17190 } 17191 if (Type.isNull() || Type->isAnyPointerType() || 17192 checkArrayExpressionDoesNotReferToWholeSize( 17193 SemaRef, SI->getAssociatedExpression(), Type)) 17194 break; 17195 } 17196 17197 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.4] 17198 // List items of map clauses in the same construct must not share 17199 // original storage. 17200 // 17201 // If the expressions are exactly the same or one is a subset of the 17202 // other, it means they are sharing storage. 17203 if (CI == CE && SI == SE) { 17204 if (CurrentRegionOnly) { 17205 if (CKind == OMPC_map) { 17206 SemaRef.Diag(ELoc, diag::err_omp_map_shared_storage) << ERange; 17207 } else { 17208 assert(CKind == OMPC_to || CKind == OMPC_from); 17209 SemaRef.Diag(ELoc, diag::err_omp_once_referenced_in_target_update) 17210 << ERange; 17211 } 17212 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here) 17213 << RE->getSourceRange(); 17214 return true; 17215 } 17216 // If we find the same expression in the enclosing data environment, 17217 // that is legal. 17218 IsEnclosedByDataEnvironmentExpr = true; 17219 return false; 17220 } 17221 17222 QualType DerivedType = 17223 std::prev(CI)->getAssociatedDeclaration()->getType(); 17224 SourceLocation DerivedLoc = 17225 std::prev(CI)->getAssociatedExpression()->getExprLoc(); 17226 17227 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1] 17228 // If the type of a list item is a reference to a type T then the type 17229 // will be considered to be T for all purposes of this clause. 17230 DerivedType = DerivedType.getNonReferenceType(); 17231 17232 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.1] 17233 // A variable for which the type is pointer and an array section 17234 // derived from that variable must not appear as list items of map 17235 // clauses of the same construct. 17236 // 17237 // Also, cover one of the cases in: 17238 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.5] 17239 // If any part of the original storage of a list item has corresponding 17240 // storage in the device data environment, all of the original storage 17241 // must have corresponding storage in the device data environment. 17242 // 17243 if (DerivedType->isAnyPointerType()) { 17244 if (CI == CE || SI == SE) { 17245 SemaRef.Diag( 17246 DerivedLoc, 17247 diag::err_omp_pointer_mapped_along_with_derived_section) 17248 << DerivedLoc; 17249 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here) 17250 << RE->getSourceRange(); 17251 return true; 17252 } 17253 if (CI->getAssociatedExpression()->getStmtClass() != 17254 SI->getAssociatedExpression()->getStmtClass() || 17255 CI->getAssociatedDeclaration()->getCanonicalDecl() == 17256 SI->getAssociatedDeclaration()->getCanonicalDecl()) { 17257 assert(CI != CE && SI != SE); 17258 SemaRef.Diag(DerivedLoc, diag::err_omp_same_pointer_dereferenced) 17259 << DerivedLoc; 17260 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here) 17261 << RE->getSourceRange(); 17262 return true; 17263 } 17264 } 17265 17266 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.4] 17267 // List items of map clauses in the same construct must not share 17268 // original storage. 17269 // 17270 // An expression is a subset of the other. 17271 if (CurrentRegionOnly && (CI == CE || SI == SE)) { 17272 if (CKind == OMPC_map) { 17273 if (CI != CE || SI != SE) { 17274 // Allow constructs like this: map(s, s.ptr[0:1]), where s.ptr is 17275 // a pointer. 17276 auto Begin = 17277 CI != CE ? CurComponents.begin() : StackComponents.begin(); 17278 auto End = CI != CE ? CurComponents.end() : StackComponents.end(); 17279 auto It = Begin; 17280 while (It != End && !It->getAssociatedDeclaration()) 17281 std::advance(It, 1); 17282 assert(It != End && 17283 "Expected at least one component with the declaration."); 17284 if (It != Begin && It->getAssociatedDeclaration() 17285 ->getType() 17286 .getCanonicalType() 17287 ->isAnyPointerType()) { 17288 IsEnclosedByDataEnvironmentExpr = false; 17289 EnclosingExpr = nullptr; 17290 return false; 17291 } 17292 } 17293 SemaRef.Diag(ELoc, diag::err_omp_map_shared_storage) << ERange; 17294 } else { 17295 assert(CKind == OMPC_to || CKind == OMPC_from); 17296 SemaRef.Diag(ELoc, diag::err_omp_once_referenced_in_target_update) 17297 << ERange; 17298 } 17299 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here) 17300 << RE->getSourceRange(); 17301 return true; 17302 } 17303 17304 // The current expression uses the same base as other expression in the 17305 // data environment but does not contain it completely. 17306 if (!CurrentRegionOnly && SI != SE) 17307 EnclosingExpr = RE; 17308 17309 // The current expression is a subset of the expression in the data 17310 // environment. 17311 IsEnclosedByDataEnvironmentExpr |= 17312 (!CurrentRegionOnly && CI != CE && SI == SE); 17313 17314 return false; 17315 }); 17316 17317 if (CurrentRegionOnly) 17318 return FoundError; 17319 17320 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.5] 17321 // If any part of the original storage of a list item has corresponding 17322 // storage in the device data environment, all of the original storage must 17323 // have corresponding storage in the device data environment. 17324 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.6] 17325 // If a list item is an element of a structure, and a different element of 17326 // the structure has a corresponding list item in the device data environment 17327 // prior to a task encountering the construct associated with the map clause, 17328 // then the list item must also have a corresponding list item in the device 17329 // data environment prior to the task encountering the construct. 17330 // 17331 if (EnclosingExpr && !IsEnclosedByDataEnvironmentExpr) { 17332 SemaRef.Diag(ELoc, 17333 diag::err_omp_original_storage_is_shared_and_does_not_contain) 17334 << ERange; 17335 SemaRef.Diag(EnclosingExpr->getExprLoc(), diag::note_used_here) 17336 << EnclosingExpr->getSourceRange(); 17337 return true; 17338 } 17339 17340 return FoundError; 17341 } 17342 17343 // Look up the user-defined mapper given the mapper name and mapped type, and 17344 // build a reference to it. 17345 static ExprResult buildUserDefinedMapperRef(Sema &SemaRef, Scope *S, 17346 CXXScopeSpec &MapperIdScopeSpec, 17347 const DeclarationNameInfo &MapperId, 17348 QualType Type, 17349 Expr *UnresolvedMapper) { 17350 if (MapperIdScopeSpec.isInvalid()) 17351 return ExprError(); 17352 // Get the actual type for the array type. 17353 if (Type->isArrayType()) { 17354 assert(Type->getAsArrayTypeUnsafe() && "Expect to get a valid array type"); 17355 Type = Type->getAsArrayTypeUnsafe()->getElementType().getCanonicalType(); 17356 } 17357 // Find all user-defined mappers with the given MapperId. 17358 SmallVector<UnresolvedSet<8>, 4> Lookups; 17359 LookupResult Lookup(SemaRef, MapperId, Sema::LookupOMPMapperName); 17360 Lookup.suppressDiagnostics(); 17361 if (S) { 17362 while (S && SemaRef.LookupParsedName(Lookup, S, &MapperIdScopeSpec)) { 17363 NamedDecl *D = Lookup.getRepresentativeDecl(); 17364 while (S && !S->isDeclScope(D)) 17365 S = S->getParent(); 17366 if (S) 17367 S = S->getParent(); 17368 Lookups.emplace_back(); 17369 Lookups.back().append(Lookup.begin(), Lookup.end()); 17370 Lookup.clear(); 17371 } 17372 } else if (auto *ULE = cast_or_null<UnresolvedLookupExpr>(UnresolvedMapper)) { 17373 // Extract the user-defined mappers with the given MapperId. 17374 Lookups.push_back(UnresolvedSet<8>()); 17375 for (NamedDecl *D : ULE->decls()) { 17376 auto *DMD = cast<OMPDeclareMapperDecl>(D); 17377 assert(DMD && "Expect valid OMPDeclareMapperDecl during instantiation."); 17378 Lookups.back().addDecl(DMD); 17379 } 17380 } 17381 // Defer the lookup for dependent types. The results will be passed through 17382 // UnresolvedMapper on instantiation. 17383 if (SemaRef.CurContext->isDependentContext() || Type->isDependentType() || 17384 Type->isInstantiationDependentType() || 17385 Type->containsUnexpandedParameterPack() || 17386 filterLookupForUDReductionAndMapper<bool>(Lookups, [](ValueDecl *D) { 17387 return !D->isInvalidDecl() && 17388 (D->getType()->isDependentType() || 17389 D->getType()->isInstantiationDependentType() || 17390 D->getType()->containsUnexpandedParameterPack()); 17391 })) { 17392 UnresolvedSet<8> URS; 17393 for (const UnresolvedSet<8> &Set : Lookups) { 17394 if (Set.empty()) 17395 continue; 17396 URS.append(Set.begin(), Set.end()); 17397 } 17398 return UnresolvedLookupExpr::Create( 17399 SemaRef.Context, /*NamingClass=*/nullptr, 17400 MapperIdScopeSpec.getWithLocInContext(SemaRef.Context), MapperId, 17401 /*ADL=*/false, /*Overloaded=*/true, URS.begin(), URS.end()); 17402 } 17403 SourceLocation Loc = MapperId.getLoc(); 17404 // [OpenMP 5.0], 2.19.7.3 declare mapper Directive, Restrictions 17405 // The type must be of struct, union or class type in C and C++ 17406 if (!Type->isStructureOrClassType() && !Type->isUnionType() && 17407 (MapperIdScopeSpec.isSet() || MapperId.getAsString() != "default")) { 17408 SemaRef.Diag(Loc, diag::err_omp_mapper_wrong_type); 17409 return ExprError(); 17410 } 17411 // Perform argument dependent lookup. 17412 if (SemaRef.getLangOpts().CPlusPlus && !MapperIdScopeSpec.isSet()) 17413 argumentDependentLookup(SemaRef, MapperId, Loc, Type, Lookups); 17414 // Return the first user-defined mapper with the desired type. 17415 if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>( 17416 Lookups, [&SemaRef, Type](ValueDecl *D) -> ValueDecl * { 17417 if (!D->isInvalidDecl() && 17418 SemaRef.Context.hasSameType(D->getType(), Type)) 17419 return D; 17420 return nullptr; 17421 })) 17422 return SemaRef.BuildDeclRefExpr(VD, Type, VK_LValue, Loc); 17423 // Find the first user-defined mapper with a type derived from the desired 17424 // type. 17425 if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>( 17426 Lookups, [&SemaRef, Type, Loc](ValueDecl *D) -> ValueDecl * { 17427 if (!D->isInvalidDecl() && 17428 SemaRef.IsDerivedFrom(Loc, Type, D->getType()) && 17429 !Type.isMoreQualifiedThan(D->getType())) 17430 return D; 17431 return nullptr; 17432 })) { 17433 CXXBasePaths Paths(/*FindAmbiguities=*/true, /*RecordPaths=*/true, 17434 /*DetectVirtual=*/false); 17435 if (SemaRef.IsDerivedFrom(Loc, Type, VD->getType(), Paths)) { 17436 if (!Paths.isAmbiguous(SemaRef.Context.getCanonicalType( 17437 VD->getType().getUnqualifiedType()))) { 17438 if (SemaRef.CheckBaseClassAccess( 17439 Loc, VD->getType(), Type, Paths.front(), 17440 /*DiagID=*/0) != Sema::AR_inaccessible) { 17441 return SemaRef.BuildDeclRefExpr(VD, Type, VK_LValue, Loc); 17442 } 17443 } 17444 } 17445 } 17446 // Report error if a mapper is specified, but cannot be found. 17447 if (MapperIdScopeSpec.isSet() || MapperId.getAsString() != "default") { 17448 SemaRef.Diag(Loc, diag::err_omp_invalid_mapper) 17449 << Type << MapperId.getName(); 17450 return ExprError(); 17451 } 17452 return ExprEmpty(); 17453 } 17454 17455 namespace { 17456 // Utility struct that gathers all the related lists associated with a mappable 17457 // expression. 17458 struct MappableVarListInfo { 17459 // The list of expressions. 17460 ArrayRef<Expr *> VarList; 17461 // The list of processed expressions. 17462 SmallVector<Expr *, 16> ProcessedVarList; 17463 // The mappble components for each expression. 17464 OMPClauseMappableExprCommon::MappableExprComponentLists VarComponents; 17465 // The base declaration of the variable. 17466 SmallVector<ValueDecl *, 16> VarBaseDeclarations; 17467 // The reference to the user-defined mapper associated with every expression. 17468 SmallVector<Expr *, 16> UDMapperList; 17469 17470 MappableVarListInfo(ArrayRef<Expr *> VarList) : VarList(VarList) { 17471 // We have a list of components and base declarations for each entry in the 17472 // variable list. 17473 VarComponents.reserve(VarList.size()); 17474 VarBaseDeclarations.reserve(VarList.size()); 17475 } 17476 }; 17477 } 17478 17479 // Check the validity of the provided variable list for the provided clause kind 17480 // \a CKind. In the check process the valid expressions, mappable expression 17481 // components, variables, and user-defined mappers are extracted and used to 17482 // fill \a ProcessedVarList, \a VarComponents, \a VarBaseDeclarations, and \a 17483 // UDMapperList in MVLI. \a MapType, \a IsMapTypeImplicit, \a MapperIdScopeSpec, 17484 // and \a MapperId are expected to be valid if the clause kind is 'map'. 17485 static void checkMappableExpressionList( 17486 Sema &SemaRef, DSAStackTy *DSAS, OpenMPClauseKind CKind, 17487 MappableVarListInfo &MVLI, SourceLocation StartLoc, 17488 CXXScopeSpec &MapperIdScopeSpec, DeclarationNameInfo MapperId, 17489 ArrayRef<Expr *> UnresolvedMappers, 17490 OpenMPMapClauseKind MapType = OMPC_MAP_unknown, 17491 bool IsMapTypeImplicit = false) { 17492 // We only expect mappable expressions in 'to', 'from', and 'map' clauses. 17493 assert((CKind == OMPC_map || CKind == OMPC_to || CKind == OMPC_from) && 17494 "Unexpected clause kind with mappable expressions!"); 17495 17496 // If the identifier of user-defined mapper is not specified, it is "default". 17497 // We do not change the actual name in this clause to distinguish whether a 17498 // mapper is specified explicitly, i.e., it is not explicitly specified when 17499 // MapperId.getName() is empty. 17500 if (!MapperId.getName() || MapperId.getName().isEmpty()) { 17501 auto &DeclNames = SemaRef.getASTContext().DeclarationNames; 17502 MapperId.setName(DeclNames.getIdentifier( 17503 &SemaRef.getASTContext().Idents.get("default"))); 17504 } 17505 17506 // Iterators to find the current unresolved mapper expression. 17507 auto UMIt = UnresolvedMappers.begin(), UMEnd = UnresolvedMappers.end(); 17508 bool UpdateUMIt = false; 17509 Expr *UnresolvedMapper = nullptr; 17510 17511 // Keep track of the mappable components and base declarations in this clause. 17512 // Each entry in the list is going to have a list of components associated. We 17513 // record each set of the components so that we can build the clause later on. 17514 // In the end we should have the same amount of declarations and component 17515 // lists. 17516 17517 for (Expr *RE : MVLI.VarList) { 17518 assert(RE && "Null expr in omp to/from/map clause"); 17519 SourceLocation ELoc = RE->getExprLoc(); 17520 17521 // Find the current unresolved mapper expression. 17522 if (UpdateUMIt && UMIt != UMEnd) { 17523 UMIt++; 17524 assert( 17525 UMIt != UMEnd && 17526 "Expect the size of UnresolvedMappers to match with that of VarList"); 17527 } 17528 UpdateUMIt = true; 17529 if (UMIt != UMEnd) 17530 UnresolvedMapper = *UMIt; 17531 17532 const Expr *VE = RE->IgnoreParenLValueCasts(); 17533 17534 if (VE->isValueDependent() || VE->isTypeDependent() || 17535 VE->isInstantiationDependent() || 17536 VE->containsUnexpandedParameterPack()) { 17537 // Try to find the associated user-defined mapper. 17538 ExprResult ER = buildUserDefinedMapperRef( 17539 SemaRef, DSAS->getCurScope(), MapperIdScopeSpec, MapperId, 17540 VE->getType().getCanonicalType(), UnresolvedMapper); 17541 if (ER.isInvalid()) 17542 continue; 17543 MVLI.UDMapperList.push_back(ER.get()); 17544 // We can only analyze this information once the missing information is 17545 // resolved. 17546 MVLI.ProcessedVarList.push_back(RE); 17547 continue; 17548 } 17549 17550 Expr *SimpleExpr = RE->IgnoreParenCasts(); 17551 17552 if (!RE->isLValue()) { 17553 if (SemaRef.getLangOpts().OpenMP < 50) { 17554 SemaRef.Diag( 17555 ELoc, diag::err_omp_expected_named_var_member_or_array_expression) 17556 << RE->getSourceRange(); 17557 } else { 17558 SemaRef.Diag(ELoc, diag::err_omp_non_lvalue_in_map_or_motion_clauses) 17559 << getOpenMPClauseName(CKind) << RE->getSourceRange(); 17560 } 17561 continue; 17562 } 17563 17564 OMPClauseMappableExprCommon::MappableExprComponentList CurComponents; 17565 ValueDecl *CurDeclaration = nullptr; 17566 17567 // Obtain the array or member expression bases if required. Also, fill the 17568 // components array with all the components identified in the process. 17569 const Expr *BE = checkMapClauseExpressionBase( 17570 SemaRef, SimpleExpr, CurComponents, CKind, /*NoDiagnose=*/false); 17571 if (!BE) 17572 continue; 17573 17574 assert(!CurComponents.empty() && 17575 "Invalid mappable expression information."); 17576 17577 if (const auto *TE = dyn_cast<CXXThisExpr>(BE)) { 17578 // Add store "this" pointer to class in DSAStackTy for future checking 17579 DSAS->addMappedClassesQualTypes(TE->getType()); 17580 // Try to find the associated user-defined mapper. 17581 ExprResult ER = buildUserDefinedMapperRef( 17582 SemaRef, DSAS->getCurScope(), MapperIdScopeSpec, MapperId, 17583 VE->getType().getCanonicalType(), UnresolvedMapper); 17584 if (ER.isInvalid()) 17585 continue; 17586 MVLI.UDMapperList.push_back(ER.get()); 17587 // Skip restriction checking for variable or field declarations 17588 MVLI.ProcessedVarList.push_back(RE); 17589 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1); 17590 MVLI.VarComponents.back().append(CurComponents.begin(), 17591 CurComponents.end()); 17592 MVLI.VarBaseDeclarations.push_back(nullptr); 17593 continue; 17594 } 17595 17596 // For the following checks, we rely on the base declaration which is 17597 // expected to be associated with the last component. The declaration is 17598 // expected to be a variable or a field (if 'this' is being mapped). 17599 CurDeclaration = CurComponents.back().getAssociatedDeclaration(); 17600 assert(CurDeclaration && "Null decl on map clause."); 17601 assert( 17602 CurDeclaration->isCanonicalDecl() && 17603 "Expecting components to have associated only canonical declarations."); 17604 17605 auto *VD = dyn_cast<VarDecl>(CurDeclaration); 17606 const auto *FD = dyn_cast<FieldDecl>(CurDeclaration); 17607 17608 assert((VD || FD) && "Only variables or fields are expected here!"); 17609 (void)FD; 17610 17611 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.10] 17612 // threadprivate variables cannot appear in a map clause. 17613 // OpenMP 4.5 [2.10.5, target update Construct] 17614 // threadprivate variables cannot appear in a from clause. 17615 if (VD && DSAS->isThreadPrivate(VD)) { 17616 DSAStackTy::DSAVarData DVar = DSAS->getTopDSA(VD, /*FromParent=*/false); 17617 SemaRef.Diag(ELoc, diag::err_omp_threadprivate_in_clause) 17618 << getOpenMPClauseName(CKind); 17619 reportOriginalDsa(SemaRef, DSAS, VD, DVar); 17620 continue; 17621 } 17622 17623 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.9] 17624 // A list item cannot appear in both a map clause and a data-sharing 17625 // attribute clause on the same construct. 17626 17627 // Check conflicts with other map clause expressions. We check the conflicts 17628 // with the current construct separately from the enclosing data 17629 // environment, because the restrictions are different. We only have to 17630 // check conflicts across regions for the map clauses. 17631 if (checkMapConflicts(SemaRef, DSAS, CurDeclaration, SimpleExpr, 17632 /*CurrentRegionOnly=*/true, CurComponents, CKind)) 17633 break; 17634 if (CKind == OMPC_map && 17635 (SemaRef.getLangOpts().OpenMP <= 45 || StartLoc.isValid()) && 17636 checkMapConflicts(SemaRef, DSAS, CurDeclaration, SimpleExpr, 17637 /*CurrentRegionOnly=*/false, CurComponents, CKind)) 17638 break; 17639 17640 // OpenMP 4.5 [2.10.5, target update Construct] 17641 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1] 17642 // If the type of a list item is a reference to a type T then the type will 17643 // be considered to be T for all purposes of this clause. 17644 auto I = llvm::find_if( 17645 CurComponents, 17646 [](const OMPClauseMappableExprCommon::MappableComponent &MC) { 17647 return MC.getAssociatedDeclaration(); 17648 }); 17649 assert(I != CurComponents.end() && "Null decl on map clause."); 17650 QualType Type; 17651 auto *ASE = dyn_cast<ArraySubscriptExpr>(VE->IgnoreParens()); 17652 auto *OASE = dyn_cast<OMPArraySectionExpr>(VE->IgnoreParens()); 17653 auto *OAShE = dyn_cast<OMPArrayShapingExpr>(VE->IgnoreParens()); 17654 if (ASE) { 17655 Type = ASE->getType().getNonReferenceType(); 17656 } else if (OASE) { 17657 QualType BaseType = 17658 OMPArraySectionExpr::getBaseOriginalType(OASE->getBase()); 17659 if (const auto *ATy = BaseType->getAsArrayTypeUnsafe()) 17660 Type = ATy->getElementType(); 17661 else 17662 Type = BaseType->getPointeeType(); 17663 Type = Type.getNonReferenceType(); 17664 } else if (OAShE) { 17665 Type = OAShE->getBase()->getType()->getPointeeType(); 17666 } else { 17667 Type = VE->getType(); 17668 } 17669 17670 // OpenMP 4.5 [2.10.5, target update Construct, Restrictions, p.4] 17671 // A list item in a to or from clause must have a mappable type. 17672 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.9] 17673 // A list item must have a mappable type. 17674 if (!checkTypeMappable(VE->getExprLoc(), VE->getSourceRange(), SemaRef, 17675 DSAS, Type)) 17676 continue; 17677 17678 Type = I->getAssociatedDeclaration()->getType().getNonReferenceType(); 17679 17680 if (CKind == OMPC_map) { 17681 // target enter data 17682 // OpenMP [2.10.2, Restrictions, p. 99] 17683 // A map-type must be specified in all map clauses and must be either 17684 // to or alloc. 17685 OpenMPDirectiveKind DKind = DSAS->getCurrentDirective(); 17686 if (DKind == OMPD_target_enter_data && 17687 !(MapType == OMPC_MAP_to || MapType == OMPC_MAP_alloc)) { 17688 SemaRef.Diag(StartLoc, diag::err_omp_invalid_map_type_for_directive) 17689 << (IsMapTypeImplicit ? 1 : 0) 17690 << getOpenMPSimpleClauseTypeName(OMPC_map, MapType) 17691 << getOpenMPDirectiveName(DKind); 17692 continue; 17693 } 17694 17695 // target exit_data 17696 // OpenMP [2.10.3, Restrictions, p. 102] 17697 // A map-type must be specified in all map clauses and must be either 17698 // from, release, or delete. 17699 if (DKind == OMPD_target_exit_data && 17700 !(MapType == OMPC_MAP_from || MapType == OMPC_MAP_release || 17701 MapType == OMPC_MAP_delete)) { 17702 SemaRef.Diag(StartLoc, diag::err_omp_invalid_map_type_for_directive) 17703 << (IsMapTypeImplicit ? 1 : 0) 17704 << getOpenMPSimpleClauseTypeName(OMPC_map, MapType) 17705 << getOpenMPDirectiveName(DKind); 17706 continue; 17707 } 17708 17709 // target, target data 17710 // OpenMP 5.0 [2.12.2, Restrictions, p. 163] 17711 // OpenMP 5.0 [2.12.5, Restrictions, p. 174] 17712 // A map-type in a map clause must be to, from, tofrom or alloc 17713 if ((DKind == OMPD_target_data || 17714 isOpenMPTargetExecutionDirective(DKind)) && 17715 !(MapType == OMPC_MAP_to || MapType == OMPC_MAP_from || 17716 MapType == OMPC_MAP_tofrom || MapType == OMPC_MAP_alloc)) { 17717 SemaRef.Diag(StartLoc, diag::err_omp_invalid_map_type_for_directive) 17718 << (IsMapTypeImplicit ? 1 : 0) 17719 << getOpenMPSimpleClauseTypeName(OMPC_map, MapType) 17720 << getOpenMPDirectiveName(DKind); 17721 continue; 17722 } 17723 17724 // OpenMP 4.5 [2.15.5.1, Restrictions, p.3] 17725 // A list item cannot appear in both a map clause and a data-sharing 17726 // attribute clause on the same construct 17727 // 17728 // OpenMP 5.0 [2.19.7.1, Restrictions, p.7] 17729 // A list item cannot appear in both a map clause and a data-sharing 17730 // attribute clause on the same construct unless the construct is a 17731 // combined construct. 17732 if (VD && ((SemaRef.LangOpts.OpenMP <= 45 && 17733 isOpenMPTargetExecutionDirective(DKind)) || 17734 DKind == OMPD_target)) { 17735 DSAStackTy::DSAVarData DVar = DSAS->getTopDSA(VD, /*FromParent=*/false); 17736 if (isOpenMPPrivate(DVar.CKind)) { 17737 SemaRef.Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa) 17738 << getOpenMPClauseName(DVar.CKind) 17739 << getOpenMPClauseName(OMPC_map) 17740 << getOpenMPDirectiveName(DSAS->getCurrentDirective()); 17741 reportOriginalDsa(SemaRef, DSAS, CurDeclaration, DVar); 17742 continue; 17743 } 17744 } 17745 } 17746 17747 // Try to find the associated user-defined mapper. 17748 ExprResult ER = buildUserDefinedMapperRef( 17749 SemaRef, DSAS->getCurScope(), MapperIdScopeSpec, MapperId, 17750 Type.getCanonicalType(), UnresolvedMapper); 17751 if (ER.isInvalid()) 17752 continue; 17753 MVLI.UDMapperList.push_back(ER.get()); 17754 17755 // Save the current expression. 17756 MVLI.ProcessedVarList.push_back(RE); 17757 17758 // Store the components in the stack so that they can be used to check 17759 // against other clauses later on. 17760 DSAS->addMappableExpressionComponents(CurDeclaration, CurComponents, 17761 /*WhereFoundClauseKind=*/OMPC_map); 17762 17763 // Save the components and declaration to create the clause. For purposes of 17764 // the clause creation, any component list that has has base 'this' uses 17765 // null as base declaration. 17766 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1); 17767 MVLI.VarComponents.back().append(CurComponents.begin(), 17768 CurComponents.end()); 17769 MVLI.VarBaseDeclarations.push_back(isa<MemberExpr>(BE) ? nullptr 17770 : CurDeclaration); 17771 } 17772 } 17773 17774 OMPClause *Sema::ActOnOpenMPMapClause( 17775 ArrayRef<OpenMPMapModifierKind> MapTypeModifiers, 17776 ArrayRef<SourceLocation> MapTypeModifiersLoc, 17777 CXXScopeSpec &MapperIdScopeSpec, DeclarationNameInfo &MapperId, 17778 OpenMPMapClauseKind MapType, bool IsMapTypeImplicit, SourceLocation MapLoc, 17779 SourceLocation ColonLoc, ArrayRef<Expr *> VarList, 17780 const OMPVarListLocTy &Locs, ArrayRef<Expr *> UnresolvedMappers) { 17781 OpenMPMapModifierKind Modifiers[] = { 17782 OMPC_MAP_MODIFIER_unknown, OMPC_MAP_MODIFIER_unknown, 17783 OMPC_MAP_MODIFIER_unknown, OMPC_MAP_MODIFIER_unknown}; 17784 SourceLocation ModifiersLoc[NumberOfOMPMapClauseModifiers]; 17785 17786 // Process map-type-modifiers, flag errors for duplicate modifiers. 17787 unsigned Count = 0; 17788 for (unsigned I = 0, E = MapTypeModifiers.size(); I < E; ++I) { 17789 if (MapTypeModifiers[I] != OMPC_MAP_MODIFIER_unknown && 17790 llvm::find(Modifiers, MapTypeModifiers[I]) != std::end(Modifiers)) { 17791 Diag(MapTypeModifiersLoc[I], diag::err_omp_duplicate_map_type_modifier); 17792 continue; 17793 } 17794 assert(Count < NumberOfOMPMapClauseModifiers && 17795 "Modifiers exceed the allowed number of map type modifiers"); 17796 Modifiers[Count] = MapTypeModifiers[I]; 17797 ModifiersLoc[Count] = MapTypeModifiersLoc[I]; 17798 ++Count; 17799 } 17800 17801 MappableVarListInfo MVLI(VarList); 17802 checkMappableExpressionList(*this, DSAStack, OMPC_map, MVLI, Locs.StartLoc, 17803 MapperIdScopeSpec, MapperId, UnresolvedMappers, 17804 MapType, IsMapTypeImplicit); 17805 17806 // We need to produce a map clause even if we don't have variables so that 17807 // other diagnostics related with non-existing map clauses are accurate. 17808 return OMPMapClause::Create(Context, Locs, MVLI.ProcessedVarList, 17809 MVLI.VarBaseDeclarations, MVLI.VarComponents, 17810 MVLI.UDMapperList, Modifiers, ModifiersLoc, 17811 MapperIdScopeSpec.getWithLocInContext(Context), 17812 MapperId, MapType, IsMapTypeImplicit, MapLoc); 17813 } 17814 17815 QualType Sema::ActOnOpenMPDeclareReductionType(SourceLocation TyLoc, 17816 TypeResult ParsedType) { 17817 assert(ParsedType.isUsable()); 17818 17819 QualType ReductionType = GetTypeFromParser(ParsedType.get()); 17820 if (ReductionType.isNull()) 17821 return QualType(); 17822 17823 // [OpenMP 4.0], 2.15 declare reduction Directive, Restrictions, C\C++ 17824 // A type name in a declare reduction directive cannot be a function type, an 17825 // array type, a reference type, or a type qualified with const, volatile or 17826 // restrict. 17827 if (ReductionType.hasQualifiers()) { 17828 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 0; 17829 return QualType(); 17830 } 17831 17832 if (ReductionType->isFunctionType()) { 17833 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 1; 17834 return QualType(); 17835 } 17836 if (ReductionType->isReferenceType()) { 17837 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 2; 17838 return QualType(); 17839 } 17840 if (ReductionType->isArrayType()) { 17841 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 3; 17842 return QualType(); 17843 } 17844 return ReductionType; 17845 } 17846 17847 Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareReductionDirectiveStart( 17848 Scope *S, DeclContext *DC, DeclarationName Name, 17849 ArrayRef<std::pair<QualType, SourceLocation>> ReductionTypes, 17850 AccessSpecifier AS, Decl *PrevDeclInScope) { 17851 SmallVector<Decl *, 8> Decls; 17852 Decls.reserve(ReductionTypes.size()); 17853 17854 LookupResult Lookup(*this, Name, SourceLocation(), LookupOMPReductionName, 17855 forRedeclarationInCurContext()); 17856 // [OpenMP 4.0], 2.15 declare reduction Directive, Restrictions 17857 // A reduction-identifier may not be re-declared in the current scope for the 17858 // same type or for a type that is compatible according to the base language 17859 // rules. 17860 llvm::DenseMap<QualType, SourceLocation> PreviousRedeclTypes; 17861 OMPDeclareReductionDecl *PrevDRD = nullptr; 17862 bool InCompoundScope = true; 17863 if (S != nullptr) { 17864 // Find previous declaration with the same name not referenced in other 17865 // declarations. 17866 FunctionScopeInfo *ParentFn = getEnclosingFunction(); 17867 InCompoundScope = 17868 (ParentFn != nullptr) && !ParentFn->CompoundScopes.empty(); 17869 LookupName(Lookup, S); 17870 FilterLookupForScope(Lookup, DC, S, /*ConsiderLinkage=*/false, 17871 /*AllowInlineNamespace=*/false); 17872 llvm::DenseMap<OMPDeclareReductionDecl *, bool> UsedAsPrevious; 17873 LookupResult::Filter Filter = Lookup.makeFilter(); 17874 while (Filter.hasNext()) { 17875 auto *PrevDecl = cast<OMPDeclareReductionDecl>(Filter.next()); 17876 if (InCompoundScope) { 17877 auto I = UsedAsPrevious.find(PrevDecl); 17878 if (I == UsedAsPrevious.end()) 17879 UsedAsPrevious[PrevDecl] = false; 17880 if (OMPDeclareReductionDecl *D = PrevDecl->getPrevDeclInScope()) 17881 UsedAsPrevious[D] = true; 17882 } 17883 PreviousRedeclTypes[PrevDecl->getType().getCanonicalType()] = 17884 PrevDecl->getLocation(); 17885 } 17886 Filter.done(); 17887 if (InCompoundScope) { 17888 for (const auto &PrevData : UsedAsPrevious) { 17889 if (!PrevData.second) { 17890 PrevDRD = PrevData.first; 17891 break; 17892 } 17893 } 17894 } 17895 } else if (PrevDeclInScope != nullptr) { 17896 auto *PrevDRDInScope = PrevDRD = 17897 cast<OMPDeclareReductionDecl>(PrevDeclInScope); 17898 do { 17899 PreviousRedeclTypes[PrevDRDInScope->getType().getCanonicalType()] = 17900 PrevDRDInScope->getLocation(); 17901 PrevDRDInScope = PrevDRDInScope->getPrevDeclInScope(); 17902 } while (PrevDRDInScope != nullptr); 17903 } 17904 for (const auto &TyData : ReductionTypes) { 17905 const auto I = PreviousRedeclTypes.find(TyData.first.getCanonicalType()); 17906 bool Invalid = false; 17907 if (I != PreviousRedeclTypes.end()) { 17908 Diag(TyData.second, diag::err_omp_declare_reduction_redefinition) 17909 << TyData.first; 17910 Diag(I->second, diag::note_previous_definition); 17911 Invalid = true; 17912 } 17913 PreviousRedeclTypes[TyData.first.getCanonicalType()] = TyData.second; 17914 auto *DRD = OMPDeclareReductionDecl::Create(Context, DC, TyData.second, 17915 Name, TyData.first, PrevDRD); 17916 DC->addDecl(DRD); 17917 DRD->setAccess(AS); 17918 Decls.push_back(DRD); 17919 if (Invalid) 17920 DRD->setInvalidDecl(); 17921 else 17922 PrevDRD = DRD; 17923 } 17924 17925 return DeclGroupPtrTy::make( 17926 DeclGroupRef::Create(Context, Decls.begin(), Decls.size())); 17927 } 17928 17929 void Sema::ActOnOpenMPDeclareReductionCombinerStart(Scope *S, Decl *D) { 17930 auto *DRD = cast<OMPDeclareReductionDecl>(D); 17931 17932 // Enter new function scope. 17933 PushFunctionScope(); 17934 setFunctionHasBranchProtectedScope(); 17935 getCurFunction()->setHasOMPDeclareReductionCombiner(); 17936 17937 if (S != nullptr) 17938 PushDeclContext(S, DRD); 17939 else 17940 CurContext = DRD; 17941 17942 PushExpressionEvaluationContext( 17943 ExpressionEvaluationContext::PotentiallyEvaluated); 17944 17945 QualType ReductionType = DRD->getType(); 17946 // Create 'T* omp_parm;T omp_in;'. All references to 'omp_in' will 17947 // be replaced by '*omp_parm' during codegen. This required because 'omp_in' 17948 // uses semantics of argument handles by value, but it should be passed by 17949 // reference. C lang does not support references, so pass all parameters as 17950 // pointers. 17951 // Create 'T omp_in;' variable. 17952 VarDecl *OmpInParm = 17953 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_in"); 17954 // Create 'T* omp_parm;T omp_out;'. All references to 'omp_out' will 17955 // be replaced by '*omp_parm' during codegen. This required because 'omp_out' 17956 // uses semantics of argument handles by value, but it should be passed by 17957 // reference. C lang does not support references, so pass all parameters as 17958 // pointers. 17959 // Create 'T omp_out;' variable. 17960 VarDecl *OmpOutParm = 17961 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_out"); 17962 if (S != nullptr) { 17963 PushOnScopeChains(OmpInParm, S); 17964 PushOnScopeChains(OmpOutParm, S); 17965 } else { 17966 DRD->addDecl(OmpInParm); 17967 DRD->addDecl(OmpOutParm); 17968 } 17969 Expr *InE = 17970 ::buildDeclRefExpr(*this, OmpInParm, ReductionType, D->getLocation()); 17971 Expr *OutE = 17972 ::buildDeclRefExpr(*this, OmpOutParm, ReductionType, D->getLocation()); 17973 DRD->setCombinerData(InE, OutE); 17974 } 17975 17976 void Sema::ActOnOpenMPDeclareReductionCombinerEnd(Decl *D, Expr *Combiner) { 17977 auto *DRD = cast<OMPDeclareReductionDecl>(D); 17978 DiscardCleanupsInEvaluationContext(); 17979 PopExpressionEvaluationContext(); 17980 17981 PopDeclContext(); 17982 PopFunctionScopeInfo(); 17983 17984 if (Combiner != nullptr) 17985 DRD->setCombiner(Combiner); 17986 else 17987 DRD->setInvalidDecl(); 17988 } 17989 17990 VarDecl *Sema::ActOnOpenMPDeclareReductionInitializerStart(Scope *S, Decl *D) { 17991 auto *DRD = cast<OMPDeclareReductionDecl>(D); 17992 17993 // Enter new function scope. 17994 PushFunctionScope(); 17995 setFunctionHasBranchProtectedScope(); 17996 17997 if (S != nullptr) 17998 PushDeclContext(S, DRD); 17999 else 18000 CurContext = DRD; 18001 18002 PushExpressionEvaluationContext( 18003 ExpressionEvaluationContext::PotentiallyEvaluated); 18004 18005 QualType ReductionType = DRD->getType(); 18006 // Create 'T* omp_parm;T omp_priv;'. All references to 'omp_priv' will 18007 // be replaced by '*omp_parm' during codegen. This required because 'omp_priv' 18008 // uses semantics of argument handles by value, but it should be passed by 18009 // reference. C lang does not support references, so pass all parameters as 18010 // pointers. 18011 // Create 'T omp_priv;' variable. 18012 VarDecl *OmpPrivParm = 18013 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_priv"); 18014 // Create 'T* omp_parm;T omp_orig;'. All references to 'omp_orig' will 18015 // be replaced by '*omp_parm' during codegen. This required because 'omp_orig' 18016 // uses semantics of argument handles by value, but it should be passed by 18017 // reference. C lang does not support references, so pass all parameters as 18018 // pointers. 18019 // Create 'T omp_orig;' variable. 18020 VarDecl *OmpOrigParm = 18021 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_orig"); 18022 if (S != nullptr) { 18023 PushOnScopeChains(OmpPrivParm, S); 18024 PushOnScopeChains(OmpOrigParm, S); 18025 } else { 18026 DRD->addDecl(OmpPrivParm); 18027 DRD->addDecl(OmpOrigParm); 18028 } 18029 Expr *OrigE = 18030 ::buildDeclRefExpr(*this, OmpOrigParm, ReductionType, D->getLocation()); 18031 Expr *PrivE = 18032 ::buildDeclRefExpr(*this, OmpPrivParm, ReductionType, D->getLocation()); 18033 DRD->setInitializerData(OrigE, PrivE); 18034 return OmpPrivParm; 18035 } 18036 18037 void Sema::ActOnOpenMPDeclareReductionInitializerEnd(Decl *D, Expr *Initializer, 18038 VarDecl *OmpPrivParm) { 18039 auto *DRD = cast<OMPDeclareReductionDecl>(D); 18040 DiscardCleanupsInEvaluationContext(); 18041 PopExpressionEvaluationContext(); 18042 18043 PopDeclContext(); 18044 PopFunctionScopeInfo(); 18045 18046 if (Initializer != nullptr) { 18047 DRD->setInitializer(Initializer, OMPDeclareReductionDecl::CallInit); 18048 } else if (OmpPrivParm->hasInit()) { 18049 DRD->setInitializer(OmpPrivParm->getInit(), 18050 OmpPrivParm->isDirectInit() 18051 ? OMPDeclareReductionDecl::DirectInit 18052 : OMPDeclareReductionDecl::CopyInit); 18053 } else { 18054 DRD->setInvalidDecl(); 18055 } 18056 } 18057 18058 Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareReductionDirectiveEnd( 18059 Scope *S, DeclGroupPtrTy DeclReductions, bool IsValid) { 18060 for (Decl *D : DeclReductions.get()) { 18061 if (IsValid) { 18062 if (S) 18063 PushOnScopeChains(cast<OMPDeclareReductionDecl>(D), S, 18064 /*AddToContext=*/false); 18065 } else { 18066 D->setInvalidDecl(); 18067 } 18068 } 18069 return DeclReductions; 18070 } 18071 18072 TypeResult Sema::ActOnOpenMPDeclareMapperVarDecl(Scope *S, Declarator &D) { 18073 TypeSourceInfo *TInfo = GetTypeForDeclarator(D, S); 18074 QualType T = TInfo->getType(); 18075 if (D.isInvalidType()) 18076 return true; 18077 18078 if (getLangOpts().CPlusPlus) { 18079 // Check that there are no default arguments (C++ only). 18080 CheckExtraCXXDefaultArguments(D); 18081 } 18082 18083 return CreateParsedType(T, TInfo); 18084 } 18085 18086 QualType Sema::ActOnOpenMPDeclareMapperType(SourceLocation TyLoc, 18087 TypeResult ParsedType) { 18088 assert(ParsedType.isUsable() && "Expect usable parsed mapper type"); 18089 18090 QualType MapperType = GetTypeFromParser(ParsedType.get()); 18091 assert(!MapperType.isNull() && "Expect valid mapper type"); 18092 18093 // [OpenMP 5.0], 2.19.7.3 declare mapper Directive, Restrictions 18094 // The type must be of struct, union or class type in C and C++ 18095 if (!MapperType->isStructureOrClassType() && !MapperType->isUnionType()) { 18096 Diag(TyLoc, diag::err_omp_mapper_wrong_type); 18097 return QualType(); 18098 } 18099 return MapperType; 18100 } 18101 18102 Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareMapperDirective( 18103 Scope *S, DeclContext *DC, DeclarationName Name, QualType MapperType, 18104 SourceLocation StartLoc, DeclarationName VN, AccessSpecifier AS, 18105 Expr *MapperVarRef, ArrayRef<OMPClause *> Clauses, Decl *PrevDeclInScope) { 18106 LookupResult Lookup(*this, Name, SourceLocation(), LookupOMPMapperName, 18107 forRedeclarationInCurContext()); 18108 // [OpenMP 5.0], 2.19.7.3 declare mapper Directive, Restrictions 18109 // A mapper-identifier may not be redeclared in the current scope for the 18110 // same type or for a type that is compatible according to the base language 18111 // rules. 18112 llvm::DenseMap<QualType, SourceLocation> PreviousRedeclTypes; 18113 OMPDeclareMapperDecl *PrevDMD = nullptr; 18114 bool InCompoundScope = true; 18115 if (S != nullptr) { 18116 // Find previous declaration with the same name not referenced in other 18117 // declarations. 18118 FunctionScopeInfo *ParentFn = getEnclosingFunction(); 18119 InCompoundScope = 18120 (ParentFn != nullptr) && !ParentFn->CompoundScopes.empty(); 18121 LookupName(Lookup, S); 18122 FilterLookupForScope(Lookup, DC, S, /*ConsiderLinkage=*/false, 18123 /*AllowInlineNamespace=*/false); 18124 llvm::DenseMap<OMPDeclareMapperDecl *, bool> UsedAsPrevious; 18125 LookupResult::Filter Filter = Lookup.makeFilter(); 18126 while (Filter.hasNext()) { 18127 auto *PrevDecl = cast<OMPDeclareMapperDecl>(Filter.next()); 18128 if (InCompoundScope) { 18129 auto I = UsedAsPrevious.find(PrevDecl); 18130 if (I == UsedAsPrevious.end()) 18131 UsedAsPrevious[PrevDecl] = false; 18132 if (OMPDeclareMapperDecl *D = PrevDecl->getPrevDeclInScope()) 18133 UsedAsPrevious[D] = true; 18134 } 18135 PreviousRedeclTypes[PrevDecl->getType().getCanonicalType()] = 18136 PrevDecl->getLocation(); 18137 } 18138 Filter.done(); 18139 if (InCompoundScope) { 18140 for (const auto &PrevData : UsedAsPrevious) { 18141 if (!PrevData.second) { 18142 PrevDMD = PrevData.first; 18143 break; 18144 } 18145 } 18146 } 18147 } else if (PrevDeclInScope) { 18148 auto *PrevDMDInScope = PrevDMD = 18149 cast<OMPDeclareMapperDecl>(PrevDeclInScope); 18150 do { 18151 PreviousRedeclTypes[PrevDMDInScope->getType().getCanonicalType()] = 18152 PrevDMDInScope->getLocation(); 18153 PrevDMDInScope = PrevDMDInScope->getPrevDeclInScope(); 18154 } while (PrevDMDInScope != nullptr); 18155 } 18156 const auto I = PreviousRedeclTypes.find(MapperType.getCanonicalType()); 18157 bool Invalid = false; 18158 if (I != PreviousRedeclTypes.end()) { 18159 Diag(StartLoc, diag::err_omp_declare_mapper_redefinition) 18160 << MapperType << Name; 18161 Diag(I->second, diag::note_previous_definition); 18162 Invalid = true; 18163 } 18164 auto *DMD = OMPDeclareMapperDecl::Create(Context, DC, StartLoc, Name, 18165 MapperType, VN, Clauses, PrevDMD); 18166 if (S) 18167 PushOnScopeChains(DMD, S); 18168 else 18169 DC->addDecl(DMD); 18170 DMD->setAccess(AS); 18171 if (Invalid) 18172 DMD->setInvalidDecl(); 18173 18174 auto *VD = cast<DeclRefExpr>(MapperVarRef)->getDecl(); 18175 VD->setDeclContext(DMD); 18176 VD->setLexicalDeclContext(DMD); 18177 DMD->addDecl(VD); 18178 DMD->setMapperVarRef(MapperVarRef); 18179 18180 return DeclGroupPtrTy::make(DeclGroupRef(DMD)); 18181 } 18182 18183 ExprResult 18184 Sema::ActOnOpenMPDeclareMapperDirectiveVarDecl(Scope *S, QualType MapperType, 18185 SourceLocation StartLoc, 18186 DeclarationName VN) { 18187 TypeSourceInfo *TInfo = 18188 Context.getTrivialTypeSourceInfo(MapperType, StartLoc); 18189 auto *VD = VarDecl::Create(Context, Context.getTranslationUnitDecl(), 18190 StartLoc, StartLoc, VN.getAsIdentifierInfo(), 18191 MapperType, TInfo, SC_None); 18192 if (S) 18193 PushOnScopeChains(VD, S, /*AddToContext=*/false); 18194 Expr *E = buildDeclRefExpr(*this, VD, MapperType, StartLoc); 18195 DSAStack->addDeclareMapperVarRef(E); 18196 return E; 18197 } 18198 18199 bool Sema::isOpenMPDeclareMapperVarDeclAllowed(const VarDecl *VD) const { 18200 assert(LangOpts.OpenMP && "Expected OpenMP mode."); 18201 const Expr *Ref = DSAStack->getDeclareMapperVarRef(); 18202 if (const auto *DRE = cast_or_null<DeclRefExpr>(Ref)) 18203 return VD->getCanonicalDecl() == DRE->getDecl()->getCanonicalDecl(); 18204 return true; 18205 } 18206 18207 const ValueDecl *Sema::getOpenMPDeclareMapperVarName() const { 18208 assert(LangOpts.OpenMP && "Expected OpenMP mode."); 18209 return cast<DeclRefExpr>(DSAStack->getDeclareMapperVarRef())->getDecl(); 18210 } 18211 18212 OMPClause *Sema::ActOnOpenMPNumTeamsClause(Expr *NumTeams, 18213 SourceLocation StartLoc, 18214 SourceLocation LParenLoc, 18215 SourceLocation EndLoc) { 18216 Expr *ValExpr = NumTeams; 18217 Stmt *HelperValStmt = nullptr; 18218 18219 // OpenMP [teams Constrcut, Restrictions] 18220 // The num_teams expression must evaluate to a positive integer value. 18221 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_num_teams, 18222 /*StrictlyPositive=*/true)) 18223 return nullptr; 18224 18225 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 18226 OpenMPDirectiveKind CaptureRegion = 18227 getOpenMPCaptureRegionForClause(DKind, OMPC_num_teams, LangOpts.OpenMP); 18228 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 18229 ValExpr = MakeFullExpr(ValExpr).get(); 18230 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 18231 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 18232 HelperValStmt = buildPreInits(Context, Captures); 18233 } 18234 18235 return new (Context) OMPNumTeamsClause(ValExpr, HelperValStmt, CaptureRegion, 18236 StartLoc, LParenLoc, EndLoc); 18237 } 18238 18239 OMPClause *Sema::ActOnOpenMPThreadLimitClause(Expr *ThreadLimit, 18240 SourceLocation StartLoc, 18241 SourceLocation LParenLoc, 18242 SourceLocation EndLoc) { 18243 Expr *ValExpr = ThreadLimit; 18244 Stmt *HelperValStmt = nullptr; 18245 18246 // OpenMP [teams Constrcut, Restrictions] 18247 // The thread_limit expression must evaluate to a positive integer value. 18248 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_thread_limit, 18249 /*StrictlyPositive=*/true)) 18250 return nullptr; 18251 18252 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 18253 OpenMPDirectiveKind CaptureRegion = getOpenMPCaptureRegionForClause( 18254 DKind, OMPC_thread_limit, LangOpts.OpenMP); 18255 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 18256 ValExpr = MakeFullExpr(ValExpr).get(); 18257 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 18258 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 18259 HelperValStmt = buildPreInits(Context, Captures); 18260 } 18261 18262 return new (Context) OMPThreadLimitClause( 18263 ValExpr, HelperValStmt, CaptureRegion, StartLoc, LParenLoc, EndLoc); 18264 } 18265 18266 OMPClause *Sema::ActOnOpenMPPriorityClause(Expr *Priority, 18267 SourceLocation StartLoc, 18268 SourceLocation LParenLoc, 18269 SourceLocation EndLoc) { 18270 Expr *ValExpr = Priority; 18271 Stmt *HelperValStmt = nullptr; 18272 OpenMPDirectiveKind CaptureRegion = OMPD_unknown; 18273 18274 // OpenMP [2.9.1, task Constrcut] 18275 // The priority-value is a non-negative numerical scalar expression. 18276 if (!isNonNegativeIntegerValue( 18277 ValExpr, *this, OMPC_priority, 18278 /*StrictlyPositive=*/false, /*BuildCapture=*/true, 18279 DSAStack->getCurrentDirective(), &CaptureRegion, &HelperValStmt)) 18280 return nullptr; 18281 18282 return new (Context) OMPPriorityClause(ValExpr, HelperValStmt, CaptureRegion, 18283 StartLoc, LParenLoc, EndLoc); 18284 } 18285 18286 OMPClause *Sema::ActOnOpenMPGrainsizeClause(Expr *Grainsize, 18287 SourceLocation StartLoc, 18288 SourceLocation LParenLoc, 18289 SourceLocation EndLoc) { 18290 Expr *ValExpr = Grainsize; 18291 Stmt *HelperValStmt = nullptr; 18292 OpenMPDirectiveKind CaptureRegion = OMPD_unknown; 18293 18294 // OpenMP [2.9.2, taskloop Constrcut] 18295 // The parameter of the grainsize clause must be a positive integer 18296 // expression. 18297 if (!isNonNegativeIntegerValue( 18298 ValExpr, *this, OMPC_grainsize, 18299 /*StrictlyPositive=*/true, /*BuildCapture=*/true, 18300 DSAStack->getCurrentDirective(), &CaptureRegion, &HelperValStmt)) 18301 return nullptr; 18302 18303 return new (Context) OMPGrainsizeClause(ValExpr, HelperValStmt, CaptureRegion, 18304 StartLoc, LParenLoc, EndLoc); 18305 } 18306 18307 OMPClause *Sema::ActOnOpenMPNumTasksClause(Expr *NumTasks, 18308 SourceLocation StartLoc, 18309 SourceLocation LParenLoc, 18310 SourceLocation EndLoc) { 18311 Expr *ValExpr = NumTasks; 18312 Stmt *HelperValStmt = nullptr; 18313 OpenMPDirectiveKind CaptureRegion = OMPD_unknown; 18314 18315 // OpenMP [2.9.2, taskloop Constrcut] 18316 // The parameter of the num_tasks clause must be a positive integer 18317 // expression. 18318 if (!isNonNegativeIntegerValue( 18319 ValExpr, *this, OMPC_num_tasks, 18320 /*StrictlyPositive=*/true, /*BuildCapture=*/true, 18321 DSAStack->getCurrentDirective(), &CaptureRegion, &HelperValStmt)) 18322 return nullptr; 18323 18324 return new (Context) OMPNumTasksClause(ValExpr, HelperValStmt, CaptureRegion, 18325 StartLoc, LParenLoc, EndLoc); 18326 } 18327 18328 OMPClause *Sema::ActOnOpenMPHintClause(Expr *Hint, SourceLocation StartLoc, 18329 SourceLocation LParenLoc, 18330 SourceLocation EndLoc) { 18331 // OpenMP [2.13.2, critical construct, Description] 18332 // ... where hint-expression is an integer constant expression that evaluates 18333 // to a valid lock hint. 18334 ExprResult HintExpr = VerifyPositiveIntegerConstantInClause(Hint, OMPC_hint); 18335 if (HintExpr.isInvalid()) 18336 return nullptr; 18337 return new (Context) 18338 OMPHintClause(HintExpr.get(), StartLoc, LParenLoc, EndLoc); 18339 } 18340 18341 /// Tries to find omp_event_handle_t type. 18342 static bool findOMPEventHandleT(Sema &S, SourceLocation Loc, 18343 DSAStackTy *Stack) { 18344 QualType OMPEventHandleT = Stack->getOMPEventHandleT(); 18345 if (!OMPEventHandleT.isNull()) 18346 return true; 18347 IdentifierInfo *II = &S.PP.getIdentifierTable().get("omp_event_handle_t"); 18348 ParsedType PT = S.getTypeName(*II, Loc, S.getCurScope()); 18349 if (!PT.getAsOpaquePtr() || PT.get().isNull()) { 18350 S.Diag(Loc, diag::err_omp_implied_type_not_found) << "omp_event_handle_t"; 18351 return false; 18352 } 18353 Stack->setOMPEventHandleT(PT.get()); 18354 return true; 18355 } 18356 18357 OMPClause *Sema::ActOnOpenMPDetachClause(Expr *Evt, SourceLocation StartLoc, 18358 SourceLocation LParenLoc, 18359 SourceLocation EndLoc) { 18360 if (!Evt->isValueDependent() && !Evt->isTypeDependent() && 18361 !Evt->isInstantiationDependent() && 18362 !Evt->containsUnexpandedParameterPack()) { 18363 if (!findOMPEventHandleT(*this, Evt->getExprLoc(), DSAStack)) 18364 return nullptr; 18365 // OpenMP 5.0, 2.10.1 task Construct. 18366 // event-handle is a variable of the omp_event_handle_t type. 18367 auto *Ref = dyn_cast<DeclRefExpr>(Evt->IgnoreParenImpCasts()); 18368 if (!Ref) { 18369 Diag(Evt->getExprLoc(), diag::err_omp_var_expected) 18370 << "omp_event_handle_t" << 0 << Evt->getSourceRange(); 18371 return nullptr; 18372 } 18373 auto *VD = dyn_cast_or_null<VarDecl>(Ref->getDecl()); 18374 if (!VD) { 18375 Diag(Evt->getExprLoc(), diag::err_omp_var_expected) 18376 << "omp_event_handle_t" << 0 << Evt->getSourceRange(); 18377 return nullptr; 18378 } 18379 if (!Context.hasSameUnqualifiedType(DSAStack->getOMPEventHandleT(), 18380 VD->getType()) || 18381 VD->getType().isConstant(Context)) { 18382 Diag(Evt->getExprLoc(), diag::err_omp_var_expected) 18383 << "omp_event_handle_t" << 1 << VD->getType() 18384 << Evt->getSourceRange(); 18385 return nullptr; 18386 } 18387 // OpenMP 5.0, 2.10.1 task Construct 18388 // [detach clause]... The event-handle will be considered as if it was 18389 // specified on a firstprivate clause. 18390 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(VD, /*FromParent=*/false); 18391 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_firstprivate && 18392 DVar.RefExpr) { 18393 Diag(Evt->getExprLoc(), diag::err_omp_wrong_dsa) 18394 << getOpenMPClauseName(DVar.CKind) 18395 << getOpenMPClauseName(OMPC_firstprivate); 18396 reportOriginalDsa(*this, DSAStack, VD, DVar); 18397 return nullptr; 18398 } 18399 } 18400 18401 return new (Context) OMPDetachClause(Evt, StartLoc, LParenLoc, EndLoc); 18402 } 18403 18404 OMPClause *Sema::ActOnOpenMPDistScheduleClause( 18405 OpenMPDistScheduleClauseKind Kind, Expr *ChunkSize, SourceLocation StartLoc, 18406 SourceLocation LParenLoc, SourceLocation KindLoc, SourceLocation CommaLoc, 18407 SourceLocation EndLoc) { 18408 if (Kind == OMPC_DIST_SCHEDULE_unknown) { 18409 std::string Values; 18410 Values += "'"; 18411 Values += getOpenMPSimpleClauseTypeName(OMPC_dist_schedule, 0); 18412 Values += "'"; 18413 Diag(KindLoc, diag::err_omp_unexpected_clause_value) 18414 << Values << getOpenMPClauseName(OMPC_dist_schedule); 18415 return nullptr; 18416 } 18417 Expr *ValExpr = ChunkSize; 18418 Stmt *HelperValStmt = nullptr; 18419 if (ChunkSize) { 18420 if (!ChunkSize->isValueDependent() && !ChunkSize->isTypeDependent() && 18421 !ChunkSize->isInstantiationDependent() && 18422 !ChunkSize->containsUnexpandedParameterPack()) { 18423 SourceLocation ChunkSizeLoc = ChunkSize->getBeginLoc(); 18424 ExprResult Val = 18425 PerformOpenMPImplicitIntegerConversion(ChunkSizeLoc, ChunkSize); 18426 if (Val.isInvalid()) 18427 return nullptr; 18428 18429 ValExpr = Val.get(); 18430 18431 // OpenMP [2.7.1, Restrictions] 18432 // chunk_size must be a loop invariant integer expression with a positive 18433 // value. 18434 if (Optional<llvm::APSInt> Result = 18435 ValExpr->getIntegerConstantExpr(Context)) { 18436 if (Result->isSigned() && !Result->isStrictlyPositive()) { 18437 Diag(ChunkSizeLoc, diag::err_omp_negative_expression_in_clause) 18438 << "dist_schedule" << ChunkSize->getSourceRange(); 18439 return nullptr; 18440 } 18441 } else if (getOpenMPCaptureRegionForClause( 18442 DSAStack->getCurrentDirective(), OMPC_dist_schedule, 18443 LangOpts.OpenMP) != OMPD_unknown && 18444 !CurContext->isDependentContext()) { 18445 ValExpr = MakeFullExpr(ValExpr).get(); 18446 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 18447 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 18448 HelperValStmt = buildPreInits(Context, Captures); 18449 } 18450 } 18451 } 18452 18453 return new (Context) 18454 OMPDistScheduleClause(StartLoc, LParenLoc, KindLoc, CommaLoc, EndLoc, 18455 Kind, ValExpr, HelperValStmt); 18456 } 18457 18458 OMPClause *Sema::ActOnOpenMPDefaultmapClause( 18459 OpenMPDefaultmapClauseModifier M, OpenMPDefaultmapClauseKind Kind, 18460 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation MLoc, 18461 SourceLocation KindLoc, SourceLocation EndLoc) { 18462 if (getLangOpts().OpenMP < 50) { 18463 if (M != OMPC_DEFAULTMAP_MODIFIER_tofrom || 18464 Kind != OMPC_DEFAULTMAP_scalar) { 18465 std::string Value; 18466 SourceLocation Loc; 18467 Value += "'"; 18468 if (M != OMPC_DEFAULTMAP_MODIFIER_tofrom) { 18469 Value += getOpenMPSimpleClauseTypeName(OMPC_defaultmap, 18470 OMPC_DEFAULTMAP_MODIFIER_tofrom); 18471 Loc = MLoc; 18472 } else { 18473 Value += getOpenMPSimpleClauseTypeName(OMPC_defaultmap, 18474 OMPC_DEFAULTMAP_scalar); 18475 Loc = KindLoc; 18476 } 18477 Value += "'"; 18478 Diag(Loc, diag::err_omp_unexpected_clause_value) 18479 << Value << getOpenMPClauseName(OMPC_defaultmap); 18480 return nullptr; 18481 } 18482 } else { 18483 bool isDefaultmapModifier = (M != OMPC_DEFAULTMAP_MODIFIER_unknown); 18484 bool isDefaultmapKind = (Kind != OMPC_DEFAULTMAP_unknown) || 18485 (LangOpts.OpenMP >= 50 && KindLoc.isInvalid()); 18486 if (!isDefaultmapKind || !isDefaultmapModifier) { 18487 std::string ModifierValue = "'alloc', 'from', 'to', 'tofrom', " 18488 "'firstprivate', 'none', 'default'"; 18489 std::string KindValue = "'scalar', 'aggregate', 'pointer'"; 18490 if (!isDefaultmapKind && isDefaultmapModifier) { 18491 Diag(KindLoc, diag::err_omp_unexpected_clause_value) 18492 << KindValue << getOpenMPClauseName(OMPC_defaultmap); 18493 } else if (isDefaultmapKind && !isDefaultmapModifier) { 18494 Diag(MLoc, diag::err_omp_unexpected_clause_value) 18495 << ModifierValue << getOpenMPClauseName(OMPC_defaultmap); 18496 } else { 18497 Diag(MLoc, diag::err_omp_unexpected_clause_value) 18498 << ModifierValue << getOpenMPClauseName(OMPC_defaultmap); 18499 Diag(KindLoc, diag::err_omp_unexpected_clause_value) 18500 << KindValue << getOpenMPClauseName(OMPC_defaultmap); 18501 } 18502 return nullptr; 18503 } 18504 18505 // OpenMP [5.0, 2.12.5, Restrictions, p. 174] 18506 // At most one defaultmap clause for each category can appear on the 18507 // directive. 18508 if (DSAStack->checkDefaultmapCategory(Kind)) { 18509 Diag(StartLoc, diag::err_omp_one_defaultmap_each_category); 18510 return nullptr; 18511 } 18512 } 18513 if (Kind == OMPC_DEFAULTMAP_unknown) { 18514 // Variable category is not specified - mark all categories. 18515 DSAStack->setDefaultDMAAttr(M, OMPC_DEFAULTMAP_aggregate, StartLoc); 18516 DSAStack->setDefaultDMAAttr(M, OMPC_DEFAULTMAP_scalar, StartLoc); 18517 DSAStack->setDefaultDMAAttr(M, OMPC_DEFAULTMAP_pointer, StartLoc); 18518 } else { 18519 DSAStack->setDefaultDMAAttr(M, Kind, StartLoc); 18520 } 18521 18522 return new (Context) 18523 OMPDefaultmapClause(StartLoc, LParenLoc, MLoc, KindLoc, EndLoc, Kind, M); 18524 } 18525 18526 bool Sema::ActOnStartOpenMPDeclareTargetDirective(SourceLocation Loc) { 18527 DeclContext *CurLexicalContext = getCurLexicalContext(); 18528 if (!CurLexicalContext->isFileContext() && 18529 !CurLexicalContext->isExternCContext() && 18530 !CurLexicalContext->isExternCXXContext() && 18531 !isa<CXXRecordDecl>(CurLexicalContext) && 18532 !isa<ClassTemplateDecl>(CurLexicalContext) && 18533 !isa<ClassTemplatePartialSpecializationDecl>(CurLexicalContext) && 18534 !isa<ClassTemplateSpecializationDecl>(CurLexicalContext)) { 18535 Diag(Loc, diag::err_omp_region_not_file_context); 18536 return false; 18537 } 18538 DeclareTargetNesting.push_back(Loc); 18539 return true; 18540 } 18541 18542 void Sema::ActOnFinishOpenMPDeclareTargetDirective() { 18543 assert(!DeclareTargetNesting.empty() && 18544 "Unexpected ActOnFinishOpenMPDeclareTargetDirective"); 18545 DeclareTargetNesting.pop_back(); 18546 } 18547 18548 NamedDecl * 18549 Sema::lookupOpenMPDeclareTargetName(Scope *CurScope, CXXScopeSpec &ScopeSpec, 18550 const DeclarationNameInfo &Id, 18551 NamedDeclSetType &SameDirectiveDecls) { 18552 LookupResult Lookup(*this, Id, LookupOrdinaryName); 18553 LookupParsedName(Lookup, CurScope, &ScopeSpec, true); 18554 18555 if (Lookup.isAmbiguous()) 18556 return nullptr; 18557 Lookup.suppressDiagnostics(); 18558 18559 if (!Lookup.isSingleResult()) { 18560 VarOrFuncDeclFilterCCC CCC(*this); 18561 if (TypoCorrection Corrected = 18562 CorrectTypo(Id, LookupOrdinaryName, CurScope, nullptr, CCC, 18563 CTK_ErrorRecovery)) { 18564 diagnoseTypo(Corrected, PDiag(diag::err_undeclared_var_use_suggest) 18565 << Id.getName()); 18566 checkDeclIsAllowedInOpenMPTarget(nullptr, Corrected.getCorrectionDecl()); 18567 return nullptr; 18568 } 18569 18570 Diag(Id.getLoc(), diag::err_undeclared_var_use) << Id.getName(); 18571 return nullptr; 18572 } 18573 18574 NamedDecl *ND = Lookup.getAsSingle<NamedDecl>(); 18575 if (!isa<VarDecl>(ND) && !isa<FunctionDecl>(ND) && 18576 !isa<FunctionTemplateDecl>(ND)) { 18577 Diag(Id.getLoc(), diag::err_omp_invalid_target_decl) << Id.getName(); 18578 return nullptr; 18579 } 18580 if (!SameDirectiveDecls.insert(cast<NamedDecl>(ND->getCanonicalDecl()))) 18581 Diag(Id.getLoc(), diag::err_omp_declare_target_multiple) << Id.getName(); 18582 return ND; 18583 } 18584 18585 void Sema::ActOnOpenMPDeclareTargetName( 18586 NamedDecl *ND, SourceLocation Loc, OMPDeclareTargetDeclAttr::MapTypeTy MT, 18587 OMPDeclareTargetDeclAttr::DevTypeTy DT) { 18588 assert((isa<VarDecl>(ND) || isa<FunctionDecl>(ND) || 18589 isa<FunctionTemplateDecl>(ND)) && 18590 "Expected variable, function or function template."); 18591 18592 // Diagnose marking after use as it may lead to incorrect diagnosis and 18593 // codegen. 18594 if (LangOpts.OpenMP >= 50 && 18595 (ND->isUsed(/*CheckUsedAttr=*/false) || ND->isReferenced())) 18596 Diag(Loc, diag::warn_omp_declare_target_after_first_use); 18597 18598 auto *VD = cast<ValueDecl>(ND); 18599 Optional<OMPDeclareTargetDeclAttr::DevTypeTy> DevTy = 18600 OMPDeclareTargetDeclAttr::getDeviceType(VD); 18601 Optional<SourceLocation> AttrLoc = OMPDeclareTargetDeclAttr::getLocation(VD); 18602 if (DevTy.hasValue() && *DevTy != DT && 18603 (DeclareTargetNesting.empty() || 18604 *AttrLoc != DeclareTargetNesting.back())) { 18605 Diag(Loc, diag::err_omp_device_type_mismatch) 18606 << OMPDeclareTargetDeclAttr::ConvertDevTypeTyToStr(DT) 18607 << OMPDeclareTargetDeclAttr::ConvertDevTypeTyToStr(*DevTy); 18608 return; 18609 } 18610 Optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res = 18611 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD); 18612 if (!Res || (!DeclareTargetNesting.empty() && 18613 *AttrLoc == DeclareTargetNesting.back())) { 18614 auto *A = OMPDeclareTargetDeclAttr::CreateImplicit( 18615 Context, MT, DT, DeclareTargetNesting.size() + 1, 18616 SourceRange(Loc, Loc)); 18617 ND->addAttr(A); 18618 if (ASTMutationListener *ML = Context.getASTMutationListener()) 18619 ML->DeclarationMarkedOpenMPDeclareTarget(ND, A); 18620 checkDeclIsAllowedInOpenMPTarget(nullptr, ND, Loc); 18621 } else if (*Res != MT) { 18622 Diag(Loc, diag::err_omp_declare_target_to_and_link) << ND; 18623 } 18624 } 18625 18626 static void checkDeclInTargetContext(SourceLocation SL, SourceRange SR, 18627 Sema &SemaRef, Decl *D) { 18628 if (!D || !isa<VarDecl>(D)) 18629 return; 18630 auto *VD = cast<VarDecl>(D); 18631 Optional<OMPDeclareTargetDeclAttr::MapTypeTy> MapTy = 18632 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD); 18633 if (SemaRef.LangOpts.OpenMP >= 50 && 18634 (SemaRef.getCurLambda(/*IgnoreNonLambdaCapturingScope=*/true) || 18635 SemaRef.getCurBlock() || SemaRef.getCurCapturedRegion()) && 18636 VD->hasGlobalStorage()) { 18637 llvm::Optional<OMPDeclareTargetDeclAttr::MapTypeTy> MapTy = 18638 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD); 18639 if (!MapTy || *MapTy != OMPDeclareTargetDeclAttr::MT_To) { 18640 // OpenMP 5.0, 2.12.7 declare target Directive, Restrictions 18641 // If a lambda declaration and definition appears between a 18642 // declare target directive and the matching end declare target 18643 // directive, all variables that are captured by the lambda 18644 // expression must also appear in a to clause. 18645 SemaRef.Diag(VD->getLocation(), 18646 diag::err_omp_lambda_capture_in_declare_target_not_to); 18647 SemaRef.Diag(SL, diag::note_var_explicitly_captured_here) 18648 << VD << 0 << SR; 18649 return; 18650 } 18651 } 18652 if (MapTy.hasValue()) 18653 return; 18654 SemaRef.Diag(VD->getLocation(), diag::warn_omp_not_in_target_context); 18655 SemaRef.Diag(SL, diag::note_used_here) << SR; 18656 } 18657 18658 static bool checkValueDeclInTarget(SourceLocation SL, SourceRange SR, 18659 Sema &SemaRef, DSAStackTy *Stack, 18660 ValueDecl *VD) { 18661 return OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD) || 18662 checkTypeMappable(SL, SR, SemaRef, Stack, VD->getType(), 18663 /*FullCheck=*/false); 18664 } 18665 18666 void Sema::checkDeclIsAllowedInOpenMPTarget(Expr *E, Decl *D, 18667 SourceLocation IdLoc) { 18668 if (!D || D->isInvalidDecl()) 18669 return; 18670 SourceRange SR = E ? E->getSourceRange() : D->getSourceRange(); 18671 SourceLocation SL = E ? E->getBeginLoc() : D->getLocation(); 18672 if (auto *VD = dyn_cast<VarDecl>(D)) { 18673 // Only global variables can be marked as declare target. 18674 if (!VD->isFileVarDecl() && !VD->isStaticLocal() && 18675 !VD->isStaticDataMember()) 18676 return; 18677 // 2.10.6: threadprivate variable cannot appear in a declare target 18678 // directive. 18679 if (DSAStack->isThreadPrivate(VD)) { 18680 Diag(SL, diag::err_omp_threadprivate_in_target); 18681 reportOriginalDsa(*this, DSAStack, VD, DSAStack->getTopDSA(VD, false)); 18682 return; 18683 } 18684 } 18685 if (const auto *FTD = dyn_cast<FunctionTemplateDecl>(D)) 18686 D = FTD->getTemplatedDecl(); 18687 if (auto *FD = dyn_cast<FunctionDecl>(D)) { 18688 llvm::Optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res = 18689 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(FD); 18690 if (IdLoc.isValid() && Res && *Res == OMPDeclareTargetDeclAttr::MT_Link) { 18691 Diag(IdLoc, diag::err_omp_function_in_link_clause); 18692 Diag(FD->getLocation(), diag::note_defined_here) << FD; 18693 return; 18694 } 18695 } 18696 if (auto *VD = dyn_cast<ValueDecl>(D)) { 18697 // Problem if any with var declared with incomplete type will be reported 18698 // as normal, so no need to check it here. 18699 if ((E || !VD->getType()->isIncompleteType()) && 18700 !checkValueDeclInTarget(SL, SR, *this, DSAStack, VD)) 18701 return; 18702 if (!E && !OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD)) { 18703 // Checking declaration inside declare target region. 18704 if (isa<VarDecl>(D) || isa<FunctionDecl>(D) || 18705 isa<FunctionTemplateDecl>(D)) { 18706 auto *A = OMPDeclareTargetDeclAttr::CreateImplicit( 18707 Context, OMPDeclareTargetDeclAttr::MT_To, 18708 OMPDeclareTargetDeclAttr::DT_Any, DeclareTargetNesting.size(), 18709 SourceRange(DeclareTargetNesting.back(), 18710 DeclareTargetNesting.back())); 18711 D->addAttr(A); 18712 if (ASTMutationListener *ML = Context.getASTMutationListener()) 18713 ML->DeclarationMarkedOpenMPDeclareTarget(D, A); 18714 } 18715 return; 18716 } 18717 } 18718 if (!E) 18719 return; 18720 checkDeclInTargetContext(E->getExprLoc(), E->getSourceRange(), *this, D); 18721 } 18722 18723 OMPClause *Sema::ActOnOpenMPToClause( 18724 ArrayRef<OpenMPMotionModifierKind> MotionModifiers, 18725 ArrayRef<SourceLocation> MotionModifiersLoc, 18726 CXXScopeSpec &MapperIdScopeSpec, DeclarationNameInfo &MapperId, 18727 SourceLocation ColonLoc, ArrayRef<Expr *> VarList, 18728 const OMPVarListLocTy &Locs, ArrayRef<Expr *> UnresolvedMappers) { 18729 OpenMPMotionModifierKind Modifiers[] = {OMPC_MOTION_MODIFIER_unknown, 18730 OMPC_MOTION_MODIFIER_unknown}; 18731 SourceLocation ModifiersLoc[NumberOfOMPMotionModifiers]; 18732 18733 // Process motion-modifiers, flag errors for duplicate modifiers. 18734 unsigned Count = 0; 18735 for (unsigned I = 0, E = MotionModifiers.size(); I < E; ++I) { 18736 if (MotionModifiers[I] != OMPC_MOTION_MODIFIER_unknown && 18737 llvm::find(Modifiers, MotionModifiers[I]) != std::end(Modifiers)) { 18738 Diag(MotionModifiersLoc[I], diag::err_omp_duplicate_motion_modifier); 18739 continue; 18740 } 18741 assert(Count < NumberOfOMPMotionModifiers && 18742 "Modifiers exceed the allowed number of motion modifiers"); 18743 Modifiers[Count] = MotionModifiers[I]; 18744 ModifiersLoc[Count] = MotionModifiersLoc[I]; 18745 ++Count; 18746 } 18747 18748 MappableVarListInfo MVLI(VarList); 18749 checkMappableExpressionList(*this, DSAStack, OMPC_to, MVLI, Locs.StartLoc, 18750 MapperIdScopeSpec, MapperId, UnresolvedMappers); 18751 if (MVLI.ProcessedVarList.empty()) 18752 return nullptr; 18753 18754 return OMPToClause::Create( 18755 Context, Locs, MVLI.ProcessedVarList, MVLI.VarBaseDeclarations, 18756 MVLI.VarComponents, MVLI.UDMapperList, Modifiers, ModifiersLoc, 18757 MapperIdScopeSpec.getWithLocInContext(Context), MapperId); 18758 } 18759 18760 OMPClause *Sema::ActOnOpenMPFromClause( 18761 ArrayRef<OpenMPMotionModifierKind> MotionModifiers, 18762 ArrayRef<SourceLocation> MotionModifiersLoc, 18763 CXXScopeSpec &MapperIdScopeSpec, DeclarationNameInfo &MapperId, 18764 SourceLocation ColonLoc, ArrayRef<Expr *> VarList, 18765 const OMPVarListLocTy &Locs, ArrayRef<Expr *> UnresolvedMappers) { 18766 OpenMPMotionModifierKind Modifiers[] = {OMPC_MOTION_MODIFIER_unknown, 18767 OMPC_MOTION_MODIFIER_unknown}; 18768 SourceLocation ModifiersLoc[NumberOfOMPMotionModifiers]; 18769 18770 // Process motion-modifiers, flag errors for duplicate modifiers. 18771 unsigned Count = 0; 18772 for (unsigned I = 0, E = MotionModifiers.size(); I < E; ++I) { 18773 if (MotionModifiers[I] != OMPC_MOTION_MODIFIER_unknown && 18774 llvm::find(Modifiers, MotionModifiers[I]) != std::end(Modifiers)) { 18775 Diag(MotionModifiersLoc[I], diag::err_omp_duplicate_motion_modifier); 18776 continue; 18777 } 18778 assert(Count < NumberOfOMPMotionModifiers && 18779 "Modifiers exceed the allowed number of motion modifiers"); 18780 Modifiers[Count] = MotionModifiers[I]; 18781 ModifiersLoc[Count] = MotionModifiersLoc[I]; 18782 ++Count; 18783 } 18784 18785 MappableVarListInfo MVLI(VarList); 18786 checkMappableExpressionList(*this, DSAStack, OMPC_from, MVLI, Locs.StartLoc, 18787 MapperIdScopeSpec, MapperId, UnresolvedMappers); 18788 if (MVLI.ProcessedVarList.empty()) 18789 return nullptr; 18790 18791 return OMPFromClause::Create( 18792 Context, Locs, MVLI.ProcessedVarList, MVLI.VarBaseDeclarations, 18793 MVLI.VarComponents, MVLI.UDMapperList, Modifiers, ModifiersLoc, 18794 MapperIdScopeSpec.getWithLocInContext(Context), MapperId); 18795 } 18796 18797 OMPClause *Sema::ActOnOpenMPUseDevicePtrClause(ArrayRef<Expr *> VarList, 18798 const OMPVarListLocTy &Locs) { 18799 MappableVarListInfo MVLI(VarList); 18800 SmallVector<Expr *, 8> PrivateCopies; 18801 SmallVector<Expr *, 8> Inits; 18802 18803 for (Expr *RefExpr : VarList) { 18804 assert(RefExpr && "NULL expr in OpenMP use_device_ptr clause."); 18805 SourceLocation ELoc; 18806 SourceRange ERange; 18807 Expr *SimpleRefExpr = RefExpr; 18808 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 18809 if (Res.second) { 18810 // It will be analyzed later. 18811 MVLI.ProcessedVarList.push_back(RefExpr); 18812 PrivateCopies.push_back(nullptr); 18813 Inits.push_back(nullptr); 18814 } 18815 ValueDecl *D = Res.first; 18816 if (!D) 18817 continue; 18818 18819 QualType Type = D->getType(); 18820 Type = Type.getNonReferenceType().getUnqualifiedType(); 18821 18822 auto *VD = dyn_cast<VarDecl>(D); 18823 18824 // Item should be a pointer or reference to pointer. 18825 if (!Type->isPointerType()) { 18826 Diag(ELoc, diag::err_omp_usedeviceptr_not_a_pointer) 18827 << 0 << RefExpr->getSourceRange(); 18828 continue; 18829 } 18830 18831 // Build the private variable and the expression that refers to it. 18832 auto VDPrivate = 18833 buildVarDecl(*this, ELoc, Type, D->getName(), 18834 D->hasAttrs() ? &D->getAttrs() : nullptr, 18835 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr); 18836 if (VDPrivate->isInvalidDecl()) 18837 continue; 18838 18839 CurContext->addDecl(VDPrivate); 18840 DeclRefExpr *VDPrivateRefExpr = buildDeclRefExpr( 18841 *this, VDPrivate, RefExpr->getType().getUnqualifiedType(), ELoc); 18842 18843 // Add temporary variable to initialize the private copy of the pointer. 18844 VarDecl *VDInit = 18845 buildVarDecl(*this, RefExpr->getExprLoc(), Type, ".devptr.temp"); 18846 DeclRefExpr *VDInitRefExpr = buildDeclRefExpr( 18847 *this, VDInit, RefExpr->getType(), RefExpr->getExprLoc()); 18848 AddInitializerToDecl(VDPrivate, 18849 DefaultLvalueConversion(VDInitRefExpr).get(), 18850 /*DirectInit=*/false); 18851 18852 // If required, build a capture to implement the privatization initialized 18853 // with the current list item value. 18854 DeclRefExpr *Ref = nullptr; 18855 if (!VD) 18856 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true); 18857 MVLI.ProcessedVarList.push_back(VD ? RefExpr->IgnoreParens() : Ref); 18858 PrivateCopies.push_back(VDPrivateRefExpr); 18859 Inits.push_back(VDInitRefExpr); 18860 18861 // We need to add a data sharing attribute for this variable to make sure it 18862 // is correctly captured. A variable that shows up in a use_device_ptr has 18863 // similar properties of a first private variable. 18864 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_firstprivate, Ref); 18865 18866 // Create a mappable component for the list item. List items in this clause 18867 // only need a component. 18868 MVLI.VarBaseDeclarations.push_back(D); 18869 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1); 18870 MVLI.VarComponents.back().push_back( 18871 OMPClauseMappableExprCommon::MappableComponent(SimpleRefExpr, D)); 18872 } 18873 18874 if (MVLI.ProcessedVarList.empty()) 18875 return nullptr; 18876 18877 return OMPUseDevicePtrClause::Create( 18878 Context, Locs, MVLI.ProcessedVarList, PrivateCopies, Inits, 18879 MVLI.VarBaseDeclarations, MVLI.VarComponents); 18880 } 18881 18882 OMPClause *Sema::ActOnOpenMPUseDeviceAddrClause(ArrayRef<Expr *> VarList, 18883 const OMPVarListLocTy &Locs) { 18884 MappableVarListInfo MVLI(VarList); 18885 18886 for (Expr *RefExpr : VarList) { 18887 assert(RefExpr && "NULL expr in OpenMP use_device_addr clause."); 18888 SourceLocation ELoc; 18889 SourceRange ERange; 18890 Expr *SimpleRefExpr = RefExpr; 18891 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange, 18892 /*AllowArraySection=*/true); 18893 if (Res.second) { 18894 // It will be analyzed later. 18895 MVLI.ProcessedVarList.push_back(RefExpr); 18896 } 18897 ValueDecl *D = Res.first; 18898 if (!D) 18899 continue; 18900 auto *VD = dyn_cast<VarDecl>(D); 18901 18902 // If required, build a capture to implement the privatization initialized 18903 // with the current list item value. 18904 DeclRefExpr *Ref = nullptr; 18905 if (!VD) 18906 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true); 18907 MVLI.ProcessedVarList.push_back(VD ? RefExpr->IgnoreParens() : Ref); 18908 18909 // We need to add a data sharing attribute for this variable to make sure it 18910 // is correctly captured. A variable that shows up in a use_device_addr has 18911 // similar properties of a first private variable. 18912 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_firstprivate, Ref); 18913 18914 // Create a mappable component for the list item. List items in this clause 18915 // only need a component. 18916 MVLI.VarBaseDeclarations.push_back(D); 18917 MVLI.VarComponents.emplace_back(); 18918 Expr *Component = SimpleRefExpr; 18919 if (VD && (isa<OMPArraySectionExpr>(RefExpr->IgnoreParenImpCasts()) || 18920 isa<ArraySubscriptExpr>(RefExpr->IgnoreParenImpCasts()))) 18921 Component = DefaultFunctionArrayLvalueConversion(SimpleRefExpr).get(); 18922 MVLI.VarComponents.back().push_back( 18923 OMPClauseMappableExprCommon::MappableComponent(Component, D)); 18924 } 18925 18926 if (MVLI.ProcessedVarList.empty()) 18927 return nullptr; 18928 18929 return OMPUseDeviceAddrClause::Create(Context, Locs, MVLI.ProcessedVarList, 18930 MVLI.VarBaseDeclarations, 18931 MVLI.VarComponents); 18932 } 18933 18934 OMPClause *Sema::ActOnOpenMPIsDevicePtrClause(ArrayRef<Expr *> VarList, 18935 const OMPVarListLocTy &Locs) { 18936 MappableVarListInfo MVLI(VarList); 18937 for (Expr *RefExpr : VarList) { 18938 assert(RefExpr && "NULL expr in OpenMP is_device_ptr clause."); 18939 SourceLocation ELoc; 18940 SourceRange ERange; 18941 Expr *SimpleRefExpr = RefExpr; 18942 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 18943 if (Res.second) { 18944 // It will be analyzed later. 18945 MVLI.ProcessedVarList.push_back(RefExpr); 18946 } 18947 ValueDecl *D = Res.first; 18948 if (!D) 18949 continue; 18950 18951 QualType Type = D->getType(); 18952 // item should be a pointer or array or reference to pointer or array 18953 if (!Type.getNonReferenceType()->isPointerType() && 18954 !Type.getNonReferenceType()->isArrayType()) { 18955 Diag(ELoc, diag::err_omp_argument_type_isdeviceptr) 18956 << 0 << RefExpr->getSourceRange(); 18957 continue; 18958 } 18959 18960 // Check if the declaration in the clause does not show up in any data 18961 // sharing attribute. 18962 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false); 18963 if (isOpenMPPrivate(DVar.CKind)) { 18964 Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa) 18965 << getOpenMPClauseName(DVar.CKind) 18966 << getOpenMPClauseName(OMPC_is_device_ptr) 18967 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 18968 reportOriginalDsa(*this, DSAStack, D, DVar); 18969 continue; 18970 } 18971 18972 const Expr *ConflictExpr; 18973 if (DSAStack->checkMappableExprComponentListsForDecl( 18974 D, /*CurrentRegionOnly=*/true, 18975 [&ConflictExpr]( 18976 OMPClauseMappableExprCommon::MappableExprComponentListRef R, 18977 OpenMPClauseKind) -> bool { 18978 ConflictExpr = R.front().getAssociatedExpression(); 18979 return true; 18980 })) { 18981 Diag(ELoc, diag::err_omp_map_shared_storage) << RefExpr->getSourceRange(); 18982 Diag(ConflictExpr->getExprLoc(), diag::note_used_here) 18983 << ConflictExpr->getSourceRange(); 18984 continue; 18985 } 18986 18987 // Store the components in the stack so that they can be used to check 18988 // against other clauses later on. 18989 OMPClauseMappableExprCommon::MappableComponent MC(SimpleRefExpr, D); 18990 DSAStack->addMappableExpressionComponents( 18991 D, MC, /*WhereFoundClauseKind=*/OMPC_is_device_ptr); 18992 18993 // Record the expression we've just processed. 18994 MVLI.ProcessedVarList.push_back(SimpleRefExpr); 18995 18996 // Create a mappable component for the list item. List items in this clause 18997 // only need a component. We use a null declaration to signal fields in 18998 // 'this'. 18999 assert((isa<DeclRefExpr>(SimpleRefExpr) || 19000 isa<CXXThisExpr>(cast<MemberExpr>(SimpleRefExpr)->getBase())) && 19001 "Unexpected device pointer expression!"); 19002 MVLI.VarBaseDeclarations.push_back( 19003 isa<DeclRefExpr>(SimpleRefExpr) ? D : nullptr); 19004 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1); 19005 MVLI.VarComponents.back().push_back(MC); 19006 } 19007 19008 if (MVLI.ProcessedVarList.empty()) 19009 return nullptr; 19010 19011 return OMPIsDevicePtrClause::Create(Context, Locs, MVLI.ProcessedVarList, 19012 MVLI.VarBaseDeclarations, 19013 MVLI.VarComponents); 19014 } 19015 19016 OMPClause *Sema::ActOnOpenMPAllocateClause( 19017 Expr *Allocator, ArrayRef<Expr *> VarList, SourceLocation StartLoc, 19018 SourceLocation ColonLoc, SourceLocation LParenLoc, SourceLocation EndLoc) { 19019 if (Allocator) { 19020 // OpenMP [2.11.4 allocate Clause, Description] 19021 // allocator is an expression of omp_allocator_handle_t type. 19022 if (!findOMPAllocatorHandleT(*this, Allocator->getExprLoc(), DSAStack)) 19023 return nullptr; 19024 19025 ExprResult AllocatorRes = DefaultLvalueConversion(Allocator); 19026 if (AllocatorRes.isInvalid()) 19027 return nullptr; 19028 AllocatorRes = PerformImplicitConversion(AllocatorRes.get(), 19029 DSAStack->getOMPAllocatorHandleT(), 19030 Sema::AA_Initializing, 19031 /*AllowExplicit=*/true); 19032 if (AllocatorRes.isInvalid()) 19033 return nullptr; 19034 Allocator = AllocatorRes.get(); 19035 } else { 19036 // OpenMP 5.0, 2.11.4 allocate Clause, Restrictions. 19037 // allocate clauses that appear on a target construct or on constructs in a 19038 // target region must specify an allocator expression unless a requires 19039 // directive with the dynamic_allocators clause is present in the same 19040 // compilation unit. 19041 if (LangOpts.OpenMPIsDevice && 19042 !DSAStack->hasRequiresDeclWithClause<OMPDynamicAllocatorsClause>()) 19043 targetDiag(StartLoc, diag::err_expected_allocator_expression); 19044 } 19045 // Analyze and build list of variables. 19046 SmallVector<Expr *, 8> Vars; 19047 for (Expr *RefExpr : VarList) { 19048 assert(RefExpr && "NULL expr in OpenMP private clause."); 19049 SourceLocation ELoc; 19050 SourceRange ERange; 19051 Expr *SimpleRefExpr = RefExpr; 19052 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 19053 if (Res.second) { 19054 // It will be analyzed later. 19055 Vars.push_back(RefExpr); 19056 } 19057 ValueDecl *D = Res.first; 19058 if (!D) 19059 continue; 19060 19061 auto *VD = dyn_cast<VarDecl>(D); 19062 DeclRefExpr *Ref = nullptr; 19063 if (!VD && !CurContext->isDependentContext()) 19064 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false); 19065 Vars.push_back((VD || CurContext->isDependentContext()) 19066 ? RefExpr->IgnoreParens() 19067 : Ref); 19068 } 19069 19070 if (Vars.empty()) 19071 return nullptr; 19072 19073 if (Allocator) 19074 DSAStack->addInnerAllocatorExpr(Allocator); 19075 return OMPAllocateClause::Create(Context, StartLoc, LParenLoc, Allocator, 19076 ColonLoc, EndLoc, Vars); 19077 } 19078 19079 OMPClause *Sema::ActOnOpenMPNontemporalClause(ArrayRef<Expr *> VarList, 19080 SourceLocation StartLoc, 19081 SourceLocation LParenLoc, 19082 SourceLocation EndLoc) { 19083 SmallVector<Expr *, 8> Vars; 19084 for (Expr *RefExpr : VarList) { 19085 assert(RefExpr && "NULL expr in OpenMP nontemporal clause."); 19086 SourceLocation ELoc; 19087 SourceRange ERange; 19088 Expr *SimpleRefExpr = RefExpr; 19089 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 19090 if (Res.second) 19091 // It will be analyzed later. 19092 Vars.push_back(RefExpr); 19093 ValueDecl *D = Res.first; 19094 if (!D) 19095 continue; 19096 19097 // OpenMP 5.0, 2.9.3.1 simd Construct, Restrictions. 19098 // A list-item cannot appear in more than one nontemporal clause. 19099 if (const Expr *PrevRef = 19100 DSAStack->addUniqueNontemporal(D, SimpleRefExpr)) { 19101 Diag(ELoc, diag::err_omp_used_in_clause_twice) 19102 << 0 << getOpenMPClauseName(OMPC_nontemporal) << ERange; 19103 Diag(PrevRef->getExprLoc(), diag::note_omp_explicit_dsa) 19104 << getOpenMPClauseName(OMPC_nontemporal); 19105 continue; 19106 } 19107 19108 Vars.push_back(RefExpr); 19109 } 19110 19111 if (Vars.empty()) 19112 return nullptr; 19113 19114 return OMPNontemporalClause::Create(Context, StartLoc, LParenLoc, EndLoc, 19115 Vars); 19116 } 19117 19118 OMPClause *Sema::ActOnOpenMPInclusiveClause(ArrayRef<Expr *> VarList, 19119 SourceLocation StartLoc, 19120 SourceLocation LParenLoc, 19121 SourceLocation EndLoc) { 19122 SmallVector<Expr *, 8> Vars; 19123 for (Expr *RefExpr : VarList) { 19124 assert(RefExpr && "NULL expr in OpenMP nontemporal clause."); 19125 SourceLocation ELoc; 19126 SourceRange ERange; 19127 Expr *SimpleRefExpr = RefExpr; 19128 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange, 19129 /*AllowArraySection=*/true); 19130 if (Res.second) 19131 // It will be analyzed later. 19132 Vars.push_back(RefExpr); 19133 ValueDecl *D = Res.first; 19134 if (!D) 19135 continue; 19136 19137 const DSAStackTy::DSAVarData DVar = 19138 DSAStack->getTopDSA(D, /*FromParent=*/true); 19139 // OpenMP 5.0, 2.9.6, scan Directive, Restrictions. 19140 // A list item that appears in the inclusive or exclusive clause must appear 19141 // in a reduction clause with the inscan modifier on the enclosing 19142 // worksharing-loop, worksharing-loop SIMD, or simd construct. 19143 if (DVar.CKind != OMPC_reduction || 19144 DVar.Modifier != OMPC_REDUCTION_inscan) 19145 Diag(ELoc, diag::err_omp_inclusive_exclusive_not_reduction) 19146 << RefExpr->getSourceRange(); 19147 19148 if (DSAStack->getParentDirective() != OMPD_unknown) 19149 DSAStack->markDeclAsUsedInScanDirective(D); 19150 Vars.push_back(RefExpr); 19151 } 19152 19153 if (Vars.empty()) 19154 return nullptr; 19155 19156 return OMPInclusiveClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars); 19157 } 19158 19159 OMPClause *Sema::ActOnOpenMPExclusiveClause(ArrayRef<Expr *> VarList, 19160 SourceLocation StartLoc, 19161 SourceLocation LParenLoc, 19162 SourceLocation EndLoc) { 19163 SmallVector<Expr *, 8> Vars; 19164 for (Expr *RefExpr : VarList) { 19165 assert(RefExpr && "NULL expr in OpenMP nontemporal clause."); 19166 SourceLocation ELoc; 19167 SourceRange ERange; 19168 Expr *SimpleRefExpr = RefExpr; 19169 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange, 19170 /*AllowArraySection=*/true); 19171 if (Res.second) 19172 // It will be analyzed later. 19173 Vars.push_back(RefExpr); 19174 ValueDecl *D = Res.first; 19175 if (!D) 19176 continue; 19177 19178 OpenMPDirectiveKind ParentDirective = DSAStack->getParentDirective(); 19179 DSAStackTy::DSAVarData DVar; 19180 if (ParentDirective != OMPD_unknown) 19181 DVar = DSAStack->getTopDSA(D, /*FromParent=*/true); 19182 // OpenMP 5.0, 2.9.6, scan Directive, Restrictions. 19183 // A list item that appears in the inclusive or exclusive clause must appear 19184 // in a reduction clause with the inscan modifier on the enclosing 19185 // worksharing-loop, worksharing-loop SIMD, or simd construct. 19186 if (ParentDirective == OMPD_unknown || DVar.CKind != OMPC_reduction || 19187 DVar.Modifier != OMPC_REDUCTION_inscan) { 19188 Diag(ELoc, diag::err_omp_inclusive_exclusive_not_reduction) 19189 << RefExpr->getSourceRange(); 19190 } else { 19191 DSAStack->markDeclAsUsedInScanDirective(D); 19192 } 19193 Vars.push_back(RefExpr); 19194 } 19195 19196 if (Vars.empty()) 19197 return nullptr; 19198 19199 return OMPExclusiveClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars); 19200 } 19201 19202 /// Tries to find omp_alloctrait_t type. 19203 static bool findOMPAlloctraitT(Sema &S, SourceLocation Loc, DSAStackTy *Stack) { 19204 QualType OMPAlloctraitT = Stack->getOMPAlloctraitT(); 19205 if (!OMPAlloctraitT.isNull()) 19206 return true; 19207 IdentifierInfo &II = S.PP.getIdentifierTable().get("omp_alloctrait_t"); 19208 ParsedType PT = S.getTypeName(II, Loc, S.getCurScope()); 19209 if (!PT.getAsOpaquePtr() || PT.get().isNull()) { 19210 S.Diag(Loc, diag::err_omp_implied_type_not_found) << "omp_alloctrait_t"; 19211 return false; 19212 } 19213 Stack->setOMPAlloctraitT(PT.get()); 19214 return true; 19215 } 19216 19217 OMPClause *Sema::ActOnOpenMPUsesAllocatorClause( 19218 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc, 19219 ArrayRef<UsesAllocatorsData> Data) { 19220 // OpenMP [2.12.5, target Construct] 19221 // allocator is an identifier of omp_allocator_handle_t type. 19222 if (!findOMPAllocatorHandleT(*this, StartLoc, DSAStack)) 19223 return nullptr; 19224 // OpenMP [2.12.5, target Construct] 19225 // allocator-traits-array is an identifier of const omp_alloctrait_t * type. 19226 if (llvm::any_of( 19227 Data, 19228 [](const UsesAllocatorsData &D) { return D.AllocatorTraits; }) && 19229 !findOMPAlloctraitT(*this, StartLoc, DSAStack)) 19230 return nullptr; 19231 llvm::SmallPtrSet<CanonicalDeclPtr<Decl>, 4> PredefinedAllocators; 19232 for (int I = 0; I < OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; ++I) { 19233 auto AllocatorKind = static_cast<OMPAllocateDeclAttr::AllocatorTypeTy>(I); 19234 StringRef Allocator = 19235 OMPAllocateDeclAttr::ConvertAllocatorTypeTyToStr(AllocatorKind); 19236 DeclarationName AllocatorName = &Context.Idents.get(Allocator); 19237 PredefinedAllocators.insert(LookupSingleName( 19238 TUScope, AllocatorName, StartLoc, Sema::LookupAnyName)); 19239 } 19240 19241 SmallVector<OMPUsesAllocatorsClause::Data, 4> NewData; 19242 for (const UsesAllocatorsData &D : Data) { 19243 Expr *AllocatorExpr = nullptr; 19244 // Check allocator expression. 19245 if (D.Allocator->isTypeDependent()) { 19246 AllocatorExpr = D.Allocator; 19247 } else { 19248 // Traits were specified - need to assign new allocator to the specified 19249 // allocator, so it must be an lvalue. 19250 AllocatorExpr = D.Allocator->IgnoreParenImpCasts(); 19251 auto *DRE = dyn_cast<DeclRefExpr>(AllocatorExpr); 19252 bool IsPredefinedAllocator = false; 19253 if (DRE) 19254 IsPredefinedAllocator = PredefinedAllocators.count(DRE->getDecl()); 19255 if (!DRE || 19256 !(Context.hasSameUnqualifiedType( 19257 AllocatorExpr->getType(), DSAStack->getOMPAllocatorHandleT()) || 19258 Context.typesAreCompatible(AllocatorExpr->getType(), 19259 DSAStack->getOMPAllocatorHandleT(), 19260 /*CompareUnqualified=*/true)) || 19261 (!IsPredefinedAllocator && 19262 (AllocatorExpr->getType().isConstant(Context) || 19263 !AllocatorExpr->isLValue()))) { 19264 Diag(D.Allocator->getExprLoc(), diag::err_omp_var_expected) 19265 << "omp_allocator_handle_t" << (DRE ? 1 : 0) 19266 << AllocatorExpr->getType() << D.Allocator->getSourceRange(); 19267 continue; 19268 } 19269 // OpenMP [2.12.5, target Construct] 19270 // Predefined allocators appearing in a uses_allocators clause cannot have 19271 // traits specified. 19272 if (IsPredefinedAllocator && D.AllocatorTraits) { 19273 Diag(D.AllocatorTraits->getExprLoc(), 19274 diag::err_omp_predefined_allocator_with_traits) 19275 << D.AllocatorTraits->getSourceRange(); 19276 Diag(D.Allocator->getExprLoc(), diag::note_omp_predefined_allocator) 19277 << cast<NamedDecl>(DRE->getDecl())->getName() 19278 << D.Allocator->getSourceRange(); 19279 continue; 19280 } 19281 // OpenMP [2.12.5, target Construct] 19282 // Non-predefined allocators appearing in a uses_allocators clause must 19283 // have traits specified. 19284 if (!IsPredefinedAllocator && !D.AllocatorTraits) { 19285 Diag(D.Allocator->getExprLoc(), 19286 diag::err_omp_nonpredefined_allocator_without_traits); 19287 continue; 19288 } 19289 // No allocator traits - just convert it to rvalue. 19290 if (!D.AllocatorTraits) 19291 AllocatorExpr = DefaultLvalueConversion(AllocatorExpr).get(); 19292 DSAStack->addUsesAllocatorsDecl( 19293 DRE->getDecl(), 19294 IsPredefinedAllocator 19295 ? DSAStackTy::UsesAllocatorsDeclKind::PredefinedAllocator 19296 : DSAStackTy::UsesAllocatorsDeclKind::UserDefinedAllocator); 19297 } 19298 Expr *AllocatorTraitsExpr = nullptr; 19299 if (D.AllocatorTraits) { 19300 if (D.AllocatorTraits->isTypeDependent()) { 19301 AllocatorTraitsExpr = D.AllocatorTraits; 19302 } else { 19303 // OpenMP [2.12.5, target Construct] 19304 // Arrays that contain allocator traits that appear in a uses_allocators 19305 // clause must be constant arrays, have constant values and be defined 19306 // in the same scope as the construct in which the clause appears. 19307 AllocatorTraitsExpr = D.AllocatorTraits->IgnoreParenImpCasts(); 19308 // Check that traits expr is a constant array. 19309 QualType TraitTy; 19310 if (const ArrayType *Ty = 19311 AllocatorTraitsExpr->getType()->getAsArrayTypeUnsafe()) 19312 if (const auto *ConstArrayTy = dyn_cast<ConstantArrayType>(Ty)) 19313 TraitTy = ConstArrayTy->getElementType(); 19314 if (TraitTy.isNull() || 19315 !(Context.hasSameUnqualifiedType(TraitTy, 19316 DSAStack->getOMPAlloctraitT()) || 19317 Context.typesAreCompatible(TraitTy, DSAStack->getOMPAlloctraitT(), 19318 /*CompareUnqualified=*/true))) { 19319 Diag(D.AllocatorTraits->getExprLoc(), 19320 diag::err_omp_expected_array_alloctraits) 19321 << AllocatorTraitsExpr->getType(); 19322 continue; 19323 } 19324 // Do not map by default allocator traits if it is a standalone 19325 // variable. 19326 if (auto *DRE = dyn_cast<DeclRefExpr>(AllocatorTraitsExpr)) 19327 DSAStack->addUsesAllocatorsDecl( 19328 DRE->getDecl(), 19329 DSAStackTy::UsesAllocatorsDeclKind::AllocatorTrait); 19330 } 19331 } 19332 OMPUsesAllocatorsClause::Data &NewD = NewData.emplace_back(); 19333 NewD.Allocator = AllocatorExpr; 19334 NewD.AllocatorTraits = AllocatorTraitsExpr; 19335 NewD.LParenLoc = D.LParenLoc; 19336 NewD.RParenLoc = D.RParenLoc; 19337 } 19338 return OMPUsesAllocatorsClause::Create(Context, StartLoc, LParenLoc, EndLoc, 19339 NewData); 19340 } 19341 19342 OMPClause *Sema::ActOnOpenMPAffinityClause( 19343 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation ColonLoc, 19344 SourceLocation EndLoc, Expr *Modifier, ArrayRef<Expr *> Locators) { 19345 SmallVector<Expr *, 8> Vars; 19346 for (Expr *RefExpr : Locators) { 19347 assert(RefExpr && "NULL expr in OpenMP shared clause."); 19348 if (isa<DependentScopeDeclRefExpr>(RefExpr) || RefExpr->isTypeDependent()) { 19349 // It will be analyzed later. 19350 Vars.push_back(RefExpr); 19351 continue; 19352 } 19353 19354 SourceLocation ELoc = RefExpr->getExprLoc(); 19355 Expr *SimpleExpr = RefExpr->IgnoreParenImpCasts(); 19356 19357 if (!SimpleExpr->isLValue()) { 19358 Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item) 19359 << 1 << 0 << RefExpr->getSourceRange(); 19360 continue; 19361 } 19362 19363 ExprResult Res; 19364 { 19365 Sema::TentativeAnalysisScope Trap(*this); 19366 Res = CreateBuiltinUnaryOp(ELoc, UO_AddrOf, SimpleExpr); 19367 } 19368 if (!Res.isUsable() && !isa<OMPArraySectionExpr>(SimpleExpr) && 19369 !isa<OMPArrayShapingExpr>(SimpleExpr)) { 19370 Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item) 19371 << 1 << 0 << RefExpr->getSourceRange(); 19372 continue; 19373 } 19374 Vars.push_back(SimpleExpr); 19375 } 19376 19377 return OMPAffinityClause::Create(Context, StartLoc, LParenLoc, ColonLoc, 19378 EndLoc, Modifier, Vars); 19379 } 19380